;;; which-func.el --- print current function in mode line
-;; Copyright (C) 1994, 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-;; Free Software Foundation, Inc.
+;; Copyright (C) 1994, 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006
+;; 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
;; Author: Alex Rezinsky <alexr@msil.sps.mot.com>
;; (doesn't seem to be responsive any more)
local-map ,which-func-keymap
face which-func
;;mouse-face highlight ; currently not evaluated :-(
- help-echo "mouse-1: go to beginning, mouse-2: toggle rest visibility, mouse-3: go to end")
+ help-echo "mouse-1: go to beginning\n\
+mouse-2: toggle rest visibility\n\
+mouse-3: go to end")
"]")
"Format for displaying the function in the mode line."
:group 'which-func
:type 'sexp)
;;;###autoload (put 'which-func-format 'risky-local-variable t)
+(defvar which-func-imenu-joiner-function (lambda (x) (car (last x)))
+ "Function to join together multiple levels of imenu nomenclature.
+Called with a single argument, a list of strings giving the names
+of the menus we had to traverse to get to the item. Returns a
+single string, the new name of the item.")
+
(defvar which-func-cleanup-function nil
"Function to transform a string before displaying it in the mode line.
The function is called with one argument, the string to display.
(or (eq which-func-modes t)
(member major-mode which-func-modes))))
- (condition-case nil
+ (condition-case err
(if (and which-func-mode
(not (member major-mode which-func-non-auto-modes))
(or (null which-func-maxout)
(setq imenu--index-alist
(save-excursion (funcall imenu-create-index-function))))
(error
+ (message "which-func-ff-hook error: %S" err)
(setq which-func-mode nil))))
(defun which-func-update ()
(force-mode-line-update)))
(error
(setq which-func-mode nil)
- (error "Error in which-func-update: %s" info))))))
+ (error "Error in which-func-update: %S" info))))))
;;;###autoload
(defalias 'which-func-mode 'which-function-mode)
With prefix ARG, turn Which Function mode on if arg is positive,
and off otherwise."
:global t :group 'which-func
+ (when (timerp which-func-update-timer)
+ (cancel-timer which-func-update-timer))
+ (setq which-func-update-timer nil)
(if which-function-mode
;;Turn it on
(progn
(or (eq which-func-modes t)
(member major-mode which-func-modes))))))
;; Turn it off
- (when (timerp which-func-update-timer)
- (cancel-timer which-func-update-timer))
- (setq which-func-update-timer nil)
(dolist (buf (buffer-list))
(with-current-buffer buf (setq which-func-mode nil)))))
(null which-function-imenu-failed))
(imenu--make-index-alist t)
(unless imenu--index-alist
- (make-local-variable 'which-function-imenu-failed)
- (setq which-function-imenu-failed t)))
+ (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 elem pair mark)
- (while alist
- (setq elem (car-safe alist)
- alist (cdr-safe alist))
- ;; Elements of alist are either ("name" . marker), or
- ;; ("submenu" ("name" . marker) ... ).
- (unless (listp (cdr elem))
- (setq elem (list elem)))
- (while elem
- (setq pair (car elem)
- elem (cdr elem))
- (and (consp pair)
- (number-or-marker-p (setq mark (cdr pair)))
- (if (>= (setq offset (- (point) mark)) 0)
- (if (< offset minoffset) ; find the closest item
- (setq minoffset offset
- name (car pair)))
- ;; Entries in order, so can skip all those after point.
- (setq elem nil)))))))
+ 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)))
+
+ ((number-or-marker-p (setq mark (cdr pair)))
+ (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))))))))))))
+
;; Try using add-log support.
(when (and (null name) (boundp 'add-log-current-defun-function)
add-log-current-defun-function)