Skip to content

Commit 5c017b2

Browse files
committed
patch 8.1.1364: design for popup window support needs more details
Problem: Design for popup window support needs more details. Solution: Add details about using a window and buffer. Rename popup_show() to popup_create() and add popup_show() and popup_hide().
1 parent e0b5949 commit 5c017b2

File tree

2 files changed

+153
-56
lines changed

2 files changed

+153
-56
lines changed

runtime/doc/popup.txt

Lines changed: 151 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
*popup.txt* For Vim version 8.1. Last change: 2019 May 12
1+
*popup.txt* For Vim version 8.1. Last change: 2019 May 21
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
55

66

7-
Displaying text with properties attached. *popup* *popup-window*
7+
Displaying text in floating window. *popup* *popup-window*
88

99
THIS IS UNDER DESIGN - ANYTHING MAY STILL CHANGE
1010

@@ -13,18 +13,67 @@ THIS IS UNDER DESIGN - ANYTHING MAY STILL CHANGE
1313
3. Examples |popup-examples|
1414

1515

16-
{not able to use text properties when the |+textprop| feature was
17-
disabled at compile time}
16+
{not available if the |+eval| feature was disabled at compile time}
17+
{not able to use text properties if the |+textprop| feature was disabled at
18+
compile time}
1819

1920
==============================================================================
2021
1. Introduction *popup-intro*
2122

22-
We are talking about popup windows here, text that goes on top of the buffer
23-
text and is under control of a plugin. Other popup functionality:
23+
We are talking about popup windows here, text that goes on top of the regular
24+
windows and is under control of a plugin. You cannot edit the text in the
25+
popup window like with regular windows.
26+
27+
A popup window can be used for such things as:
28+
- briefly show a message without changing the command line
29+
- prompt the user with a dialog
30+
- display information while typing
31+
- give extra information for auto-completion
32+
33+
The text in the popup window can be colored with |text-properties|. It is
34+
also possible to use syntax highlighting.
35+
36+
A popup window has a window-ID like other windows, but behaves differently.
37+
The size can be up to the whole Vim window and it overlaps other windows.
38+
It contains a buffer, and that buffer is always associated with the popup
39+
window. The window cannot be used in Normal, Visual or Insert mode, it does
40+
not get keyboard focus. You can use functions like `setbufline()` to change
41+
the text in the buffer. There are more differences from how this window and
42+
buffer behave compared to regular windows and buffers, see |popup-buffer|.
43+
44+
If this is not what you are looking for, check out other popup functionality:
2445
- popup menu, see |popup-menu|
2546
- balloon, see |balloon-eval|
2647

27-
TODO
48+
49+
TODO:
50+
51+
Example how to use syntax highlighting of a code snippet.
52+
53+
Scrolling: When the screen scrolls up for output of an Ex command, what
54+
happens with popups?
55+
1. Stay where they are. Problem: listed text may go behind and can't be read.
56+
2. Scroll with the page. What if they get updated? Either postpone, or take
57+
the scroll offset into account.
58+
Probably 2. is the best choice.
59+
60+
Positioning relative to the popup-menu to avoid overlapping with it; add a
61+
function to get the position and size of the popup-menu.
62+
63+
64+
IMPLEMENTATION:
65+
- Put code in popupwin.c
66+
- Use win_update() for displaying
67+
- At first redraw all windows NOT_VALID when the popup moves or hides.
68+
- At first always display the popup windows at the end of update_screen(),
69+
lowest zindex first.
70+
- Later make it more efficient and avoid flicker
71+
- Use a separate list of windows, one for each tab and one global. Also put
72+
"aucmd_win" in there.
73+
- add optional {buf} command to execute(). Only works for a buffer that is
74+
visible in a window in the current tab or in a popup window.
75+
E.g. for execute('syntax enable', 'silent', bufnr)
76+
2877

2978
==============================================================================
3079
2. Functions *popup-functions*
@@ -33,56 +82,66 @@ THIS IS UNDER DESIGN - ANYTHING MAY STILL CHANGE
3382

3483
Proposal and discussion on issue #4063: https://github.com/vim/vim/issues/4063
3584

36-
[to be moved to eval.txt later]
37-
38-
popup_show({lines}, {options}) *popup_show()*
39-
Open a popup window showing {lines}, which is a list of lines,
40-
where each line has text and text properties.
85+
[functions to be moved to eval.txt later, keep list of functions here]
4186

87+
popup_create({text}, {options}) *popup_create()*
88+
Open a popup window showing {text}, which is either:
89+
- a string
90+
- a list of strings
91+
- a list of text lines with text properties
4292
{options} is a dictionary with many possible entries.
93+
See |popup_create-usage| for details.
4394

