Hello,

--> Motivation

The attached patch adds a new autocmd event that is triggered on
normal-mode search commands. The use case I have is the following:

  :au SearchCommand * setl cursorline | setl cursorcolumn

which would make it easier to see which search result your cursor is
focused on while jumping around. I also found someone online asking
for an autocmd that did this:

  https://stackoverflow.com/q/37812852

--> Thoughts on where to trigger the autocmd

First, I thought about triggering the event only if !(opts &
SEARCH_KEEP) inside do_search(), as a general way to catch search
commands that are to some extent user-visible. So in addition to the
normal-mode search commands, this would also trigger on:

  - :/ and :? due to get_address() and cmdline_not_changed case in
    getcmdline().
  - gui_do_find_repl()
  - jumpto_tag(), if 'cpoption' contains 't'

However, I didn't like this for a few reasons:

  - Complicated to describe in the documentation
  - It's nice that one can use :/ and :? as an easy escape-hatch to do
    what / and ? do without triggering the autocmd.
  - gui_do_find_repl() and jumpto_tag() didn't seem to match the use
    cases I had in mind.
  - It loses context about how the search is being used; looking at
    SEARCH_KEEP is insufficient. More on this below.

So I thought about doing it in normal_search(). However, I noticed
that nv_next() calls normal_search() twice in a special cirumstance.

--> The patch

So, rather than adding some boolean flag, and because there were only
three functions that call normal_search(), I decided to trigger the
event in those three functions instead.

As suggested by CONTRIBUTING.md, I have attached a unified-diff format
patch, along with documentation updates and an accompanying test.
Specifically, I modified test_autocmd.vim to check that normal-mode
search commands trigger the event exactly-once, and that other similar
search features do not trigger it at all.

Let me know if anything else needs to be done.

Thanks,
Genki

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index fe67774cf..3002f1c95 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -341,6 +341,8 @@ Name			triggered by ~
 
 |RemoteReply|		a reply from a server Vim was received
 
+|SearchCommand|		upon search command in Normal mode
+
 |QuickFixCmdPre|	before a quickfix command is run
 |QuickFixCmdPost|	after a quickfix command is run
 
@@ -810,6 +812,9 @@ MenuPopup			Just before showing the popup menu (under the
 					o	Operator-pending
 					i	Insert
 					c	Command line
+							*SearchCommand*
+SearchCommand			When a search command is run in Normal mode.
+				Specifically, those commands from |search-commands|.
 							*OptionSet*
 OptionSet			After setting an option.  The pattern is
 				matched against the long option name.
diff --git a/runtime/doc/pattern.txt b/runtime/doc/pattern.txt
index a4d0d2e50..a07c965d1 100644
--- a/runtime/doc/pattern.txt
+++ b/runtime/doc/pattern.txt
@@ -157,6 +157,10 @@ Note that for the |:global| command this behaves like a normal message, for Vi
 compatibility.  For the |:s| command the "e" flag can be used to avoid the
 error message |:s_flags|.
 
+See the |SearchCommand| autocommand event if you want to take action on a
+search command done in Normal mode. For example: >
+	:au SearchCommand * setl cursorline | setl cursorcolumn
+<
 					*search-offset* *{offset}*
 These commands search for the specified pattern.  With "/" and "?" an
 additional offset may be given.  There are two types of offsets: line offsets
diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim
index 68a8ed129..59c53776a 100644
--- a/runtime/syntax/vim.vim
+++ b/runtime/syntax/vim.vim
@@ -66,7 +66,7 @@ syn keyword vimErrSetting contained	bioskey biosk conskey consk autoprint beauti
 
 " AutoCmd Events {{{2
 syn case ignore
-syn keyword vimAutoEvent contained	BufAdd BufCreate BufDelete BufEnter BufFilePost BufFilePre BufHidden BufLeave BufNew BufNewFile BufRead BufReadCmd BufReadPost BufReadPre BufUnload BufWinEnter BufWinLeave BufWipeout BufWrite BufWriteCmd BufWritePost BufWritePre CmdlineEnter CmdlineLeave CmdUndefined CmdwinEnter CmdwinLeave ColorScheme CompleteDone CursorHold CursorHoldI CursorMoved CursorMovedI EncodingChanged FileAppendCmd FileAppendPost FileAppendPre FileChangedRO FileChangedShell FileChangedShellPost FileEncoding FileReadCmd FileReadPost FileReadPre FileType FileWriteCmd FileWritePost FileWritePre FilterReadPost FilterReadPre FilterWritePost FilterWritePre FocusGained FocusLost FuncUndefined GUIEnter GUIFailed InsertChange InsertCharPre InsertEnter InsertLeave MenuPopup OptionSet QuickFixCmdPost QuickFixCmdPre QuitPre RemoteReply SessionLoadPost ShellCmdPost ShellFilterPost SourceCmd SourcePre SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TabClosed TabEnter TabLeave TabNew TermChanged TermResponse TextChanged TextChangedI User VimEnter VimLeave VimLeavePre VimResized WinEnter WinLeave WinNew 
+syn keyword vimAutoEvent contained	BufAdd BufCreate BufDelete BufEnter BufFilePost BufFilePre BufHidden BufLeave BufNew BufNewFile BufRead BufReadCmd BufReadPost BufReadPre BufUnload BufWinEnter BufWinLeave BufWipeout BufWrite BufWriteCmd BufWritePost BufWritePre CmdlineEnter CmdlineLeave CmdUndefined CmdwinEnter CmdwinLeave ColorScheme CompleteDone CursorHold CursorHoldI CursorMoved CursorMovedI EncodingChanged FileAppendCmd FileAppendPost FileAppendPre FileChangedRO FileChangedShell FileChangedShellPost FileEncoding FileReadCmd FileReadPost FileReadPre FileType FileWriteCmd FileWritePost FileWritePre FilterReadPost FilterReadPre FilterWritePost FilterWritePre FocusGained FocusLost FuncUndefined GUIEnter GUIFailed InsertChange InsertCharPre InsertEnter InsertLeave MenuPopup OptionSet QuickFixCmdPost QuickFixCmdPre QuitPre RemoteReply SearchCommand SessionLoadPost ShellCmdPost ShellFilterPost SourceCmd SourcePre SpellFileMissing StdinReadPost StdinReadPre SwapExists Syntax TabClosed TabEnter TabLeave TabNew TermChanged TermResponse TextChanged TextChangedI User VimEnter VimLeave VimLeavePre VimResized WinEnter WinLeave WinNew 
 
 " Highlight commonly used Groupnames {{{2
 syn keyword vimGroup contained	Comment Constant String Character Number Boolean Float Identifier Function Statement Conditional Repeat Label Operator Keyword Exception PreProc Include Define Macro PreCondit Type StorageClass Structure Typedef Special SpecialChar Tag Delimiter SpecialComment Debug Underlined Ignore Error Todo 
diff --git a/src/fileio.c b/src/fileio.c
index 8798cff1b..aa440aca9 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -7815,6 +7815,7 @@ static struct event_name
     {"QuickFixCmdPre",	EVENT_QUICKFIXCMDPRE},
     {"QuitPre",		EVENT_QUITPRE},
     {"RemoteReply",	EVENT_REMOTEREPLY},
+    {"SearchCommand",	EVENT_SEARCHCOMMAND},
     {"SessionLoadPost",	EVENT_SESSIONLOADPOST},
     {"ShellCmdPost",	EVENT_SHELLCMDPOST},
     {"ShellFilterPost",	EVENT_SHELLFILTERPOST},
diff --git a/src/normal.c b/src/normal.c
index 31ec36306..d07f6cba3 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -5819,6 +5819,7 @@ nv_ident(cmdarg_T *cap)
 	init_history();
 	add_to_history(HIST_SEARCH, buf, TRUE, NUL);
 #endif
+	apply_autocmds(EVENT_SEARCHCOMMAND, NULL, NULL, FALSE, curbuf);
 	(void)normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0);
     }
     else
