@@ -4676,7 +4676,73 @@ current_quote(
46764676
46774677#endif /* FEAT_TEXTOBJ */
46784678
4679- static int is_one_char (char_u * pattern , int move , pos_T * cur , int direction );
4679+ /*
4680+ * Check if the pattern is one character long or zero-width.
4681+ * If move is TRUE, check from the beginning of the buffer, else from position
4682+ * "cur".
4683+ * "direction" is FORWARD or BACKWARD.
4684+ * Returns TRUE, FALSE or -1 for failure.
4685+ */
4686+ static int
4687+ is_zero_width (char_u * pattern , int move , pos_T * cur , int direction )
4688+ {
4689+ regmmatch_T regmatch ;
4690+ int nmatched = 0 ;
4691+ int result = -1 ;
4692+ pos_T pos ;
4693+ int save_called_emsg = called_emsg ;
4694+ int flag = 0 ;
4695+
4696+ if (pattern == NULL )
4697+ pattern = spats [last_idx ].pat ;
4698+
4699+ if (search_regcomp (pattern , RE_SEARCH , RE_SEARCH ,
4700+ SEARCH_KEEP , & regmatch ) == FAIL )
4701+ return -1 ;
4702+
4703+ // init startcol correctly
4704+ regmatch .startpos [0 ].col = -1 ;
4705+ // move to match
4706+ if (move )
4707+ {
4708+ CLEAR_POS (& pos );
4709+ }
4710+ else
4711+ {
4712+ pos = * cur ;
4713+ // accept a match at the cursor position
4714+ flag = SEARCH_START ;
4715+ }
4716+
4717+ if (searchit (curwin , curbuf , & pos , NULL , direction , pattern , 1 ,
4718+ SEARCH_KEEP + flag , RE_SEARCH , NULL ) != FAIL )
4719+ {
4720+ // Zero-width pattern should match somewhere, then we can check if
4721+ // start and end are in the same position.
4722+ called_emsg = FALSE;
4723+ do
4724+ {
4725+ regmatch .startpos [0 ].col ++ ;
4726+ nmatched = vim_regexec_multi (& regmatch , curwin , curbuf ,
4727+ pos .lnum , regmatch .startpos [0 ].col , NULL , NULL );
4728+ if (nmatched != 0 )
4729+ break ;
4730+ } while (direction == FORWARD ? regmatch .startpos [0 ].col < pos .col
4731+ : regmatch .startpos [0 ].col > pos .col );
4732+
4733+ if (!called_emsg )
4734+ {
4735+ result = (nmatched != 0
4736+ && regmatch .startpos [0 ].lnum == regmatch .endpos [0 ].lnum
4737+ && regmatch .startpos [0 ].col == regmatch .endpos [0 ].col );
4738+ }
4739+ }
4740+
4741+ called_emsg |= save_called_emsg ;
4742+ vim_regfree (regmatch .regprog );
4743+ return result ;
4744+ }
4745+
46804746
46814747/*
46824748 * Find next search match under cursor, cursor at end.
@@ -4697,7 +4763,7 @@ current_search(
46974763 char_u old_p_ws = p_ws ;
46984764 int flags = 0 ;
46994765 pos_T save_VIsual = VIsual ;
4700- int one_char ;
4766+ int zero_width ;
47014767
47024768 /* wrapping should not occur */
47034769 p_ws = FALSE;
@@ -4706,29 +4772,20 @@ current_search(
47064772 if (VIsual_active && * p_sel == 'e' && LT_POS (VIsual , curwin -> w_cursor ))
47074773 dec_cursor ();
47084774
4775+ orig_pos = pos = curwin -> w_cursor ;
47094776 if (VIsual_active )
47104777 {
4711- orig_pos = curwin -> w_cursor ;
4712-
4713- pos = curwin -> w_cursor ;
4714-
4715- /* make sure, searching further will extend the match */
4716- if (VIsual_active )
4717- {
4718- if (forward )
4719- incl (& pos );
4720- else
4721- decl (& pos );
4722- }
4778+ if (forward )
4779+ incl (& pos );
4780+ else
4781+ decl (& pos );
47234782 }
4724- else
4725- orig_pos = pos = curwin -> w_cursor ;
47264783
47274784 /* Is the pattern is zero-width?, this time, don't care about the direction
47284785 */
4729- one_char = is_one_char (spats [last_idx ].pat , TRUE, & curwin -> w_cursor ,
4786+ zero_width = is_zero_width (spats [last_idx ].pat , TRUE, & curwin -> w_cursor ,
47304787 FORWARD );
4731- if (one_char == -1 )
4788+ if (zero_width == -1 )
47324789 {
47334790 p_ws = old_p_ws ;
47344791 return FAIL ; /* pattern not found */
@@ -4747,7 +4804,7 @@ current_search(
47474804 dir = !i ;
47484805
47494806 flags = 0 ;
4750- if (!dir && !one_char )
4807+ if (!dir && !zero_width )
47514808 flags = SEARCH_END ;
47524809 end_pos = pos ;
47534810
@@ -4784,7 +4841,6 @@ current_search(
47844841 ml_get (curwin -> w_buffer -> b_ml .ml_line_count ));
47854842 }
47864843 }
4787- p_ws = old_p_ws ;
47884844 }
47894845
47904846 start_pos = pos ;
@@ -4797,10 +4853,11 @@ current_search(
47974853 curwin -> w_cursor = end_pos ;
47984854 if (LT_POS (VIsual , end_pos ))
47994855 dec_cursor ();
4856+ else if (VIsual_active && LT_POS (curwin -> w_cursor , VIsual ))
4857+ curwin -> w_cursor = pos ; // put the cursor on the start of the match
48004858 VIsual_active = TRUE;
48014859 VIsual_mode = 'v' ;
48024860
4803- redraw_curbuf_later (INVERTED ); /* update the inversion */
48044861 if (* p_sel == 'e' )
48054862 {
48064863 /* Correction for exclusive selection depends on the direction. */
@@ -4828,77 +4885,6 @@ current_search(
48284885 return OK ;
48294886}
48304887
4831- /*
4832- * Check if the pattern is one character long or zero-width.
4833- * If move is TRUE, check from the beginning of the buffer, else from position
4834- * "cur".
4835- * "direction" is FORWARD or BACKWARD.
4836- * Returns TRUE, FALSE or -1 for failure.
4837- */
4838- static int
4839- is_one_char (char_u * pattern , int move , pos_T * cur , int direction )
4840- {
4841- regmmatch_T regmatch ;
4842- int nmatched = 0 ;
4843- int result = -1 ;
4844- pos_T pos ;
4845- int save_called_emsg = called_emsg ;
4846- int flag = 0 ;
4847-
4848- if (pattern == NULL )
4849- pattern = spats [last_idx ].pat ;
4850-
4851- if (search_regcomp (pattern , RE_SEARCH , RE_SEARCH ,
4852- SEARCH_KEEP , & regmatch ) == FAIL )
4853- return -1 ;
4854-
4855- /* init startcol correctly */
4856- regmatch .startpos [0 ].col = -1 ;
4857- /* move to match */
4858- if (move )
4859- {
4860- CLEAR_POS (& pos );
4861- }
4862- else
4863- {
4864- pos = * cur ;
4865- /* accept a match at the cursor position */
4866- flag = SEARCH_START ;
4867- }
4868-
4869- if (searchit (curwin , curbuf , & pos , NULL , direction , pattern , 1 ,
4870- SEARCH_KEEP + flag , RE_SEARCH , NULL ) != FAIL )
4871- {
4872- /* Zero-width pattern should match somewhere, then we can check if
4873- * start and end are in the same position. */
4874- called_emsg = FALSE;
4875- do
4876- {
4877- regmatch .startpos [0 ].col ++ ;
4878- nmatched = vim_regexec_multi (& regmatch , curwin , curbuf ,
4879- pos .lnum , regmatch .startpos [0 ].col , NULL , NULL );
4880- if (nmatched != 0 )
4881- break ;
4882- } while (direction == FORWARD ? regmatch .startpos [0 ].col < pos .col
4883- : regmatch .startpos [0 ].col > pos .col );
4884-
4885- if (!called_emsg )
4886- {
4887- result = (nmatched != 0
4888- && regmatch .startpos [0 ].lnum == regmatch .endpos [0 ].lnum
4889- && regmatch .startpos [0 ].col == regmatch .endpos [0 ].col );
4890- // one char width
4891- if (!result && nmatched != 0
4892- && inc (& pos ) >= 0 && pos .col == regmatch .endpos [0 ].col )
4893- result = TRUE;
4894- }
4895- }
4896-
4897- called_emsg |= save_called_emsg ;
4898- vim_regfree (regmatch .regprog );
4899- return result ;
4900- }
4901-
49024888#if defined(FEAT_LISP ) || defined(FEAT_CINDENT ) || defined(FEAT_TEXTOBJ ) \
49034889 || defined(PROTO )
49044890/*
0 commit comments