;-*- Mode:LISP; Package:STEVE; Readtable:CL; Base:10 -*- ;Copyright (c) May 1983 by Christopher Eliot ; and Massachusetts Institute of Technology. All rights reserved. ;Permission to copy all or part of this material is granted, provided ; that the copies are not made or distributed for resale, the MIT ; copyright notice and reference to the source file and the software ; distribution version appear, and that notice is given that copying ; is by permission of Massachusetts Institute of Technology. ; ;Defun-search and Buffer-search ; (defvar *function-search*) (defvar *last-defun-search-string* "") (defun defun-search (buffer string &key (first-line (buffer-content buffer)) (delimited nil)) (cond ((null delimited) (loop for line first first-line then (line-next line) while (not (null line)) if (and (+p (line-char-count line)) (char= (char (line-chars line) 0) left-paren) (string-search-for-substring (line-chars line) string)) return line)) (t (loop for line first first-line then (line-next line) while (not (null line)) if (and (+p (line-char-count line)) (char= (char (line-chars line) 0) left-paren) (delimited-substring-search (line-chars line) string)) return line)))) (defun host-specified (string-path) (let ((p1 (string-search-char #\: string-path))) (and (not (null p1)) (not (null (string-search-char #\: string-path (1+& p1))))))) (defun find-module-source-file (module) (let* ((vasl-file (si:module-loaded-file module)) (path) (host)) (setq vasl-file (car (errset (pathname vasl-file) nil))) (setq path (cond ((null vasl-file) nil) ((probe-file vasl-file) (setq path (si:vas-source-file vasl-file))) (t (setq path (send (send vasl-file :new-type "lisp") :new-version nil))))) (when (and (stringp path) (host-specified path)) ;; Si:Vas-Source-File may return a path with a HOST like HTJR. ;; If the host is not in the host tables then PATHNAME will ;; bomb. Since there is only one host, and we don't want ;; to force people to add all NIL-GROUP machines to their ;; host tables we just kludge the string to remove the host. ;; The next line was missing the zero. That looks ;; like a random mistake someone made with the editor. ;; 4/17/84 --CRE (setq host (substring path 0 (string-search-char #\: path))) ;; strip off the host and only one colon (just to be safe) (setq path (substring path (1+& (string-search-char #\: path)))) ;; if there is another colon, strip it off too (when (char= (char path 0) #\:) (setq path (substring path 1)))) (setq path (car (errset (send (pathname path) :new-version nil) nil))) ;; Errset is used because some VASL files have bad filenames in them. (cond ((null path)) ((probe-file path)) ((probe-file (send path :new-device nil)) (setq path (send path :new-device nil))) ((and (string-equal host "HTJR") ; *** kludge! *** (probe-file (send path :new-device "nil$disk"))) (setq path (send path :new-device "nil$disk")))) (and (probe-file path) path))) ;Search for a function. Load the source file if it can be found. ;Search all buffers for it if it is not defined. ;Values are the same as global-defun-search. ;What about packages? (defun symbol-from-string (string) (with-input-from-string (foo (string-append (string-upcase string) " ")) (read foo))) (defun function-search (function) (when (not (symbolp function)) (setq function (symbol-from-string function))) (let ((module) (path)) (cond ((or (null function) (not (fboundp function)) (null (setq module (whereis function))) (null (setq path (find-module-source-file module)))) (global-defun-search (string function) :delimited (and function (fboundp function)))) (t (let ((line)) (with-error-line (format terminal-io "Pathname: ~a" (send path :string-for-editor)) (when (null (point-selected path :create (probe-file path))) (ed-warn "Cannot Locate Source File")) (setq line (defun-search *editor-buffer* (string function) :delimited t))) (values *editor-buffer* line)))))) ;(defun find-file-from-pathname-soft (pathname) ; (let ((point (point pathname :create nil))) ; (cond ((not (null point)) ; (select-point-in-current-window point) ; t) ; ((null (probe-file pathname)) ; nil) ; (t (setq point (make-point (send pathname :name) nil)) ; (setf (buffer-file-name (edit-cursor-buffer point)) pathname) ; (select-point-in-current-window point) ; (read-file-into-buffer pathname) ; t)))) ; ;(defun find-file-from-pathname-soft (pathname) ; (point-selected pathname :create (probe-file pathname))) (defun global-defun-search (string &key (buffers *all-buffers*) (first-buffer-first-line nil) (delimited nil)) (loop for buffer in buffers for search first (defun-search buffer string :first-line first-buffer-first-line :delimited delimited) then (defun-search buffer string :delimited delimited) if (not (null search)) return (values buffer search))) (defun find-defun (function-name &aux (mark (copy-bp *editor-cursor*))) (multiple-value-bind (buffer line) (global-defun-search function-name) (unless (or (null buffer) (null line)) (edit-cursor-goto buffer line 0) (push-mark-no-copy mark) (reposition-window) t))) (defun find-function (function-name &aux (mark (copy-bp *editor-cursor*))) (multiple-value-bind (buffer line) (function-search function-name) (unless (null buffer) (edit-cursor-goto buffer (or line (buffer-content buffer)) 0) (push-mark-no-copy mark) (cond ((null line) (ed-warn "The function seems to have been deleted")) (t (reposition-window))) t))) (editor-bind-key #\meta-. defun-search-all-buffers) (defun defun-search-all-buffers (&aux type) (setq type (if (argument?) (not *function-search*) *function-search*)) (with-query-line (cond ((null type) (oustr "Global Defun Search: " terminal-io)) (t (oustr "Find Function: " terminal-io))) (let ((string (si:ttyscanner #'readline-with-exit terminal-io terminal-io () T 0)) (*argument* 1) (argument-supplied? nil)) ;For set-file-read-only. (when (not (stringp string)) (ed-warn "Aborted")) (setq *last-defun-search-string* string) (unless (if (not (null type)) (find-function string) (find-defun string)) (ed-warn "Not Found")))) nil) (editor-bind-key #\control-meta-. defun-search-continue) (defun defun-search-continue () (let ((buffers (loop for (buffer . rest) on *all-buffers* if (eq buffer *editor-buffer*) return (cons buffer rest))) (buffer) (line)) (multiple-value (buffer line) (global-defun-search *last-defun-search-string* :buffer buffers :first-buffer-first-line (line-next (bp-line *editor-cursor*)) :delimited nil)) (when (or (null buffer) (null line)) (ed-warn "Not Found")) (let ((mark (copy-bp *editor-cursor*))) (edit-cursor-goto buffer line 0) (push-mark-no-copy mark)) (reposition-window)) nil)