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