💾 Archived View for gemini.susa.net › Vim › vim_popups.gmi captured on 2023-07-10 at 13:49:06. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2021-11-30)
-=-=-=-=-=-=-
Taken from this stackexchange answer.
The answer, given by user 'B Layer', in the above link was so clear and complete, I wanted to preserve it here. The full answer has image examples and also covers z-index and masking, which I have omitted here because they really need images to make clear.
Vim 8.2's popup windows allow Vimscript authors and plugin developers to create one or more floating, modal windows that, among other things, can be used for tool tips, notifications/alerts, dialog boxes and transient menus.
Window and Buffer
Each popup is a Vim window and an associated buffer. The window and buffer have a number of unique characteristics including:
There are six different functions for creating a popup. That's a lot but only one of them is required, popup_create() and the others are "pre-packaged" configurations with particular purposes. Here they are with brief descriptions (from :h popup-functions):
Text appearance can be controlled with syntax highlighting or using text properties (another major new feature in Vim 8.2...like syntax highlighting except it sticks to associated text as it moves in the buffer). There are also a number of attributes or "options" that control certain other look-and-feel characteristics. This is a sampling of those options.
Option values can be defined on creation of a popup window or afterwards through the popup_setoptions() function.
A popup's lifetime can be controlled several ways including by timer, upon mouse movement or user input or programmatically with popup_close(). In a pinch, there is the nuclear option popup_clear() that will dismiss any and all existing popups.
How a popup processes user input can be controlled with so-called "filters". There are a couple of builtin filters including the "yesno" filter demonstrated in the examples below.
Each popup can have an assigned callback function. When the popup is closed this function is called with the "result". This is most applicable for popups acting as menus. The result, in that case, is usually just the number of the row that the user selected. We'll see this in action, too, in the examples.
Let's look at examples of some of the features mentioned above.
For a time-limited notification popup:
call popup_notification("Get the hell out of Dodge!", #{ line: 5, col: 10, highlight: 'WildMenu', } )
As noted above this will show for three seconds then close.
Now for a simple menu:
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]} )
Note the added title and padding option to put a little space between the title and side borders and the menu items. Note the callback 'MenuCB', which outputs the chosen item.
In this example we'll use the builtin filter popup_filter_yesno. This will wait until the user has clicked a close key (x or <Esc>) or one of Y, y, N, or n. Yes replies cause the callback to be called with result 1. No sends result 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'})
If I choose Y or y the message ("You said 'yay'") will show on the status line.
If you specify your own filter function then you can intercept a subset of key presses, handling them in whatever way you choose and pass the rest on to the generic filter, popup_filter_menu(). There's an example at :h popup-examples.
Let's try the base function, popup_create().
call popup_create(poplist, #{ close: 'click' })
Where poplist begins with: [' 1 Vim Launch and App Startup', ' 2 General Use (Editing)', ' 3 Auto Commands', ' 4 Scripting', ' 5 Syntax and Basics', ' 6 Variables', ' 7 Windows', ...etc...]. The idea here is to show what a hierarchical menu (i.e. having depth > 1) looks like.
This is what a popup with all default options looks like (not counting the close: 'click' option so I had an easy way to dismiss it): positioned in the middle of the window, no borders, dimensions dictated by the contained text.
Okay, hopefully that gives everyone a good feeling for what popups are capable of. There are certainly some features I haven't covered or only mentioned briefly including:
Asynchronous content fill-in
Popup manipulation functions (e.g. popup_move(), popup_setoptions())
User-defined filters
Key mappings
Running a terminal in a popup window
To learn more about those and everything else popup related visit the dedicated 1000+ line chapter in the Vim help docs with :h popups.