From: Alan Mackenzie Date: Wed, 20 May 2020 18:02:13 +0000 (+0000) Subject: which-function-mode: put hook function on after-change-major-mode-hook X-Git-Tag: emacs-28.0.90~7311 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=bd64571ef213a4279f897b7446e97ccd76fe4516;p=emacs.git which-function-mode: put hook function on after-change-major-mode-hook , rather than find-file-hook. This keeps which-function-mode active should the major mode be reinitialized. Also accept a null result from add-log-current-defun as definitive, should that function have run. This fixes bug #40714. * lisp/progmodes/which-func.el (which-func-ff-hook): Put on after-change-major-mode-hook. (which-function): Enhance the logic to accept a null result from add-log-current-defun. --- diff --git a/lisp/progmodes/which-func.el b/lisp/progmodes/which-func.el index 1cee552b0c0..266f40abbae 100644 --- a/lisp/progmodes/which-func.el +++ b/lisp/progmodes/which-func.el @@ -186,7 +186,7 @@ and you want to simplify them for the mode line "Non-nil means display current function name in mode line. This makes a difference only if `which-function-mode' is non-nil.") -(add-hook 'find-file-hook 'which-func-ff-hook t) +(add-hook 'after-change-major-mode-hook 'which-func-ff-hook t) (defun which-func-try-to-enable () (unless (or (not which-function-mode) @@ -195,7 +195,7 @@ This makes a difference only if `which-function-mode' is non-nil.") (member major-mode which-func-modes))))) (defun which-func-ff-hook () - "File find hook for Which Function mode. + "`after-change-major-mode-hook' for Which Function mode. It creates the Imenu index for the buffer, if necessary." (which-func-try-to-enable) @@ -282,52 +282,55 @@ If no function name is found, return nil." (when (null name) (setq name (add-log-current-defun))) ;; If Imenu is loaded, try to make an index alist with it. + ;; If `add-log-current-defun' ran and gave nil, accept that. (when (and (null name) - (boundp 'imenu--index-alist) - (or (null imenu--index-alist) - ;; Update if outdated - (/= (buffer-chars-modified-tick) imenu-menubar-modified-tick)) - (null which-function-imenu-failed)) - (ignore-errors (imenu--make-index-alist t)) - (unless imenu--index-alist - (set (make-local-variable 'which-function-imenu-failed) t))) - ;; If we have an index alist, use it. - (when (and (null name) - (boundp 'imenu--index-alist) imenu--index-alist) - (let ((alist imenu--index-alist) - (minoffset (point-max)) - offset pair mark imstack namestack) - ;; Elements of alist are either ("name" . marker), or - ;; ("submenu" ("name" . marker) ... ). The list can be - ;; arbitrarily nested. - (while (or alist imstack) - (if (null alist) - (setq alist (car imstack) - namestack (cdr namestack) - imstack (cdr imstack)) - - (setq pair (car-safe alist) - alist (cdr-safe alist)) - - (cond - ((atom pair)) ; Skip anything not a cons. - - ((imenu--subalist-p pair) - (setq imstack (cons alist imstack) - namestack (cons (car pair) namestack) - alist (cdr pair))) - - ((or (number-or-marker-p (setq mark (cdr pair))) - (and (overlayp mark) - (setq mark (overlay-start mark)))) - (when (and (>= (setq offset (- (point) mark)) 0) - (< offset minoffset)) ; Find the closest item. - (setq minoffset offset - name (if (null which-func-imenu-joiner-function) - (car pair) - (funcall - which-func-imenu-joiner-function - (reverse (cons (car pair) namestack)))))))))))) + (null add-log-current-defun-function)) + (when (and (null name) + (boundp 'imenu--index-alist) + (or (null imenu--index-alist) + ;; Update if outdated + (/= (buffer-chars-modified-tick) imenu-menubar-modified-tick)) + (null which-function-imenu-failed)) + (ignore-errors (imenu--make-index-alist t)) + (unless imenu--index-alist + (set (make-local-variable 'which-function-imenu-failed) t))) + ;; If we have an index alist, use it. + (when (and (null name) + (boundp 'imenu--index-alist) imenu--index-alist) + (let ((alist imenu--index-alist) + (minoffset (point-max)) + offset pair mark imstack namestack) + ;; Elements of alist are either ("name" . marker), or + ;; ("submenu" ("name" . marker) ... ). The list can be + ;; arbitrarily nested. + (while (or alist imstack) + (if (null alist) + (setq alist (car imstack) + namestack (cdr namestack) + imstack (cdr imstack)) + + (setq pair (car-safe alist) + alist (cdr-safe alist)) + + (cond + ((atom pair)) ; Skip anything not a cons. + + ((imenu--subalist-p pair) + (setq imstack (cons alist imstack) + namestack (cons (car pair) namestack) + alist (cdr pair))) + + ((or (number-or-marker-p (setq mark (cdr pair))) + (and (overlayp mark) + (setq mark (overlay-start mark)))) + (when (and (>= (setq offset (- (point) mark)) 0) + (< offset minoffset)) ; Find the closest item. + (setq minoffset offset + name (if (null which-func-imenu-joiner-function) + (car pair) + (funcall + which-func-imenu-joiner-function + (reverse (cons (car pair) namestack))))))))))))) ;; Filter the name if requested. (when name (if which-func-cleanup-function