diff options
author | Philip Kaludercic <philipk@posteo.net> | 2022-08-12 16:05:05 +0200 |
---|---|---|
committer | Philip Kaludercic <philipk@posteo.net> | 2022-08-12 16:05:05 +0200 |
commit | 1823349e6a61b2997b27cdb1ff42c69739693455 (patch) | |
tree | ed09268f8e57ab9196ff59df000c5f1268e09853 /lisp/emacs-lisp/lisp-mode.el | |
parent | faa7f03b0c5b6d2c51bb185cf5a0f422ba0fb956 (diff) | |
parent | 829b131e5b3ad3b077be9d31215770b251341c68 (diff) | |
download | emacs-1823349e6a61b2997b27cdb1ff42c69739693455.tar.gz emacs-1823349e6a61b2997b27cdb1ff42c69739693455.tar.bz2 emacs-1823349e6a61b2997b27cdb1ff42c69739693455.zip |
Merge remote-tracking branch 'origin/master' into feature/package+vc
Diffstat (limited to 'lisp/emacs-lisp/lisp-mode.el')
-rw-r--r-- | lisp/emacs-lisp/lisp-mode.el | 68 |
1 files changed, 50 insertions, 18 deletions
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index c906ee6e31d..c31fbec640c 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -728,30 +728,62 @@ font-lock keywords will not be case sensitive." len)))) (defun lisp-current-defun-name () - "Return the name of the defun at point, or nil." + "Return the name of the defun at point. +If there is no defun at point, return the first symbol from the +top-level form. If there is no top-level form, return nil. + +(\"defun\" here means \"form that defines something\", and is +decided heuristically.)" (save-excursion - (let ((location (point))) + (let ((location (point)) + name) ;; If we are now precisely at the beginning of a defun, make sure ;; beginning-of-defun finds that one rather than the previous one. - (or (eobp) (forward-char 1)) + (unless (eobp) + (forward-char 1)) (beginning-of-defun) ;; Make sure we are really inside the defun found, not after it. - (when (and (looking-at "\\s(") - (progn (end-of-defun) - (< location (point))) - (progn (forward-sexp -1) - (>= location (point)))) - (if (looking-at "\\s(") - (forward-char 1)) - ;; Skip the defining construct name, typically "defun" or + (when (and (looking-at "(") + (progn + (end-of-defun) + (< location (point))) + (progn + (forward-sexp -1) + (>= location (point)))) + (when (looking-at "(") + (forward-char 1)) + ;; Read the defining construct name, typically "defun" or ;; "defvar". - (forward-sexp 1) - ;; The second element is usually a symbol being defined. If it - ;; is not, use the first symbol in it. - (skip-chars-forward " \t\n'(") - (buffer-substring-no-properties (point) - (progn (forward-sexp 1) - (point))))))) + (let ((symbol (ignore-errors (read (current-buffer))))) + (when (and symbol (not (symbolp symbol))) + (setq symbol nil)) + ;; If there's an edebug spec, use that to determine what the + ;; name is. + (when symbol + (let ((spec (get symbol 'edebug-form-spec))) + (save-excursion + (when (and (eq (car-safe spec) '&define) + (memq 'name spec)) + (pop spec) + (while (and spec (not name)) + (let ((candidate (ignore-errors (read (current-buffer))))) + (when (eq (pop spec) 'name) + (setq name candidate + spec nil)))))))) + ;; We didn't have an edebug spec (or couldn't find the + ;; name). If the symbol starts with \"def\", then it's + ;; likely that the next symbol is the name. + (when (and (not name) + (string-match-p "\\(\\`\\|-\\)def" (symbol-name symbol))) + (when-let ((candidate (ignore-errors (read (current-buffer))))) + (cond + ((symbolp candidate) + (setq name candidate)) + ((and (consp candidate) + (symbolp (car (delete 'quote candidate)))) + (setq name (car (delete 'quote candidate))))))) + (when-let ((result (or name symbol))) + (symbol-name result))))))) (defvar-keymap lisp-mode-shared-map :doc "Keymap for commands shared by all sorts of Lisp modes." |