#1 楼
背景:最近我在玩Vim 8.2的弹出窗口(我有一个小插件,可以导航标记文档中的部分,并且我正在查看显示弹出窗口中的部分层次结构)。我认为收集到的信息可以进行不错的介绍...概述
Vim 8.2的弹出窗口允许Vimscript作者和插件开发人员创建一个或多个浮动对象,模态窗口,除其他外,可用于工具提示,通知/警报,对话框和临时菜单。
窗口和缓冲区
每个弹出窗口都是一个Vim窗口和一个关联的缓冲区。窗口和缓冲区具有许多独特的特性,包括:
弹出窗口覆盖了部分或全部vim常规窗口/缓冲区。它们不包含游标,但是游标在其下方的常规缓冲区中,可通过弹出窗口查看。 (为避免丢失您的位置,我想。)
弹出窗口可以彼此堆叠,堆叠顺序由每个窗口的
zindex
属性的值确定。缓冲区不是
'buflisted'
是'bufhidden'
,并且具有“弹出” 'buftype'
。可以通过几种方式指定缓冲区的初始内容,包括将内容放入字符串或字符串列表。您还可以使用通过
bufadd()
创建的现有缓冲区(并具有其他一些必需的特性)。该缓冲区没有交换文件或撤消功能,并且不能通过常规方式进行编辑,但是可以在创建后用
popup_settext()
修改内容窗口/缓冲区的外观是高度可定制的。
创建
有六种不同的功能可用于创建弹出窗口。数量很多,但是只需要其中之一,
popup_create()
和其他都是具有特定用途的“预包装”配置。这些是简短说明(来自:h popup-functions
):popup_create()
-位于屏幕中心popup_atcursor()
-在光标位置上方,在鼠标移动时关闭popup_beval()
-在v:beval_变量指示的位置,在鼠标移动时关闭popup_notification()
-显示三个通知秒popup_dialog()
-以填充和边框居中popup_menu()
-提示从列表中选择项目自定义
可以通过语法突出显示或使用文本属性(Vim 8.2的另一个主要新功能……类似于语法突出显示,但它在缓冲区中移动时会粘附在关联的文本上)来控制文本外观。还有许多控制某些其他外观特征的属性或“选项”。这是这些选项的示例。
放置位置/大小:
line
,col
,pos
(例如“底部”),maxheight
,resize
(通过鼠标),drag
(用鼠标),minwidth
(注意:窗口的高度/宽度通常取决于所包含文本的宽度和高度。)外观:
padding
,border
,borderchars
,highlight
(a :hi
),title
,mask
(请参见下面的示例)行为:time
(直到关闭),callback
(函数),filter
(输入处理)可以在创建对象时定义选项值弹出窗口或随后通过
popup_setoptions()
函数。交互作用
弹出窗口的生存期可以通过多种方式控制,包括通过计时器,鼠标移动或用户输入时或通过
popup_close()
编程控制。紧要关头,有一个核选项popup_clear()
可以消除任何现有的所有弹出窗口。如何通过所谓的“过滤器”控制弹出窗口如何处理用户输入。有几个内置过滤器,包括以下示例中演示的“ yesno”过滤器。
每个弹出窗口都可以分配一个回调函数。当弹出窗口关闭时,使用“结果”调用此函数。这最适用于充当菜单的弹出窗口。在那种情况下,结果通常只是用户选择的行号。我们还将在示例中看到这一点。
示例
让我们看一下上面提到的某些功能的示例。
通知
有时间限制的通知弹出窗口:
call popup_notification("Get the hell out of Dodge!", #{ line: 5, col: 10, highlight: 'WildMenu', } )
如上所述,这将显示保持三秒钟,然后关闭。
菜单
现在为一个简单的菜单:
func! MenuCB(id, result)
echo "You chose item #".a:result
endfunc
call popup_menu(['The quick fox...', '...jumped over...', '...the lazy dogs!'],
#{ title: "Well? Pick one", callback: 'MenuCB', line: 25, col: 40, highlight: 'Question', border: [], close: 'click', padding: [1,1,0,1]} )
请注意,添加了
title
和padding
选项,以便在标题和侧边框与菜单项之间留一些空间。选择最后一行会导致... 是/否对话框
在此示例中,我们将使用内置过滤器
popup_filter_yesno
。这将一直等到用户单击关闭键(x
或<Esc>
)或Y
,y
,N
或n
中的一个。是的答复导致以结果1调用回调。否发送结果0。func! YayOrNay(id, result)
if a:result | echo "You said 'yay'" | endif
endfunc
call popup_dialog('[y]ay or [n]ay?', #{ filter: 'popup_filter_yesno', callback: 'YayOrNay'})
如果我选择
Y
或y
消息(“您说'是'”)将显示在状态行上。如果您指定自己的过滤器功能,则可以拦截按键的子集,以您选择的任何方式处理按键和将其余的传递给通用过滤器
popup_filter_menu()
。 :h popup-examples
上有一个示例。基本案例
让我们尝试基本函数
popup_create()
。call popup_create(poplist, #{ close: 'click' })
其中
poplist
始于:[' 1 Vim Launch and App Startup', ' 2 General Use (Editing)', ' 3 Auto Commands', ' 4 Scripting', ' 5 Syntax and Basics', ' 6 Variables', ' 7 Windows', ...etc...]
。这里的想法是查看分层菜单(即,深度> 1)是什么样子。这是带有所有默认选项的弹出窗口的外观(不计入
close: 'click'
选项,因此我有一种简单的方法将其关闭):位于窗口中间,无边框,尺寸由所包含的文本决定。Z-Index和Masking
最后,让我们看一下z-index的功能,并且主要出于娱乐目的,演示mask属性。使用“遮罩”,您可以
指定弹出窗口坐标,弹出窗口的那些部分将呈现为透明。我还没有想到将其完全实用,所以在这里我只是切掉了几个角,在东西上戳了几个大洞。
call popup_create(poplist, #{ zindex: 20, line: 5, col: 20, close: 'click',
mask: [[1, 10, 1, 3], [-10, -4, 3, 5], [10, 23, -5, -2], [-10, -1, -3, -1]] })
通常,人们希望将其他弹出窗口放置在现有弹出窗口之上。但是通过为
zindex
属性指定一个较低的值...。call popup_create(poplist, #{ zindex: 10, line: 7, col: 25, close: 'click', highlight: 'CursorLine' })
...我们可以使其弹出式显示:
(花哨的粉红色?这是许多配色方案中弹出式窗口的默认颜色。:p许多自动完成功能的用户都可能认出它。)
其他功能
好吧,希望能使所有人对弹出窗口的功能有很好的感觉。肯定有一些我没有涉及或仅简短提及的功能,包括:
异步内容填充
弹出操作功能(例如
popup_move()
,popup_setoptions()
)用户定义的过滤器
键映射
在弹出窗口中运行终端
要了解更多有关弹出式窗口的信息,请访问Vim帮助中的1000+行一章带有
:h popups
的文档。评论
降价轮廓跳跃的事情听起来很有用...我很想一直关注它的发展
– D. Ben Knoble♦
20-4-5的14:21
@ D.BenKnoble我为自己创建了它,但是如果达到了适当的稳定性/可用性水平,我可以共享它。但是请注意,我说的是markUP。具体来说,我使用了asciidoc(tor),它与markdown类似,但功能强大得多。
– B层
20年4月5日在22:37
很棒的答案!很高兴看到这么多例子
– mowwwalker
20年4月6日在17:45
@MaximKim看起来我们正在做类似的事情。在您调用popup_create时,将滚动条:1添加到选项映射中,如果文本不适合,则会出现滚动条。我还没有尝试过它们,因为即使我最大的asciidoctor doc(可能会渲染到150个印刷页面(我应该写一本书))也只有19个顶级部分。我确实有一个巨大的显示器,并使用高大的窗户,公平的说。
– B层
20-4-8在20:02
@ D.BenKnoble标记部分导航器与弹出窗口配合使用非常好。我必须添加自定义密钥处理程序,以便可以使用数字来选择部分(默认情况下,您只会看到Up / Down或j / k,它吸引了40个或更多部分),我每天都在挖掘它并使用它。在我分享之前可能还需要一段时间...待办事项清单仍然很长...但是我几乎可以肯定会。
– B层
20 May 10 '14:14
评论
@MartinTournoij我刚刚注意到您所获得的巨额奖金。我对赏金的理解是一维的(也就是说,它是关于吸引更多和/或更好的答案),但是现在我已经进行了一些研究,我认为我了解您的实际意图(如您选择的原因和选择的等待时间所表明)我对他说:“谢谢!您真是太慷慨了。” :)是的,我只是想将其添加到您的答案中。出于某种原因,当您填写“奖励现有答案”时,您仍然需要等待24小时。🤷无论如何,我获得的声誉太高了,仅仅是因为我很早就很活跃。当我遇到它们时,我想我还可以将它们附加到一些特殊的答案上。
我读过各种meta线程,尽管Jeff Atwood(IMO并不十分有说服力)坚持一个线程是必要的,但仍有很多人质疑24h的要求。但是也有许多人说他们喜欢,实际上,有些人选择整周延期,因为这是他们打算给予赏金的发帖人的额外奖励。怎么样?他们认为,额外的可见度悬而未决的问题/答案可能会导致原本不会收到的海报获得更多投票。无论如何,再次感谢!