• which-func-mode in derived mode

    From Axel Reichert@mail@axel-reichert.de to gnu.emacs.help on Thu Jun 8 18:45:12 2023
    From Newsgroup: gnu.emacs.help

    --=-=-=
    Content-Type: text/plain

    Hello,

    I am struggling to get which-function-mode activated in a derived
    mode. I have trimmed the problem down successfully to a minimum example
    that looks as follows:


    --=-=-=
    Content-Type: application/emacs-lisp
    Content-Disposition: inline; filename=mini-mode.el
    Content-Transfer-Encoding: quoted-printable

    (add-to-list 'auto-mode-alist '("\\.mini\\'" . mini-mode))

    (defun mini-mode-which-func ()
    "XXX")

    (add-hook 'which-func-functions #'mini-mode-which-func)

    (define-derived-mode mini-mode
    text-mode "Mini"
    "Major mode for editing .mini files."
    (add-hook 'mini-mode-hook #'(lambda ()
    (setq-local foo "bar")
    (which-function-mode 1)
    (setq-local which-function-mode t)
    (setq-local which-func-mode t)
    (message "Hook has been setup.")))
    (run-mode-hooks))

    (provide 'mini)

    --=-=-=
    Content-Type: text/plain


    When I start GUN Emacs 27.1 (Devuan Linux) with

    emacs -Q -l mini-mode.el foo.mini

    it opens an empty foo.mini correcty in mini-mode, as confirmed by C-h m
    and the mode line.

    C-h v foo RET

    shows that foo is locally set to "bar", but void globally. Likewise, which-function-mode (the variable) is set to t, but which-func-mode is
    nil, even though I have set it to t in my mode's hook. This hook is
    executed, as confirmed by the text message "Hook has been setup"
    immediately after opening foo.mini.

    However, the dummy "XXX" used as "which-func" is not shown in the mode
    line.

    Only if I run

    M-x mini-mode RET

    again or do a

    M-: (setq-local which-func-mode t) RET

    the "XXX" appears in the mode line, as desired.

    What I am doing wrong or how do I get which-func-mode activated in my
    derived mode automatically?

    Pointers much appreciated!

    Best regards

    Axel

    --=-=-=--
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Thomas Dupond@thomas@dupond.eu to gnu.emacs.help on Fri Jun 9 10:55:23 2023
    From Newsgroup: gnu.emacs.help

    Dear Alex,

    Axel Reichert <mail@axel-reichert.de> a |-crit :
    Hello,

    I am struggling to get which-function-mode activated in a derived
    mode. I have trimmed the problem down successfully to a minimum example
    that looks as follows:

    (add-to-list 'auto-mode-alist '("\\.mini\\'" . mini-mode))

    (defun mini-mode-which-func ()
    "XXX")

    (add-hook 'which-func-functions #'mini-mode-which-func)

    (define-derived-mode mini-mode
    text-mode "Mini"
    "Major mode for editing .mini files."
    (add-hook 'mini-mode-hook #'(lambda ()
    (setq-local foo "bar")
    (which-function-mode 1)
    (setq-local which-function-mode t)
    (setq-local which-func-mode t)
    (message "Hook has been setup.")))
    (run-mode-hooks))

    (provide 'mini)


    When I start GUN Emacs 27.1 (Devuan Linux) with

    emacs -Q -l mini-mode.el foo.mini

    it opens an empty foo.mini correcty in mini-mode, as confirmed by C-h m
    and the mode line.

    C-h v foo RET

    shows that foo is locally set to "bar", but void globally. Likewise, which-function-mode (the variable) is set to t, but which-func-mode is
    nil, even though I have set it to t in my mode's hook. This hook is
    executed, as confirmed by the text message "Hook has been setup"
    immediately after opening foo.mini.

    However, the dummy "XXX" used as "which-func" is not shown in the mode
    line.

    Only if I run

    M-x mini-mode RET

    again or do a

    M-: (setq-local which-func-mode t) RET

    the "XXX" appears in the mode line, as desired.

    What I am doing wrong or how do I get which-func-mode activated in my
    derived mode automatically?

    Pointers much appreciated!

    I do not know really the issue, however I think that it has to do with
    imenu. It looks like which-functions-mode uses imenu to understand
    where begins and ends a function. Trying to use imenu in Text Mode
    throws an error.

    Regards,
    Thomas
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Axel Reichert@mail@axel-reichert.de to gnu.emacs.help on Fri Jun 9 17:31:45 2023
    From Newsgroup: gnu.emacs.help

    Thomas Dupond <thomas@dupond.eu> writes:

    Axel Reichert <mail@axel-reichert.de> a |-crit :

    What I am doing wrong or how do I get which-func-mode activated in my
    derived mode automatically?

    Pointers much appreciated!

    I do not know really the issue, however I think that it has to do with
    imenu. It looks like which-functions-mode uses imenu to understand
    where begins and ends a function. Trying to use imenu in Text Mode
    throws an error.

    I had this suspicion as well, but discarded it because the second

    M-x mini-mode

    succeeds, as does setting which-func-mode to t manually. However, just
    for the sake of testing, I have now based my mini-mode not on text-mode,
    but on c-mode, and, heureka, the "XXX" is shown in the mode line!

    Now I will search the docs about Imenu and try to find out how to teach
    it that text-mode is not a no-go. Let's see.

    Thanks for the hint!

    Axel
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Thomas Dupond@thomas@dupond.eu to gnu.emacs.help on Mon Jun 12 14:44:47 2023
    From Newsgroup: gnu.emacs.help

    Dear Alex,

    Axel Reichert <mail@axel-reichert.de> a |-crit :
    Thomas Dupond <thomas@dupond.eu> writes:

    Axel Reichert <mail@axel-reichert.de> a |-crit :

    What I am doing wrong or how do I get which-func-mode activated in my
    derived mode automatically?

    Pointers much appreciated!

    I do not know really the issue, however I think that it has to do with
    imenu. It looks like which-functions-mode uses imenu to understand
    where begins and ends a function. Trying to use imenu in Text Mode
    throws an error.

    I had this suspicion as well, but discarded it because the second

    M-x mini-mode

    succeeds, as does setting which-func-mode to t manually. However, just
    for the sake of testing, I have now based my mini-mode not on text-mode,
    but on c-mode, and, heureka, the "XXX" is shown in the mode line!

    Now I will search the docs about Imenu and try to find out how to teach
    it that text-mode is not a no-go. Let's see.

    I delved a little bit deeper and apparently you should be able to do
    what you want after you have defined the variable
    imenu-generic-expression or the variable imenu-create-index-function.
    Fortran mode uses the former and Org mode the latter (respectively in fortran-mode.el and org-compat.el).

    For example I wrote this based on your first message and it displays
    the current markdown-like title (only for lines beginning
    with one or two stars) with which-func:

    (add-to-list 'auto-mode-alist '("\\.mini\\'" . mini-mode))

    (define-derived-mode mini-mode
    text-mode "Mini"
    "Major mode for editing .mini files."
    (which-function-mode 1)
    (defvar mini-imenu-generic-expression
    (list
    (list
    nil
    "^\*\\ \\(.*\\)$"
    1)
    (list
    nil
    "^\*\*\\ \\(.*\\)$"
    1)))
    (set (make-local-variable 'imenu-generic-expression)
    mini-imenu-generic-expression))

    (provide 'mini)

    --
    Regards,
    Thomas
    --- Synchronet 3.21d-Linux NewsLink 1.2
  • From Axel Reichert@mail@axel-reichert.de to gnu.emacs.help on Fri Jun 16 07:52:15 2023
    From Newsgroup: gnu.emacs.help

    Thomas Dupond <thomas@dupond.eu> writes:

    I delved a little bit deeper and apparently you should be able to do
    what you want after you have defined the variable
    imenu-generic-expression or the variable imenu-create-index-function.
    Fortran mode uses the former and Org mode the latter (respectively in fortran-mode.el and org-compat.el).

    Many thanks for your research! It works now:

    (add-to-list 'auto-mode-alist '("\\.mini2\\'" . mini2-mode))

    (defun mini2-mode-which-func ()
    "XXX")

    (add-hook 'which-func-functions #'mini2-mode-which-func)

    (define-derived-mode mini2-mode
    text-mode "Mini2"
    "Major mode for editing .mini2 files."
    (which-function-mode 1)
    (defvar mini2-imenu-generic-expression
    (list
    (list
    nil
    "^\*\\ \\(.*\\)$"
    1)
    (list
    nil
    "^\*\*\\ \\(.*\\)$"
    1)))
    (set (make-local-variable 'imenu-generic-expression)
    mini2-imenu-generic-expression))

    (provide 'mini2)

    correctly shows "XXX" in the mode line after

    emacs -Q -l mini2-mode.el foo.mini2

    Thanks again and best regards

    Axel (not Alex)
    --- Synchronet 3.21d-Linux NewsLink 1.2