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.

AhLeung
  • 1,083
  • 5
  • 14

2 Answers2

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)))
erikstokes
  • 12,686
  • 2
  • 34
  • 56
  • 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 Jun 19 '21 at 16:02
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

Daanturo
  • 180
  • 8