From 0bd07bea095a8000cffa4f379c1fa53e009c1143 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Thu, 2 Feb 2023 18:52:52 +0000 Subject: feat(TextPutPost): add TextPutPost autocommand Adds a new autocommand, TextPutPost. This autocommand fires when the user puts text with p or P. The motivating feature for this change was to implement a plugin that "carries" Java imports between files. I.e. yanking from one java file and pasting into another would automatically add the imports required. --- src/nvim/auevents.lua | 1 + src/nvim/ops.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua index a75ee3bbd5..fb0062e524 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -110,6 +110,7 @@ return { 'TextChangedP', -- text was modified in Insert mode(popup) 'TextChangedT', -- text was modified in Terminal mode 'TextYankPost', -- after a yank or delete was done (y, d, c) + 'TextPutPost', -- after a put was done (p, P) 'UIEnter', -- after UI attaches 'UILeave', -- after UI detaches 'User', -- user defined autocommand diff --git a/src/nvim/ops.c b/src/nvim/ops.c index 435ca106ab..cb56cb7027 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -2910,6 +2910,56 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg) recursive = false; } +/// Execute autocommands for TextPutPost. +/// +/// @param oap Operator arguments. +/// @param reg The yank register used. +static void do_autocmd_textputpost(int regname, yankreg_T *reg) + FUNC_ATTR_NONNULL_ALL +{ + static bool recursive = false; + int len; + + if (recursive || !has_event(EVENT_TEXTPUTPOST)) { + // No autocommand was defined, or we yanked from this autocommand. + return; + } + + recursive = true; + + save_v_event_T save_v_event; + // Set the v:event dictionary with information about the yank. + dict_T *dict = get_v_event(&save_v_event); + + // The yanked text contents. + list_T *const list = tv_list_alloc((ptrdiff_t)reg->y_size); + for (size_t i = 0; i < reg->y_size; i++) { + tv_list_append_string(list, (const char *)reg->y_array[i], -1); + } + tv_list_set_lock(list, VAR_FIXED); + (void)tv_dict_add_list(dict, S_LEN("regcontents"), list); + + // Register type. + char buf[NUMBUFLEN + 6]; + format_reg_type(reg->y_type, reg->y_width, buf, ARRAY_SIZE(buf)); + (void)tv_dict_add_str(dict, S_LEN("regtype"), buf); + + // Name of requested register, or empty string for unnamed operation. + len = (*utf_char2len)(regname); + buf[len] = 0; + utf_char2bytes(regname, buf); + recursive = true; + (void)tv_dict_add_str(dict, S_LEN("regname"), buf); + + tv_dict_set_keys_readonly(dict); + textlock++; + apply_autocmds(EVENT_TEXTPUTPOST, NULL, NULL, false, curbuf); + textlock--; + restore_v_event(dict, &save_v_event); + + recursive = false; +} + /// Put contents of register "regname" into the text. /// Caller must check "regname" to be valid! /// @@ -3693,6 +3743,8 @@ error: curwin->w_set_curswant = true; end: + do_autocmd_textputpost(regname, reg); + if (cmdmod.cmod_flags & CMOD_LOCKMARKS) { curbuf->b_op_start = orig_start; curbuf->b_op_end = orig_end; -- cgit From eaa89c11d0f8aefbb512de769c6c82f61a8baca3 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Tue, 28 Feb 2023 21:53:42 +0000 Subject: feat(aucmd_textputpost): only fire the event if the reg is not NULL --- src/nvim/ops.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/nvim/ops.c b/src/nvim/ops.c index cb56cb7027..17a0d6e543 100644 --- a/src/nvim/ops.c +++ b/src/nvim/ops.c @@ -3743,7 +3743,9 @@ error: curwin->w_set_curswant = true; end: - do_autocmd_textputpost(regname, reg); + if (reg) { + do_autocmd_textputpost(regname, reg); + } if (cmdmod.cmod_flags & CMOD_LOCKMARKS) { curbuf->b_op_start = orig_start; -- cgit