I have which-function-mode enabled and from time to time it shows ???. Is it possible to customize this to eg '∅'. I have tried to customize group "Which Func" but did not find something suiteable.

Also I do not completely understand when ??? is shown and what is means.

  • 1
    I would have tagged this question with which-function-mode but lack the reputation necessary to get this privilige.
    – Matthias
    Oct 25 '16 at 7:55

??? is displayed if which-func-mode (or which-function-mode in Emacs 25) can't determine the name of the current function. To customize it, modify the variable which-func-unknown, which is the "String to display in the mode line when current function is unknown."

(setq which-func-unknown "∅")

Its default value is "???".


??? means which-function-mode can't find current function name.

Read code of which-function-mode you will find that imenu setup in your major mode hook provides function names used by other plugins like which-function-mode.

So the real problem is how to setup imenu in major mode hook.

Here is a simplified version of my setup for js-mode,

(setq javascript-common-imenu-regex-list
      '(("Controller" "[. \t]controller([ \t]*['\"]\\([^'\"]+\\)" 1)
        ("Controller" "[. \t]controllerAs:[ \t]*['\"]\\([^'\"]+\\)" 1)
        ("Filter" "[. \t]filter([ \t]*['\"]\\([^'\"]+\\)" 1)
        ("State" "[. \t]state[(:][ \t]*['\"]\\([^'\"]+\\)" 1)
        ("Factory" "[. \t]factory([ \t]*['\"]\\([^'\"]+\\)" 1)
        ("Service" "[. \t]service([ \t]*['\"]\\([^'\"]+\\)" 1)
        ("Module" "[. \t]module( *['\"]\\([a-zA-Z0-9_.]+\\)['\"], *\\[" 1)
        ("ngRoute" "[. \t]when(\\(['\"][a-zA-Z0-9_\/]+['\"]\\)" 1)
        ("Directive" "[. \t]directive([ \t]*['\"]\\([^'\"]+\\)" 1)
        ("Event" "[. \t]\$on([ \t]*['\"]\\([^'\"]+\\)" 1)
        ("Config" "[. \t]config([ \t]*function *( *\\([^\)]+\\)" 1)
        ("Config" "[. \t]config([ \t]*\\[ *['\"]\\([^'\"]+\\)" 1)
        ("OnChange" "[ \t]*\$(['\"]\\([^'\"]*\\)['\"]).*\.change *( *function" 1)
        ("OnClick" "[ \t]*\$([ \t]*['\"]\\([^'\"]*\\)['\"]).*\.click *( *function" 1)
        ("Watch" "[. \t]\$watch( *['\"]\\([^'\"]+\\)" 1)
        ("Function" "function[ \t]+\\([a-zA-Z0-9_$.]+\\)[ \t]*(" 1)
        ("Function" "^[ \t]*\\([a-zA-Z0-9_$.]+\\)[ \t]*=[ \t]*function[ \t]*(" 1)
        ;; {{ es6 beginning
        ("Function" "^[ \t]*\\([A-Za-z_$][A-Za-z0-9_$]+\\)[ \t]*([a-zA-Z0-9, ]*) *\{ *$" 1) ;; es6 fn1 () { }
        ("Function" "^[ \t]*\\([A-Za-z_$][A-Za-z0-9_$]+\\)[ \t]*=[ \t]*(?[a-zA-Z0-9, ]*)?[ \t]*=>[ \t]*\{ *$" 1) ;; es6 fn1 = (e) => (var, var2) {
        ;; }}
        ("Task" "[. \t]task([ \t]*['\"]\\([^'\"]+\\)" 1)

;; js-mode imenu enhancement
;; @see http://stackoverflow.com/questions/20863386/idomenu-not-working-in-javascript-mode
(defun mo-js-imenu-make-index ()
    (imenu--generic-function javascript-common-imenu-regex-list)))

(defun mo-js-mode-hook ()
  (setq imenu-create-index-function 'mo-js-imenu-make-index))

(add-hook 'js-mode-hook 'mo-js-mode-hook)

My actual setup is more complicated (https://github.com/redguardtoo/emacs.d/blob/master/lisp/init-javascript.el)

Some major modes provide advanced imenu utilities out of the box.

If there are multiple major modes for one programming language, the solution could be as simple as choosing a better major mode.

For example, both js-mode and js2-mode supports javascript, but js2-mode provides better imenu utilities. If you use js2-mode for javascript code, your which-function-mode works with much less manual imenu setup code.

My article http://blog.binchen.org/posts/why-emacs-is-better-editor.html discuss the technical details on hacking js2-mode imenu code if you are still not satisfied with js2-mode's default imenu setup.

The reason you need hacking is that some major modes will provide their own imenu framework. For example, in web-mode you need change web-mode-imenu-regexp-list instead of standard imenu variables.

Grep my emacs configuration at https://github.com/redguardtoo/emacs.d/tree/master/lisp , you will find many samples on imenu setup.

  • Very extensive answer. It really inspires me to go more into depth about imenu and how it works! Thank you.
    – Matthias
    Oct 28 '16 at 8:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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