使用动态菜单添加按钮到emacs的模式行?

Bad*_*ptr 8 emacs elisp modeline

我正在为emacs制作自己的次要模式.现在我想添加按钮到modeline.必须单击此按钮才会出现弹出菜单.此菜单的项目取决于用户的操作.我知道有一种方法可以使用`minor-mode-alist'向modeline添加一个功能按钮,但我不知道如何制作动态菜单.

Bad*_*ptr 6

好.解决方案成立.:)
首先:定义一些keymap:

(defconst my-mode-line-map
  (let ((map (make-sparse-keymap)))
    (define-key map [mode-line down-mouse-1]
      (make-sparse-keymap))
    map))
Run Code Online (Sandbox Code Playgroud)

第二:将带有属性字符串的列表附加到模式行:

(setq global-mode-string 
  (append global-mode-string 
    (list
      (propertize string-name
        'local-map my-mode-line-map
        'mouse-face 'mode-line-highlight))))
Run Code Online (Sandbox Code Playgroud)

第三:现在你可以添加项目了

 (define-key my-mode-line-map 
   (vconcat [mode-line down-mouse-1]
     (list some_generated_id_for_future_use))
   (cons name function))
Run Code Online (Sandbox Code Playgroud)

...并删除

 (define-key my-mode-line-map 
   (vconcat [mode-line down-mouse-1] 
     (list id_of_button_that_u_gave_when_add))
   nil)
Run Code Online (Sandbox Code Playgroud)


Bad*_*ptr 1

我找到了更合适的方法:当你定义次要模式时,你可以指定 :lighter param

(define-minor-mode my-minor-mode
  "docstring"
  nil
  :lighter (:eval (format "%s%.5s" "#" "some code if you want dynamic label"))
  ;or just string :lighter "static string"
  :keymap my-minor-mode-map
... ... ... rest of code ....
Run Code Online (Sandbox Code Playgroud)

然后你可以使用简易菜单:

(require 'easymenu)

(easy-menu-define my-minor-mode-menu
  my-minor-mode-map
  "Menu for my-minor-mode"
   '("some text"
      "-")) ;separator

; and then add menu items with easy-menu-add-item and remove with easy-menu-remove-item
; it's nothing hard. Read the docs ;)
Run Code Online (Sandbox Code Playgroud)

该菜单将被添加到全局菜单栏,如果您单击模型行上的自动添加(因为您指定了:lighter 参数)次要模式按钮,它将弹出。