From: Lars Ingebrigtsen Date: Mon, 11 Oct 2021 11:15:41 +0000 (+0200) Subject: Allow :keys in menus to be computed dynamically X-Git-Tag: emacs-29.0.90~3671^2~619 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=74d3a1e7d6450f226d2f942d0c0e3410eea87dfc;p=emacs.git Allow :keys in menus to be computed dynamically * doc/lispref/keymaps.texi (Extended Menu Items): Document it (bug#28930). * src/keyboard.c (parse_menu_item): Allow :keys to be a function. --- diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index 407bdca5ed4..066d8b3693a 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -2319,6 +2319,12 @@ This property specifies that @var{string} is the string to display as the keyboard equivalent for this menu item. You can use the @samp{\\[...]} documentation construct in @var{string}. +This property can also be a function (which will be called with no +arguments). This function should return a string. This function will +be called every time the menu is computed, so using a function that +takes a lot of time to compute is not a good idea, and it should +expect to be called from any context. + @item :filter @var{filter-fn} This property provides a way to compute the menu item dynamically. The property value @var{filter-fn} should be a function of one argument; diff --git a/etc/NEWS b/etc/NEWS index b91a5cbb721..010a6e51e3b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -134,6 +134,11 @@ with recent versions of Firefox. * Lisp Changes in Emacs 29.1 ++++ +** :keys in 'menu-item' can now be a function. +If so, it is called whenever the menu is computed, and can be used to +calculate the keys dynamically. + +++ ** New major mode 'clean-mode'. This is a new major mode meant for debugging. It kills absolutely all diff --git a/src/keyboard.c b/src/keyboard.c index 9a50a5e5eb7..7184b1509b1 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -7841,7 +7841,9 @@ parse_menu_item (Lisp_Object item, int inmenubar) else if (EQ (tem, QCkeys)) { tem = XCAR (item); - if (CONSP (tem) || STRINGP (tem)) + if (FUNCTIONP (tem)) + ASET (item_properties, ITEM_PROPERTY_KEYEQ, call0 (tem)); + else if (CONSP (tem) || STRINGP (tem)) ASET (item_properties, ITEM_PROPERTY_KEYEQ, tem); } else if (EQ (tem, QCbutton) && CONSP (XCAR (item)))