9

I am using (which-function-mode t) to show current function name / org-heading on the mode line. I would like to limit the number of characters it shows on the mode line, but I couldn't find any option like max-func-name in which-func.el.

I can limit the string by redefining which-func-update-1 with (which-function) replaced by (truncate-string-to-width (which-function) 30):

(defun which-func-update-1 (window)
  "Update the Which Function mode display for window WINDOW."
  (with-selected-window window
    (when which-func-mode
      (condition-case info
          (let ((current (truncate-string-to-width (which-function) 30)))
            (unless (equal current (gethash window which-func-table))
              (puthash window current which-func-table)
              (force-mode-line-update)))
        (error
         (setq which-func-mode nil)
         (error "Error in which-func-update: %S" info))))))

But it is too hacky..

I tried to use advice as follow:

(defadvice which-func-update-1 (around testing activate)
  (cl-letf (((symbol-function 'which-function) (lambda () (truncate-string-to-width (which-function) 30)))) 
    ad-do-it))

But it generates infinite loop.

Anyone know how to limit the string length without modifying which-func.el? Thanks.

2 Answers 2

3

By inspecting which-function's source, this was found at the end of the definition:

    ;; Filter the name if requested.
    (when name
      (if which-func-cleanup-function
      (funcall which-func-cleanup-function name)
    name))

(I have no idea whether this was added in a recent Emacs version.)

Therefore, setting which-func-cleanup-function seems to be the "official" way to customize it's output now.

For example:

(defun my-which-func-cleanup-function (str)
  (truncate-string-to-width str 30))
(setq which-func-cleanup-function #'my-which-func-cleanup-function)

Edit: Correct argument usage

Edit2: Correctly use defun outside of setq

3
  • 1
    Should the "s" be "str"? Commented Jun 16, 2021 at 11:06
  • 1
    The return value of defun is undefined.
    – Basil
    Commented Jun 19, 2021 at 16:00
  • @Basil oh I didn't know that, thank you for pointing it out, I just always assumed that defun returned the function symbol
    – Daanturo
    Commented Jun 20, 2021 at 8:34
8

Instead of around advice use filter-return which will get the return value of the advised function and can do what it likes with it:

(advice-add 'which-function :filter-return
            (lambda (s) (truncate-string-to-width s 30)))
1
  • I suggest either a) using define-advice; b) using a named function in place of a lambda; or c) passing a name property in the last argument to advice-add, so that the advice can easily be removed as needed.
    – Basil
    Commented Jun 19, 2021 at 16:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.