44-
Returns a unique ID to be used with |popup_close()|.
95+
Returns a window-ID, which can be used with other popup
96+
functions. Use `winbufnr()` to get the number of the buffer
97+
in the window: >
98+
let winid = popup_create('hello', {})
99+
let bufnr = winbufnr(winid)
100+
call setbufline(bufnr, 2, 'second line')
45101
46-
See |popup_show-usage| for details.
47102
48-
49-
popup_dialog({lines}, {options}) *popup_dialog()*
50-
Just like |popup_show()| but with different default options:
51-
pos "center"
52-
zindex 200
53-
border []
103+
popup_dialog({text}, {options}) *popup_dialog()*
104+
Just like |popup_create()| but with these default options: >
105+
call popup_create({text}, {
106+
\ 'pos': 'center',
107+
\ 'zindex': 200,
108+
\ 'border': [],
109+
\})
110+
< Use {options} to change the properties.
54111

55112

56113
popup_notification({text}, {options}) *popup_notification()*
57-
Show the string {text} for 3 seconds at the top of the Vim
58-
window. This works like: >
59-
call popup_show([{'text': {text}}], {
114+
Show the {text} for 3 seconds at the top of the Vim window.
115+
This works like: >
116+
call popup_create({text}, {
60117
\ 'line': 1,
61118
\ 'col': 10,
62119
\ 'time': 3000,
120+
\ 'tab': -1,
63121
\ 'zindex': 200,
64122
\ 'highlight': 'WarningMsg',
65123
\ 'border: [],
66124
\ })
67125
< Use {options} to change the properties.
68126

127+
69128
popup_atcursor({text}, {options}) *popup_atcursor()*
70-
Show the string {text} above the cursor, and close it when the
71-
cursor moves. This works like: >
72-
call popup_show([{'text': {text}}], {
129+
Show the {text} above the cursor, and close it when the cursor
130+
moves. This works like: >
131+
call popup_create({text}, {
73132
\ 'line': 'cursor-1',
74133
\ 'col': 'cursor',
75-
\ 'zindex': 50,
76134
\ 'moved': 'WORD',
77135
\ })
78136
< Use {options} to change the properties.
79137

80138

81-
popup_menu({lines}, {options}) *popup_atcursor()*
82-
Show the {lines} near the cursor, handle selecting one of the
139+
popup_menu({text}, {options}) *popup_menu()*
140+
Show the {text} near the cursor, handle selecting one of the
83141
items with cursorkeys, and close it an item is selected with
84-
Space or Enter. This works like: >
85-
call popup_show({lines}, {
142+
Space or Enter. {text} should have multiple lines to make this
143+
useful. This works like: >
144+
call popup_create({text}, {
86145
\ 'pos': 'center',
87146
\ 'zindex': 200,
88147
\ 'wrap': 0,
@@ -93,9 +152,17 @@ popup_menu({lines}, {options}) *popup_atcursor()*
93152
"callback" to a function that handles the selected item.
94153

95154

155+
popup_show({id}) *popup_show()*
156+
If {id} is a hidden popup, show it now.
157+
158+
popup_hide({id}) *popup_hide()*
159+
If {id} is a displayed popup, hide it now. If the popup has a
160+
filter it will not be invoked for so long as the popup is
161+
hidden.
162+
96163
popup_move({id}, {options}) *popup_move()*
97164
Move popup {id} to the position speficied with {options}.
98-
{options} may contain the items from |popup_show()| that
165+
{options} may contain the items from |popup_create()| that
99166
specify the popup position: "line", "col", "pos", "maxheight",
100167
"minheight", "maxwidth" and "minwidth".
101168

@@ -116,21 +183,6 @@ popup_filter_yesno({id}, {key}) *popup_filter_yesno()*
116183
pressing 'n'.
117184

118185

119-
popup_setlines({id}, {lnum}, {lines}) *popup_setlines()*
120-
In popup {id} set line {lnum} and following to {lines}.
121-
122-
{lnum} is one-based and must be either an existing line or
123-
just one below the last line, in which case the line gets
124-
appended.
125-
126-
{lines} has the same format as one item in {lines} of
127-
|popup_show()|. Existing lines are replaced. When {lines}
128-
extends below the last line of the popup lines are appended.
129-
130-
popup_getlines({id}) *popup_getlines()*
131-
Return the {lines} for popup {id}.
132-
133-
134186
popup_setoptions({id}, {options}) *popup_setoptions()*
135187
Override options in popup {id} with entries in {options}.
136188

@@ -142,19 +194,46 @@ popup_getoptions({id}) *popup_getoptions()*
142194
popup_close({id}) *popup_close()*
143195
Close popup {id}.
144196

197+
*:popupclear* *:popupc*
198+
:popupc[lear] Emergency solution to a misbehaving plugin: close all popup
199+
windows.
145200

146-
POPUP_SHOW() ARGUMENTS *popup_show-usage*
147201

148-
The first argument of |popup_show()| is a list of text lines. Each item in
149-
the list is a dictionary with these entries:
150-
text The text to display.
202+
POPUP BUFFER AND WINDOW *popup-buffer*
203+
204+
A new buffer is created to hold the text and text properties of the popup
205+
window. The buffer is always associated with the popup window and
206+
manipulation is restricted:
207+
- the buffer has no name
208+
- 'buftype' is "popup"
209+
- 'swapfile' is off
210+
- 'bufhidden' is "hide"
211+
- 'buflisted' is off
212+
TODO: more
213+
214+
The window does have a cursor position, but the cursor is not displayed.
215+
216+
Options can be set on the window with `setwinvar()`, e.g.: >
217+
call setwinvar(winid, '&wrap', 0)
218+
And options can be set on the buffer with `setbufvar()`, e.g.: >
219+
call setbufvar(winbufnr(winid), '&filetype', 'java')
220+
221+
222+
POPUP_CREATE() ARGUMENTS *popup_create-usage*
223+
224+
The first argument of |popup_create()| specifies the text to be displayed, and
225+
optionally text properties. It is in one of three forms:
226+
- a string
227+
- a list of strings
228+
- a list of dictionaries, where each dictionary has these entries:
229+
text String with the text to display.
151230
props A list of text properties. Optional.
152231
Each entry is a dictionary, like the third argument of
153232
|prop_add()|, but specifying the column in the
154233
dictionary with a "col" entry, see below:
155234
|popup-props|.
156235

157-
The second argument of |popup_show()| is a dictionary with options:
236+
The second argument of |popup_create()| is a dictionary with options:
158237
line screen line where to position the popup; can use
159238
"cursor", "cursor+1" or "cursor-1" to use the line of
160239
the cursor and add or subtract a number of lines;
@@ -168,10 +247,20 @@ The second argument of |popup_show()| is a dictionary with options:
168247
used for. Default is "botleft". Alternatively
169248
"center" can be used to position the popup somewhere
170249
near the cursor.
250+
flip when TRUE (the default) and the position is relative
251+
to the cursor, flip to below or above the cursor to
252+
avoid overlap with the |popupmenu-completion| or
253+
another popup with a higher "zindex"
171254
maxheight maximum height
172255
minheight minimum height
173256
maxwidth maximum width
174257
minwidth minimum width
258+
hidden when TRUE the popup exists but is not displayed; use
259+
`popup_show()` to unhide it.
260+
tab when -1: display the popup on all tabs; when 0 (the
261+
default): display the popup on the current tab;
262+
otherwise the number of the tab page the popup is
263+
displayed on; when invalid the current tab is used
175264
title text to be displayed above the first item in the
176265
popup, on top of any border
177266
wrap TRUE to make the lines wrap (default TRUE)
@@ -229,9 +318,11 @@ same, since they only apply to one line.
229318

230319
POPUP FILTER *popup-filter*
231320

232-
A callback that gets any typed keys while a popup is displayed. It can return
233-
TRUE to indicate the key has been handled and is to be discarded, or FALSE to
234-
let Vim handle the key as usual in the current state.
321+
A callback that gets any typed keys while a popup is displayed. The filter is
322+
not invoked for as long as the popup is hidden.
323+
324+
The filter can return TRUE to indicate the key has been handled and is to be
325+
discarded, or FALSE to let Vim handle the key as usual in the current state.
235326

236327
The filter function is called with two arguments: the ID of the popup and the
237328
key.
@@ -241,6 +332,10 @@ Some common key actions:
241332
cursor keys select another entry
242333
Tab accept current suggestion
243334

335+
A mouse click arrives as <LeftMouse>. The coordinates are in
336+
v:mouse_popup_col and v:mouse_popup_row. The top-left screen cell of the
337+
popup is col 1, row 1 (not counting the border).
338+
244339
Vim provides standard filters |popup_filter_menu()| and
245340
|popup_filter_yesno()|.
246341

@@ -265,7 +360,7 @@ Prompt the user to press y/Y or n/N: >
265360
endif
266361
endfunc
267362
268-
call popup_show([{'text': 'Continue? y/n'}], {
363+
call popup_create(['Continue? y/n'], {
269364
\ 'filter': 'popup_filter_yesno',
270365
\ 'callback': 'MyDialogHandler',
271366
\ })

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,8 @@ static char *(features[]) =
767767

768768
static int included_patches[] =
769769
{ /* Add new patch number below this line */
770+
/**/
771+
1364,
770772
/**/
771773
1363,
772774
/**/

0 commit comments

Comments
 (0)