diff options
-rw-r--r-- | runtime/doc/autocmd.txt | 28 | ||||
-rw-r--r-- | runtime/doc/deprecated.txt | 2 | ||||
-rw-r--r-- | runtime/doc/eval.txt | 1 | ||||
-rw-r--r-- | runtime/doc/gui.txt | 31 | ||||
-rw-r--r-- | runtime/doc/usr_31.txt | 29 | ||||
-rw-r--r-- | runtime/doc/vim_diff.txt | 2 | ||||
-rw-r--r-- | src/nvim/api/ui.c | 4 | ||||
-rw-r--r-- | src/nvim/aucmd.c | 22 | ||||
-rw-r--r-- | src/nvim/aucmd.h | 2 | ||||
-rw-r--r-- | src/nvim/auevents.lua | 4 | ||||
-rw-r--r-- | src/nvim/channel.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_cmds2.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_cmds2.h | 21 | ||||
-rw-r--r-- | src/nvim/main.c | 7 | ||||
-rw-r--r-- | src/nvim/ui.c | 16 | ||||
-rw-r--r-- | src/nvim/ui_bridge.c | 12 | ||||
-rw-r--r-- | src/nvim/ui_compositor.c | 2 | ||||
-rw-r--r-- | test/functional/api/ui_spec.lua | 21 | ||||
-rw-r--r-- | test/functional/terminal/tui_spec.lua | 31 |
19 files changed, 142 insertions, 97 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 6b39f1a103..05a4167b48 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -280,8 +280,8 @@ Name triggered by ~ Startup and exit |VimEnter| after doing all the startup stuff -|GUIEnter| after starting the GUI successfully -|GUIFailed| after starting the GUI failed +|UIEnter| after a UI attaches +|UILeave| after a UI detaches |TermResponse| after the terminal response to t_RV is received |QuitPre| when using `:quit`, before deciding whether to exit |ExitPre| when using a command that may make Vim exit @@ -805,19 +805,17 @@ FuncUndefined When a user function is used but it isn't NOTE: When writing Vim scripts a better alternative is to use an autoloaded function. See |autoload-functions|. - *GUIEnter* -GUIEnter After starting the GUI successfully, and after - opening the window. It is triggered before - VimEnter when using gvim. Can be used to - position the window from a gvimrc file: > - :autocmd GUIEnter * winpos 100 50 -< *GUIFailed* -GUIFailed After starting the GUI failed. Vim may - continue to run in the terminal, if possible - (only on Unix and alikes, when connecting the - X server fails). You may want to quit Vim: > - :autocmd GUIFailed * qall -< *InsertChange* + *UIEnter* +UIEnter After a UI connects via |nvim_ui_attach()|, + after VimEnter. Can be used for GUI-specific + configuration. + Sets these |v:event| keys: + chan + *UILeave* +UILeave After a UI disconnects from Nvim. + Sets these |v:event| keys: + chan + *InsertChange* InsertChange When typing <Insert> while in Insert or Replace mode. The |v:insertmode| variable indicates the new mode. diff --git a/runtime/doc/deprecated.txt b/runtime/doc/deprecated.txt index 27e60be368..b76a37810c 100644 --- a/runtime/doc/deprecated.txt +++ b/runtime/doc/deprecated.txt @@ -28,6 +28,8 @@ Environment Variables ~ Events ~ *EncodingChanged* Never fired; 'encoding' is always "utf-8". *FileEncoding* Never fired; equivalent to |EncodingChanged|. +*GUIEnter* Never fired; use |UIEnter| instead. +*GUIFailed* Never fired. Keycodes ~ *<MouseDown>* Use <ScrollWheelUp> instead. diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index ec0a28abe8..c38edb5f92 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1567,6 +1567,7 @@ v:event Dictionary of event data for the current |autocommand|. Valid abort Whether the event triggered during an aborting condition (e.g. |c_Esc| or |c_CTRL-C| for |CmdlineLeave|). + chan |channel-id| or 0 for "internal". cmdlevel Level of cmdline. cmdtype Type of cmdline, |cmdline-char|. cwd Current working directory. diff --git a/runtime/doc/gui.txt b/runtime/doc/gui.txt index f8c7693d45..0df776010b 100644 --- a/runtime/doc/gui.txt +++ b/runtime/doc/gui.txt @@ -4,7 +4,7 @@ VIM REFERENCE MANUAL by Bram Moolenaar -Vim's Graphical User Interface *gui* *GUI* +Nvim Graphical User Interface *gui* *GUI* Type |gO| to see the table of contents. @@ -12,30 +12,11 @@ Vim's Graphical User Interface *gui* *GUI* Starting the GUI *gui-start* *E229* *E233* *ginit.vim* *gui-init* *gvimrc* *$MYGVIMRC* -The gvimrc file is where GUI-specific startup commands should be placed. It -is always sourced after the |init.vim| file. If you have one then the -$MYGVIMRC environment variable has its name. - -When the GUI starts up initializations are carried out, in this order: -- If the system menu file exists, it is sourced. The name of this file is - normally "$VIMRUNTIME/menu.vim". You can check this with ":version". Also - see |$VIMRUNTIME|. To skip loading the system menu include 'M' in - 'guioptions'. *buffers-menu* *no_buffers_menu* - The system menu file includes a "Buffers" menu. If you don't want this, set - the "no_buffers_menu" variable in your init.vim (not ginit.vim!): > - :let no_buffers_menu = 1 -< NOTE: Switching on syntax highlighting also loads the menu file, thus - disabling the Buffers menu must be done before ":syntax on". - The path names are truncated to 35 characters. You can truncate them at a - different length, for example 50, like this: > - :let bmenu_max_pathlen = 50 - -All this happens AFTER the normal Vim initializations, like reading your -vimrc file. See |initialization|. -But the GUI window is only opened after all the initializations have been -carried out. If you want some commands to be executed just after opening the -GUI window, use the |GUIEnter| autocommand event. Example: > - :autocmd GUIEnter * winpos 100 50 +For GUI-specific configuration Nvim provides the |UIEnter| event. This +happens after other |initialization|s, like reading your vimrc file. + +Example: this sets "g:gui" to the value of the UI's "rgb" field: > + :autocmd UIEnter * let g:gui = filter(nvim_list_uis(),{k,v-> v.chan==v:event.chan})[0].rgb < *:winp* *:winpos* *E188* diff --git a/runtime/doc/usr_31.txt b/runtime/doc/usr_31.txt index fb9a4fd223..74de3f1042 100644 --- a/runtime/doc/usr_31.txt +++ b/runtime/doc/usr_31.txt @@ -236,35 +236,6 @@ using the terminal for something else. The "-f" argument is used here to run the GUI in the foreground. You can also use ":gui -f". -THE GVIM STARTUP FILE - -When gvim starts, it reads the gvimrc file. That's similar to the vimrc file -used when starting Vim. The gvimrc file can be used for settings and commands -that are only to be used when the GUI is going to be started. For example, -you can set the 'lines' option to set a different window size: > - - :set lines=55 - -You don't want to do this in a terminal, since its size is fixed (except for -an xterm that supports resizing). - The gvimrc file is searched for in the same locations as the vimrc file. -Normally its name is "~/.config/nvim/ginit.vim". -The $MYGVIMRC environment variable is set to it, thus you can use this command -to edit the file, if you have one: > - - :edit $MYGVIMRC -< - If for some reason you don't want to use the normal gvimrc file, you can -specify another one with the "-U" argument: > - - gvim -U thisrc ... - -That allows starting gvim for different kinds of editing. You could set -another font size, for example. - To completely skip reading a gvimrc file: > - - gvim -U NONE ... - ============================================================================== Next chapter: |usr_32.txt| The undo tree diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 7381ae4e2b..45a94bb961 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -154,6 +154,8 @@ Events: |TermClose| |TermOpen| |TextYankPost| + |UIEnter| + |UILeave| |VimResume| |VimSuspend| diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index ada26a2a07..75ee05761b 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -57,7 +57,7 @@ void remote_ui_disconnect(uint64_t channel_id) pmap_del(uint64_t)(connected_uis, channel_id); xfree(ui->data); ui->data = NULL; // Flag UI as "stopped". - ui_detach_impl(ui); + ui_detach_impl(ui, channel_id); xfree(ui); } @@ -168,7 +168,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, ui->data = data; pmap_put(uint64_t)(connected_uis, channel_id, ui); - ui_attach_impl(ui); + ui_attach_impl(ui, channel_id); } /// @deprecated diff --git a/src/nvim/aucmd.c b/src/nvim/aucmd.c index 3bb0fcec3b..a9a7d834a4 100644 --- a/src/nvim/aucmd.c +++ b/src/nvim/aucmd.c @@ -7,11 +7,32 @@ #include "nvim/main.h" #include "nvim/ui.h" #include "nvim/aucmd.h" +#include "nvim/eval.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "aucmd.c.generated.h" #endif +void do_autocmd_uienter(uint64_t chanid, bool attached) +{ + static bool recursive = false; + + if (recursive) { + return; // disallow recursion + } + recursive = true; + + dict_T *dict = get_vim_var_dict(VV_EVENT); + assert(chanid < VARNUMBER_MAX); + tv_dict_add_nr(dict, S_LEN("chan"), (varnumber_T)chanid); + tv_dict_set_keys_readonly(dict); + apply_autocmds(attached ? EVENT_UIENTER : EVENT_UILEAVE, + NULL, NULL, false, curbuf); + tv_dict_clear(dict); + + recursive = false; +} + static void focusgained_event(void **argv) { bool *gainedp = argv[0]; @@ -38,4 +59,3 @@ static void do_autocmd_focusgained(bool gained) NULL, NULL, false, curbuf); recursive = false; } - diff --git a/src/nvim/aucmd.h b/src/nvim/aucmd.h index 6570ba7a92..9a4dd79a78 100644 --- a/src/nvim/aucmd.h +++ b/src/nvim/aucmd.h @@ -1,6 +1,8 @@ #ifndef NVIM_AUCMD_H #define NVIM_AUCMD_H +#include <stdint.h> + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "aucmd.h.generated.h" #endif diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index 12fc8fd02a..c808af37b1 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -96,6 +96,8 @@ return { 'TextChangedI', -- text was modified in Insert mode(no popup) 'TextChangedP', -- text was modified in Insert mode(popup) 'TextYankPost', -- after a yank or delete was done (y, d, c) + 'UIEnter', -- after UI attaches + 'UILeave', -- after UI detaches 'User', -- user defined autocommand 'VimEnter', -- after starting Vim 'VimLeave', -- before exiting Vim @@ -123,5 +125,7 @@ return { TabNewEntered=true, TermClose=true, TermOpen=true, + UIEnter=true, + UILeave=true, }, } diff --git a/src/nvim/channel.c b/src/nvim/channel.c index 104c79efd9..f9102fa0e2 100644 --- a/src/nvim/channel.c +++ b/src/nvim/channel.c @@ -172,6 +172,7 @@ static Channel *channel_alloc(ChannelStreamType type) chan->refcount = 1; chan->exit_status = -1; chan->streamtype = type; + assert(chan->id <= VARNUMBER_MAX); pmap_put(uint64_t)(channels, chan->id, chan); return chan; } @@ -190,6 +191,7 @@ void channel_create_event(Channel *chan, const char *ext_source) source = (const char *)IObuff; } + assert(chan->id <= VARNUMBER_MAX); Dictionary info = channel_info(chan->id); typval_T tv = TV_INITIAL_VALUE; // TODO(bfredl): do the conversion in one step. Also would be nice diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index affdda0386..25528e667f 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -3111,8 +3111,6 @@ int do_source(char_u *fname, int check_other, int is_vimrc) } if (is_vimrc == DOSO_VIMRC) { vimrc_found(fname_exp, (char_u *)"MYVIMRC"); - } else if (is_vimrc == DOSO_GVIMRC) { - vimrc_found(fname_exp, (char_u *)"MYGVIMRC"); } #ifdef USE_CRNL diff --git a/src/nvim/ex_cmds2.h b/src/nvim/ex_cmds2.h index 0a164cdeb8..f85ea94ed6 100644 --- a/src/nvim/ex_cmds2.h +++ b/src/nvim/ex_cmds2.h @@ -7,19 +7,18 @@ typedef void (*DoInRuntimepathCB)(char_u *, void *); -/* - * flags for check_changed() - */ -#define CCGD_AW 1 /* do autowrite if buffer was changed */ -#define CCGD_MULTWIN 2 /* check also when several wins for the buf */ -#define CCGD_FORCEIT 4 /* ! used */ -#define CCGD_ALLBUF 8 /* may write all buffers */ -#define CCGD_EXCMD 16 /* may suggest using ! */ +// +// flags for check_changed() +// +#define CCGD_AW 1 // do autowrite if buffer was changed +#define CCGD_MULTWIN 2 // check also when several wins for the buf +#define CCGD_FORCEIT 4 // ! used +#define CCGD_ALLBUF 8 // may write all buffers +#define CCGD_EXCMD 16 // may suggest using ! -/* last argument for do_source() */ +// last argument for do_source() #define DOSO_NONE 0 -#define DOSO_VIMRC 1 /* loading vimrc file */ -#define DOSO_GVIMRC 2 /* loading gvimrc file */ +#define DOSO_VIMRC 1 // loading vimrc file #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ex_cmds2.h.generated.h" diff --git a/src/nvim/main.c b/src/nvim/main.c index bca8991b0f..e7835ccbf1 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -12,6 +12,7 @@ #include "nvim/ascii.h" #include "nvim/vim.h" #include "nvim/main.h" +#include "nvim/aucmd.h" #include "nvim/buffer.h" #include "nvim/charset.h" #include "nvim/diff.h" @@ -351,7 +352,7 @@ int main(int argc, char **argv) bool use_remote_ui = (embedded_mode && !headless_mode); bool use_builtin_ui = (!headless_mode && !embedded_mode && !silent_mode); if (use_remote_ui || use_builtin_ui) { - TIME_MSG("waiting for UI to make request"); + TIME_MSG("waiting for UI"); if (use_remote_ui) { remote_ui_wait_for_attach(); } else { @@ -537,6 +538,10 @@ int main(int argc, char **argv) set_vim_var_nr(VV_VIM_DID_ENTER, 1L); apply_autocmds(EVENT_VIMENTER, NULL, NULL, false, curbuf); TIME_MSG("VimEnter autocommands"); + if (use_remote_ui || use_builtin_ui) { + do_autocmd_uienter(use_remote_ui ? CHAN_STDIO : 0, true); + TIME_MSG("UIEnter autocommands"); + } // Adjust default register name for "unnamed" in 'clipboard'. Can only be // done after the clipboard is available and all initial commands that may diff --git a/src/nvim/ui.c b/src/nvim/ui.c index 25077675bf..79fa8b8223 100644 --- a/src/nvim/ui.c +++ b/src/nvim/ui.c @@ -9,6 +9,7 @@ #include "nvim/vim.h" #include "nvim/log.h" +#include "nvim/aucmd.h" #include "nvim/ui.h" #include "nvim/charset.h" #include "nvim/cursor.h" @@ -268,7 +269,7 @@ void ui_busy_stop(void) } } -void ui_attach_impl(UI *ui) +void ui_attach_impl(UI *ui, uint64_t chanid) { if (ui_count == MAX_UI_COUNT) { abort(); @@ -292,9 +293,14 @@ void ui_attach_impl(UI *ui) ui_send_all_hls(ui); } ui_refresh(); + + bool is_compositor = (ui == uis[0]); + if (!is_compositor) { + do_autocmd_uienter(chanid, true); + } } -void ui_detach_impl(UI *ui) +void ui_detach_impl(UI *ui, uint64_t chanid) { size_t shift_index = MAX_UI_COUNT; @@ -326,6 +332,8 @@ void ui_detach_impl(UI *ui) if (!ui->ui_ext[kUIMultigrid] && !ui->ui_ext[kUIFloatDebug]) { ui_comp_detach(ui); } + + do_autocmd_uienter(chanid, false); } void ui_set_ext_option(UI *ui, UIExtension ext, bool active) @@ -476,9 +484,7 @@ Array ui_array(void) PUT(info, ui_ext_names[j], BOOLEAN_OBJ(ui->ui_ext[j])); } } - if (ui->inspect) { - ui->inspect(ui, &info); - } + ui->inspect(ui, &info); ADD(all_uis, DICTIONARY_OBJ(info)); } return all_uis; diff --git a/src/nvim/ui_bridge.c b/src/nvim/ui_bridge.c index 91cd458702..9a1988739c 100644 --- a/src/nvim/ui_bridge.c +++ b/src/nvim/ui_bridge.c @@ -63,6 +63,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler) rv->bridge.set_icon = ui_bridge_set_icon; rv->bridge.option_set = ui_bridge_option_set; rv->bridge.raw_line = ui_bridge_raw_line; + rv->bridge.inspect = ui_bridge_inspect; rv->scheduler = scheduler; for (UIExtension i = 0; (int)i < kUIExtCount; i++) { @@ -85,7 +86,8 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler) } uv_mutex_unlock(&rv->mutex); - ui_attach_impl(&rv->bridge); + ui_attach_impl(&rv->bridge, 0); + return &rv->bridge; } @@ -106,7 +108,8 @@ static void ui_bridge_stop(UI *b) { // Detach bridge first, so that "stop" is the last event the TUI loop // receives from the main thread. #8041 - ui_detach_impl(b); + ui_detach_impl(b, 0); + UIBridgeData *bridge = (UIBridgeData *)b; bool stopped = bridge->stopped = false; UI_BRIDGE_CALL(b, stop, 1, b); @@ -213,3 +216,8 @@ static void ui_bridge_option_set_event(void **argv) api_free_object(value); xfree(argv[3]); } + +static void ui_bridge_inspect(UI *ui, Dictionary *info) +{ + PUT(*info, "chan", INTEGER_OBJ(0)); +} diff --git a/src/nvim/ui_compositor.c b/src/nvim/ui_compositor.c index f91442642d..1af027d415 100644 --- a/src/nvim/ui_compositor.c +++ b/src/nvim/ui_compositor.c @@ -83,7 +83,7 @@ void ui_comp_init(void) kv_push(layers, &default_grid); curgrid = &default_grid; - ui_attach_impl(compositor); + ui_attach_impl(compositor, 0); } void ui_comp_syn_init(void) diff --git a/test/functional/api/ui_spec.lua b/test/functional/api/ui_spec.lua index 2758da6a1f..279cd1856d 100644 --- a/test/functional/api/ui_spec.lua +++ b/test/functional/api/ui_spec.lua @@ -35,3 +35,24 @@ describe('nvim_ui_attach()', function() pcall_err(request, 'nvim_ui_attach', 40, 10, { rgb=false })) end) end) + +it('autocmds UIEnter/UILeave', function() + clear{ + args_rm={'--headless'}, + args={ + '--cmd', 'let g:evs = []', + '--cmd', 'autocmd UIEnter * :call add(g:evs, "UIEnter") | let g:uienter_ev = deepcopy(v:event)', + '--cmd', 'autocmd UILeave * :call add(g:evs, "UILeave") | let g:uileave_ev = deepcopy(v:event)', + '--cmd', 'autocmd VimEnter * :call add(g:evs, "VimEnter")', + }} + local screen = Screen.new() + screen:attach() + eq({chan=1}, eval('g:uienter_ev')) + screen:detach() + eq({chan=1}, eval('g:uileave_ev')) + eq({ + 'VimEnter', + 'UIEnter', + 'UILeave', + }, eval('g:evs')) +end) diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 789f5d4c2f..c55093cb0f 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -721,8 +721,8 @@ describe('TUI', function() | {4:~ }| {5: }| - [[['height', 6], ['override', v:false], ['rgb', v:| - false], ['width', 50]]] | + [[['chan', 0], ['height', 6], ['override', v:false| + ], ['rgb', v:false], ['width', 50]]] | {10:Press ENTER or type command to continue}{1: } | {3:-- TERMINAL --} | ]=]) @@ -767,11 +767,36 @@ describe('TUI', function() end) end) +describe('TUI UIEnter/UILeave', function() + it('fires exactly once, after VimEnter', function() + clear() + local screen = thelpers.screen_setup(0, + '["'..nvim_prog..'", "-u", "NONE", "-i", "NONE"' + ..[[, "--cmd", "set noswapfile noshowcmd noruler"]] + ..[[, "--cmd", "let g:evs = []"]] + ..[[, "--cmd", "autocmd UIEnter * :call add(g:evs, 'UIEnter')"]] + ..[[, "--cmd", "autocmd UILeave * :call add(g:evs, 'UILeave')"]] + ..[[, "--cmd", "autocmd VimEnter * :call add(g:evs, 'VimEnter')"]] + ..']' + ) + feed_data(":echo g:evs\n") + screen:expect{grid=[[ + {1: } | + {4:~ }| + {4:~ }| + {4:~ }| + {5:[No Name] }| + ['VimEnter', 'UIEnter'] | + {3:-- TERMINAL --} | + ]]} + end) +end) + describe('TUI FocusGained/FocusLost', function() local screen before_each(function() - helpers.clear() + clear() screen = thelpers.screen_setup(0, '["'..nvim_prog ..'", "-u", "NONE", "-i", "NONE", "--cmd", "set noswapfile noshowcmd noruler"]') feed_data(":autocmd FocusGained * echo 'gained'\n") |