1 ;;; -*- Mode: Emacs-Lisp -*-
5 ;;; This file is part of ILISP.
6 ;;; Please refer to the file COPYING for copyrights and licensing
8 ;;; Please refer to the file ACKNOWLEGDEMENTS for an (incomplete) list
9 ;;; of present and past contributors.
11 ;;; $Id: ilisp-src.el,v 1.4 2001-07-02 09:40:49 youngs Exp $
15 ;;; See ilisp.el for more information.
17 ;;;%Source file operations
18 (unless (boundp 'tags-file-name)
19 (defvar tags-file-name nil))
21 (defvar lisp-last-definition nil "Last definition (name type) looked for.")
23 (defvar lisp-last-file nil "Last used source file.")
25 (defvar lisp-first-point nil "First point found in last source file.")
27 (defvar lisp-last-point nil "Last point in last source file.")
29 (defvar lisp-last-locator nil "Last source locator used.")
31 (defvar lisp-search nil "Set to T when searching for definitions.")
33 (defvar lisp-using-tags nil "Set to T when using tags.")
36 (defvar lisp-edit-files t
37 "Controls editing of of source files through Emacs' buffers.
38 If T, then buffers in one of 'lisp-source-modes' will be searched by
39 'edit-definitions-lisp' if the source cannot be found through the
40 inferior LISP. It can also be a list of files to edit definitions
41 from set up by \(\\[lisp-directory]). If it is set to nil, then no
42 additional files will be searched.")
45 (defun lisp-extensions ()
46 "Return a regexp for matching file extensions.
47 The extensions are those of files that enter one of
48 'lisp-source-modes' according to 'auto-mode-alist'."
49 (let ((entries auto-mode-alist)
51 (dolist (entry entries)
52 (when (memq (cdr entry) lisp-source-modes)
54 (concat "\\|" (car entry) extensions))))
55 (substring extensions 2)))
58 (defun lisp-directory (directory add)
59 "Edit the files in DIRECTORY.
60 The files must have an 'auto-mode' alist entry in 'lisp-source-modes'.
61 With a positive prefix, add the files on to the already existing
62 files. With a negative prefix, clear the list. In either case set
63 tags-file-name to nil so that tags are not used."
65 (list (if (not (eq current-prefix-arg '-))
66 (read-file-name "Lisp Directory: "
71 (setq tags-file-name nil)
73 (progn (setq lisp-edit-files t)
74 (message "No current lisp directory"))
76 (message "Added %s as a lisp directory" directory)
77 (message "%s is the lisp directory" directory))
78 (setq directory (expand-file-name directory))
79 (if (file-directory-p directory)
82 (directory-files directory t (lisp-extensions))
83 (if add (if (eq lisp-edit-files t) nil lisp-edit-files))))
84 (error "%s is not a directory" directory))))
88 (defun fix-source-filenames ()
89 "Apply the 'ilisp-source-directory-fixup-alist' to the current buffer.
90 (The buffer should be *Edit-Definitions*) The aim is to change any
91 pre-compiledsource-file locations to point to local source file
94 See 'ilisp-source-directory-fixup-alist'."
95 (let ((alist (ilisp-value 'ilisp-source-directory-fixup-alist t))
100 (setq cons (car alist))
101 (goto-char (point-min))
102 (if (re-search-forward (car cons) (point-max) t)
103 (replace-match (cdr cons)))
104 (setq alist (cdr alist)))))))
106 (defun lisp-setup-edit-definitions (message edit-files)
107 "Set up *Edit-Definitions* with MESSAGE.
108 If EDIT-FILES is T, insert all buffer filenames that are in one of
109 lisp-source-modes into the current buffer. If it is a list of files
110 set up by lisp-directory, insert those in the buffer. If it is a
111 string put that in the buffer."
114 ;; 19990804 Marco Antoniotti
115 ;; Are we sure we want to set 'lisp-using-tags' to nil?
116 (setq lisp-using-tags nil
117 lisp-search (not (stringp edit-files)))
118 (set-buffer (get-buffer-create "*Edit-Definitions*"))
124 (if (eq edit-files t)
125 (let ((buffers (buffer-list)))
127 (let ((buffer (car buffers)))
130 (and (memq major-mode lisp-source-modes)
131 (buffer-file-name buffer)))
132 (progn (insert ?\") (insert (buffer-file-name buffer))
134 (setq buffers (cdr buffers))))
135 (if (stringp edit-files)
136 (progn (insert edit-files)
137 ;; Remove garbage collection messages
138 (replace-regexp "^;[^\n]*\n" "")
139 (fix-source-filenames))
140 (let ((files edit-files))
145 (setq files (cdr files))))))
146 (goto-char (point-min))
148 (set-buffer-modified-p nil))
150 (substitute-command-keys
151 "Use \\[lisp-directory] to define source files."))))
154 (defun lisp-locate-definition (locator definition file point
157 "Use LOCATOR to find the next DEFINITION (symbol . type) in FILE.
158 Search starts at POINT, optionally BACKWARDS and POP to buffer. Return T
161 (if (not (file-exists-p file))
163 (message "File %s doesn't exist!" file)
166 (let* ((symbol (car definition))
167 (type (cdr definition))
168 (first (not (eq lisp-last-file file)))
169 (buffer (current-buffer))
171 (lisp-find-file file pop)
172 (if first (setq lisp-first-point (point)))
175 (goto-char (point-max))
181 (progn (forward-line 1) (beginning-of-line))))
183 (message "Search %s for %s" file symbol)
184 (message "Searching %s for %s %s" file type
185 (setq name (lisp-buffer-symbol symbol))))
186 (if (funcall locator symbol type first back)
188 (setq lisp-last-file file
189 lisp-last-point (point))
195 (message "Found %s %s definition" type name)
196 (message "Found %s"))
199 (goto-char lisp-first-point)
205 (defun lisp-next-file (back)
206 "Return the next filename in *Edit-Definitions*, or nil if none."
209 (set-buffer (get-buffer-create "*Edit-Definitions*"))
211 (progn (forward-line -1)
212 (if (looking-at "\n")
219 (skip-chars-forward "^\"")
221 (progn (bury-buffer (current-buffer))
223 (let* ((start (progn (forward-char 1) (point))))
224 (skip-chars-forward "^\"")
226 (prog1 (buffer-substring start (point))
228 (bury-buffer (current-buffer))))))
229 (if (not (eq file 't)) file)))
232 (defun lisp-next-definition (back pop)
233 "Go to the next definition from *Edit-Definitions*.
234 Movement is BACK with prefix and POPping. Return 'first if found
235 first time, 'none if no definition ever, T if another definition is
236 found, and nil if no more definitions are found."
244 (lisp-locate-definition ;Same file
246 lisp-last-definition lisp-last-file lisp-last-point back))
247 (let ((file (lisp-next-file back)))
249 (if (lisp-locate-definition
250 lisp-last-locator lisp-last-definition
252 (prog1 pop (setq pop nil)))
254 (setq result (if (not lisp-search) 'none)))
256 (set-buffer (window-buffer (selected-window)))
260 (defun next-definition-lisp (back &optional pop)
261 "Edit the next definition from *Edit-Definitions*.
262 Movement is BACK with prefix and optionally POPping or call
263 'tags-loop-continue' if using tags."
267 (let* ((result (lisp-next-definition back pop))
268 (symbol (car lisp-last-definition))
269 (type (cdr lisp-last-definition))
270 (name (if (not (eq type 't)) (lisp-buffer-symbol symbol))))
271 (cond ((or (eq result 'first) (eq result 't))
273 (message "Found %s %s definition" type name)
274 (message "Found %s" symbol)))
276 (error "Can't find %s %s definition" type name))
279 (error "No more %s %s definitions" type name)
280 (message "Done")))))))
283 ;;;%%Edit-definitions
284 (defun edit-definitions-lisp (symbol type &optional stay search locator)
285 "Find the source files for the TYPE definitions of SYMBOL.
286 If STAY, use the same window. If SEARCH, do not look for symbol in
287 inferior LISP. The definition will be searched for through the
288 inferior LISP and if not found it will be searched for in the current
289 tags file and if not found in the files in lisp-edit-files set up by
290 \(\\[lisp-directory]) or the buffers in one of lisp-source-modes if
291 lisp-edit-files is T. If lisp-edit-files is nil, no search will be
292 done if not found through the inferior LISP. TYPES are from
293 ilisp-source-types which is an alist of symbol strings or list
294 strings. With a negative prefix, look for the current symbol as the
295 first type in ilisp-source-types."
297 (let* ((types (ilisp-value 'ilisp-source-types t))
298 (default (if types (car (car types))))
299 (function (lisp-function-name))
300 (symbol (lisp-buffer-symbol function)))
301 (if (lisp-minus-prefix)
302 (list function default)
303 (list (ilisp-read-symbol
304 (format "Edit Definition [%s]: " symbol)
309 (ilisp-completing-read
310 (format "Type [%s]: " default)
312 (let* ((name (lisp-buffer-symbol symbol))
313 (symbol-name (lisp-symbol-name symbol))
314 (command (ilisp-value 'ilisp-find-source-command t))
316 (if (and command (not search) (comint-check-proc ilisp-buffer))
318 (format command symbol-name
319 (lisp-symbol-package symbol)
321 (concat "Finding " type " " name " definitions")
324 (result (and source (lisp-last-line source)))
325 (source-ok (not (or (ilisp-value 'comint-errorp t)
327 (string-match "nil" (car result)))))
331 (if (and tags-file-name (not source-ok))
332 (progn (setq lisp-using-tags t)
335 ;; Search through all files listed in tags table
336 (setq tags-loop-scan (list locator
339 tags-loop-operate nil)
340 (tags-loop-continue t))
343 (if (string-match "Lucid" emacs-version)
344 (find-tag symbol-name stay)
345 (find-tag symbol-name nil stay))))
349 (setq lisp-last-definition (cons symbol type)
351 lisp-last-locator (or locator (ilisp-value 'ilisp-locator)))
352 (lisp-setup-edit-definitions
353 (format "%s %s definitions:" type name)
354 (if source-ok (cdr result) lisp-edit-files))
355 (next-definition-lisp nil t))))))
358 (defun lisp-locate-search (pattern type first back)
359 "Find PATTERN in the current buffer."
361 (search-backward pattern nil t)
362 (search-forward pattern nil t)))
365 (defun lisp-locate-regexp (regexp type first back)
366 "Find REGEXP in the current buffer."
368 (re-search-backward regexp nil t)
369 (re-search-forward regexp nil t)))
373 (defvar lisp-last-pattern nil "Last search regexp.")
375 (defun search-lisp (pattern regexp)
376 "Search for PATTERN through the files or buffers.
377 Search for file in 'lisp-edit-files' if it is a list or the
378 current buffers in one of 'lisp-source-modes' otherwise. If
379 lisp-edit-files is nil, no search will be done. If called with a
380 prefix, search for regexp. If there is a tags file, call 'tags-search'
383 (list (read-string (if current-prefix-arg
384 "Search for regexp: "
385 "Search for: ") lisp-last-pattern)
388 (progn (setq lisp-using-tags t)
389 (tags-search (if regexp pattern (regexp-quote pattern))))
390 (setq lisp-last-pattern pattern
391 lisp-last-definition (cons pattern t)
393 lisp-last-locator (if regexp
395 'lisp-locate-search))
396 (lisp-setup-edit-definitions (format "Searching for %s:" pattern)
398 (next-definition-lisp nil nil)))
401 (defvar lisp-last-replace nil "Last replace regexp.")
403 (defun replace-lisp (old new regexp)
404 "Query replace OLD by NEW through the files or the current buffers.
405 The query is done in 'lisp-edit-files' if it is a list and the current
406 buffers in one of 'lisp-source-modes' otherwise. If 'lisp-edit-files'
407 is NIL, no search will be done. If called with a prefix, replace
408 regexps. If there is a tags file, then call tags-query-replace
411 (let ((old (read-string (if current-prefix-arg
413 "Replace: ") lisp-last-pattern)))
415 (read-string (if current-prefix-arg
416 (format "Replace regexp %s by: " old)
417 (format "Replace %s by: " old))
419 current-prefix-arg)))
420 (cond (tags-file-name
421 (setq lisp-using-tags t)
422 (tags-query-replace (if regexp old (regexp-quote old))
425 (setq lisp-last-pattern old
426 lisp-last-replace new)
427 (lisp-setup-edit-definitions
428 (format "Replacing %s by %s:\n\n" old new)
431 (while (setq file (lisp-next-file nil))
432 (lisp-find-file file)
433 (let ((point (point)))
434 (goto-char (point-min))
436 (re-search-forward old nil t)
437 (search-forward old nil t))
438 (progn (beginning-of-line)
440 (query-replace-regexp old new)
441 (query-replace old new)))
442 (goto-char point))))))))
445 (defvar lisp-callers nil
446 "T if we found callers through inferior LISP.")
449 (defun who-calls-lisp (function &optional no-show)
450 "Put the functions that call FUNCTION into the buffer *All-Callers*.
451 Show the buffer *All-Callers* unless NO-SHOW is T. Return T if successful."
453 (let* ((function (lisp-defun-name))
454 (symbol (lisp-buffer-symbol function)))
455 (if (lisp-minus-prefix)
457 (list (ilisp-read-symbol
458 (format "Who Calls [%s]: " symbol)
461 (let* ((name (lisp-buffer-symbol function))
462 (command (ilisp-value 'ilisp-callers-command t))
467 (lisp-symbol-name function)
468 (lisp-symbol-package function))
469 (concat "Finding callers of " name)
471 (last-line (if callers (lisp-last-line callers)))
472 (case-fold-search t))
473 (set-buffer (get-buffer-create "*All-Callers*"))
475 (insert (format "All callers of function %s:\n\n" name))
476 (if (and command (not (ilisp-value 'comint-errorp t)))
477 (if (string-match "nil" (car last-line))
478 (error "%s has no callers" name)
480 (insert (cdr last-line))
481 (goto-char (point-min))
482 ;; Remove garbage collection messages
483 (replace-regexp "^;[^\n]*\n" "")
484 (goto-char (point-min))
487 (if (ilisp-temp-buffer-show-function)
488 (funcall (ilisp-temp-buffer-show-function)
489 (get-buffer "*All-Callers*"))
490 (view-buffer "*All-Callers*")))
492 (insert "Using the current source files to find callers.")
496 (defun next-caller-lisp (back &optional pop)
497 "Edit the next caller from *All-Callers*.
498 With prefix, edit the previous caller. If it can't get caller
499 information from the inferior LISP, this will search using the current
500 source files. See lisp-directory."
503 (if (not lisp-callers)
504 (next-definition-lisp back pop)
505 (set-buffer (get-buffer-create "*All-Callers*"))
506 (if back (forward-line -1))
507 (skip-chars-forward " \t\n")
510 (bury-buffer (current-buffer))
511 (error "No more callers"))
512 (let* ((start (point))
515 (skip-chars-forward "^ \t\n")
516 (buffer-substring start (point)))))
517 (bury-buffer (current-buffer))
518 (edit-definitions-lisp (lisp-string-to-symbol caller-function)
519 (car (car (ilisp-value 'ilisp-source-types)))
523 (defun edit-callers-lisp (function)
524 "Edit the callers of FUNCTION.
525 With a minus prefix use the symbol at the start of the current defun."
527 (let* ((function (lisp-defun-name)))
528 (if (lisp-minus-prefix)
530 (list (ilisp-read-symbol
531 (format "Edit callers of [%s]: "
532 (lisp-buffer-symbol function))
535 (if (save-excursion (setq lisp-callers (who-calls-lisp function t)))
537 (setq lisp-last-locator (ilisp-value 'ilisp-calls-locator))
538 (next-caller-lisp nil t))
539 (edit-definitions-lisp function "calls" nil t
540 (ilisp-value 'ilisp-calls-locator))))
543 (defun lisp-re (back format &rest args)
544 "Search BACK if T using FORMAT applied to ARGS."
545 (let ((regexp (apply 'format format args)))
547 (re-search-backward regexp nil t)
548 (re-search-forward regexp nil t))))
551 (defun lisp-locate-ilisp (symbol type first back)
552 "Find SYMBOL's TYPE definition in the current file.
553 Return T if successful. A definition is of the form
554 \(def<whitespace>(?name<whitespace>."
556 "^[ \t\n]*(def[^ \t\n]*[ \t\n]+(?%s[ \t\n(]+"
557 (regexp-quote (lisp-symbol-name symbol))))
560 (defun lisp-locate-calls (symbol type first back)
561 "Locate calls to SYMBOL."
562 (lisp-re back "\\(#'\\|(\\|'\\)%s\\([ \t\n]+\\|)\\)"
563 (regexp-quote (lisp-buffer-symbol symbol))))
568 ;;; ilisp-cl-source-locater-patterns --
572 ;;; 19990804 Marco Antoniotti
573 ;;; The new ones (method and generic-fucntion) should be carefully checked.
575 (defvar ilisp-cl-source-locater-patterns
577 "^\\(
\ 6.\\)?[ \t\n]*(def[^ \t\n
\ 6]*\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)(setf\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)%s[ \t\n]*\\(
\ 6.\\)?[ \t\n]*)")
580 "^\\(
\ 6.\\)?[ \t\n]*(defun\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)%s[ \t\n(
\ 6]")
583 "^\\(
\ 6.\\)?[ \t\n]*(defmacro\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)%s[ \t\n(
\ 6]")
586 "^\\(
\ 6.\\)?[ \t\n]*(def\\(\\(var\\)\\|\\(parameter\\)\\|constant\\)\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)%s[ \t\n(
\ 6]")
589 "^\\(
\ 6.\\)?[ \t\n]*(defstruct\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)(?[ \t\n]*\\(
\ 6.\\)?[ \t\n]*%s[ \t\n(
\ 6]")
592 "^\\(
\ 6.\\)?[ \t\n]*(deftype\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)%s[ \t\n(
\ 6]")
595 "^\\(
\ 6.\\)?[ \t\n]*(defclass\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)%s[ \t\n(
\ 6]")
598 "^\\(
\ 6.\\)?[ \t\n]*(defmethod\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)%s[ \t\n(
\ 6]")
601 "^\\(
\ 6.\\)?[ \t\n]*(defgeneric\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)%s[ \t\n(
\ 6]")
605 (defun ilisp-locate-clisp-defn (name type back)
606 (let ((pattern (car (cdr (assoc (intern type)
607 ilisp-cl-source-locater-patterns)))))
609 (lisp-re back pattern name))))
613 (defun ilisp-locate-clos-method (name type back)
614 (if (string-match "(\\([^(]*\\)\\(([^)]*)\\)" type)
615 (let* ((quals (substring type (match-beginning 1) (match-end 1)))
617 (read (substring type (match-beginning 2) (match-end 2))))
620 (while (setq position (string-match
621 "\\([ \t\n]+
\ 6.[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\|[ \t\n]+\\)"
624 (concat (substring quals 0 position)
625 "\\([ \t\n]+
\ 6.[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\|[ \t\n]+\\)"
626 (substring quals (match-end 0)))))
632 "[ \t\n]*\\(
\ 6.\\)?[ \t\n]*([ \t\n]*\\(
\ 6.\\)?[ \t\n]*[^ \t\n
\ 6]*\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)%s[ \t\n]*\\(
\ 6.\\)?[ \t\n]*"
636 "^\\(
\ 6.\\)?[ \t\n]*(def[^ \t\n
\ 6]*\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)%s\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)%s[^ \t\n
\ 6]*([^ \t\n
\ 6]*%s"
637 name quals class-re))))
642 (defun lisp-locate-clisp (symbol type first back)
643 "Try to find SYMBOL's TYPE definition in the current buffer.
644 Return T if sucessful. FIRST is T if this is the first time in a
645 file. BACK is T to go backwards."
647 (let* ((name (regexp-quote (lisp-symbol-name symbol)))
649 ;; Automatically generated defstruct accessors
650 (if (string-match "-" name)
651 (let ((struct (substring name 0 (1- (match-end 0)))))
653 "^\\(
\ 6.\\)?[ \t\n]*(def[^ \t\n
\ 6]*\\([ \t\n]+\\(
\ 6.\\)?\\|\\|[ \t\n]*
\ 6.[ \t\n]+\\)(?%s[ \t\n)
\ 6]\\|:conc-name\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)%s-"
655 ;; Defclass accessors
657 "\\(:accessor\\|:writer\\|:reader\\)\\([ \t\n]+\\(
\ 6.\\)?+[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)%s[ \t\n)
\ 6]"))
659 (if (equal type "any")
663 "^\\(
\ 6.\\)?[ \t\n]*(def[^ \t\n
\ 6]*\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)\\((setf\\([ \t\n]+\\(
\ 6.\\)?[ \t\n]*\\|[ \t\n]*
\ 6.[ \t\n]+\\)\\|(?[ \t\n]*\\(
\ 6.\\)?[ \t\n]*\\)%s[ \t\n)
\ 6]"
664 (if prefix (concat "\\|" prefix))
669 ;; (qualifiers* (type1 type2 ...))
670 (ilisp-locate-clos-method name type back)
672 (ilisp-locate-clisp-defn name type back)
675 (when first (lisp-locate-ilisp symbol type first back))
676 ;; Automatically generated defstruct accessors
677 (when (and first prefix) (lisp-re back prefix))
678 ;; Defclass accessors
679 (lisp-re back class name)
683 ;;;%% Locators for Scheme
685 ;;; Matthias Koeppe <mail.math.uni-magdeburg.de>
687 ;;; The standard locators would fail on "(define (thunk) ....)" and
688 ;;; report "(define (procedure ...) ....)" as a call to procedure.
690 (defun ilisp-locate-scheme-definition (symbol type first back)
691 "Find SYMBOL's TYPE definition in the current file. Return T if successful.
692 This is the Scheme counterpart of `lisp-locate-ilisp'."
694 "[ \t\n]*(def[^ \t\n]*[ \t\n]+(*%s\[ \t\n()]"
695 (regexp-quote (lisp-symbol-name symbol))))
697 (defun ilisp-locate-scheme-calls (symbol type first back)
698 "Locate calls to SYMBOL.
699 This is the Scheme counterpart of `lisp-locate-calls'."
701 (format "[( \t\n]+%s[ \t\n()]+"
703 ;; Scheme has no package prefixes, so we use
704 ;; lisp-symbol-name instead of lisp-buffer-symbol.
705 (lisp-symbol-name symbol))))
706 (def-regexp "[ \t\n]*(def[^ \t\n]*[ \t\n]+(*")
708 (while (eq result 'unknown)
711 (re-search-backward call-regexp nil t)
712 (re-search-forward call-regexp nil t))
713 (if (not (save-excursion ; check whether definition
714 (goto-char (match-beginning 0))
715 (backward-sexp) (backward-char)
716 (looking-at def-regexp)))
718 (t (setq result nil))))
722 ;;; end of file -- ilisp-src.el --