elisp: create dynamic menu with easy-menu and evaluate part of code during creation and not when called

136 views Asked by At

I'm trying to create a dynamic menu for my own compiling plugin, but I have hit a wall. This is the code that I have at the moment:

(defun mme-tools-create-menu ()
  (easy-menu-define mme-tools-menu erlang-mode-map "MME-Tools-Menu" 
    '("MME-Tools"
      ("Current Subsystem"
       ["Run gmake" mme-tools-build]
       ["Build beams" mme-tools-build-beam]
       ["Run Posttest" mme-tools-build-posttest]
       ["Run Move" mme-tools-build-move])
      ("Build Subsystem")))
  (dolist (path mmepaths)
    (if (string-match "code" path)
        (let* ((ss (file-name-base path))
               (uss (upcase ss)))
          (easy-menu-add-item mme-tools-menu '("Build Subsystem") 
                              [uss (mme-tools-build-path-subsystem " -j10 beam" (getenv ss))])))))

What I want the code to do is to make a sub-menu called "Build Subsystem" and fill it with entries. But no entries are created. Any help would be appreciated.

2

There are 2 answers

2
Stefan On

I'd suggest you do something like

(easy-menu-define mme-tools-menu erlang-mode-map "MME-Tools-Menu"
  `("MME-Tools"
    ("Current Subsystem"
     ["Run gmake" mme-tools-build]
     ["Build beams" mme-tools-build-beam]
     ["Run Posttest" mme-tools-build-posttest]
     ["Run Move" mme-tools-build-move])
    ("Build Subsystem"
     ,@(mapcar (lambda (path)
                 (when (string-match "code" path)
                   (let* ((ss (file-name-base path))
                          (uss (upcase ss)))
                     (vector uss `(mme-tools-build-path-subsystem " -j10 beam" (getenv ',ss))))))))))
0
Drew On

I suspect you might be looking for something like this, but it's hard to know without seeing more code. You should be able to debug this yourself, using macroexpand etc. until you get a proper set of arguments to pass to easy-menu-define.

Wrt Stefan's code, this adds the missing mapcar second arg, as you mentioned, and it removes the backquote before (mme-tools-build-path-subsystem...) (just a guess).

(easy-menu-define
    mme-tools-menu
    erlang-mode-map "MME-Tools-Menu"
    `("MME-Tools"
      ("Current Subsystem"
       ["Run gmake" mme-tools-build]
       ["Build beams" mme-tools-build-beam]
       ["Run Posttest" mme-tools-build-posttest]
       ["Run Move" mme-tools-build-move])
      ("Build Subsystem"
       ,@(mapcar (lambda (path)
                   (when (string-match "code" path)
                     (let* ((ss (file-name-base path))
                            (uss (upcase ss)))
                       (vector uss
                               (mme-tools-build-path-subsystem
                                 " -j10 beam" (getenv ',ss))))))
                 mmepaths))))