Don't let completion break `declare' handling
[emacs.git] / lisp / progmodes / elisp-mode.el
blobd02951dcf62262ca4e4d31941ddafac09c40f0e1
1 ;;; elisp-mode.el --- Emacs Lisp mode -*- lexical-binding:t -*-
3 ;; Copyright (C) 1985-1986, 1999-2016 Free Software Foundation, Inc.
5 ;; Maintainer: emacs-devel@gnu.org
6 ;; Keywords: lisp, languages
7 ;; Package: emacs
9 ;; This file is part of GNU Emacs.
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.
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.
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/>.
24 ;;; Commentary:
26 ;; The major mode for editing Emacs Lisp code.
27 ;; This mode is documented in the Emacs manual.
29 ;;; Code:
31 (require 'cl-generic)
32 (require 'lisp-mode)
33 (eval-when-compile (require 'cl-lib))
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))
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'.")
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"))
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"))
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.")
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")))
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))
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)))))
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)
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.
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))
245 ;; Font-locking support.
247 (defun elisp--font-lock-flush-elisp-buffers (&optional file)
248 ;; FIXME: Aren't we only ever called from after-load-functions?
249 ;; Don't flush during load unless called from after-load-functions.
250 ;; In that case, FILE is non-nil. It's somehow strange that
251 ;; load-in-progress is t when an after-load-function is called since
252 ;; that should run *after* the load...
253 (when (or (not load-in-progress) file)
254 ;; FIXME: If the loaded file did not define any macros, there shouldn't
255 ;; be any need to font-lock-flush all the Elisp buffers.
256 (dolist (buf (buffer-list))
257 (with-current-buffer buf
258 (when (derived-mode-p 'emacs-lisp-mode)
259 ;; So as to take into account new macros that may have been defined
260 ;; by the just-loaded file.
261 (font-lock-flush))))))
263 ;;; Completion at point for Elisp
265 (defun elisp--local-variables-1 (vars sexp)
266 "Return the vars locally bound around the witness, or nil if not found."
267 (let (res)
268 (while
269 (unless
270 (setq res
271 (pcase sexp
272 (`(,(or `let `let*) ,bindings)
273 (let ((vars vars))
274 (when (eq 'let* (car sexp))
275 (dolist (binding (cdr (reverse bindings)))
276 (push (or (car-safe binding) binding) vars)))
277 (elisp--local-variables-1
278 vars (car (cdr-safe (car (last bindings)))))))
279 (`(,(or `let `let*) ,bindings . ,body)
280 (let ((vars vars))
281 (dolist (binding bindings)
282 (push (or (car-safe binding) binding) vars))
283 (elisp--local-variables-1 vars (car (last body)))))
284 (`(lambda ,_args)
285 ;; FIXME: Look for the witness inside `args'.
286 (setq sexp nil))
287 (`(lambda ,args . ,body)
288 (elisp--local-variables-1
289 (append (remq '&optional (remq '&rest args)) vars)
290 (car (last body))))
291 (`(condition-case ,_ ,e) (elisp--local-variables-1 vars e))
292 (`(condition-case ,v ,_ . ,catches)
293 (elisp--local-variables-1
294 (cons v vars) (cdr (car (last catches)))))
295 (`(quote . ,_)
296 ;; FIXME: Look for the witness inside sexp.
297 (setq sexp nil))
298 ;; FIXME: Handle `cond'.
299 (`(,_ . ,_)
300 (elisp--local-variables-1 vars (car (last sexp))))
301 (`elisp--witness--lisp (or vars '(nil)))
302 (_ nil)))
303 ;; We didn't find the witness in the last element so we try to
304 ;; backtrack to the last-but-one.
305 (setq sexp (ignore-errors (butlast sexp)))))
306 res))
308 (defun elisp--local-variables ()
309 "Return a list of locally let-bound variables at point."
310 (save-excursion
311 (skip-syntax-backward "w_")
312 (let* ((ppss (syntax-ppss))
313 (txt (buffer-substring-no-properties (or (car (nth 9 ppss)) (point))
314 (or (nth 8 ppss) (point))))
315 (closer ()))
316 (dolist (p (nth 9 ppss))
317 (push (cdr (syntax-after p)) closer))
318 (setq closer (apply #'string closer))
319 (let* ((sexp (condition-case nil
320 (car (read-from-string
321 (concat txt "elisp--witness--lisp" closer)))
322 ((invalid-read-syntax end-of-file) nil)))
323 (macroexpand-advice (lambda (expander form &rest args)
324 (condition-case nil
325 (apply expander form args)
326 (error form))))
327 (sexp
328 (unwind-protect
329 (progn
330 (advice-add 'macroexpand :around macroexpand-advice)
331 (macroexpand-all sexp))
332 (advice-remove 'macroexpand macroexpand-advice)))
333 (vars (elisp--local-variables-1 nil sexp)))
334 (delq nil
335 (mapcar (lambda (var)
336 (and (symbolp var)
337 (not (string-match (symbol-name var) "\\`[&_]"))
338 ;; Eliminate uninterned vars.
339 (intern-soft var)
340 var))
341 vars))))))
343 (defvar elisp--local-variables-completion-table
344 ;; Use `defvar' rather than `defconst' since defconst would purecopy this
345 ;; value, which would doubly fail: it would fail because purecopy can't
346 ;; handle the recursive bytecode object, and it would fail because it would
347 ;; move `lastpos' and `lastvars' to pure space where they'd be immutable!
348 (let ((lastpos nil) (lastvars nil))
349 (letrec ((hookfun (lambda ()
350 (setq lastpos nil)
351 (remove-hook 'post-command-hook hookfun))))
352 (completion-table-dynamic
353 (lambda (_string)
354 (save-excursion
355 (skip-syntax-backward "_w")
356 (let ((newpos (cons (point) (current-buffer))))
357 (unless (equal lastpos newpos)
358 (add-hook 'post-command-hook hookfun)
359 (setq lastpos newpos)
360 (setq lastvars
361 (mapcar #'symbol-name (elisp--local-variables))))))
362 lastvars)))))
364 (defun elisp--expect-function-p (pos)
365 "Return non-nil if the symbol at point is expected to be a function."
367 (and (eq (char-before pos) ?')
368 (eq (char-before (1- pos)) ?#))
369 (save-excursion
370 (let ((parent (nth 1 (syntax-ppss pos))))
371 (when parent
372 (goto-char parent)
373 (and
374 (looking-at (concat "(\\(cl-\\)?"
375 (regexp-opt '("declare-function"
376 "function" "defadvice"
377 "callf" "callf2"
378 "defsetf"))
379 "[ \t\r\n]+"))
380 (eq (match-end 0) pos)))))))
382 (defun elisp--form-quoted-p (pos)
383 "Return non-nil if the form at POS is not evaluated.
384 It can be quoted, or be inside a quoted form."
385 ;; FIXME: Do some macro expansion maybe.
386 (save-excursion
387 (let ((state (syntax-ppss pos)))
388 (or (nth 8 state) ; Code inside strings usually isn't evaluated.
389 ;; FIXME: The 9th element is undocumented.
390 (let ((nesting (cons (point) (reverse (nth 9 state))))
391 res)
392 (while (and nesting (not res))
393 (goto-char (pop nesting))
394 (cond
395 ((or (eq (char-after) ?\[)
396 (progn
397 (skip-chars-backward " ")
398 (memq (char-before) '(?' ?` ?‘))))
399 (setq res t))
400 ((eq (char-before) ?,)
401 (setq nesting nil))))
402 res)))))
404 ;; FIXME: Support for Company brings in features which straddle eldoc.
405 ;; We should consolidate this, so that major modes can provide all that
406 ;; data all at once:
407 ;; - a function to extract "the reference at point" (may be more complex
408 ;; than a mere string, to distinguish various namespaces).
409 ;; - a function to jump to such a reference.
410 ;; - a function to show the signature/interface of such a reference.
411 ;; - a function to build a help-buffer about that reference.
412 ;; FIXME: Those functions should also be used by the normal completion code in
413 ;; the *Completions* buffer.
415 (defun elisp--company-doc-buffer (str)
416 (let ((symbol (intern-soft str)))
417 ;; FIXME: we really don't want to "display-buffer and then undo it".
418 (save-window-excursion
419 ;; Make sure we don't display it in another frame, otherwise
420 ;; save-window-excursion won't be able to undo it.
421 (let ((display-buffer-overriding-action
422 '(nil . ((inhibit-switch-frame . t)))))
423 (ignore-errors
424 (cond
425 ((fboundp symbol) (describe-function symbol))
426 ((boundp symbol) (describe-variable symbol))
427 ((featurep symbol) (describe-package symbol))
428 ((facep symbol) (describe-face symbol))
429 (t (signal 'user-error nil)))
430 (help-buffer))))))
432 (defun elisp--company-doc-string (str)
433 (let* ((symbol (intern-soft str))
434 (doc (if (fboundp symbol)
435 (documentation symbol t)
436 (documentation-property symbol 'variable-documentation t))))
437 (and (stringp doc)
438 (string-match ".*$" doc)
439 (match-string 0 doc))))
441 ;; can't (require 'find-func) in a preloaded file
442 (declare-function find-library-name "find-func" (library))
443 (declare-function find-function-library "find-func" (function &optional l-o v))
445 (defun elisp--company-location (str)
446 (let ((sym (intern-soft str)))
447 (cond
448 ((fboundp sym) (find-definition-noselect sym nil))
449 ((boundp sym) (find-definition-noselect sym 'defvar))
450 ((featurep sym)
451 (require 'find-func)
452 (cons (find-file-noselect (find-library-name
453 (symbol-name sym)))
455 ((facep sym) (find-definition-noselect sym 'defface)))))
457 (defun elisp-completion-at-point ()
458 "Function used for `completion-at-point-functions' in `emacs-lisp-mode'.
459 If the context at point allows only a certain category of
460 symbols (e.g. functions, or variables) then the returned
461 completions are restricted to that category. In contexts where
462 any symbol is possible (following a quote, for example),
463 functions are annotated with \"<f>\" via the
464 `:annotation-function' property."
465 (with-syntax-table emacs-lisp-mode-syntax-table
466 (let* ((pos (point))
467 (beg (condition-case nil
468 (save-excursion
469 (backward-sexp 1)
470 (skip-chars-forward "`',‘#")
471 (point))
472 (scan-error pos)))
473 (end
474 (unless (or (eq beg (point-max))
475 (member (char-syntax (char-after beg))
476 '(?\s ?\" ?\( ?\))))
477 (condition-case nil
478 (save-excursion
479 (goto-char beg)
480 (forward-sexp 1)
481 (skip-chars-backward "'’")
482 (when (>= (point) pos)
483 (point)))
484 (scan-error pos))))
485 ;; t if in function position.
486 (funpos (eq (char-before beg) ?\())
487 (quoted (elisp--form-quoted-p beg)))
488 (when (and end (or (not (nth 8 (syntax-ppss)))
489 (memq (char-before beg) '(?` ?‘))))
490 (let ((table-etc
491 (if (or (not funpos) quoted)
492 ;; FIXME: We could look at the first element of the list and
493 ;; use it to provide a more specific completion table in some
494 ;; cases. E.g. filter out keywords that are not understood by
495 ;; the macro/function being called.
496 (cond
497 ((elisp--expect-function-p beg)
498 (list nil obarray
499 :predicate #'fboundp
500 :company-doc-buffer #'elisp--company-doc-buffer
501 :company-docsig #'elisp--company-doc-string
502 :company-location #'elisp--company-location))
503 (quoted
504 (list nil obarray
505 ;; Don't include all symbols (bug#16646).
506 :predicate (lambda (sym)
507 (or (boundp sym)
508 (fboundp sym)
509 (featurep sym)
510 (symbol-plist sym)))
511 :annotation-function
512 (lambda (str) (if (fboundp (intern-soft str)) " <f>"))
513 :company-doc-buffer #'elisp--company-doc-buffer
514 :company-docsig #'elisp--company-doc-string
515 :company-location #'elisp--company-location))
517 (list nil (completion-table-merge
518 elisp--local-variables-completion-table
519 (apply-partially #'completion-table-with-predicate
520 obarray
521 #'boundp
522 'strict))
523 :company-doc-buffer #'elisp--company-doc-buffer
524 :company-docsig #'elisp--company-doc-string
525 :company-location #'elisp--company-location)))
526 ;; Looks like a funcall position. Let's double check.
527 (save-excursion
528 (goto-char (1- beg))
529 (let ((parent
530 (condition-case nil
531 (progn (up-list -1) (forward-char 1)
532 (let ((c (char-after)))
533 (if (eq c ?\() ?\(
534 (if (memq (char-syntax c) '(?w ?_))
535 (read (current-buffer))))))
536 (error nil))))
537 (pcase parent
538 ;; FIXME: Rather than hardcode special cases here,
539 ;; we should use something like a symbol-property.
540 (`declare
541 (list t (mapcar (lambda (x) (symbol-name (car x)))
542 (delete-dups
543 ;; FIXME: We should include some
544 ;; docstring with each entry.
545 (append macro-declarations-alist
546 defun-declarations-alist
547 nil))))) ; Copy both alists.
548 ((and (or `condition-case `condition-case-unless-debug)
549 (guard (save-excursion
550 (ignore-errors
551 (forward-sexp 2)
552 (< (point) beg)))))
553 (list t obarray
554 :predicate (lambda (sym) (get sym 'error-conditions))))
555 ((and (or ?\( `let `let*)
556 (guard (save-excursion
557 (goto-char (1- beg))
558 (when (eq parent ?\()
559 (up-list -1))
560 (forward-symbol -1)
561 (looking-at "\\_<let\\*?\\_>"))))
562 (list t obarray
563 :predicate #'boundp
564 :company-doc-buffer #'elisp--company-doc-buffer
565 :company-docsig #'elisp--company-doc-string
566 :company-location #'elisp--company-location))
567 (_ (list nil obarray
568 :predicate #'fboundp
569 :company-doc-buffer #'elisp--company-doc-buffer
570 :company-docsig #'elisp--company-doc-string
571 :company-location #'elisp--company-location
572 ))))))))
573 (nconc (list beg end)
574 (if (null (car table-etc))
575 (cdr table-etc)
576 (cons
577 (if (memq (char-syntax (or (char-after end) ?\s))
578 '(?\s ?>))
579 (cadr table-etc)
580 (apply-partially 'completion-table-with-terminator
581 " " (cadr table-etc)))
582 (cddr table-etc)))))))))
584 (defun lisp-completion-at-point (&optional _predicate)
585 (declare (obsolete elisp-completion-at-point "25.1"))
586 (elisp-completion-at-point))
588 ;;; Xref backend
590 (declare-function xref-make-bogus-location "xref" (message))
591 (declare-function xref-make "xref" (summary location))
592 (declare-function xref-collect-references "xref" (symbol dir))
594 (defun elisp--xref-backend () 'elisp)
596 ;; WORKAROUND: This is nominally a constant, but the text properties
597 ;; are not preserved thru dump if use defconst. See bug#21237.
598 (defvar elisp--xref-format
599 (let ((str "(%s %s)"))
600 (put-text-property 1 3 'face 'font-lock-keyword-face str)
601 (put-text-property 4 6 'face 'font-lock-function-name-face str)
602 str))
604 ;; WORKAROUND: This is nominally a constant, but the text properties
605 ;; are not preserved thru dump if use defconst. See bug#21237.
606 (defvar elisp--xref-format-extra
607 (let ((str "(%s %s %s)"))
608 (put-text-property 1 3 'face 'font-lock-keyword-face str)
609 (put-text-property 4 6 'face 'font-lock-function-name-face str)
610 str))
612 (defvar find-feature-regexp);; in find-func.el
614 (defun elisp--xref-make-xref (type symbol file &optional summary)
615 "Return an xref for TYPE SYMBOL in FILE.
616 TYPE must be a type in `find-function-regexp-alist' (use nil for
617 'defun). If SUMMARY is non-nil, use it for the summary;
618 otherwise build the summary from TYPE and SYMBOL."
619 (xref-make (or summary
620 (format elisp--xref-format (or type 'defun) symbol))
621 (xref-make-elisp-location symbol type file)))
623 (defvar elisp-xref-find-def-functions nil
624 "List of functions to be run from `elisp--xref-find-definitions' to add additional xrefs.
625 Called with one arg; the symbol whose definition is desired.
626 Each function should return a list of xrefs, or nil; the first
627 non-nil result supercedes the xrefs produced by
628 `elisp--xref-find-definitions'.")
630 (cl-defmethod xref-backend-definitions ((_backend (eql elisp)) identifier)
631 (require 'find-func)
632 ;; FIXME: use information in source near point to filter results:
633 ;; (dvc-log-edit ...) - exclude 'feature
634 ;; (require 'dvc-log-edit) - only 'feature
635 ;; Semantic may provide additional information
637 (let ((sym (intern-soft identifier)))
638 (when sym
639 (elisp--xref-find-definitions sym))))
641 (defun elisp--xref-find-definitions (symbol)
642 ;; The file name is not known when `symbol' is defined via interactive eval.
643 (let (xrefs)
645 (let ((temp elisp-xref-find-def-functions))
646 (while (and (null xrefs)
647 temp)
648 (setq xrefs (append xrefs (funcall (pop temp) symbol)))))
650 (unless xrefs
651 ;; alphabetical by result type symbol
653 ;; FIXME: advised function; list of advice functions
654 ;; FIXME: aliased variable
656 ;; Coding system symbols do not appear in ‘load-history’,
657 ;; so we can’t get a location for them.
659 (when (and (symbolp symbol)
660 (symbol-function symbol)
661 (symbolp (symbol-function symbol)))
662 ;; aliased function
663 (let* ((alias-symbol symbol)
664 (alias-file (symbol-file alias-symbol))
665 (real-symbol (symbol-function symbol))
666 (real-file (find-lisp-object-file-name real-symbol 'defun)))
668 (when real-file
669 (push (elisp--xref-make-xref nil real-symbol real-file) xrefs))
671 (when alias-file
672 (push (elisp--xref-make-xref 'defalias alias-symbol alias-file) xrefs))))
674 (when (facep symbol)
675 (let ((file (find-lisp-object-file-name symbol 'defface)))
676 (when file
677 (push (elisp--xref-make-xref 'defface symbol file) xrefs))))
679 (when (fboundp symbol)
680 (let ((file (find-lisp-object-file-name symbol (symbol-function symbol)))
681 generic doc)
682 (when file
683 (cond
684 ((eq file 'C-source)
685 ;; First call to find-lisp-object-file-name for an object
686 ;; defined in C; the doc strings from the C source have
687 ;; not been loaded yet. Second call will return "src/*.c"
688 ;; in file; handled by 't' case below.
689 (push (elisp--xref-make-xref nil symbol (help-C-file-name (symbol-function symbol) 'subr)) xrefs))
691 ((and (setq doc (documentation symbol t))
692 ;; This doc string is defined in cl-macs.el cl-defstruct
693 (string-match "Constructor for objects of type `\\(.*\\)'" doc))
694 ;; `symbol' is a name for the default constructor created by
695 ;; cl-defstruct, so return the location of the cl-defstruct.
696 (let* ((type-name (match-string 1 doc))
697 (type-symbol (intern type-name))
698 (file (find-lisp-object-file-name type-symbol 'define-type))
699 (summary (format elisp--xref-format-extra
700 'cl-defstruct
701 (concat "(" type-name)
702 (concat "(:constructor " (symbol-name symbol) "))"))))
703 (push (elisp--xref-make-xref 'define-type type-symbol file summary) xrefs)
706 ((setq generic (cl--generic symbol))
707 ;; FIXME: move this to elisp-xref-find-def-functions, in cl-generic.el
709 ;; A generic function. If there is a default method, it
710 ;; will appear in the method table, with no
711 ;; specializers.
713 ;; If the default method is declared by the cl-defgeneric
714 ;; declaration, it will have the same location as the
715 ;; cl-defgeneric, so we want to exclude it from the
716 ;; result. In this case, it will have a null doc
717 ;; string. User declarations of default methods may also
718 ;; have null doc strings, but we hope that is
719 ;; rare. Perhaps this heuristic will discourage that.
720 (dolist (method (cl--generic-method-table generic))
721 (let* ((info (cl--generic-method-info method));; qual-string combined-args doconly
722 (specializers (cl--generic-method-specializers method))
723 (non-default nil)
724 (met-name (cons symbol specializers))
725 (file (find-lisp-object-file-name met-name 'cl-defmethod)))
726 (dolist (item specializers)
727 ;; default method has all 't' in specializers
728 (setq non-default (or non-default (not (equal t item)))))
730 (when (and file
731 (or non-default
732 (nth 2 info))) ;; assuming only co-located default has null doc string
733 (if specializers
734 (let ((summary (format elisp--xref-format-extra 'cl-defmethod symbol (nth 1 info))))
735 (push (elisp--xref-make-xref 'cl-defmethod met-name file summary) xrefs))
737 (let ((summary (format elisp--xref-format-extra 'cl-defmethod symbol "()")))
738 (push (elisp--xref-make-xref 'cl-defmethod met-name file summary) xrefs))))
741 (if (and (setq doc (documentation symbol t))
742 ;; This doc string is created somewhere in
743 ;; cl--generic-make-function for an implicit
744 ;; defgeneric.
745 (string-match "\n\n(fn ARG &rest ARGS)" doc))
746 ;; This symbol is an implicitly defined defgeneric, so
747 ;; don't return it.
749 (push (elisp--xref-make-xref 'cl-defgeneric symbol file) xrefs))
753 (push (elisp--xref-make-xref nil symbol file) xrefs))
754 ))))
756 (when (boundp symbol)
757 ;; A variable
758 (let ((file (find-lisp-object-file-name symbol 'defvar)))
759 (when file
760 (cond
761 ((eq file 'C-source)
762 ;; The doc strings from the C source have not been loaded
763 ;; yet; help-C-file-name does that. Second call will
764 ;; return "src/*.c" in file; handled below.
765 (push (elisp--xref-make-xref 'defvar symbol (help-C-file-name symbol 'var)) xrefs))
767 ((string= "src/" (substring file 0 4))
768 ;; The variable is defined in a C source file; don't check
769 ;; for define-minor-mode.
770 (push (elisp--xref-make-xref 'defvar symbol file) xrefs))
772 ((memq symbol minor-mode-list)
773 ;; The symbol is a minor mode. These should be defined by
774 ;; "define-minor-mode", which means the variable and the
775 ;; function are declared in the same place. So we return only
776 ;; the function, arbitrarily.
778 ;; There is an exception, when the variable is defined in C
779 ;; code, as for abbrev-mode.
781 ;; IMPROVEME: If the user is searching for the identifier at
782 ;; point, we can determine whether it is a variable or
783 ;; function by looking at the source code near point.
785 ;; IMPROVEME: The user may actually be asking "do any
786 ;; variables by this name exist"; we need a way to specify
787 ;; that.
788 nil)
791 (push (elisp--xref-make-xref 'defvar symbol file) xrefs))
793 ))))
795 (when (featurep symbol)
796 (let ((file (ignore-errors
797 (find-library-name (symbol-name symbol)))))
798 (when file
799 (push (elisp--xref-make-xref 'feature symbol file) xrefs))))
800 );; 'unless xrefs'
802 xrefs))
804 (declare-function project-external-roots "project")
806 (cl-defmethod xref-backend-apropos ((_backend (eql elisp)) regexp)
807 (apply #'nconc
808 (let (lst)
809 (dolist (sym (apropos-internal regexp))
810 (push (elisp--xref-find-definitions sym) lst))
811 (nreverse lst))))
813 (defvar elisp--xref-identifier-completion-table
814 (apply-partially #'completion-table-with-predicate
815 obarray
816 (lambda (sym)
817 (or (boundp sym)
818 (fboundp sym)
819 (featurep sym)
820 (facep sym)))
821 'strict))
823 (cl-defmethod xref-backend-identifier-completion-table ((_backend (eql elisp)))
824 elisp--xref-identifier-completion-table)
826 (cl-defstruct (xref-elisp-location
827 (:constructor xref-make-elisp-location (symbol type file)))
828 "Location of an Emacs Lisp symbol definition."
829 symbol type file)
831 (cl-defmethod xref-location-marker ((l xref-elisp-location))
832 (pcase-let (((cl-struct xref-elisp-location symbol type file) l))
833 (let ((buffer-point (find-function-search-for-symbol symbol type file)))
834 (with-current-buffer (car buffer-point)
835 (save-excursion
836 (goto-char (or (cdr buffer-point) (point-min)))
837 (point-marker))))))
839 (cl-defmethod xref-location-group ((l xref-elisp-location))
840 (xref-elisp-location-file l))
842 (defun elisp-load-path-roots ()
843 (if (boundp 'package-user-dir)
844 (cons package-user-dir load-path)
845 load-path))
847 ;;; Elisp Interaction mode
849 (defvar lisp-interaction-mode-map
850 (let ((map (make-sparse-keymap))
851 (menu-map (make-sparse-keymap "Lisp-Interaction")))
852 (set-keymap-parent map lisp-mode-shared-map)
853 (define-key map "\e\C-x" 'eval-defun)
854 (define-key map "\e\C-q" 'indent-pp-sexp)
855 (define-key map "\e\t" 'completion-at-point)
856 (define-key map "\n" 'eval-print-last-sexp)
857 (bindings--define-key map [menu-bar lisp-interaction]
858 (cons "Lisp-Interaction" menu-map))
859 (bindings--define-key menu-map [eval-defun]
860 '(menu-item "Evaluate Defun" eval-defun
861 :help "Evaluate the top-level form containing point, or after point"))
862 (bindings--define-key menu-map [eval-print-last-sexp]
863 '(menu-item "Evaluate and Print" eval-print-last-sexp
864 :help "Evaluate sexp before point; print value into current buffer"))
865 (bindings--define-key menu-map [edebug-defun-lisp-interaction]
866 '(menu-item "Instrument Function for Debugging" edebug-defun
867 :help "Evaluate the top level form point is in, stepping through with Edebug"
868 :keys "C-u C-M-x"))
869 (bindings--define-key menu-map [indent-pp-sexp]
870 '(menu-item "Indent or Pretty-Print" indent-pp-sexp
871 :help "Indent each line of the list starting just after point, or prettyprint it"))
872 (bindings--define-key menu-map [complete-symbol]
873 '(menu-item "Complete Lisp Symbol" completion-at-point
874 :help "Perform completion on Lisp symbol preceding point"))
875 map)
876 "Keymap for Lisp Interaction mode.
877 All commands in `lisp-mode-shared-map' are inherited by this map.")
879 (define-derived-mode lisp-interaction-mode emacs-lisp-mode "Lisp Interaction"
880 "Major mode for typing and evaluating Lisp forms.
881 Like Lisp mode except that \\[eval-print-last-sexp] evals the Lisp expression
882 before point, and prints its value into the buffer, advancing point.
883 Note that printing is controlled by `eval-expression-print-length'
884 and `eval-expression-print-level'.
886 Commands:
887 Delete converts tabs to spaces as it moves back.
888 Paragraphs are separated only by blank lines.
889 Semicolons start comments.
891 \\{lisp-interaction-mode-map}"
892 :abbrev-table nil)
894 ;;; Emacs Lisp Byte-Code mode
896 (eval-and-compile
897 (defconst emacs-list-byte-code-comment-re
898 (concat "\\(#\\)@\\([0-9]+\\) "
899 ;; Make sure it's a docstring and not a lazy-loaded byte-code.
900 "\\(?:[^(]\\|([^\"]\\)")))
902 (defun elisp--byte-code-comment (end &optional _point)
903 "Try to syntactically mark the #@NNN ....^_ docstrings in byte-code files."
904 (let ((ppss (syntax-ppss)))
905 (when (and (nth 4 ppss)
906 (eq (char-after (nth 8 ppss)) ?#))
907 (let* ((n (save-excursion
908 (goto-char (nth 8 ppss))
909 (when (looking-at emacs-list-byte-code-comment-re)
910 (string-to-number (match-string 2)))))
911 ;; `maxdiff' tries to make sure the loop below terminates.
912 (maxdiff n))
913 (when n
914 (let* ((bchar (match-end 2))
915 (b (position-bytes bchar)))
916 (goto-char (+ b n))
917 (while (let ((diff (- (position-bytes (point)) b n)))
918 (unless (zerop diff)
919 (when (> diff maxdiff) (setq diff maxdiff))
920 (forward-char (- diff))
921 (setq maxdiff (if (> diff 0) diff
922 (max (1- maxdiff) 1)))
923 t))))
924 (if (<= (point) end)
925 (put-text-property (1- (point)) (point)
926 'syntax-table
927 (string-to-syntax "> b"))
928 (goto-char end)))))))
930 (defun elisp-byte-code-syntax-propertize (start end)
931 (goto-char start)
932 (elisp--byte-code-comment end (point))
933 (funcall
934 (syntax-propertize-rules
935 (emacs-list-byte-code-comment-re
936 (1 (prog1 "< b" (elisp--byte-code-comment end (point))))))
937 start end))
939 ;;;###autoload
940 (add-to-list 'auto-mode-alist '("\\.elc\\'" . elisp-byte-code-mode))
941 ;;;###autoload
942 (define-derived-mode elisp-byte-code-mode emacs-lisp-mode
943 "Elisp-Byte-Code"
944 "Major mode for *.elc files."
945 ;; TODO: Add way to disassemble byte-code under point.
946 (setq-local open-paren-in-column-0-is-defun-start nil)
947 (setq-local syntax-propertize-function
948 #'elisp-byte-code-syntax-propertize))
951 ;;; Globally accessible functionality
953 (defun eval-print-last-sexp (&optional eval-last-sexp-arg-internal)
954 "Evaluate sexp before point; print value into current buffer.
956 Normally, this function truncates long output according to the value
957 of the variables `eval-expression-print-length' and
958 `eval-expression-print-level'. With a prefix argument of zero,
959 however, there is no such truncation. Such a prefix argument
960 also causes integers to be printed in several additional formats
961 \(octal, hexadecimal, and character).
963 If `eval-expression-debug-on-error' is non-nil, which is the default,
964 this command arranges for all errors to enter the debugger."
965 (interactive "P")
966 (let ((standard-output (current-buffer)))
967 (terpri)
968 (eval-last-sexp (or eval-last-sexp-arg-internal t))
969 (terpri)))
972 (defun last-sexp-setup-props (beg end value alt1 alt2)
973 "Set up text properties for the output of `elisp--eval-last-sexp'.
974 BEG and END are the start and end of the output in current-buffer.
975 VALUE is the Lisp value printed, ALT1 and ALT2 are strings for the
976 alternative printed representations that can be displayed."
977 (let ((map (make-sparse-keymap)))
978 (define-key map "\C-m" 'elisp-last-sexp-toggle-display)
979 (define-key map [down-mouse-2] 'mouse-set-point)
980 (define-key map [mouse-2] 'elisp-last-sexp-toggle-display)
981 (add-text-properties
982 beg end
983 `(printed-value (,value ,alt1 ,alt2)
984 mouse-face highlight
985 keymap ,map
986 help-echo "RET, mouse-2: toggle abbreviated display"
987 rear-nonsticky (mouse-face keymap help-echo
988 printed-value)))))
991 (defun elisp-last-sexp-toggle-display (&optional _arg)
992 "Toggle between abbreviated and unabbreviated printed representations."
993 (interactive "P")
994 (save-restriction
995 (widen)
996 (let ((value (get-text-property (point) 'printed-value)))
997 (when value
998 (let ((beg (or (previous-single-property-change (min (point-max) (1+ (point)))
999 'printed-value)
1000 (point)))
1001 (end (or (next-single-char-property-change (point) 'printed-value) (point)))
1002 (standard-output (current-buffer))
1003 (point (point)))
1004 (delete-region beg end)
1005 (insert (nth 1 value))
1006 (or (= beg point)
1007 (setq point (1- (point))))
1008 (last-sexp-setup-props beg (point)
1009 (nth 0 value)
1010 (nth 2 value)
1011 (nth 1 value))
1012 (goto-char (min (point-max) point)))))))
1014 (defun prin1-char (char) ;FIXME: Move it, e.g. to simple.el.
1015 "Return a string representing CHAR as a character rather than as an integer.
1016 If CHAR is not a character, return nil."
1017 (and (integerp char)
1018 (eventp char)
1019 (let ((c (event-basic-type char))
1020 (mods (event-modifiers char))
1021 string)
1022 ;; Prevent ?A from turning into ?\S-a.
1023 (if (and (memq 'shift mods)
1024 (zerop (logand char ?\S-\^@))
1025 (not (let ((case-fold-search nil))
1026 (char-equal c (upcase c)))))
1027 (setq c (upcase c) mods nil))
1028 ;; What string are we considering using?
1029 (condition-case nil
1030 (setq string
1031 (concat
1033 (mapconcat
1034 (lambda (modif)
1035 (cond ((eq modif 'super) "\\s-")
1036 (t (string ?\\ (upcase (aref (symbol-name modif) 0)) ?-))))
1037 mods "")
1038 (cond
1039 ((memq c '(?\; ?\( ?\) ?\{ ?\} ?\[ ?\] ?\" ?\' ?\\)) (string ?\\ c))
1040 ((eq c 127) "\\C-?")
1042 (string c)))))
1043 (error nil))
1044 ;; Verify the string reads a CHAR, not to some other character.
1045 ;; If it doesn't, return nil instead.
1046 (and string
1047 (= (car (read-from-string string)) char)
1048 string))))
1050 (defun elisp--preceding-sexp ()
1051 "Return sexp before the point."
1052 (let ((opoint (point))
1053 (left-quote ?‘)
1054 expr)
1055 (save-excursion
1056 (with-syntax-table emacs-lisp-mode-syntax-table
1057 ;; If this sexp appears to be enclosed in `...' or ‘...’
1058 ;; then ignore the surrounding quotes.
1059 (cond ((eq (preceding-char) ?’)
1060 (progn (forward-char -1) (setq opoint (point))))
1061 ((or (eq (following-char) ?\')
1062 (eq (preceding-char) ?\'))
1063 (setq left-quote ?\`)))
1064 (forward-sexp -1)
1065 ;; If we were after `?\e' (or similar case),
1066 ;; use the whole thing, not just the `e'.
1067 (when (eq (preceding-char) ?\\)
1068 (forward-char -1)
1069 (when (eq (preceding-char) ??)
1070 (forward-char -1)))
1072 ;; Skip over hash table read syntax.
1073 (and (> (point) (1+ (point-min)))
1074 (looking-back "#s" (- (point) 2))
1075 (forward-char -2))
1077 ;; Skip over `#N='s.
1078 (when (eq (preceding-char) ?=)
1079 (let (labeled-p)
1080 (save-excursion
1081 (skip-chars-backward "0-9#=")
1082 (setq labeled-p (looking-at "\\(#[0-9]+=\\)+")))
1083 (when labeled-p
1084 (forward-sexp -1))))
1086 (save-restriction
1087 (if (eq (following-char) left-quote)
1088 ;; vladimir@cs.ualberta.ca 30-Jul-1997: Skip ` in `variable' so
1089 ;; that the value is returned, not the name.
1090 (forward-char))
1091 (when (looking-at ",@?") (goto-char (match-end 0)))
1092 (narrow-to-region (point-min) opoint)
1093 (setq expr (read (current-buffer)))
1094 ;; If it's an (interactive ...) form, it's more useful to show how an
1095 ;; interactive call would use it.
1096 ;; FIXME: Is it really the right place for this?
1097 (when (eq (car-safe expr) 'interactive)
1098 (setq expr
1099 `(call-interactively
1100 (lambda (&rest args) ,expr args))))
1101 expr)))))
1102 (define-obsolete-function-alias 'preceding-sexp 'elisp--preceding-sexp "25.1")
1104 (defun elisp--eval-last-sexp (eval-last-sexp-arg-internal)
1105 "Evaluate sexp before point; print value in the echo area.
1106 If EVAL-LAST-SEXP-ARG-INTERNAL is non-nil, print output into
1107 current buffer. If EVAL-LAST-SEXP-ARG-INTERNAL is `0', print
1108 output with no limit on the length and level of lists, and
1109 include additional formats for integers \(octal, hexadecimal, and
1110 character)."
1111 (let ((standard-output (if eval-last-sexp-arg-internal (current-buffer) t)))
1112 ;; Setup the lexical environment if lexical-binding is enabled.
1113 (elisp--eval-last-sexp-print-value
1114 (eval (eval-sexp-add-defvars (elisp--preceding-sexp)) lexical-binding)
1115 eval-last-sexp-arg-internal)))
1117 (defun elisp--eval-last-sexp-print-value (value &optional eval-last-sexp-arg-internal)
1118 (let ((unabbreviated (let ((print-length nil) (print-level nil))
1119 (prin1-to-string value)))
1120 (print-length (and (not (zerop (prefix-numeric-value
1121 eval-last-sexp-arg-internal)))
1122 eval-expression-print-length))
1123 (print-level (and (not (zerop (prefix-numeric-value
1124 eval-last-sexp-arg-internal)))
1125 eval-expression-print-level))
1126 (beg (point))
1127 end)
1128 (prog1
1129 (prin1 value)
1130 (let ((str (eval-expression-print-format value)))
1131 (if str (princ str)))
1132 (setq end (point))
1133 (when (and (bufferp standard-output)
1134 (or (not (null print-length))
1135 (not (null print-level)))
1136 (not (string= unabbreviated
1137 (buffer-substring-no-properties beg end))))
1138 (last-sexp-setup-props beg end value
1139 unabbreviated
1140 (buffer-substring-no-properties beg end))
1141 ))))
1144 (defvar elisp--eval-last-sexp-fake-value (make-symbol "t"))
1146 (defun eval-sexp-add-defvars (exp &optional pos)
1147 "Prepend EXP with all the `defvar's that precede it in the buffer.
1148 POS specifies the starting position where EXP was found and defaults to point."
1149 (setq exp (macroexpand-all exp)) ;Eager macro-expansion.
1150 (if (not lexical-binding)
1152 (save-excursion
1153 (unless pos (setq pos (point)))
1154 (let ((vars ()))
1155 (goto-char (point-min))
1156 (while (re-search-forward
1157 "(def\\(?:var\\|const\\|custom\\)[ \t\n]+\\([^; '()\n\t]+\\)"
1158 pos t)
1159 (let ((var (intern (match-string 1))))
1160 (and (not (special-variable-p var))
1161 (save-excursion
1162 (zerop (car (syntax-ppss (match-beginning 0)))))
1163 (push var vars))))
1164 `(progn ,@(mapcar (lambda (v) `(defvar ,v)) vars) ,exp)))))
1166 (defun eval-last-sexp (eval-last-sexp-arg-internal)
1167 "Evaluate sexp before point; print value in the echo area.
1168 Interactively, with prefix argument, print output into current buffer.
1170 Normally, this function truncates long output according to the value
1171 of the variables `eval-expression-print-length' and
1172 `eval-expression-print-level'. With a prefix argument of zero,
1173 however, there is no such truncation. Such a prefix argument
1174 also causes integers to be printed in several additional formats
1175 \(octal, hexadecimal, and character).
1177 If `eval-expression-debug-on-error' is non-nil, which is the default,
1178 this command arranges for all errors to enter the debugger."
1179 (interactive "P")
1180 (if (null eval-expression-debug-on-error)
1181 (elisp--eval-last-sexp eval-last-sexp-arg-internal)
1182 (let ((value
1183 (let ((debug-on-error elisp--eval-last-sexp-fake-value))
1184 (cons (elisp--eval-last-sexp eval-last-sexp-arg-internal)
1185 debug-on-error))))
1186 (unless (eq (cdr value) elisp--eval-last-sexp-fake-value)
1187 (setq debug-on-error (cdr value)))
1188 (car value))))
1190 (defun elisp--eval-defun-1 (form)
1191 "Treat some expressions specially.
1192 Reset the `defvar' and `defcustom' variables to the initial value.
1193 \(For `defcustom', use the :set function if there is one.)
1194 Reinitialize the face according to the `defface' specification."
1195 ;; The code in edebug-defun should be consistent with this, but not
1196 ;; the same, since this gets a macroexpanded form.
1197 (cond ((not (listp form))
1198 form)
1199 ((and (eq (car form) 'defvar)
1200 (cdr-safe (cdr-safe form))
1201 (boundp (cadr form)))
1202 ;; Force variable to be re-set.
1203 `(progn (defvar ,(nth 1 form) nil ,@(nthcdr 3 form))
1204 (setq-default ,(nth 1 form) ,(nth 2 form))))
1205 ;; `defcustom' is now macroexpanded to
1206 ;; `custom-declare-variable' with a quoted value arg.
1207 ((and (eq (car form) 'custom-declare-variable)
1208 (default-boundp (eval (nth 1 form) lexical-binding)))
1209 ;; Force variable to be bound, using :set function if specified.
1210 (let ((setfunc (memq :set form)))
1211 (when setfunc
1212 (setq setfunc (car-safe (cdr-safe setfunc)))
1213 (or (functionp setfunc) (setq setfunc nil)))
1214 (funcall (or setfunc 'set-default)
1215 (eval (nth 1 form) lexical-binding)
1216 ;; The second arg is an expression that evaluates to
1217 ;; an expression. The second evaluation is the one
1218 ;; normally performed not by normal execution but by
1219 ;; custom-initialize-set (for example), which does not
1220 ;; use lexical-binding.
1221 (eval (eval (nth 2 form) lexical-binding))))
1222 form)
1223 ;; `defface' is macroexpanded to `custom-declare-face'.
1224 ((eq (car form) 'custom-declare-face)
1225 ;; Reset the face.
1226 (let ((face-symbol (eval (nth 1 form) lexical-binding)))
1227 (setq face-new-frame-defaults
1228 (assq-delete-all face-symbol face-new-frame-defaults))
1229 (put face-symbol 'face-defface-spec nil)
1230 (put face-symbol 'face-override-spec nil))
1231 form)
1232 ((eq (car form) 'progn)
1233 (cons 'progn (mapcar #'elisp--eval-defun-1 (cdr form))))
1234 (t form)))
1236 (defun elisp--eval-defun ()
1237 "Evaluate defun that point is in or before.
1238 The value is displayed in the echo area.
1239 If the current defun is actually a call to `defvar',
1240 then reset the variable using the initial value expression
1241 even if the variable already has some other value.
1242 \(Normally `defvar' does not change the variable's value
1243 if it already has a value.)
1245 Return the result of evaluation."
1246 ;; FIXME: the print-length/level bindings should only be applied while
1247 ;; printing, not while evaluating.
1248 (let ((debug-on-error eval-expression-debug-on-error)
1249 (print-length eval-expression-print-length)
1250 (print-level eval-expression-print-level))
1251 (save-excursion
1252 ;; Arrange for eval-region to "read" the (possibly) altered form.
1253 ;; eval-region handles recording which file defines a function or
1254 ;; variable.
1255 (let ((standard-output t)
1256 beg end form)
1257 ;; Read the form from the buffer, and record where it ends.
1258 (save-excursion
1259 (end-of-defun)
1260 (beginning-of-defun)
1261 (setq beg (point))
1262 (setq form (read (current-buffer)))
1263 (setq end (point)))
1264 ;; Alter the form if necessary.
1265 (let ((form (eval-sexp-add-defvars
1266 (elisp--eval-defun-1 (macroexpand form)))))
1267 (eval-region beg end standard-output
1268 (lambda (_ignore)
1269 ;; Skipping to the end of the specified region
1270 ;; will make eval-region return.
1271 (goto-char end)
1272 form))))))
1273 (let ((str (eval-expression-print-format (car values))))
1274 (if str (princ str)))
1275 ;; The result of evaluation has been put onto VALUES. So return it.
1276 (car values))
1278 (defun eval-defun (edebug-it)
1279 "Evaluate the top-level form containing point, or after point.
1281 If the current defun is actually a call to `defvar' or `defcustom',
1282 evaluating it this way resets the variable using its initial value
1283 expression (using the defcustom's :set function if there is one), even
1284 if the variable already has some other value. \(Normally `defvar' and
1285 `defcustom' do not alter the value if there already is one.) In an
1286 analogous way, evaluating a `defface' overrides any customizations of
1287 the face, so that it becomes defined exactly as the `defface' expression
1288 says.
1290 If `eval-expression-debug-on-error' is non-nil, which is the default,
1291 this command arranges for all errors to enter the debugger.
1293 With a prefix argument, instrument the code for Edebug.
1295 If acting on a `defun' for FUNCTION, and the function was
1296 instrumented, `Edebug: FUNCTION' is printed in the echo area. If not
1297 instrumented, just FUNCTION is printed.
1299 If not acting on a `defun', the result of evaluation is displayed in
1300 the echo area. This display is controlled by the variables
1301 `eval-expression-print-length' and `eval-expression-print-level',
1302 which see."
1303 (interactive "P")
1304 (cond (edebug-it
1305 (require 'edebug)
1306 (eval-defun (not edebug-all-defs)))
1308 (if (null eval-expression-debug-on-error)
1309 (elisp--eval-defun)
1310 (let (new-value value)
1311 (let ((debug-on-error elisp--eval-last-sexp-fake-value))
1312 (setq value (elisp--eval-defun))
1313 (setq new-value debug-on-error))
1314 (unless (eq elisp--eval-last-sexp-fake-value new-value)
1315 (setq debug-on-error new-value))
1316 value)))))
1318 ;;; ElDoc Support
1320 (defvar elisp--eldoc-last-data (make-vector 3 nil)
1321 "Bookkeeping; elements are as follows:
1322 0 - contains the last symbol read from the buffer.
1323 1 - contains the string last displayed in the echo area for variables,
1324 or argument string for functions.
1325 2 - `function' if function args, `variable' if variable documentation.")
1327 (defun elisp-eldoc-documentation-function ()
1328 "`eldoc-documentation-function' (which see) for Emacs Lisp."
1329 (let ((current-symbol (elisp--current-symbol))
1330 (current-fnsym (elisp--fnsym-in-current-sexp)))
1331 (cond ((null current-fnsym)
1332 nil)
1333 ((eq current-symbol (car current-fnsym))
1334 (or (apply #'elisp-get-fnsym-args-string current-fnsym)
1335 (elisp-get-var-docstring current-symbol)))
1337 (or (elisp-get-var-docstring current-symbol)
1338 (apply #'elisp-get-fnsym-args-string current-fnsym))))))
1340 (defun elisp-get-fnsym-args-string (sym &optional index prefix)
1341 "Return a string containing the parameter list of the function SYM.
1342 If SYM is a subr and no arglist is obtainable from the docstring
1343 or elsewhere, return a 1-line docstring."
1344 (let ((argstring
1345 (cond
1346 ((not (and sym (symbolp sym) (fboundp sym))) nil)
1347 ((and (eq sym (aref elisp--eldoc-last-data 0))
1348 (eq 'function (aref elisp--eldoc-last-data 2)))
1349 (aref elisp--eldoc-last-data 1))
1351 (let* ((advertised (gethash (indirect-function sym)
1352 advertised-signature-table t))
1354 (args
1355 (cond
1356 ((listp advertised) advertised)
1357 ((setq doc (help-split-fundoc
1358 (condition-case nil (documentation sym t)
1359 (invalid-function nil))
1360 sym))
1361 (car doc))
1362 (t (help-function-arglist sym)))))
1363 ;; Stringify, and store before highlighting, downcasing, etc.
1364 (elisp--last-data-store sym (elisp-function-argstring args)
1365 'function))))))
1366 ;; Highlight, truncate.
1367 (if argstring
1368 (elisp--highlight-function-argument
1369 sym argstring index
1370 (or prefix
1371 (concat (propertize (symbol-name sym) 'face
1372 (if (functionp sym)
1373 'font-lock-function-name-face
1374 'font-lock-keyword-face))
1375 ": "))))))
1377 (defun elisp--highlight-function-argument (sym args index prefix)
1378 "Highlight argument INDEX in ARGS list for function SYM.
1379 In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'."
1380 ;; FIXME: This should probably work on the list representation of `args'
1381 ;; rather than its string representation.
1382 ;; FIXME: This function is much too long, we need to split it up!
1383 (let ((start nil)
1384 (end 0)
1385 (argument-face 'eldoc-highlight-function-argument)
1386 (args-lst (mapcar (lambda (x)
1387 (replace-regexp-in-string
1388 "\\`[(]\\|[)]\\'" "" x))
1389 (split-string args))))
1390 ;; Find the current argument in the argument string. We need to
1391 ;; handle `&rest' and informal `...' properly.
1393 ;; FIXME: What to do with optional arguments, like in
1394 ;; (defun NAME ARGLIST [DOCSTRING] BODY...) case?
1395 ;; The problem is there is no robust way to determine if
1396 ;; the current argument is indeed a docstring.
1398 ;; When `&key' is used finding position based on `index'
1399 ;; would be wrong, so find the arg at point and determine
1400 ;; position in ARGS based on this current arg.
1401 (when (string-match "&key" args)
1402 (let* (case-fold-search
1403 key-have-value
1404 (sym-name (symbol-name sym))
1405 (cur-w (current-word))
1406 (args-lst-ak (cdr (member "&key" args-lst)))
1407 (limit (save-excursion
1408 (when (re-search-backward sym-name nil t)
1409 (match-end 0))))
1410 (cur-a (if (and cur-w (string-match ":\\([^ ()]*\\)" cur-w))
1411 (substring cur-w 1)
1412 (save-excursion
1413 (let (split)
1414 (when (re-search-backward ":\\([^()\n]*\\)" limit t)
1415 (setq split (split-string (match-string 1) " " t))
1416 (prog1 (car split)
1417 (when (cdr split)
1418 (setq key-have-value t))))))))
1419 ;; If `cur-a' is not one of `args-lst-ak'
1420 ;; assume user is entering an unknown key
1421 ;; referenced in last position in signature.
1422 (other-key-arg (and (stringp cur-a)
1423 args-lst-ak
1424 (not (member (upcase cur-a) args-lst-ak))
1425 (upcase (car (last args-lst-ak))))))
1426 (unless (string= cur-w sym-name)
1427 ;; The last keyword have already a value
1428 ;; i.e :foo a b and cursor is at b.
1429 ;; If signature have also `&rest'
1430 ;; (assume it is after the `&key' section)
1431 ;; go to the arg after `&rest'.
1432 (if (and key-have-value
1433 (save-excursion
1434 (not (re-search-forward ":.*" (point-at-eol) t)))
1435 (string-match "&rest \\([^ ()]*\\)" args))
1436 (setq index nil ; Skip next block based on positional args.
1437 start (match-beginning 1)
1438 end (match-end 1))
1439 ;; If `cur-a' is nil probably cursor is on a positional arg
1440 ;; before `&key', in this case, exit this block and determine
1441 ;; position with `index'.
1442 (when (and cur-a ; A keyword arg (dot removed) or nil.
1443 (or (string-match
1444 (concat "\\_<" (upcase cur-a) "\\_>") args)
1445 (string-match
1446 (concat "\\_<" other-key-arg "\\_>") args)))
1447 (setq index nil ; Skip next block based on positional args.
1448 start (match-beginning 0)
1449 end (match-end 0)))))))
1450 ;; Handle now positional arguments.
1451 (while (and index (>= index 1))
1452 (if (string-match "[^ ()]+" args end)
1453 (progn
1454 (setq start (match-beginning 0)
1455 end (match-end 0))
1456 (let ((argument (match-string 0 args)))
1457 (cond ((string= argument "&rest")
1458 ;; All the rest arguments are the same.
1459 (setq index 1))
1460 ((string= argument "&optional")) ; Skip.
1461 ((string= argument "&allow-other-keys")) ; Skip.
1462 ;; Back to index 0 in ARG1 ARG2 ARG2 ARG3 etc...
1463 ;; like in `setq'.
1464 ((or (and (string-match-p "\\.\\.\\.\\'" argument)
1465 (string= argument (car (last args-lst))))
1466 (and (string-match-p "\\.\\.\\.\\'"
1467 (substring args 1 (1- (length args))))
1468 (= (length (remove "..." args-lst)) 2)
1469 (> index 1) (eq (logand index 1) 1)))
1470 (setq index 0))
1472 (setq index (1- index))))))
1473 (setq end (length args)
1474 start (1- end)
1475 argument-face 'font-lock-warning-face
1476 index 0)))
1477 (let ((doc args))
1478 (when start
1479 (setq doc (copy-sequence args))
1480 (add-text-properties start end (list 'face argument-face) doc))
1481 (setq doc (eldoc-docstring-format-sym-doc prefix doc))
1482 doc)))
1484 ;; Return a string containing a brief (one-line) documentation string for
1485 ;; the variable.
1486 (defun elisp-get-var-docstring (sym)
1487 (cond ((not sym) nil)
1488 ((and (eq sym (aref elisp--eldoc-last-data 0))
1489 (eq 'variable (aref elisp--eldoc-last-data 2)))
1490 (aref elisp--eldoc-last-data 1))
1492 (let ((doc (documentation-property sym 'variable-documentation t)))
1493 (when doc
1494 (let ((doc (eldoc-docstring-format-sym-doc
1495 sym (elisp--docstring-first-line doc)
1496 'font-lock-variable-name-face)))
1497 (elisp--last-data-store sym doc 'variable)))))))
1499 (defun elisp--last-data-store (symbol doc type)
1500 (aset elisp--eldoc-last-data 0 symbol)
1501 (aset elisp--eldoc-last-data 1 doc)
1502 (aset elisp--eldoc-last-data 2 type)
1503 doc)
1505 ;; Note that any leading `*' in the docstring (which indicates the variable
1506 ;; is a user option) is removed.
1507 (defun elisp--docstring-first-line (doc)
1508 (and (stringp doc)
1509 (substitute-command-keys
1510 (save-match-data
1511 ;; Don't use "^" in the regexp below since it may match
1512 ;; anywhere in the doc-string.
1513 (let ((start (if (string-match "\\`\\*" doc) (match-end 0) 0)))
1514 (cond ((string-match "\n" doc)
1515 (substring doc start (match-beginning 0)))
1516 ((zerop start) doc)
1517 (t (substring doc start))))))))
1519 ;; Return a list of current function name and argument index.
1520 (defun elisp--fnsym-in-current-sexp ()
1521 (save-excursion
1522 (let ((argument-index (1- (elisp--beginning-of-sexp))))
1523 ;; If we are at the beginning of function name, this will be -1.
1524 (when (< argument-index 0)
1525 (setq argument-index 0))
1526 ;; Don't do anything if current word is inside a string.
1527 (if (= (or (char-after (1- (point))) 0) ?\")
1529 (list (elisp--current-symbol) argument-index)))))
1531 ;; Move to the beginning of current sexp. Return the number of nested
1532 ;; sexp the point was over or after.
1533 (defun elisp--beginning-of-sexp ()
1534 (let ((parse-sexp-ignore-comments t)
1535 (num-skipped-sexps 0))
1536 (condition-case _
1537 (progn
1538 ;; First account for the case the point is directly over a
1539 ;; beginning of a nested sexp.
1540 (condition-case _
1541 (let ((p (point)))
1542 (forward-sexp -1)
1543 (forward-sexp 1)
1544 (when (< (point) p)
1545 (setq num-skipped-sexps 1)))
1546 (error))
1547 (while
1548 (let ((p (point)))
1549 (forward-sexp -1)
1550 (when (< (point) p)
1551 (setq num-skipped-sexps (1+ num-skipped-sexps))))))
1552 (error))
1553 num-skipped-sexps))
1555 ;; returns nil unless current word is an interned symbol.
1556 (defun elisp--current-symbol ()
1557 (let ((c (char-after (point))))
1558 (and c
1559 (memq (char-syntax c) '(?w ?_))
1560 (intern-soft (current-word)))))
1562 (defun elisp-function-argstring (arglist)
1563 "Return ARGLIST as a string enclosed by ().
1564 ARGLIST is either a string, or a list of strings or symbols."
1565 (let ((str (cond ((stringp arglist) arglist)
1566 ((not (listp arglist)) nil)
1567 (t (substitute-command-keys
1568 (help--make-usage-docstring 'toto arglist))))))
1569 (if (and str (string-match "\\`([^ )]+ ?" str))
1570 (replace-match "(" t t str)
1571 str)))
1573 (provide 'elisp-mode)
1574 ;;; elisp-mode.el ends here