如何实现类似于Magit中使用的弹出菜单
题 我想以弹出菜单的形式创建用户界面,该弹出菜单类似于Magit中使用的弹出菜单。 特征 弹出窗口的定义 在此问题的上下文中,弹出窗口意味着很少有包含菜单项集合的临时窗口,以便用户可以选择其中一项,并且只能选择其中一项。 在屏幕上的位置 允许弹出窗口出现在屏幕的任何部分,但是希望它应该非常明显,因此应该出现在当前活动的窗口旁边。 弹出缓冲区的内容 项目应以漂亮的表格形式显示。问题的上下文很漂亮,这意味着视觉上很吸引人,可以通过将菜单项置于直行中来轻松实现此效果complete--insert-string,例如参见 。本段用于进一步说明,您可以按照自己的方式进行操作,这不会使您的答案不正确。 菜单项的选择 选择可以通过一次按键或使用鼠标(尽管不是很重要,因此包含不支持鼠标的命题的答案是合法的)来执行。如果您提出支持鼠标的解决方案,请注意,用户应该能够以直观的方式选择菜单项,即,通过左键单击所需的选项。 NB鼠标可以以多种方式使用,也欢迎使用其他方式表示选择。 消除弹出窗口 一旦用户以上述方式选择了菜单项,就应从缓冲区中消除缓冲区并因此将其窗口从视图中清除并杀死。调用弹出菜单之前已处于活动状态的窗口应再次获得焦点(即变为活动状态)。 返回值和参数 优选地,动作的这种结果应该导致返回Lisp对象。Lisp对象可以是: nil—这表示用户已通过按C-g或以其他方式† 终止了弹出菜单。 string—字符串(允许使用符号)应string-equal 位于作为实际项目集合提供给弹出菜单的字符串之一上。 让程序的其余部分知道用户的选择,或者可能没有用户选择的替代方法是可以接受的。但是,如果不清楚如何执行其他操作,请立即让所有答题者即兴回答,也不要要求我进一步说明这方面。 这都是为了返回值。至于输入参数,它们至少应包括代表可能选择(即菜单项)的字符串集合。 可接受的答案 预期答案可以采用以下形式: 足够的代码段,使受过教育的读者可以编写如上所述的功能;不需要或不需要编写整个工作功能。但是,为了避免不确定性(可以省略大量代码吗?),我应该注意,应在答案的文本部分中描述代码段的缺失部分。 指向实现类似功能的现有库的链接。为避免不确定性,我应该注意,在我们的情况下,类似意味着该库可用于创建具有至少2个或3个上述功能的弹出窗口(请参见上面的定义)。如果提议的库与无法满足先前陈述的条件不同,则将对每个此类情况进行独立判断,并且如果OP认为有用,将始终予以驳回。 内置Emacs功能或第三方功能的描述,这些功能可用于实现“功能”部分中描述的任何功能,请参见上文。为了避免不确定性,请注明你的答案可以很清楚如何是谁想要实现未来的读者有用的弹出,类似于Magit使用弹出式菜单。 †中止弹出菜单的替代方法可能包括以下几种(但不仅限于这些): 在弹出菜单窗口之外单击; 杀死包含弹出窗口的缓冲区而没有做出选择。