| *popup.txt* For Vim version 8.1. Last change: 2019 Jun 02 |
| |
| |
| VIM REFERENCE MANUAL by Bram Moolenaar |
| |
| |
| Displaying text in floating window. *popup* *popup-window* |
| |
| THIS IS UNDER DESIGN - ANYTHING MAY STILL CHANGE |
| |
| 1. Introduction |popup-intro| |
| 2. Functions |popup-functions| |
| 3. Examples |popup-examples| |
| |
| |
| {not available if the |+textprop| feature was disabled at compile time} |
| |
| ============================================================================== |
| 1. Introduction *popup-intro* |
| |
| We are talking about popup windows here, text that goes on top of the regular |
| windows and is under control of a plugin. You cannot edit the text in the |
| popup window like with regular windows. |
| |
| A popup window can be used for such things as: |
| - briefly show a message without overwriting the command line |
| - prompt the user with a dialog |
| - display contextual information while typing |
| - give extra information for auto-completion |
| |
| The text in the popup window can be colored with |text-properties|. It is |
| also possible to use syntax highlighting. |
| |
| The default color used is "Pmenu". If you prefer something else use the |
| "highlight" argument or the 'wincolor' option, e.g.: > |
| hi MyPopupColor ctermbg=lightblue guibg=lightblue |
| call setwinvar(winid, '&wincolor', 'MyPopupColor') |
| |
| 'hlsearch' and match highlighting are not displayed in a popup window. |
| |
| A popup window has a window-ID like other windows, but behaves differently. |
| The size can be up to the whole Vim window and it overlaps other windows. |
| Popup windows can also overlap each other. |
| |
| The popup window contains a buffer, and that buffer is always associated with |
| the popup window. The window cannot be used in Normal, Visual or Insert mode, |
| it does not get keyboard focus. You can use functions like `setbufline()` to |
| change the text in the buffer. There are more differences from how this |
| window and buffer behave compared to regular windows and buffers, see |
| |popup-buffer|. |
| |
| If this is not what you are looking for, check out other popup functionality: |
| - popup menu, see |popup-menu| |
| - balloon, see |balloon-eval| |
| |
| |
| WINDOW POSITION AND SIZE *popup-position* |
| |
| The height of the window is normally equal to the number of, possibly |
| wrapping, lines in the buffer. It can be limited with the "maxheight" |
| property. You can use empty lines to increase the height or the "minheight" |
| property. |
| |
| The width of the window is normally equal to the longest line in the buffer. |
| It can be limited with the "maxwidth" property. You can use spaces to |
| increase the width or the "minwidth" property. |
| |
| By default the 'wrap' option is set, so that no text disappears. Otherwise, |
| if there is not enough space then the window is shifted left in order to |
| display more text. This can be disabled with the "fixed" property. Also |
| disabled when right-aligned. |
| |
| Vim tries to show the popup in the location you specify. In some cases, e.g. |
| when the popup would go outside of the Vim window, it will show it somewhere |
| else. E.g. if you use `popup_atcursor()` the popup normally shows just above |
| the current cursor position, but if the cursor is close to the top of the Vim |
| window it will be placed below the cursor position. |
| |
| |
| |
| TODO: |
| |
| Scrolling: When the screen scrolls up for output of an Ex command, what |
| happens with popups? |
| 1. Stay where they are. Problem: listed text may go behind and can't be read. |
| 2. Scroll with the page. What if they get updated? Either postpone, or take |
| the scroll offset into account. |
| Probably 2. is the best choice. |
| |
| |
| IMPLEMENTATION: |
| - Code is in popupwin.c |
| - Why does 'nrformats' leak from the popup window buffer??? |
| - Make redrawing more efficient and avoid flicker. |
| First draw popups, creating a mask, use the mask in screen_line() when |
| drawing other windows and stuff. Mask contains zindex of popups. |
| Keep mask until next update_screen(), use when drawing status lines. |
| Remove update_popup() calls after draw_tabline()/updating statusline |
| Fix redrawing problem with completion. |
| Fix redrawing problem when scrolling non-current window |
| - Disable commands, feedkeys(), CTRL-W, etc. in a popup window. |
| Use NOT_IN_POPUP_WINDOW for more commands. |
| - Invoke filter with character before mapping? |
| - Figure out the size and position better. |
| if wrapping splits a double-wide character |
| if wrapping inserts indent |
| - Can the buffer be re-used, to avoid using up lots of buffer numbers? |
| - Implement all the unimplemented options and features. |
| |
| |
| ============================================================================== |
| 2. Functions *popup-functions* |
| |
| THIS IS UNDER DESIGN - ANYTHING MAY STILL CHANGE |
| |
| [functions to be moved to eval.txt later, keep overview of functions here] |
| |
| popup_create({text}, {options}) *popup_create()* |
| Open a popup window showing {text}, which is either: |
| - a string |
| - a list of strings |
| - a list of text lines with text properties |
| |
| {options} is a dictionary with many possible entries. |
| See |popup_create-usage| for details. |
| |
| Returns a window-ID, which can be used with other popup |
| functions. Use `winbufnr()` to get the number of the buffer |
| in the window: > |
| let winid = popup_create('hello', {}) |
| let bufnr = winbufnr(winid) |
| call setbufline(bufnr, 2, 'second line') |
| < In case of failure zero is returned. |
| |
| |
| popup_close({id} [, {result}]) *popup_close()* |
| Close popup {id}. The window and the associated buffer will |
| be deleted. |
| |
| If the popup has a callback it will be called just before the |
| popup window is deleted. If the optional {result} is present |
| it will be passed as the second argument of the callback. |
| Otherwise zero is passed to the callback. |
| |
| |
| popup_dialog({text}, {options}) *popup_dialog()* |
| {not implemented yet} |
| Just like |popup_create()| but with these default options: > |
| call popup_create({text}, { |
| \ 'pos': 'center', |
| \ 'zindex': 200, |
| \ 'border': [], |
| \ 'padding': [], |
| \}) |
| < Use {options} to change the properties. |
| |
| |
| popup_notification({text}, {options}) *popup_notification()* |
| {not implemented yet} |
| Show the {text} for 3 seconds at the top of the Vim window. |
| This works like: > |
| call popup_create({text}, { |
| \ 'line': 1, |
| \ 'col': 10, |
| \ 'time': 3000, |
| \ 'tab': -1, |
| \ 'zindex': 200, |
| \ 'highlight': 'WarningMsg', |
| \ 'border': [], |
| \ }) |
| < Use {options} to change the properties. |
| |
| |
| popup_atcursor({text}, {options}) *popup_atcursor()* |
| Show the {text} above the cursor, and close it when the cursor |
| moves. This works like: > |
| call popup_create({text}, { |
| \ 'pos': 'botleft', |
| \ 'line': 'cursor-1', |
| \ 'col': 'cursor', |
| \ 'moved': 'WORD', |
| \ }) |
| < Use {options} to change the properties. |
| |
| |
| popup_menu({text}, {options}) *popup_menu()* |
| {not implemented yet} |
| Show the {text} near the cursor, handle selecting one of the |
| items with cursorkeys, and close it an item is selected with |
| Space or Enter. {text} should have multiple lines to make this |
| useful. This works like: > |
| call popup_create({text}, { |
| \ 'pos': 'center', |
| \ 'zindex': 200, |
| \ 'wrap': 0, |
| \ 'border': [], |
| \ 'filter': 'popup_filter_menu', |
| \ }) |
| < Use {options} to change the properties. Should at least set |
| "callback" to a function that handles the selected item. |
| |
| |
| popup_hide({id}) *popup_hide()* |
| If {id} is a displayed popup, hide it now. If the popup has a |
| filter it will not be invoked for so long as the popup is |
| hidden. |
| If window {id} does not exist nothing happens. If window {id} |
| exists but is not a popup window an error is given. *E993* |
| |
| popup_show({id}) *popup_show()* |
| If {id} is a hidden popup, show it now. |
| For {id} see `popup_hide()`. |
| |
| popup_move({id}, {options}) *popup_move()* |
| Move popup {id} to the position speficied with {options}. |
| {options} may contain the items from |popup_create()| that |
| specify the popup position: "line", "col", "pos", "maxheight", |
| "minheight", "maxwidth" and "minwidth". |
| For {id} see `popup_hide()`. |
| |
| |
| popup_filter_menu({id}, {key}) *popup_filter_menu()* |
| {not implemented yet} |
| Filter that can be used for a popup. It handles the cursor |
| keys to move the selected index in the popup. Space and Enter |
| can be used to select an item. Invokes the "callback" of the |
| popup menu with the index of the selected line as the second |
| argument. |
| |
| |
| popup_filter_yesno({id}, {key}) *popup_filter_yesno()* |
| {not implemented yet} |
| Filter that can be used for a popup. It handles only the keys |
| 'y', 'Y' and 'n' or 'N'. Invokes the "callback" of the |
| popup menu with the 1 for 'y' or 'Y' and zero for 'n' or 'N' |
| as the second argument. Pressing Esc and CTRL-C works like |
| pressing 'n'. |
| |
| |
| popup_setoptions({id}, {options}) *popup_setoptions()* |
| {not implemented yet} |
| Override options in popup {id} with entries in {options}. |
| |
| |
| popup_getoptions({id}) *popup_getoptions()* |
| Return the {options} for popup {id} in a Dict. |
| A zero value means the option was not set. For "zindex" the |
| default value is returned, not zero. |
| |
| The "highlight" entry is omitted, use the 'wincolor' option |
| for that: > |
| let hl = getwinvar(winid, '&wincolor') |
| |
| < If popup window {id} is not found an empty Dict is returned. |
| |
| popup_getpos({id}) *popup_getpos()* |
| Return the position and size of popup {id}. Returns a Dict |
| with these entries: |
| col screen column of the popup, one-based |
| line screen line of the popup, one-based |
| width width of the whole popup in screen cells |
| height height of the whole popup in screen cells |
| core_col screen column of the text box |
| core_line screen line of the text box |
| core_width width of the text box in screen cells |
| core_height height of the text box in screen cells |
| visible one if the popup is displayed, zero if hidden |
| Note that these are the actual screen positions. They differ |
| from the values in `popup_getoptions()` for the sizing and |
| positioning mechanism applied. |
| |
| The "core_" values exclude the padding and border. |
| |
| If popup window {id} is not found an empty Dict is returned. |
| |
| |
| *:popupclear* *:popupc* |
| :popupc[lear] Emergency solution to a misbehaving plugin: close all popup |
| windows. |
| |
| |
| POPUP BUFFER AND WINDOW *popup-buffer* |
| |
| A new buffer is created to hold the text and text properties of the popup |
| window. The buffer is always associated with the popup window and |
| manipulation is restricted: |
| - the buffer has no name |
| - 'buftype' is "popup" |
| - 'swapfile' is off |
| - 'bufhidden' is "hide" |
| - 'buflisted' is off |
| - 'undolevels' is -1: no undo at all |
| - all other buffer-local and window_local options are set to their Vim default |
| value. |
| |
| It is possible to change the specifically mentioned options, but anything |
| might break then, so better leave them alone. |
| |
| The window does have a cursor position, but the cursor is not displayed. |
| |
| To execute a command in the context of the popup window and buffer use |
| `win_execute()`. Example: > |
| call win_execute(winid, 'syntax enable') |
| |
| Options can be set on the window with `setwinvar()`, e.g.: > |
| call setwinvar(winid, '&wrap', 0) |
| And options can be set on the buffer with `setbufvar()`, e.g.: > |
| call setbufvar(winbufnr(winid), '&filetype', 'java') |
| Note that this does not trigger autocommands. Use `win_execute()` if you do |
| need them. |
| |
| |
| POPUP_CREATE() ARGUMENTS *popup_create-usage* |
| |
| The first argument of |popup_create()| specifies the text to be displayed, and |
| optionally text properties. It is in one of three forms: |
| - a string |
| - a list of strings |
| - a list of dictionaries, where each dictionary has these entries: |
| text String with the text to display. |
| props A list of text properties. Optional. |
| Each entry is a dictionary, like the third argument of |
| |prop_add()|, but specifying the column in the |
| dictionary with a "col" entry, see below: |
| |popup-props|. |
| |
| The second argument of |popup_create()| is a dictionary with options: |
| line Screen line where to position the popup. Can use a |
| number or "cursor", "cursor+1" or "cursor-1" to use |
| the line of the cursor and add or subtract a number of |
| lines. If omitted the popup is vertically centered. |
| The first line is 1. |
| col Screen column where to position the popup. Can use a |
| number or "cursor" to use the column of the cursor, |
| "cursor+9" or "cursor-9" to add or subtract a number |
| of columns. If omitted the popup is horizontally |
| centered. The first column is 1. |
| pos "topleft", "topright", "botleft" or "botright": |
| defines what corner of the popup "line" and "col" are |
| used for. When not set "topleft" is used. |
| Alternatively "center" can be used to position the |
| popup in the center of the Vim window, in which case |
| "line" and "col" are ignored. |
| fixed When FALSE (the default), and: |
| - "pos" is "botleft" or "topleft", and |
| - "wrap" is off, and |
| - the popup would be truncated at the right edge of |
| the screen, then |
| the popup is moved to the left so as to fit the |
| contents on the screen. Set to TRUE to disable this. |
| flip When TRUE (the default) and the position is relative |
| to the cursor, flip to below or above the cursor to |
| avoid overlap with the |popupmenu-completion| or |
| another popup with a higher "zindex". |
| {not implemented yet} |
| maxheight Maximum height of the contents, excluding border and |
| padding. |
| minheight Minimum height of the contents, excluding border and |
| padding. |
| maxwidth Maximum width of the contents, excluding border and |
| padding. |
| minwidth Minimum width of the contents, excluding border and |
| padding. |
| hidden When TRUE the popup exists but is not displayed; use |
| `popup_show()` to unhide it. |
| {not implemented yet} |
| tab When -1: display the popup on all tabs. |
| When 0 (the default): display the popup on the current |
| tab. |
| Otherwise the number of the tab page the popup is |
| displayed on; when invalid the current tab is used. |
| {only -1 and 0 are implemented} |
| title Text to be displayed above the first item in the |
| popup, on top of any border. If there is no top |
| border on line of padding is added to put the title on. |
| {not implemented yet} |
| wrap TRUE to make the lines wrap (default TRUE). |
| highlight Highlight group name to use for the text, stored in |
| the 'wincolor' option. |
| padding List with numbers, defining the padding |
| above/right/below/left of the popup (similar to CSS). |
| An empty list uses a padding of 1 all around. The |
| padding goes around the text, inside any border. |
| Padding uses the 'wincolor' highlight. |
| Example: [1, 2, 1, 3] has 1 line of padding above, 2 |
| columns on the right, 1 line below and 3 columns on |
| the left. |
| border List with numbers, defining the border thickness |
| above/right/below/left of the popup (similar to CSS). |
| Only values of zero and non-zero are recognized. |
| An empty list uses a border all around. |
| borderhighlight List of highlight group names to use for the border. |
| When one entry it is used for all borders, otherwise |
| the highlight for the top/right/bottom/left border. |
| Example: ['TopColor', 'RightColor', 'BottomColor, |
| 'LeftColor'] |
| borderchars List with characters, defining the character to use |
| for the top/right/bottom/left border. Optionally |
| followed by the character to use for the |
| topleft/topright/botright/botleft corner. |
| Example: ['-', '|', '-', '|', '┌', '┐', '┘', '└'] |
| When the list has one character it is used for all. |
| When the list has two characters the first is used for |
| the border lines, the second for the corners. |
| By default a double line is used all around when |
| 'encoding' is "utf-8", otherwise ASCII characters are |
| used. |
| zindex Priority for the popup, default 50. |
| time Time in milliseconds after which the popup will close. |
| When omitted |popup_close()| must be used. |
| moved Specifies to close the popup if the cursor moved: |
| - "any": if the cursor moved at all |
| - "word": if the cursor moved outside |<cword>| |
| - "WORD": if the cursor moved outside |<cWORD>| |
| - [{start}, {end}]: if the cursor moved before column |
| {start} or after {end} |
| The popup also closes if the cursor moves to another |
| line or to another window. |
| filter A callback that can filter typed characters, see |
| |popup-filter|. |
| callback A callback that is called when the popup closes, e.g. |
| when using |popup_filter_menu()|, see |popup-callback|. |
| |
| Depending on the "zindex" the popup goes under or above other popups. The |
| completion menu (|popup-menu|) has zindex 100. For messages that occur for a |
| short time the suggestion is to use zindex 1000. |
| |
| By default text wraps, which causes a line in {lines} to occupy more than one |
| screen line. When "wrap" is FALSE then the text outside of the popup or |
| outside of the Vim window will not be displayed, thus truncated. |
| |
| |
| POPUP TEXT PROPERTIES *popup-props* |
| |
| These are similar to the third argument of |prop_add()| except: |
| - "lnum" is always the current line in the list |
| - "bufnr" is always the buffer of the popup |
| - "col" is in the Dict instead of a separate argument |
| - "transparent" is extra |
| So we get: |
| col starting column, counted in bytes, use one for the |
| first column. |
| length length of text in bytes; can be zero |
| end_lnum line number for the end of the text |
| end_col column just after the text; not used when "length" is |
| present; when {col} and "end_col" are equal, this is a |
| zero-width text property |
| id user defined ID for the property; when omitted zero is |
| used |
| type name of the text property type, as added with |
| |prop_type_add()| |
| transparent do not show these characters, show the text under it; |
| if there is a border character to the right or below |
| it will be made transparent as well |
| {not implemented yet} |
| |
| |
| POPUP FILTER *popup-filter* |
| |
| A callback that gets any typed keys while a popup is displayed. The filter is |
| not invoked when the popup is hidden. |
| |
| The filter can return TRUE to indicate the key has been handled and is to be |
| discarded, or FALSE to let Vim handle the key as usual in the current state. |
| In case it returns FALSE and there is another popup window visible, that |
| filter is also called. The filter of the popup window with the highest zindex |
| is called first. |
| |
| The filter function is called with two arguments: the ID of the popup and the |
| key, e.g.: > |
| func MyFilter(winid, key) |
| if a:key == "\<F2>" |
| " do something |
| return 1 |
| endif |
| if a:key == 'x' |
| call popup_close(a:winid) |
| return 1 |
| endif |
| return 0 |
| endfunc |
| |
| Currently the key is what results after any mapping. This may change... |
| |
| Some common key actions: |
| x close the popup (see note below) |
| cursor keys select another entry |
| Tab accept current suggestion |
| |
| A mouse click arrives as <LeftMouse>. The coordinates are in |
| v:mouse_popup_col and v:mouse_popup_row. The top-left screen cell of the |
| popup is col 1, row 1 (not counting the border). |
| |
| Vim provides standard filters |popup_filter_menu()| and |
| |popup_filter_yesno()|. |
| |
| Note that "x" is the normal way to close a popup. You may want to use Esc, |
| but since many keys start with an Esc character, there may be a delay before |
| Vim recognizes the Esc key. If you do use Esc, it is reecommended to set the |
| 'ttimeoutlen' option to 100 and set 'timeout' and/or 'ttimeout'. |
| |
| |
| POPUP CALLBACK *popup-callback* |
| |
| A callback that is invoked when the popup closes. Used by |
| |popup_filter_menu()|. |
| |
| The callback is invoked with two arguments: the ID of the popup window and the |
| result, which could be an index in the popup lines, or whatever was passed as |
| the second argument of `popup_close()`. |
| |
| If the popup is closed because the cursor moved, the number -1 is passed to |
| the callback. |
| |
| ============================================================================== |
| 3. Examples *popup-examples* |
| |
| TODO |
| |
| Prompt the user to press y/Y or n/N: > |
| |
| func MyDialogHandler(id, result) |
| if a:result |
| " ... 'y' or 'Y' was pressed |
| endif |
| endfunc |
| |
| call popup_create(['Continue? y/n'], { |
| \ 'filter': 'popup_filter_yesno', |
| \ 'callback': 'MyDialogHandler', |
| \ }) |
| < |
| |
| vim:tw=78:ts=8:noet:ft=help:norl: |