@@ -6352,6 +6353,8 @@ nv_search(cmdarg_T *cap)
 	return;
     }
 
+    apply_autocmds(EVENT_SEARCHCOMMAND, NULL, NULL, FALSE, curbuf);
+
     (void)normal_search(cap, cap->cmdchar, cap->searchbuf,
 			(cap->arg || !EQUAL_POS(save_cursor, curwin->w_cursor))
 							   ? 0 : SEARCH_MARK);
@@ -6364,6 +6367,8 @@ nv_search(cmdarg_T *cap)
     static void
 nv_next(cmdarg_T *cap)
 {
+    apply_autocmds(EVENT_SEARCHCOMMAND, NULL, NULL, FALSE, curbuf);
+
     pos_T old = curwin->w_cursor;
     int   i = normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg);
 
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index d1ce56197..f24f29520 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -1304,3 +1304,33 @@ func Test_ChangedP()
 
   bw!
 endfunc
+
+function Test_search_command()
+  new
+  call setline(1, "test")
+
+  let s:search_command = 0
+  autocmd SearchCommand * let s:search_command += 1
+
+  " Normal-mode search commands should activate the autocmd...
+  exe "normal! /test\n"
+  call assert_equal(1, s:search_command)
+  exe "normal! ?test\n"
+  call assert_equal(2, s:search_command)
+  exe "normal! n"
+  call assert_equal(3, s:search_command)
+  exe "normal! *"
+  call assert_equal(4, s:search_command)
+  exe "normal! g#"
+  call assert_equal(5, s:search_command)
+
+  " ... but other search-related features should not.
+  call search('test')
+  call assert_equal(5, s:search_command)
+  :s/test//
+  call assert_equal(5, s:search_command)
+  :/test
+  call assert_equal(5, s:search_command)
+
+  bwipe!
+endfunc
diff --git a/src/vim.h b/src/vim.h
index 5e9f7d6d1..780c74900 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1325,6 +1325,7 @@ enum auto_event
     EVENT_CURSORHOLDI,		/* idem, in Insert mode */
     EVENT_FUNCUNDEFINED,	/* if calling a function which doesn't exist */
     EVENT_REMOTEREPLY,		/* upon string reception from a remote vim */
+    EVENT_SEARCHCOMMAND,	/* upon search command in Normal mode */
     EVENT_SWAPEXISTS,		/* found existing swap file */
     EVENT_SOURCEPRE,		/* before sourcing a Vim script */
     EVENT_SOURCECMD,		/* sourcing a Vim script using command */

Raspunde prin e-mail lui