]> code.delx.au - gnu-emacs/blob - lisp/progmodes/elisp-mode.el
-
[gnu-emacs] / lisp / progmodes / elisp-mode.el
1 ;;; elisp-mode.el --- Emacs Lisp mode -*- lexical-binding:t -*-
2
3 ;; Copyright (C) 1985-1986, 1999-2016 Free Software Foundation, Inc.
4
5 ;; Maintainer: emacs-devel@gnu.org
6 ;; Keywords: lisp, languages
7 ;; Package: emacs
8
9 ;; This file is part of GNU Emacs.
10
11 ;; GNU Emacs is free software: you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation, either version 3 of the License, or
14 ;; (at your option) any later version.
15
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
23
24 ;;; Commentary:
25
26 ;; The major mode for editing Emacs Lisp code.
27 ;; This mode is documented in the Emacs manual.
28
29 ;;; Code:
30
31 (require 'cl-generic)
32 (require 'lisp-mode)
33 (eval-when-compile (require 'cl-lib))
34
35 (define-abbrev-table 'emacs-lisp-mode-abbrev-table ()
36 "Abbrev table for Emacs Lisp mode.
37 It has `lisp-mode-abbrev-table' as its parent."
38 :parents (list lisp-mode-abbrev-table))
39
40 (defvar emacs-lisp-mode-syntax-table
41 (let ((table (make-syntax-table lisp--mode-syntax-table)))
42 (modify-syntax-entry ?\[ "(] " table)
43 (modify-syntax-entry ?\] ")[ " table)
44 table)
45 "Syntax table used in `emacs-lisp-mode'.")
46
47 (defvar emacs-lisp-mode-map
48 (let ((map (make-sparse-keymap "Emacs-Lisp"))
49 (menu-map (make-sparse-keymap "Emacs-Lisp"))
50 (lint-map (make-sparse-keymap))
51 (prof-map (make-sparse-keymap))
52 (tracing-map (make-sparse-keymap)))
53 (set-keymap-parent map lisp-mode-shared-map)
54 (define-key map "\e\t" 'completion-at-point)
55 (define-key map "\e\C-x" 'eval-defun)
56 (define-key map "\e\C-q" 'indent-pp-sexp)
57 (bindings--define-key map [menu-bar emacs-lisp]
58 (cons "Emacs-Lisp" menu-map))
59 (bindings--define-key menu-map [eldoc]
60 '(menu-item "Auto-Display Documentation Strings" eldoc-mode
61 :button (:toggle . (bound-and-true-p eldoc-mode))
62 :help "Display the documentation string for the item under cursor"))
63 (bindings--define-key menu-map [checkdoc]
64 '(menu-item "Check Documentation Strings" checkdoc
65 :help "Check documentation strings for style requirements"))
66 (bindings--define-key menu-map [re-builder]
67 '(menu-item "Construct Regexp" re-builder
68 :help "Construct a regexp interactively"))
69 (bindings--define-key menu-map [tracing] (cons "Tracing" tracing-map))
70 (bindings--define-key tracing-map [tr-a]
71 '(menu-item "Untrace All" untrace-all
72 :help "Untrace all currently traced functions"))
73 (bindings--define-key tracing-map [tr-uf]
74 '(menu-item "Untrace Function..." untrace-function
75 :help "Untrace function, and possibly activate all remaining advice"))
76 (bindings--define-key tracing-map [tr-sep] menu-bar-separator)
77 (bindings--define-key tracing-map [tr-q]
78 '(menu-item "Trace Function Quietly..." trace-function-background
79 :help "Trace the function with trace output going quietly to a buffer"))
80 (bindings--define-key tracing-map [tr-f]
81 '(menu-item "Trace Function..." trace-function
82 :help "Trace the function given as an argument"))
83 (bindings--define-key menu-map [profiling] (cons "Profiling" prof-map))
84 (bindings--define-key prof-map [prof-restall]
85 '(menu-item "Remove Instrumentation for All Functions" elp-restore-all
86 :help "Restore the original definitions of all functions being profiled"))
87 (bindings--define-key prof-map [prof-restfunc]
88 '(menu-item "Remove Instrumentation for Function..." elp-restore-function
89 :help "Restore an instrumented function to its original definition"))
90
91 (bindings--define-key prof-map [sep-rem] menu-bar-separator)
92 (bindings--define-key prof-map [prof-resall]
93 '(menu-item "Reset Counters for All Functions" elp-reset-all
94 :help "Reset the profiling information for all functions being profiled"))
95 (bindings--define-key prof-map [prof-resfunc]
96 '(menu-item "Reset Counters for Function..." elp-reset-function
97 :help "Reset the profiling information for a function"))
98 (bindings--define-key prof-map [prof-res]
99 '(menu-item "Show Profiling Results" elp-results
100 :help "Display current profiling results"))
101 (bindings--define-key prof-map [prof-pack]
102 '(menu-item "Instrument Package..." elp-instrument-package
103 :help "Instrument for profiling all function that start with a prefix"))
104 (bindings--define-key prof-map [prof-func]
105 '(menu-item "Instrument Function..." elp-instrument-function
106 :help "Instrument a function for profiling"))
107 ;; Maybe this should be in a separate submenu from the ELP stuff?
108 (bindings--define-key prof-map [sep-natprof] menu-bar-separator)
109 (bindings--define-key prof-map [prof-natprof-stop]
110 '(menu-item "Stop Native Profiler" profiler-stop
111 :help "Stop recording profiling information"
112 :enable (and (featurep 'profiler)
113 (profiler-running-p))))
114 (bindings--define-key prof-map [prof-natprof-report]
115 '(menu-item "Show Profiler Report" profiler-report
116 :help "Show the current profiler report"
117 :enable (and (featurep 'profiler)
118 (profiler-running-p))))
119 (bindings--define-key prof-map [prof-natprof-start]
120 '(menu-item "Start Native Profiler..." profiler-start
121 :help "Start recording profiling information"))
122
123 (bindings--define-key menu-map [lint] (cons "Linting" lint-map))
124 (bindings--define-key lint-map [lint-di]
125 '(menu-item "Lint Directory..." elint-directory
126 :help "Lint a directory"))
127 (bindings--define-key lint-map [lint-f]
128 '(menu-item "Lint File..." elint-file
129 :help "Lint a file"))
130 (bindings--define-key lint-map [lint-b]
131 '(menu-item "Lint Buffer" elint-current-buffer
132 :help "Lint the current buffer"))
133 (bindings--define-key lint-map [lint-d]
134 '(menu-item "Lint Defun" elint-defun
135 :help "Lint the function at point"))
136 (bindings--define-key menu-map [edebug-defun]
137 '(menu-item "Instrument Function for Debugging" edebug-defun
138 :help "Evaluate the top level form point is in, stepping through with Edebug"
139 :keys "C-u C-M-x"))
140 (bindings--define-key menu-map [separator-byte] menu-bar-separator)
141 (bindings--define-key menu-map [disas]
142 '(menu-item "Disassemble Byte Compiled Object..." disassemble
143 :help "Print disassembled code for OBJECT in a buffer"))
144 (bindings--define-key menu-map [byte-recompile]
145 '(menu-item "Byte-recompile Directory..." byte-recompile-directory
146 :help "Recompile every `.el' file in DIRECTORY that needs recompilation"))
147 (bindings--define-key menu-map [emacs-byte-compile-and-load]
148 '(menu-item "Byte-compile and Load" emacs-lisp-byte-compile-and-load
149 :help "Byte-compile the current file (if it has changed), then load compiled code"))
150 (bindings--define-key menu-map [byte-compile]
151 '(menu-item "Byte-compile This File" emacs-lisp-byte-compile
152 :help "Byte compile the file containing the current buffer"))
153 (bindings--define-key menu-map [separator-eval] menu-bar-separator)
154 (bindings--define-key menu-map [ielm]
155 '(menu-item "Interactive Expression Evaluation" ielm
156 :help "Interactively evaluate Emacs Lisp expressions"))
157 (bindings--define-key menu-map [eval-buffer]
158 '(menu-item "Evaluate Buffer" eval-buffer
159 :help "Execute the current buffer as Lisp code"))
160 (bindings--define-key menu-map [eval-region]
161 '(menu-item "Evaluate Region" eval-region
162 :help "Execute the region as Lisp code"
163 :enable mark-active))
164 (bindings--define-key menu-map [eval-sexp]
165 '(menu-item "Evaluate Last S-expression" eval-last-sexp
166 :help "Evaluate sexp before point; print value in echo area"))
167 (bindings--define-key menu-map [separator-format] menu-bar-separator)
168 (bindings--define-key menu-map [comment-region]
169 '(menu-item "Comment Out Region" comment-region
170 :help "Comment or uncomment each line in the region"
171 :enable mark-active))
172 (bindings--define-key menu-map [indent-region]
173 '(menu-item "Indent Region" indent-region
174 :help "Indent each nonblank line in the region"
175 :enable mark-active))
176 (bindings--define-key menu-map [indent-line]
177 '(menu-item "Indent Line" lisp-indent-line))
178 map)
179 "Keymap for Emacs Lisp mode.
180 All commands in `lisp-mode-shared-map' are inherited by this map.")
181
182 (defun emacs-lisp-byte-compile ()
183 "Byte compile the file containing the current buffer."
184 (interactive)
185 (if buffer-file-name
186 (byte-compile-file buffer-file-name)
187 (error "The buffer must be saved in a file first")))
188
189 (defun emacs-lisp-byte-compile-and-load ()
190 "Byte-compile the current file (if it has changed), then load compiled code."
191 (interactive)
192 (or buffer-file-name
193 (error "The buffer must be saved in a file first"))
194 (require 'bytecomp)
195 ;; Recompile if file or buffer has changed since last compilation.
196 (if (and (buffer-modified-p)
197 (y-or-n-p (format "Save buffer %s first? " (buffer-name))))
198 (save-buffer))
199 (byte-recompile-file buffer-file-name nil 0 t))
200
201 (defun emacs-lisp-macroexpand ()
202 "Macroexpand the form after point.
203 Comments in the form will be lost."
204 (interactive)
205 (let* ((start (point))
206 (exp (read (current-buffer)))
207 ;; Compute it before, since it may signal errors.
208 (new (macroexpand-1 exp)))
209 (if (equal exp new)
210 (message "Not a macro call, nothing to expand")
211 (delete-region start (point))
212 (pp new (current-buffer))
213 (if (bolp) (delete-char -1))
214 (indent-region start (point)))))
215
216 (defcustom emacs-lisp-mode-hook nil
217 "Hook run when entering Emacs Lisp mode."
218 :options '(eldoc-mode imenu-add-menubar-index checkdoc-minor-mode)
219 :type 'hook
220 :group 'lisp)
221
222 ;;;###autoload
223 (define-derived-mode emacs-lisp-mode prog-mode "Emacs-Lisp"
224 "Major mode for editing Lisp code to run in Emacs.
225 Commands:
226 Delete converts tabs to spaces as it moves back.
227 Blank lines separate paragraphs. Semicolons start comments.
228
229 \\{emacs-lisp-mode-map}"
230 :group 'lisp
231 (defvar project-vc-external-roots-function)
232 (lisp-mode-variables nil nil 'elisp)
233 (add-hook 'after-load-functions #'elisp--font-lock-flush-elisp-buffers)
234 (setq-local electric-pair-text-pairs
235 (append '((?\` . ?\') (?‘ . ?’)) electric-pair-text-pairs))
236 (setq-local electric-quote-string t)
237 (setq imenu-case-fold-search nil)
238 (add-function :before-until (local 'eldoc-documentation-function)
239 #'elisp-eldoc-documentation-function)
240 (add-hook 'xref-backend-functions #'elisp--xref-backend nil t)
241 (setq-local project-vc-external-roots-function #'elisp-load-path-roots)
242 (add-hook 'completion-at-point-functions
243 #'elisp-completion-at-point nil 'local))
244
245 ;; Font-locking support.
246
247 (defun elisp--font-lock-flush-elisp-buffers (&optional file)
248 ;; We're only ever called from after-load-functions, load-in-progress can
249 ;; still be t in case of nested loads.
250 (when (or (not load-in-progress) file)
251 ;; FIXME: If the loaded file did not define any macros, there shouldn't
252 ;; be any need to font-lock-flush all the Elisp buffers.
253 (dolist (buf (buffer-list))
254 (with-current-buffer buf
255 (when (derived-mode-p 'emacs-lisp-mode)
256 ;; So as to take into account new macros that may have been defined
257 ;; by the just-loaded file.
258 (font-lock-flush))))))
259
260 ;;; Completion at point for Elisp
261
262 (defun elisp--local-variables-1 (vars sexp)
263 "Return the vars locally bound around the witness, or nil if not found."
264 (let (res)
265 (while
266 (unless
267 (setq res
268 (pcase sexp
269 (`(,(or `let `let*) ,bindings)
270 (let ((vars vars))
271 (when (eq 'let* (car sexp))
272 (dolist (binding (cdr (reverse bindings)))
273 (push (or (car-safe binding) binding) vars)))
274 (elisp--local-variables-1
275 vars (car (cdr-safe (car (last bindings)))))))
276 (`(,(or `let `let*) ,bindings . ,body)
277 (let ((vars vars))
278 (dolist (binding bindings)
279 (push (or (car-safe binding) binding) vars))
280 (elisp--local-variables-1 vars (car (last body)))))
281 (`(lambda ,_args)
282 ;; FIXME: Look for the witness inside `args'.
283 (setq sexp nil))
284 (`(lambda ,args . ,body)
285 (elisp--local-variables-1
286 (append (remq '&optional (remq '&rest args)) vars)
287 (car (last body))))
288 (`(condition-case ,_ ,e) (elisp--local-variables-1 vars e))
289 (`(condition-case ,v ,_ . ,catches)
290 (elisp--local-variables-1
291 (cons v vars) (cdr (car (last catches)))))
292 (`(quote . ,_)
293 ;; FIXME: Look for the witness inside sexp.
294 (setq sexp nil))
295 ;; FIXME: Handle `cond'.
296 (`(,_ . ,_)
297 (elisp--local-variables-1 vars (car (last sexp))))
298 (`elisp--witness--lisp (or vars '(nil)))
299 (_ nil)))
300 ;; We didn't find the witness in the last element so we try to
301 ;; backtrack to the last-but-one.
302 (setq sexp (ignore-errors (butlast sexp)))))
303 res))
304
305 (defun elisp--local-variables ()
306 "Return a list of locally let-bound variables at point."
307 (save-excursion
308 (skip-syntax-backward "w_")
309 (let* ((ppss (syntax-ppss))
310 (txt (buffer-substring-no-properties (or (car (nth 9 ppss)) (point))
311 (or (nth 8 ppss) (point))))
312 (closer ()))
313 (dolist (p (nth 9 ppss))
314 (push (cdr (syntax-after p)) closer))
315 (setq closer (apply #'string closer))
316 (let* ((sexp (condition-case nil
317 (car (read-from-string
318 (concat txt "elisp--witness--lisp" closer)))
319 ((invalid-read-syntax end-of-file) nil)))
320 (macroexpand-advice (lambda (expander form &rest args)
321 (condition-case nil
322 (apply expander form args)
323 (error form))))
324 (sexp
325 (unwind-protect
326 (progn
327 (advice-add 'macroexpand :around macroexpand-advice)
328 (macroexpand-all sexp))
329 (advice-remove 'macroexpand macroexpand-advice)))
330 (vars (elisp--local-variables-1 nil sexp)))
331 (delq nil
332 (mapcar (lambda (var)
333 (and (symbolp var)
334 (not (string-match (symbol-name var) "\\`[&_]"))
335 ;; Eliminate uninterned vars.
336 (intern-soft var)
337 var))
338 vars))))))
339
340 (defvar elisp--local-variables-completion-table
341 ;; Use `defvar' rather than `defconst' since defconst would purecopy this
342 ;; value, which would doubly fail: it would fail because purecopy can't
343 ;; handle the recursive bytecode object, and it would fail because it would
344 ;; move `lastpos' and `lastvars' to pure space where they'd be immutable!
345 (let ((lastpos nil) (lastvars nil))
346 (letrec ((hookfun (lambda ()
347 (setq lastpos nil)
348 (remove-hook 'post-command-hook hookfun))))
349 (completion-table-dynamic
350 (lambda (_string)
351 (save-excursion
352 (skip-syntax-backward "_w")
353 (let ((newpos (cons (point) (current-buffer))))
354 (unless (equal lastpos newpos)
355 (add-hook 'post-command-hook hookfun)
356 (setq lastpos newpos)
357 (setq lastvars
358 (mapcar #'symbol-name (elisp--local-variables))))))
359 lastvars)))))
360
361 (defun elisp--expect-function-p (pos)
362 "Return non-nil if the symbol at point is expected to be a function."
363 (or
364 (and (eq (char-before pos) ?')
365 (eq (char-before (1- pos)) ?#))
366 (save-excursion
367 (let ((parent (nth 1 (syntax-ppss pos))))
368 (when parent
369 (goto-char parent)
370 (and
371 (looking-at (concat "(\\(cl-\\)?"
372 (regexp-opt '("declare-function"
373 "function" "defadvice"
374 "callf" "callf2"
375 "defsetf"))
376 "[ \t\r\n]+"))
377 (eq (match-end 0) pos)))))))
378
379 (defun elisp--form-quoted-p (pos)
380 "Return non-nil if the form at POS is not evaluated.
381 It can be quoted, or be inside a quoted form."
382 ;; FIXME: Do some macro expansion maybe.
383 (save-excursion
384 (let ((state (syntax-ppss pos)))
385 (or (nth 8 state) ; Code inside strings usually isn't evaluated.
386 ;; FIXME: The 9th element is undocumented.
387 (let ((nesting (cons (point) (reverse (nth 9 state))))
388 res)
389 (while (and nesting (not res))
390 (goto-char (pop nesting))
391 (cond
392 ((or (eq (char-after) ?\[)
393 (progn
394 (skip-chars-backward " ")
395 (memq (char-before) '(?' ?` ?‘))))
396 (setq res t))
397 ((eq (char-before) ?,)
398 (setq nesting nil))))
399 res)))))
400
401 ;; FIXME: Support for Company brings in features which straddle eldoc.
402 ;; We should consolidate this, so that major modes can provide all that
403 ;; data all at once:
404 ;; - a function to extract "the reference at point" (may be more complex
405 ;; than a mere string, to distinguish various namespaces).
406 ;; - a function to jump to such a reference.
407 ;; - a function to show the signature/interface of such a reference.
408 ;; - a function to build a help-buffer about that reference.
409 ;; FIXME: Those functions should also be used by the normal completion code in
410 ;; the *Completions* buffer.
411
412 (defun elisp--company-doc-buffer (str)
413 (let ((symbol (intern-soft str)))
414 ;; FIXME: we really don't want to "display-buffer and then undo it".
415 (save-window-excursion
416 ;; Make sure we don't display it in another frame, otherwise
417 ;; save-window-excursion won't be able to undo it.
418 (let ((display-buffer-overriding-action
419 '(nil . ((inhibit-switch-frame . t)))))
420 (ignore-errors
421 (cond
422 ((fboundp symbol) (describe-function symbol))
423 ((boundp symbol) (describe-variable symbol))
424 ((featurep symbol) (describe-package symbol))
425 ((facep symbol) (describe-face symbol))
426 (t (signal 'user-error nil)))
427 (help-buffer))))))
428
429 (defun elisp--company-doc-string (str)
430 (let* ((symbol (intern-soft str))
431 (doc (if (fboundp symbol)
432 (documentation symbol t)
433 (documentation-property symbol 'variable-documentation t))))
434 (and (stringp doc)
435 (string-match ".*$" doc)
436 (match-string 0 doc))))
437
438 ;; can't (require 'find-func) in a preloaded file
439 (declare-function find-library-name "find-func" (library))
440 (declare-function find-function-library "find-func" (function &optional l-o v))
441
442 (defun elisp--company-location (str)
443 (let ((sym (intern-soft str)))
444 (cond
445 ((fboundp sym) (find-definition-noselect sym nil))
446 ((boundp sym) (find-definition-noselect sym 'defvar))
447 ((featurep sym)
448 (require 'find-func)
449 (cons (find-file-noselect (find-library-name
450 (symbol-name sym)))
451 0))
452 ((facep sym) (find-definition-noselect sym 'defface)))))
453
454 (defun elisp-completion-at-point ()
455 "Function used for `completion-at-point-functions' in `emacs-lisp-mode'."
456 (with-syntax-table emacs-lisp-mode-syntax-table
457 (let* ((pos (point))
458 (beg (condition-case nil
459 (save-excursion
460 (backward-sexp 1)
461 (skip-chars-forward "`',‘#")
462 (point))
463 (scan-error pos)))
464 (end
465 (unless (or (eq beg (point-max))
466 (member (char-syntax (char-after beg))
467 '(?\s ?\" ?\( ?\))))
468 (condition-case nil
469 (save-excursion
470 (goto-char beg)
471 (forward-sexp 1)
472 (skip-chars-backward "'’")
473 (when (>= (point) pos)
474 (point)))
475 (scan-error pos))))
476 ;; t if in function position.
477 (funpos (eq (char-before beg) ?\())
478 (quoted (elisp--form-quoted-p beg)))
479 (when (and end (or (not (nth 8 (syntax-ppss)))
480 (memq (char-before beg) '(?` ?‘))))
481 (let ((table-etc
482 (if (or (not funpos) quoted)
483 ;; FIXME: We could look at the first element of the list and
484 ;; use it to provide a more specific completion table in some
485 ;; cases. E.g. filter out keywords that are not understood by
486 ;; the macro/function being called.
487 (cond
488 ((elisp--expect-function-p beg)
489 (list nil obarray
490 :predicate #'fboundp
491 :company-doc-buffer #'elisp--company-doc-buffer
492 :company-docsig #'elisp--company-doc-string
493 :company-location #'elisp--company-location))
494 (quoted
495 (list nil obarray
496 ;; Don't include all symbols (bug#16646).
497 :predicate (lambda (sym)
498 (or (boundp sym)
499 (fboundp sym)
500 (featurep sym)
501 (symbol-plist sym)))
502 :annotation-function
503 (lambda (str) (if (fboundp (intern-soft str)) " <f>"))
504 :company-doc-buffer #'elisp--company-doc-buffer
505 :company-docsig #'elisp--company-doc-string
506 :company-location #'elisp--company-location))
507 (t
508 (list nil (completion-table-merge
509 elisp--local-variables-completion-table
510 (apply-partially #'completion-table-with-predicate
511 obarray
512 #'boundp
513 'strict))
514 :company-doc-buffer #'elisp--company-doc-buffer
515 :company-docsig #'elisp--company-doc-string
516 :company-location #'elisp--company-location)))
517 ;; Looks like a funcall position. Let's double check.
518 (save-excursion
519 (goto-char (1- beg))
520 (let ((parent
521 (condition-case nil
522 (progn (up-list -1) (forward-char 1)
523 (let ((c (char-after)))
524 (if (eq c ?\() ?\(
525 (if (memq (char-syntax c) '(?w ?_))
526 (read (current-buffer))))))
527 (error nil))))
528 (pcase parent
529 ;; FIXME: Rather than hardcode special cases here,
530 ;; we should use something like a symbol-property.
531 (`declare
532 (list t (mapcar (lambda (x) (symbol-name (car x)))
533 (delete-dups
534 ;; FIXME: We should include some
535 ;; docstring with each entry.
536 (append
537 macro-declarations-alist
538 defun-declarations-alist)))))
539 ((and (or `condition-case `condition-case-unless-debug)
540 (guard (save-excursion
541 (ignore-errors
542 (forward-sexp 2)
543 (< (point) beg)))))
544 (list t obarray
545 :predicate (lambda (sym) (get sym 'error-conditions))))
546 ((and (or ?\( `let `let*)
547 (guard (save-excursion
548 (goto-char (1- beg))
549 (when (eq parent ?\()
550 (up-list -1))
551 (forward-symbol -1)
552 (looking-at "\\_<let\\*?\\_>"))))
553 (list t obarray
554 :predicate #'boundp
555 :company-doc-buffer #'elisp--company-doc-buffer
556 :company-docsig #'elisp--company-doc-string
557 :company-location #'elisp--company-location))
558 (_ (list nil obarray
559 :predicate #'fboundp
560 :company-doc-buffer #'elisp--company-doc-buffer
561 :company-docsig #'elisp--company-doc-string
562 :company-location #'elisp--company-location
563 ))))))))
564 (nconc (list beg end)
565 (if (null (car table-etc))
566 (cdr table-etc)
567 (cons
568 (if (memq (char-syntax (or (char-after end) ?\s))
569 '(?\s ?>))
570 (cadr table-etc)
571 (apply-partially 'completion-table-with-terminator
572 " " (cadr table-etc)))
573 (cddr table-etc)))))))))
574
575 (defun lisp-completion-at-point (&optional _predicate)
576 (declare (obsolete elisp-completion-at-point "25.1"))
577 (elisp-completion-at-point))
578
579 ;;; Xref backend
580
581 (declare-function xref-make-bogus-location "xref" (message))
582 (declare-function xref-make "xref" (summary location))
583 (declare-function xref-collect-references "xref" (symbol dir))
584
585 (defun elisp--xref-backend () 'elisp)
586
587 ;; WORKAROUND: This is nominally a constant, but the text properties
588 ;; are not preserved thru dump if use defconst. See bug#21237.
589 (defvar elisp--xref-format
590 (let ((str "(%s %s)"))
591 (put-text-property 1 3 'face 'font-lock-keyword-face str)
592 (put-text-property 4 6 'face 'font-lock-function-name-face str)
593 str))
594
595 ;; WORKAROUND: This is nominally a constant, but the text properties
596 ;; are not preserved thru dump if use defconst. See bug#21237.
597 (defvar elisp--xref-format-extra
598 (let ((str "(%s %s %s)"))
599 (put-text-property 1 3 'face 'font-lock-keyword-face str)
600 (put-text-property 4 6 'face 'font-lock-function-name-face str)
601 str))
602
603 (defvar find-feature-regexp);; in find-func.el
604
605 (defun elisp--xref-make-xref (type symbol file &optional summary)
606 "Return an xref for TYPE SYMBOL in FILE.
607 TYPE must be a type in `find-function-regexp-alist' (use nil for
608 'defun). If SUMMARY is non-nil, use it for the summary;
609 otherwise build the summary from TYPE and SYMBOL."
610 (xref-make (or summary
611 (format elisp--xref-format (or type 'defun) symbol))
612 (xref-make-elisp-location symbol type file)))
613
614 (defvar elisp-xref-find-def-functions nil
615 "List of functions to be run from `elisp--xref-find-definitions' to add additional xrefs.
616 Called with one arg; the symbol whose definition is desired.
617 Each function should return a list of xrefs, or nil; the first
618 non-nil result supercedes the xrefs produced by
619 `elisp--xref-find-definitions'.")
620
621 (cl-defmethod xref-backend-definitions ((_backend (eql elisp)) identifier)
622 (require 'find-func)
623 ;; FIXME: use information in source near point to filter results:
624 ;; (dvc-log-edit ...) - exclude 'feature
625 ;; (require 'dvc-log-edit) - only 'feature
626 ;; Semantic may provide additional information
627 ;;
628 (let ((sym (intern-soft identifier)))
629 (when sym
630 (elisp--xref-find-definitions sym))))
631
632 (defun elisp--xref-find-definitions (symbol)
633 ;; The file name is not known when `symbol' is defined via interactive eval.
634 (let (xrefs)
635
636 (let ((temp elisp-xref-find-def-functions))
637 (while (and (null xrefs)
638 temp)
639 (setq xrefs (append xrefs (funcall (pop temp) symbol)))))
640
641 (unless xrefs
642 ;; alphabetical by result type symbol
643
644 ;; FIXME: advised function; list of advice functions
645 ;; FIXME: aliased variable
646
647 ;; Coding system symbols do not appear in ‘load-history’,
648 ;; so we can’t get a location for them.
649
650 (when (and (symbolp symbol)
651 (symbol-function symbol)
652 (symbolp (symbol-function symbol)))
653 ;; aliased function
654 (let* ((alias-symbol symbol)
655 (alias-file (symbol-file alias-symbol))
656 (real-symbol (symbol-function symbol))
657 (real-file (find-lisp-object-file-name real-symbol 'defun)))
658
659 (when real-file
660 (push (elisp--xref-make-xref nil real-symbol real-file) xrefs))
661
662 (when alias-file
663 (push (elisp--xref-make-xref 'defalias alias-symbol alias-file) xrefs))))
664
665 (when (facep symbol)
666 (let ((file (find-lisp-object-file-name symbol 'defface)))
667 (when file
668 (push (elisp--xref-make-xref 'defface symbol file) xrefs))))
669
670 (when (fboundp symbol)
671 (let ((file (find-lisp-object-file-name symbol (symbol-function symbol)))
672 generic doc)
673 (when file
674 (cond
675 ((eq file 'C-source)
676 ;; First call to find-lisp-object-file-name for an object
677 ;; defined in C; the doc strings from the C source have
678 ;; not been loaded yet. Second call will return "src/*.c"
679 ;; in file; handled by 't' case below.
680 (push (elisp--xref-make-xref nil symbol (help-C-file-name (symbol-function symbol) 'subr)) xrefs))
681
682 ((and (setq doc (documentation symbol t))
683 ;; This doc string is defined in cl-macs.el cl-defstruct
684 (string-match "Constructor for objects of type `\\(.*\\)'" doc))
685 ;; `symbol' is a name for the default constructor created by
686 ;; cl-defstruct, so return the location of the cl-defstruct.
687 (let* ((type-name (match-string 1 doc))
688 (type-symbol (intern type-name))
689 (file (find-lisp-object-file-name type-symbol 'define-type))
690 (summary (format elisp--xref-format-extra
691 'cl-defstruct
692 (concat "(" type-name)
693 (concat "(:constructor " (symbol-name symbol) "))"))))
694 (push (elisp--xref-make-xref 'define-type type-symbol file summary) xrefs)
695 ))
696
697 ((setq generic (cl--generic symbol))
698 ;; FIXME: move this to elisp-xref-find-def-functions, in cl-generic.el
699
700 ;; A generic function. If there is a default method, it
701 ;; will appear in the method table, with no
702 ;; specializers.
703 ;;
704 ;; If the default method is declared by the cl-defgeneric
705 ;; declaration, it will have the same location as the
706 ;; cl-defgeneric, so we want to exclude it from the
707 ;; result. In this case, it will have a null doc
708 ;; string. User declarations of default methods may also
709 ;; have null doc strings, but we hope that is
710 ;; rare. Perhaps this heuristic will discourage that.
711 (dolist (method (cl--generic-method-table generic))
712 (let* ((info (cl--generic-method-info method));; qual-string combined-args doconly
713 (specializers (cl--generic-method-specializers method))
714 (non-default nil)
715 (met-name (cons symbol specializers))
716 (file (find-lisp-object-file-name met-name 'cl-defmethod)))
717 (dolist (item specializers)
718 ;; default method has all 't' in specializers
719 (setq non-default (or non-default (not (equal t item)))))
720
721 (when (and file
722 (or non-default
723 (nth 2 info))) ;; assuming only co-located default has null doc string
724 (if specializers
725 (let ((summary (format elisp--xref-format-extra 'cl-defmethod symbol (nth 1 info))))
726 (push (elisp--xref-make-xref 'cl-defmethod met-name file summary) xrefs))
727
728 (let ((summary (format elisp--xref-format-extra 'cl-defmethod symbol "()")))
729 (push (elisp--xref-make-xref 'cl-defmethod met-name file summary) xrefs))))
730 ))
731
732 (if (and (setq doc (documentation symbol t))
733 ;; This doc string is created somewhere in
734 ;; cl--generic-make-function for an implicit
735 ;; defgeneric.
736 (string-match "\n\n(fn ARG &rest ARGS)" doc))
737 ;; This symbol is an implicitly defined defgeneric, so
738 ;; don't return it.
739 nil
740 (push (elisp--xref-make-xref 'cl-defgeneric symbol file) xrefs))
741 )
742
743 (t
744 (push (elisp--xref-make-xref nil symbol file) xrefs))
745 ))))
746
747 (when (boundp symbol)
748 ;; A variable
749 (let ((file (find-lisp-object-file-name symbol 'defvar)))
750 (when file
751 (cond
752 ((eq file 'C-source)
753 ;; The doc strings from the C source have not been loaded
754 ;; yet; help-C-file-name does that. Second call will
755 ;; return "src/*.c" in file; handled below.
756 (push (elisp--xref-make-xref 'defvar symbol (help-C-file-name symbol 'var)) xrefs))
757
758 ((string= "src/" (substring file 0 4))
759 ;; The variable is defined in a C source file; don't check
760 ;; for define-minor-mode.
761 (push (elisp--xref-make-xref 'defvar symbol file) xrefs))
762
763 ((memq symbol minor-mode-list)
764 ;; The symbol is a minor mode. These should be defined by
765 ;; "define-minor-mode", which means the variable and the
766 ;; function are declared in the same place. So we return only
767 ;; the function, arbitrarily.
768 ;;
769 ;; There is an exception, when the variable is defined in C
770 ;; code, as for abbrev-mode.
771 ;;
772 ;; IMPROVEME: If the user is searching for the identifier at
773 ;; point, we can determine whether it is a variable or
774 ;; function by looking at the source code near point.
775 ;;
776 ;; IMPROVEME: The user may actually be asking "do any
777 ;; variables by this name exist"; we need a way to specify
778 ;; that.
779 nil)
780
781 (t
782 (push (elisp--xref-make-xref 'defvar symbol file) xrefs))
783
784 ))))
785
786 (when (featurep symbol)
787 (let ((file (ignore-errors
788 (find-library-name (symbol-name symbol)))))
789 (when file
790 (push (elisp--xref-make-xref 'feature symbol file) xrefs))))
791 );; 'unless xrefs'
792
793 xrefs))
794
795 (declare-function project-external-roots "project")
796
797 (cl-defmethod xref-backend-apropos ((_backend (eql elisp)) regexp)
798 (apply #'nconc
799 (let (lst)
800 (dolist (sym (apropos-internal regexp))
801 (push (elisp--xref-find-definitions sym) lst))
802 (nreverse lst))))
803
804 (defvar elisp--xref-identifier-completion-table
805 (apply-partially #'completion-table-with-predicate
806 obarray
807 (lambda (sym)
808 (or (boundp sym)
809 (fboundp sym)
810 (featurep sym)
811 (facep sym)))
812 'strict))
813
814 (cl-defmethod xref-backend-identifier-completion-table ((_backend (eql elisp)))
815 elisp--xref-identifier-completion-table)
816
817 (cl-defstruct (xref-elisp-location
818 (:constructor xref-make-elisp-location (symbol type file)))
819 "Location of an Emacs Lisp symbol definition."
820 symbol type file)
821
822 (cl-defmethod xref-location-marker ((l xref-elisp-location))
823 (pcase-let (((cl-struct xref-elisp-location symbol type file) l))
824 (let ((buffer-point (find-function-search-for-symbol symbol type file)))
825 (with-current-buffer (car buffer-point)
826 (goto-char (or (cdr buffer-point) (point-min)))
827 (point-marker)))))
828
829 (cl-defmethod xref-location-group ((l xref-elisp-location))
830 (xref-elisp-location-file l))
831
832 (defun elisp-load-path-roots ()
833 (if (boundp 'package-user-dir)
834 (cons package-user-dir load-path)
835 load-path))
836
837 ;;; Elisp Interaction mode
838
839 (defvar lisp-interaction-mode-map
840 (let ((map (make-sparse-keymap))
841 (menu-map (make-sparse-keymap "Lisp-Interaction")))
842 (set-keymap-parent map lisp-mode-shared-map)
843 (define-key map "\e\C-x" 'eval-defun)
844 (define-key map "\e\C-q" 'indent-pp-sexp)
845 (define-key map "\e\t" 'completion-at-point)
846 (define-key map "\n" 'eval-print-last-sexp)
847 (bindings--define-key map [menu-bar lisp-interaction]
848 (cons "Lisp-Interaction" menu-map))
849 (bindings--define-key menu-map [eval-defun]
850 '(menu-item "Evaluate Defun" eval-defun
851 :help "Evaluate the top-level form containing point, or after point"))
852 (bindings--define-key menu-map [eval-print-last-sexp]
853 '(menu-item "Evaluate and Print" eval-print-last-sexp
854 :help "Evaluate sexp before point; print value into current buffer"))
855 (bindings--define-key menu-map [edebug-defun-lisp-interaction]
856 '(menu-item "Instrument Function for Debugging" edebug-defun
857 :help "Evaluate the top level form point is in, stepping through with Edebug"
858 :keys "C-u C-M-x"))
859 (bindings--define-key menu-map [indent-pp-sexp]
860 '(menu-item "Indent or Pretty-Print" indent-pp-sexp
861 :help "Indent each line of the list starting just after point, or prettyprint it"))
862 (bindings--define-key menu-map [complete-symbol]
863 '(menu-item "Complete Lisp Symbol" completion-at-point
864 :help "Perform completion on Lisp symbol preceding point"))
865 map)
866 "Keymap for Lisp Interaction mode.
867 All commands in `lisp-mode-shared-map' are inherited by this map.")
868
869 (define-derived-mode lisp-interaction-mode emacs-lisp-mode "Lisp Interaction"
870 "Major mode for typing and evaluating Lisp forms.
871 Like Lisp mode except that \\[eval-print-last-sexp] evals the Lisp expression
872 before point, and prints its value into the buffer, advancing point.
873 Note that printing is controlled by `eval-expression-print-length'
874 and `eval-expression-print-level'.
875
876 Commands:
877 Delete converts tabs to spaces as it moves back.
878 Paragraphs are separated only by blank lines.
879 Semicolons start comments.
880
881 \\{lisp-interaction-mode-map}"
882 :abbrev-table nil)
883
884 ;;; Emacs Lisp Byte-Code mode
885
886 (eval-and-compile
887 (defconst emacs-list-byte-code-comment-re
888 (concat "\\(#\\)@\\([0-9]+\\) "
889 ;; Make sure it's a docstring and not a lazy-loaded byte-code.
890 "\\(?:[^(]\\|([^\"]\\)")))
891
892 (defun elisp--byte-code-comment (end &optional _point)
893 "Try to syntactically mark the #@NNN ....^_ docstrings in byte-code files."
894 (let ((ppss (syntax-ppss)))
895 (when (and (nth 4 ppss)
896 (eq (char-after (nth 8 ppss)) ?#))
897 (let* ((n (save-excursion
898 (goto-char (nth 8 ppss))
899 (when (looking-at emacs-list-byte-code-comment-re)
900 (string-to-number (match-string 2)))))
901 ;; `maxdiff' tries to make sure the loop below terminates.
902 (maxdiff n))
903 (when n
904 (let* ((bchar (match-end 2))
905 (b (position-bytes bchar)))
906 (goto-char (+ b n))
907 (while (let ((diff (- (position-bytes (point)) b n)))
908 (unless (zerop diff)
909 (when (> diff maxdiff) (setq diff maxdiff))
910 (forward-char (- diff))
911 (setq maxdiff (if (> diff 0) diff
912 (max (1- maxdiff) 1)))
913 t))))
914 (if (<= (point) end)
915 (put-text-property (1- (point)) (point)
916 'syntax-table
917 (string-to-syntax "> b"))
918 (goto-char end)))))))
919
920 (defun elisp-byte-code-syntax-propertize (start end)
921 (goto-char start)
922 (elisp--byte-code-comment end (point))
923 (funcall
924 (syntax-propertize-rules
925 (emacs-list-byte-code-comment-re
926 (1 (prog1 "< b" (elisp--byte-code-comment end (point))))))
927 start end))
928
929 ;;;###autoload
930 (add-to-list 'auto-mode-alist '("\\.elc\\'" . elisp-byte-code-mode))
931 ;;;###autoload
932 (define-derived-mode elisp-byte-code-mode emacs-lisp-mode
933 "Elisp-Byte-Code"
934 "Major mode for *.elc files."
935 ;; TODO: Add way to disassemble byte-code under point.
936 (setq-local open-paren-in-column-0-is-defun-start nil)
937 (setq-local syntax-propertize-function
938 #'elisp-byte-code-syntax-propertize))
939
940
941 ;;; Globally accessible functionality
942
943 (defun eval-print-last-sexp (&optional eval-last-sexp-arg-internal)
944 "Evaluate sexp before point; print value into current buffer.
945
946 Normally, this function truncates long output according to the value
947 of the variables `eval-expression-print-length' and
948 `eval-expression-print-level'. With a prefix argument of zero,
949 however, there is no such truncation. Such a prefix argument
950 also causes integers to be printed in several additional formats
951 \(octal, hexadecimal, and character).
952
953 If `eval-expression-debug-on-error' is non-nil, which is the default,
954 this command arranges for all errors to enter the debugger."
955 (interactive "P")
956 (let ((standard-output (current-buffer)))
957 (terpri)
958 (eval-last-sexp (or eval-last-sexp-arg-internal t))
959 (terpri)))
960
961
962 (defun last-sexp-setup-props (beg end value alt1 alt2)
963 "Set up text properties for the output of `elisp--eval-last-sexp'.
964 BEG and END are the start and end of the output in current-buffer.
965 VALUE is the Lisp value printed, ALT1 and ALT2 are strings for the
966 alternative printed representations that can be displayed."
967 (let ((map (make-sparse-keymap)))
968 (define-key map "\C-m" 'elisp-last-sexp-toggle-display)
969 (define-key map [down-mouse-2] 'mouse-set-point)
970 (define-key map [mouse-2] 'elisp-last-sexp-toggle-display)
971 (add-text-properties
972 beg end
973 `(printed-value (,value ,alt1 ,alt2)
974 mouse-face highlight
975 keymap ,map
976 help-echo "RET, mouse-2: toggle abbreviated display"
977 rear-nonsticky (mouse-face keymap help-echo
978 printed-value)))))
979
980
981 (defun elisp-last-sexp-toggle-display (&optional _arg)
982 "Toggle between abbreviated and unabbreviated printed representations."
983 (interactive "P")
984 (save-restriction
985 (widen)
986 (let ((value (get-text-property (point) 'printed-value)))
987 (when value
988 (let ((beg (or (previous-single-property-change (min (point-max) (1+ (point)))
989 'printed-value)
990 (point)))
991 (end (or (next-single-char-property-change (point) 'printed-value) (point)))
992 (standard-output (current-buffer))
993 (point (point)))
994 (delete-region beg end)
995 (insert (nth 1 value))
996 (or (= beg point)
997 (setq point (1- (point))))
998 (last-sexp-setup-props beg (point)
999 (nth 0 value)
1000 (nth 2 value)
1001 (nth 1 value))
1002 (goto-char (min (point-max) point)))))))
1003
1004 (defun prin1-char (char) ;FIXME: Move it, e.g. to simple.el.
1005 "Return a string representing CHAR as a character rather than as an integer.
1006 If CHAR is not a character, return nil."
1007 (and (integerp char)
1008 (eventp char)
1009 (let ((c (event-basic-type char))
1010 (mods (event-modifiers char))
1011 string)
1012 ;; Prevent ?A from turning into ?\S-a.
1013 (if (and (memq 'shift mods)
1014 (zerop (logand char ?\S-\^@))
1015 (not (let ((case-fold-search nil))
1016 (char-equal c (upcase c)))))
1017 (setq c (upcase c) mods nil))
1018 ;; What string are we considering using?
1019 (condition-case nil
1020 (setq string
1021 (concat
1022 "?"
1023 (mapconcat
1024 (lambda (modif)
1025 (cond ((eq modif 'super) "\\s-")
1026 (t (string ?\\ (upcase (aref (symbol-name modif) 0)) ?-))))
1027 mods "")
1028 (cond
1029 ((memq c '(?\; ?\( ?\) ?\{ ?\} ?\[ ?\] ?\" ?\' ?\\)) (string ?\\ c))
1030 ((eq c 127) "\\C-?")
1031 (t
1032 (string c)))))
1033 (error nil))
1034 ;; Verify the string reads a CHAR, not to some other character.
1035 ;; If it doesn't, return nil instead.
1036 (and string
1037 (= (car (read-from-string string)) char)
1038 string))))
1039
1040 (defun elisp--preceding-sexp ()
1041 "Return sexp before the point."
1042 (let ((opoint (point))
1043 (left-quote ?‘)
1044 expr)
1045 (save-excursion
1046 (with-syntax-table emacs-lisp-mode-syntax-table
1047 ;; If this sexp appears to be enclosed in `...' or ‘...’
1048 ;; then ignore the surrounding quotes.
1049 (cond ((eq (preceding-char) ?’)
1050 (progn (forward-char -1) (setq opoint (point))))
1051 ((or (eq (following-char) ?\')
1052 (eq (preceding-char) ?\'))
1053 (setq left-quote ?\`)))
1054 (forward-sexp -1)
1055 ;; If we were after `?\e' (or similar case),
1056 ;; use the whole thing, not just the `e'.
1057 (when (eq (preceding-char) ?\\)
1058 (forward-char -1)
1059 (when (eq (preceding-char) ??)
1060 (forward-char -1)))
1061
1062 ;; Skip over hash table read syntax.
1063 (and (> (point) (1+ (point-min)))
1064 (looking-back "#s" (- (point) 2))
1065 (forward-char -2))
1066
1067 ;; Skip over `#N='s.
1068 (when (eq (preceding-char) ?=)
1069 (let (labeled-p)
1070 (save-excursion
1071 (skip-chars-backward "0-9#=")
1072 (setq labeled-p (looking-at "\\(#[0-9]+=\\)+")))
1073 (when labeled-p
1074 (forward-sexp -1))))
1075
1076 (save-restriction
1077 (if (eq (following-char) left-quote)
1078 ;; vladimir@cs.ualberta.ca 30-Jul-1997: Skip ` in `variable' so
1079 ;; that the value is returned, not the name.
1080 (forward-char))
1081 (when (looking-at ",@?") (goto-char (match-end 0)))
1082 (narrow-to-region (point-min) opoint)
1083 (setq expr (read (current-buffer)))
1084 ;; If it's an (interactive ...) form, it's more useful to show how an
1085 ;; interactive call would use it.
1086 ;; FIXME: Is it really the right place for this?
1087 (when (eq (car-safe expr) 'interactive)
1088 (setq expr
1089 `(call-interactively
1090 (lambda (&rest args) ,expr args))))
1091 expr)))))
1092 (define-obsolete-function-alias 'preceding-sexp 'elisp--preceding-sexp "25.1")
1093
1094 (defun elisp--eval-last-sexp (eval-last-sexp-arg-internal)
1095 "Evaluate sexp before point; print value in the echo area.
1096 If EVAL-LAST-SEXP-ARG-INTERNAL is non-nil, print output into
1097 current buffer. If EVAL-LAST-SEXP-ARG-INTERNAL is `0', print
1098 output with no limit on the length and level of lists, and
1099 include additional formats for integers \(octal, hexadecimal, and
1100 character)."
1101 (let ((standard-output (if eval-last-sexp-arg-internal (current-buffer) t)))
1102 ;; Setup the lexical environment if lexical-binding is enabled.
1103 (elisp--eval-last-sexp-print-value
1104 (eval (eval-sexp-add-defvars (elisp--preceding-sexp)) lexical-binding)
1105 eval-last-sexp-arg-internal)))
1106
1107 (defun elisp--eval-last-sexp-print-value (value &optional eval-last-sexp-arg-internal)
1108 (let ((unabbreviated (let ((print-length nil) (print-level nil))
1109 (prin1-to-string value)))
1110 (print-length (and (not (zerop (prefix-numeric-value
1111 eval-last-sexp-arg-internal)))
1112 eval-expression-print-length))
1113 (print-level (and (not (zerop (prefix-numeric-value
1114 eval-last-sexp-arg-internal)))
1115 eval-expression-print-level))
1116 (beg (point))
1117 end)
1118 (prog1
1119 (prin1 value)
1120 (let ((str (eval-expression-print-format value)))
1121 (if str (princ str)))
1122 (setq end (point))
1123 (when (and (bufferp standard-output)
1124 (or (not (null print-length))
1125 (not (null print-level)))
1126 (not (string= unabbreviated
1127 (buffer-substring-no-properties beg end))))
1128 (last-sexp-setup-props beg end value
1129 unabbreviated
1130 (buffer-substring-no-properties beg end))
1131 ))))
1132
1133
1134 (defvar elisp--eval-last-sexp-fake-value (make-symbol "t"))
1135
1136 (defun eval-sexp-add-defvars (exp &optional pos)
1137 "Prepend EXP with all the `defvar's that precede it in the buffer.
1138 POS specifies the starting position where EXP was found and defaults to point."
1139 (setq exp (macroexpand-all exp)) ;Eager macro-expansion.
1140 (if (not lexical-binding)
1141 exp
1142 (save-excursion
1143 (unless pos (setq pos (point)))
1144 (let ((vars ()))
1145 (goto-char (point-min))
1146 (while (re-search-forward
1147 "(def\\(?:var\\|const\\|custom\\)[ \t\n]+\\([^; '()\n\t]+\\)"
1148 pos t)
1149 (let ((var (intern (match-string 1))))
1150 (and (not (special-variable-p var))
1151 (save-excursion
1152 (zerop (car (syntax-ppss (match-beginning 0)))))
1153 (push var vars))))
1154 `(progn ,@(mapcar (lambda (v) `(defvar ,v)) vars) ,exp)))))
1155
1156 (defun eval-last-sexp (eval-last-sexp-arg-internal)
1157 "Evaluate sexp before point; print value in the echo area.
1158 Interactively, with prefix argument, print output into current buffer.
1159
1160 Normally, this function truncates long output according to the value
1161 of the variables `eval-expression-print-length' and
1162 `eval-expression-print-level'. With a prefix argument of zero,
1163 however, there is no such truncation. Such a prefix argument
1164 also causes integers to be printed in several additional formats
1165 \(octal, hexadecimal, and character).
1166
1167 If `eval-expression-debug-on-error' is non-nil, which is the default,
1168 this command arranges for all errors to enter the debugger."
1169 (interactive "P")
1170 (if (null eval-expression-debug-on-error)
1171 (elisp--eval-last-sexp eval-last-sexp-arg-internal)
1172 (let ((value
1173 (let ((debug-on-error elisp--eval-last-sexp-fake-value))
1174 (cons (elisp--eval-last-sexp eval-last-sexp-arg-internal)
1175 debug-on-error))))
1176 (unless (eq (cdr value) elisp--eval-last-sexp-fake-value)
1177 (setq debug-on-error (cdr value)))
1178 (car value))))
1179
1180 (defun elisp--eval-defun-1 (form)
1181 "Treat some expressions specially.
1182 Reset the `defvar' and `defcustom' variables to the initial value.
1183 \(For `defcustom', use the :set function if there is one.)
1184 Reinitialize the face according to the `defface' specification."
1185 ;; The code in edebug-defun should be consistent with this, but not
1186 ;; the same, since this gets a macroexpanded form.
1187 (cond ((not (listp form))
1188 form)
1189 ((and (eq (car form) 'defvar)
1190 (cdr-safe (cdr-safe form))
1191 (boundp (cadr form)))
1192 ;; Force variable to be re-set.
1193 `(progn (defvar ,(nth 1 form) nil ,@(nthcdr 3 form))
1194 (setq-default ,(nth 1 form) ,(nth 2 form))))
1195 ;; `defcustom' is now macroexpanded to
1196 ;; `custom-declare-variable' with a quoted value arg.
1197 ((and (eq (car form) 'custom-declare-variable)
1198 (default-boundp (eval (nth 1 form) lexical-binding)))
1199 ;; Force variable to be bound, using :set function if specified.
1200 (let ((setfunc (memq :set form)))
1201 (when setfunc
1202 (setq setfunc (car-safe (cdr-safe setfunc)))
1203 (or (functionp setfunc) (setq setfunc nil)))
1204 (funcall (or setfunc 'set-default)
1205 (eval (nth 1 form) lexical-binding)
1206 ;; The second arg is an expression that evaluates to
1207 ;; an expression. The second evaluation is the one
1208 ;; normally performed not by normal execution but by
1209 ;; custom-initialize-set (for example), which does not
1210 ;; use lexical-binding.
1211 (eval (eval (nth 2 form) lexical-binding))))
1212 form)
1213 ;; `defface' is macroexpanded to `custom-declare-face'.
1214 ((eq (car form) 'custom-declare-face)
1215 ;; Reset the face.
1216 (let ((face-symbol (eval (nth 1 form) lexical-binding)))
1217 (setq face-new-frame-defaults
1218 (assq-delete-all face-symbol face-new-frame-defaults))
1219 (put face-symbol 'face-defface-spec nil)
1220 (put face-symbol 'face-override-spec nil))
1221 form)
1222 ((eq (car form) 'progn)
1223 (cons 'progn (mapcar #'elisp--eval-defun-1 (cdr form))))
1224 (t form)))
1225
1226 (defun elisp--eval-defun ()
1227 "Evaluate defun that point is in or before.
1228 The value is displayed in the echo area.
1229 If the current defun is actually a call to `defvar',
1230 then reset the variable using the initial value expression
1231 even if the variable already has some other value.
1232 \(Normally `defvar' does not change the variable's value
1233 if it already has a value.)
1234
1235 Return the result of evaluation."
1236 ;; FIXME: the print-length/level bindings should only be applied while
1237 ;; printing, not while evaluating.
1238 (let ((debug-on-error eval-expression-debug-on-error)
1239 (print-length eval-expression-print-length)
1240 (print-level eval-expression-print-level))
1241 (save-excursion
1242 ;; Arrange for eval-region to "read" the (possibly) altered form.
1243 ;; eval-region handles recording which file defines a function or
1244 ;; variable.
1245 (let ((standard-output t)
1246 beg end form)
1247 ;; Read the form from the buffer, and record where it ends.
1248 (save-excursion
1249 (end-of-defun)
1250 (beginning-of-defun)
1251 (setq beg (point))
1252 (setq form (read (current-buffer)))
1253 (setq end (point)))
1254 ;; Alter the form if necessary.
1255 (let ((form (eval-sexp-add-defvars
1256 (elisp--eval-defun-1 (macroexpand form)))))
1257 (eval-region beg end standard-output
1258 (lambda (_ignore)
1259 ;; Skipping to the end of the specified region
1260 ;; will make eval-region return.
1261 (goto-char end)
1262 form))))))
1263 (let ((str (eval-expression-print-format (car values))))
1264 (if str (princ str)))
1265 ;; The result of evaluation has been put onto VALUES. So return it.
1266 (car values))
1267
1268 (defun eval-defun (edebug-it)
1269 "Evaluate the top-level form containing point, or after point.
1270
1271 If the current defun is actually a call to `defvar' or `defcustom',
1272 evaluating it this way resets the variable using its initial value
1273 expression (using the defcustom's :set function if there is one), even
1274 if the variable already has some other value. \(Normally `defvar' and
1275 `defcustom' do not alter the value if there already is one.) In an
1276 analogous way, evaluating a `defface' overrides any customizations of
1277 the face, so that it becomes defined exactly as the `defface' expression
1278 says.
1279
1280 If `eval-expression-debug-on-error' is non-nil, which is the default,
1281 this command arranges for all errors to enter the debugger.
1282
1283 With a prefix argument, instrument the code for Edebug.
1284
1285 If acting on a `defun' for FUNCTION, and the function was
1286 instrumented, `Edebug: FUNCTION' is printed in the echo area. If not
1287 instrumented, just FUNCTION is printed.
1288
1289 If not acting on a `defun', the result of evaluation is displayed in
1290 the echo area. This display is controlled by the variables
1291 `eval-expression-print-length' and `eval-expression-print-level',
1292 which see."
1293 (interactive "P")
1294 (cond (edebug-it
1295 (require 'edebug)
1296 (eval-defun (not edebug-all-defs)))
1297 (t
1298 (if (null eval-expression-debug-on-error)
1299 (elisp--eval-defun)
1300 (let (new-value value)
1301 (let ((debug-on-error elisp--eval-last-sexp-fake-value))
1302 (setq value (elisp--eval-defun))
1303 (setq new-value debug-on-error))
1304 (unless (eq elisp--eval-last-sexp-fake-value new-value)
1305 (setq debug-on-error new-value))
1306 value)))))
1307
1308 ;;; ElDoc Support
1309
1310 (defvar elisp--eldoc-last-data (make-vector 3 nil)
1311 "Bookkeeping; elements are as follows:
1312 0 - contains the last symbol read from the buffer.
1313 1 - contains the string last displayed in the echo area for variables,
1314 or argument string for functions.
1315 2 - `function' if function args, `variable' if variable documentation.")
1316
1317 (defun elisp-eldoc-documentation-function ()
1318 "`eldoc-documentation-function' (which see) for Emacs Lisp."
1319 (let ((current-symbol (elisp--current-symbol))
1320 (current-fnsym (elisp--fnsym-in-current-sexp)))
1321 (cond ((null current-fnsym)
1322 nil)
1323 ((eq current-symbol (car current-fnsym))
1324 (or (apply #'elisp-get-fnsym-args-string current-fnsym)
1325 (elisp-get-var-docstring current-symbol)))
1326 (t
1327 (or (elisp-get-var-docstring current-symbol)
1328 (apply #'elisp-get-fnsym-args-string current-fnsym))))))
1329
1330 (defun elisp-get-fnsym-args-string (sym &optional index prefix)
1331 "Return a string containing the parameter list of the function SYM.
1332 If SYM is a subr and no arglist is obtainable from the docstring
1333 or elsewhere, return a 1-line docstring."
1334 (let ((argstring
1335 (cond
1336 ((not (and sym (symbolp sym) (fboundp sym))) nil)
1337 ((and (eq sym (aref elisp--eldoc-last-data 0))
1338 (eq 'function (aref elisp--eldoc-last-data 2)))
1339 (aref elisp--eldoc-last-data 1))
1340 (t
1341 (let* ((advertised (gethash (indirect-function sym)
1342 advertised-signature-table t))
1343 doc
1344 (args
1345 (cond
1346 ((listp advertised) advertised)
1347 ((setq doc (help-split-fundoc
1348 (condition-case nil (documentation sym t)
1349 (invalid-function nil))
1350 sym))
1351 (car doc))
1352 (t (help-function-arglist sym)))))
1353 ;; Stringify, and store before highlighting, downcasing, etc.
1354 (elisp--last-data-store sym (elisp-function-argstring args)
1355 'function))))))
1356 ;; Highlight, truncate.
1357 (if argstring
1358 (elisp--highlight-function-argument
1359 sym argstring index
1360 (or prefix
1361 (concat (propertize (symbol-name sym) 'face
1362 (if (functionp sym)
1363 'font-lock-function-name-face
1364 'font-lock-keyword-face))
1365 ": "))))))
1366
1367 (defun elisp--highlight-function-argument (sym args index prefix)
1368 "Highlight argument INDEX in ARGS list for function SYM.
1369 In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'."
1370 ;; FIXME: This should probably work on the list representation of `args'
1371 ;; rather than its string representation.
1372 ;; FIXME: This function is much too long, we need to split it up!
1373 (let ((start nil)
1374 (end 0)
1375 (argument-face 'eldoc-highlight-function-argument)
1376 (args-lst (mapcar (lambda (x)
1377 (replace-regexp-in-string
1378 "\\`[(]\\|[)]\\'" "" x))
1379 (split-string args))))
1380 ;; Find the current argument in the argument string. We need to
1381 ;; handle `&rest' and informal `...' properly.
1382 ;;
1383 ;; FIXME: What to do with optional arguments, like in
1384 ;; (defun NAME ARGLIST [DOCSTRING] BODY...) case?
1385 ;; The problem is there is no robust way to determine if
1386 ;; the current argument is indeed a docstring.
1387
1388 ;; When `&key' is used finding position based on `index'
1389 ;; would be wrong, so find the arg at point and determine
1390 ;; position in ARGS based on this current arg.
1391 (when (string-match "&key" args)
1392 (let* (case-fold-search
1393 key-have-value
1394 (sym-name (symbol-name sym))
1395 (cur-w (current-word))
1396 (args-lst-ak (cdr (member "&key" args-lst)))
1397 (limit (save-excursion
1398 (when (re-search-backward sym-name nil t)
1399 (match-end 0))))
1400 (cur-a (if (and cur-w (string-match ":\\([^ ()]*\\)" cur-w))
1401 (substring cur-w 1)
1402 (save-excursion
1403 (let (split)
1404 (when (re-search-backward ":\\([^()\n]*\\)" limit t)
1405 (setq split (split-string (match-string 1) " " t))
1406 (prog1 (car split)
1407 (when (cdr split)
1408 (setq key-have-value t))))))))
1409 ;; If `cur-a' is not one of `args-lst-ak'
1410 ;; assume user is entering an unknown key
1411 ;; referenced in last position in signature.
1412 (other-key-arg (and (stringp cur-a)
1413 args-lst-ak
1414 (not (member (upcase cur-a) args-lst-ak))
1415 (upcase (car (last args-lst-ak))))))
1416 (unless (string= cur-w sym-name)
1417 ;; The last keyword have already a value
1418 ;; i.e :foo a b and cursor is at b.
1419 ;; If signature have also `&rest'
1420 ;; (assume it is after the `&key' section)
1421 ;; go to the arg after `&rest'.
1422 (if (and key-have-value
1423 (save-excursion
1424 (not (re-search-forward ":.*" (point-at-eol) t)))
1425 (string-match "&rest \\([^ ()]*\\)" args))
1426 (setq index nil ; Skip next block based on positional args.
1427 start (match-beginning 1)
1428 end (match-end 1))
1429 ;; If `cur-a' is nil probably cursor is on a positional arg
1430 ;; before `&key', in this case, exit this block and determine
1431 ;; position with `index'.
1432 (when (and cur-a ; A keyword arg (dot removed) or nil.
1433 (or (string-match
1434 (concat "\\_<" (upcase cur-a) "\\_>") args)
1435 (string-match
1436 (concat "\\_<" other-key-arg "\\_>") args)))
1437 (setq index nil ; Skip next block based on positional args.
1438 start (match-beginning 0)
1439 end (match-end 0)))))))
1440 ;; Handle now positional arguments.
1441 (while (and index (>= index 1))
1442 (if (string-match "[^ ()]+" args end)
1443 (progn
1444 (setq start (match-beginning 0)
1445 end (match-end 0))
1446 (let ((argument (match-string 0 args)))
1447 (cond ((string= argument "&rest")
1448 ;; All the rest arguments are the same.
1449 (setq index 1))
1450 ((string= argument "&optional")) ; Skip.
1451 ((string= argument "&allow-other-keys")) ; Skip.
1452 ;; Back to index 0 in ARG1 ARG2 ARG2 ARG3 etc...
1453 ;; like in `setq'.
1454 ((or (and (string-match-p "\\.\\.\\.\\'" argument)
1455 (string= argument (car (last args-lst))))
1456 (and (string-match-p "\\.\\.\\.\\'"
1457 (substring args 1 (1- (length args))))
1458 (= (length (remove "..." args-lst)) 2)
1459 (> index 1) (eq (logand index 1) 1)))
1460 (setq index 0))
1461 (t
1462 (setq index (1- index))))))
1463 (setq end (length args)
1464 start (1- end)
1465 argument-face 'font-lock-warning-face
1466 index 0)))
1467 (let ((doc args))
1468 (when start
1469 (setq doc (copy-sequence args))
1470 (add-text-properties start end (list 'face argument-face) doc))
1471 (setq doc (eldoc-docstring-format-sym-doc prefix doc))
1472 doc)))
1473
1474 ;; Return a string containing a brief (one-line) documentation string for
1475 ;; the variable.
1476 (defun elisp-get-var-docstring (sym)
1477 (cond ((not sym) nil)
1478 ((and (eq sym (aref elisp--eldoc-last-data 0))
1479 (eq 'variable (aref elisp--eldoc-last-data 2)))
1480 (aref elisp--eldoc-last-data 1))
1481 (t
1482 (let ((doc (documentation-property sym 'variable-documentation t)))
1483 (when doc
1484 (let ((doc (eldoc-docstring-format-sym-doc
1485 sym (elisp--docstring-first-line doc)
1486 'font-lock-variable-name-face)))
1487 (elisp--last-data-store sym doc 'variable)))))))
1488
1489 (defun elisp--last-data-store (symbol doc type)
1490 (aset elisp--eldoc-last-data 0 symbol)
1491 (aset elisp--eldoc-last-data 1 doc)
1492 (aset elisp--eldoc-last-data 2 type)
1493 doc)
1494
1495 ;; Note that any leading `*' in the docstring (which indicates the variable
1496 ;; is a user option) is removed.
1497 (defun elisp--docstring-first-line (doc)
1498 (and (stringp doc)
1499 (substitute-command-keys
1500 (save-match-data
1501 ;; Don't use "^" in the regexp below since it may match
1502 ;; anywhere in the doc-string.
1503 (let ((start (if (string-match "\\`\\*" doc) (match-end 0) 0)))
1504 (cond ((string-match "\n" doc)
1505 (substring doc start (match-beginning 0)))
1506 ((zerop start) doc)
1507 (t (substring doc start))))))))
1508 \f
1509 ;; Return a list of current function name and argument index.
1510 (defun elisp--fnsym-in-current-sexp ()
1511 (save-excursion
1512 (let ((argument-index (1- (elisp--beginning-of-sexp))))
1513 ;; If we are at the beginning of function name, this will be -1.
1514 (when (< argument-index 0)
1515 (setq argument-index 0))
1516 ;; Don't do anything if current word is inside a string.
1517 (if (= (or (char-after (1- (point))) 0) ?\")
1518 nil
1519 (list (elisp--current-symbol) argument-index)))))
1520
1521 ;; Move to the beginning of current sexp. Return the number of nested
1522 ;; sexp the point was over or after.
1523 (defun elisp--beginning-of-sexp ()
1524 (let ((parse-sexp-ignore-comments t)
1525 (num-skipped-sexps 0))
1526 (condition-case _
1527 (progn
1528 ;; First account for the case the point is directly over a
1529 ;; beginning of a nested sexp.
1530 (condition-case _
1531 (let ((p (point)))
1532 (forward-sexp -1)
1533 (forward-sexp 1)
1534 (when (< (point) p)
1535 (setq num-skipped-sexps 1)))
1536 (error))
1537 (while
1538 (let ((p (point)))
1539 (forward-sexp -1)
1540 (when (< (point) p)
1541 (setq num-skipped-sexps (1+ num-skipped-sexps))))))
1542 (error))
1543 num-skipped-sexps))
1544
1545 ;; returns nil unless current word is an interned symbol.
1546 (defun elisp--current-symbol ()
1547 (let ((c (char-after (point))))
1548 (and c
1549 (memq (char-syntax c) '(?w ?_))
1550 (intern-soft (current-word)))))
1551
1552 (defun elisp-function-argstring (arglist)
1553 "Return ARGLIST as a string enclosed by ().
1554 ARGLIST is either a string, or a list of strings or symbols."
1555 (let ((str (cond ((stringp arglist) arglist)
1556 ((not (listp arglist)) nil)
1557 (t (help--make-usage-docstring 'toto arglist)))))
1558 (if (and str (string-match "\\`([^ )]+ ?" str))
1559 (replace-match "(" t t str)
1560 str)))
1561
1562 (provide 'elisp-mode)
1563 ;;; elisp-mode.el ends here