imenu不适用于python模式或c ++模式

RNA*_*RNA 2 emacs

imenu为我工作emacs-lisp-mode-hook.但是当我为python或c ++模式尝试以下操作时,它不起作用:

(add-hook 'python-mode-hook
          (lambda ()
             (add-to-list
              'imenu-generic-expression
              '("Sections" "^#### [ \\(.+\\) ]$" 1))
             (imenu-add-to-menubar "Position")))

(add-hook 'c++-mode-hook
          (lambda ()
             (add-to-list
              'imenu-generic-expression
              '("Sections" "^//// [ \\(.+\\) ]$" 1))
             (imenu-add-to-menubar "Position")))
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么?

小智 8

问题是这两种模式(假设你使用内置python-mode),设置imenu-create-index-function(用于创建索引的函数)imenu-default-create-index-function.此函数依次尝试使用imenu-prev-index-position-function,imenu-extract-index-name-function提取imenu 的值,imenu-generic-expression如果设置了两个变量,则不使用if(参见imenu-default-create-index-functionin 的定义imenu.el).这就是为什么不使用您设置的值的原因.我们在这里可以做的是定义一个使用两者的自定义函数,imenu-default-create-index-functionimenu-generic-expression结合它们的结果并返回它.然后我们可以设置imenu-create-index-function自定义函数的值.下面是这种自定义函数的示例

(defun my-merge-imenu ()
  (interactive)
  (let ((mode-imenu (imenu-default-create-index-function))
        (custom-imenu (imenu--generic-function imenu-generic-expression)))
    (append mode-imenu custom-imenu)))
Run Code Online (Sandbox Code Playgroud)

然后我们可以将其设置imenu-create-index-function为主模式挂钩的值,例如.对于python-mode

(add-hook 'python-mode-hook
          (lambda ()
            (add-to-list
             'imenu-generic-expression
             '("Sections" "^#### \\[ \\(.*\\) \\]$" 1))
            (imenu-add-to-menubar "Position")
            (setq imenu-create-index-function 'my-merge-imenu)))
Run Code Online (Sandbox Code Playgroud)

类似的解决方案应该适用c++-mode.

关于使用正则表达式的说明:有一个在你的正则表达式的错误,因为[是你需要逃避它来搭配正常的元字符[,你还需要逃避\,因为你是在一个字符串,所以正确的正则表达式的字符串会"^#### \\[ \\(.*\\) \\]$"