[patch] CTRL-L with incsearch, ignorecase and smartcase

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

[patch] CTRL-L with incsearch, ignorecase and smartcase

Martin Toft
Hi,

this patch addresses the following bug:

    When 'smartcase' is set and using CTRL-L to add to the search
    pattern it may result in no matches.  Convert chars to lower case?
    (Erik Wognsen, 2009 Apr 16)

The description is taken from
http://code.google.com/p/vim/source/browse/runtime/doc/todo.txt?r=63157185aea525b39b1238df3ffbf4ec0fea10b1#482
and the original mail thread describing the problem is
http://groups.google.com/group/vim_use/browse_thread/thread/7321c95ebde237e3/2cd4e07431dcaf3c

The patch does what the description suggests, i.e. the added character
is converted to lowercase if 'ignorecase' and 'smartcase' are set and
CTRL-L is pressed during an incremental search.

Martin


diff -r 63157185aea5 runtime/doc/cmdline.txt
--- a/runtime/doc/cmdline.txt Sat Jun 05 12:49:46 2010 +0200
+++ b/runtime/doc/cmdline.txt Sat Jun 05 20:58:28 2010 +0200
@@ -416,7 +416,9 @@
  than the pattern, no completion is done.
  When 'incsearch' is set, entering a search pattern for "/" or
  "?" and the current match is displayed then CTRL-L will add
- one character from the end of the current match.
+ one character from the end of the current match.  If
+ 'ignorecase' and 'smartcase' are set, the added character is
+ converted to lowercase.
 
 The 'wildchar' option defaults to <Tab> (CTRL-E when in Vi compatible mode; in
 a previous version <Esc> was used).  In the pattern standard wildcards '*' and
diff -r 63157185aea5 runtime/doc/options.txt
--- a/runtime/doc/options.txt Sat Jun 05 12:49:46 2010 +0200
+++ b/runtime/doc/options.txt Sat Jun 05 20:58:28 2010 +0200
@@ -3939,7 +3939,8 @@
  The highlighting can be set with the 'i' flag in 'highlight'.
  See also: 'hlsearch'.
  CTRL-L can be used to add one character from after the current match
- to the command line.
+ to the command line.  If 'ignorecase' and 'smartcase' are set, the
+ added character is converted to lowercase.
  CTRL-R CTRL-W can be used to add the word at the end of the current
  match, excluding the characters that were already typed.
  NOTE: This option is reset when 'compatible' is set.
diff -r 63157185aea5 src/ex_getln.c
--- a/src/ex_getln.c Sat Jun 05 12:49:46 2010 +0200
+++ b/src/ex_getln.c Sat Jun 05 20:58:28 2010 +0200
@@ -1411,6 +1411,10 @@
    && !equalpos(curwin->w_cursor, old_cursor))
     {
  c = gchar_cursor();
+ /* If 'ignorecase' and 'smartcase' are set, convert the
+ * character to lowercase */
+ if (p_ic && p_scs)
+    c = MB_TOLOWER(c);
  if (c != NUL)
  {
     if (c == firstc || vim_strchr((char_u *)(

--
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
enk
Reply | Threaded
Open this post in threaded view
|

Re: CTRL-L with incsearch, ignorecase and smartcase

enk
Hi Martin,
thanks for looking into it!

I just remembered one thing, though:

If there's already something upper case in the search pattern and the
new char is converted to lower case, the pattern will again stop
matching! Maybe the search pattern needs to be scanned for case
inside  the "if (p_ic && p_scs)" and only convert to lower case if the
search pattern is already only lower case (i.e. not triggering the
case sensitivity of 'smartcase')?

/Erik


On Jun 5, 11:07 pm, Martin Toft <[hidden email]> wrote:

> Hi,
>
> this patch addresses the following bug:
>
>     When 'smartcase' is set and using CTRL-L to add to the search
>     pattern it may result in no matches.  Convert chars to lower case?
>     (Erik Wognsen, 2009 Apr 16)
>
> The description is taken fromhttp://code.google.com/p/vim/source/browse/runtime/doc/todo.txt?r=631...
> and the original mail thread describing the problem ishttp://groups.google.com/group/vim_use/browse_thread/thread/7321c95eb...
>
> The patch does what the description suggests, i.e. the added character
> is converted to lowercase if 'ignorecase' and 'smartcase' are set and
> CTRL-L is pressed during an incremental search.
>
> Martin
>
> diff -r 63157185aea5 runtime/doc/cmdline.txt
> --- a/runtime/doc/cmdline.txt   Sat Jun 05 12:49:46 2010 +0200
> +++ b/runtime/doc/cmdline.txt   Sat Jun 05 20:58:28 2010 +0200
> @@ -416,7 +416,9 @@
>                 than the pattern, no completion is done.
>                 When 'incsearch' is set, entering a search pattern for "/" or
>                 "?" and the current match is displayed then CTRL-L will add
> -               one character from the end of the current match.
> +               one character from the end of the current match.  If
> +               'ignorecase' and 'smartcase' are set, the added character is
> +               converted to lowercase.
>
>  The 'wildchar' option defaults to <Tab> (CTRL-E when in Vi compatible mode; in
>  a previous version <Esc> was used).  In the pattern standard wildcards '*' and
> diff -r 63157185aea5 runtime/doc/options.txt
> --- a/runtime/doc/options.txt   Sat Jun 05 12:49:46 2010 +0200
> +++ b/runtime/doc/options.txt   Sat Jun 05 20:58:28 2010 +0200
> @@ -3939,7 +3939,8 @@
>         The highlighting can be set with the 'i' flag in 'highlight'.
>         See also: 'hlsearch'.
>         CTRL-L can be used to add one character from after the current match
> -       to the command line.
> +       to the command line.  If 'ignorecase' and 'smartcase' are set, the
> +       added character is converted to lowercase.
>         CTRL-R CTRL-W can be used to add the word at the end of the current
>         match, excluding the characters that were already typed.
>         NOTE: This option is reset when 'compatible' is set.
> diff -r 63157185aea5 src/ex_getln.c
> --- a/src/ex_getln.c    Sat Jun 05 12:49:46 2010 +0200
> +++ b/src/ex_getln.c    Sat Jun 05 20:58:28 2010 +0200
> @@ -1411,6 +1411,10 @@
>                                    && !equalpos(curwin->w_cursor, old_cursor))
>                     {
>                         c = gchar_cursor();
> +                       /* If 'ignorecase' and 'smartcase' are set, convert the
> +                        * character to lowercase */
> +                       if (p_ic && p_scs)
> +                           c = MB_TOLOWER(c);
>                         if (c != NUL)
>                         {
>                             if (c == firstc || vim_strchr((char_u *)(

--
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
Reply | Threaded
Open this post in threaded view
|

Re: CTRL-L with incsearch, ignorecase and smartcase

Martin Toft
On Mon, Jun 07, 2010 at 09:12:26AM -0700, Erik Wognsen wrote:
> If there's already something upper case in the search pattern and the
> new char is converted to lower case, the pattern will again stop
> matching! Maybe the search pattern needs to be scanned for case
> inside  the "if (p_ic && p_scs)" and only convert to lower case if the
> search pattern is already only lower case (i.e. not triggering the
> case sensitivity of 'smartcase')?

Yeah, I missed that case in my first attempt.  Please see (and test) the
patch below.

It refactors some code out of search.c and adds the function
has_uppercase to misc1.c.  In misc1.c it turns a "return" into a
"Return" in an unrelated comment because I was in that area of the file
anyway.

The diff is made using "hg extdiff -p -o -rc" as I know context diffs
are appreciated :-)

Martin


diff -rc vim.63157185aea5/runtime/doc/cmdline.txt vim/runtime/doc/cmdline.txt
*** vim.63157185aea5/runtime/doc/cmdline.txt Tue Jun  8 23:33:29 2010
--- vim/runtime/doc/cmdline.txt Tue Jun  8 23:33:29 2010
***************
*** 416,422 ****
  than the pattern, no completion is done.
  When 'incsearch' is set, entering a search pattern for "/" or
  "?" and the current match is displayed then CTRL-L will add
! one character from the end of the current match.
 
  The 'wildchar' option defaults to <Tab> (CTRL-E when in Vi compatible mode; in
  a previous version <Esc> was used).  In the pattern standard wildcards '*' and
--- 416,425 ----
  than the pattern, no completion is done.
  When 'incsearch' is set, entering a search pattern for "/" or
  "?" and the current match is displayed then CTRL-L will add
! one character from the end of the current match.  If
! 'ignorecase' and 'smartcase' are set and the command line has
! no uppercase characters, the added character is converted to
! lowercase.
 
  The 'wildchar' option defaults to <Tab> (CTRL-E when in Vi compatible mode; in
  a previous version <Esc> was used).  In the pattern standard wildcards '*' and
diff -rc vim.63157185aea5/runtime/doc/options.txt vim/runtime/doc/options.txt
*** vim.63157185aea5/runtime/doc/options.txt Tue Jun  8 23:33:29 2010
--- vim/runtime/doc/options.txt Tue Jun  8 23:33:29 2010
***************
*** 3939,3945 ****
  The highlighting can be set with the 'i' flag in 'highlight'.
  See also: 'hlsearch'.
  CTRL-L can be used to add one character from after the current match
! to the command line.
  CTRL-R CTRL-W can be used to add the word at the end of the current
  match, excluding the characters that were already typed.
  NOTE: This option is reset when 'compatible' is set.
--- 3939,3947 ----
  The highlighting can be set with the 'i' flag in 'highlight'.
  See also: 'hlsearch'.
  CTRL-L can be used to add one character from after the current match
! to the command line.  If 'ignorecase' and 'smartcase' are set and the
! command line has no uppercase characters, the added character is
! converted to lowercase.
  CTRL-R CTRL-W can be used to add the word at the end of the current
  match, excluding the characters that were already typed.
  NOTE: This option is reset when 'compatible' is set.
diff -rc vim.63157185aea5/src/ex_getln.c vim/src/ex_getln.c
*** vim.63157185aea5/src/ex_getln.c Tue Jun  8 23:33:29 2010
--- vim/src/ex_getln.c Tue Jun  8 23:33:29 2010
***************
*** 1411,1416 ****
--- 1411,1421 ----
    && !equalpos(curwin->w_cursor, old_cursor))
     {
  c = gchar_cursor();
+ /* If 'ignorecase' and 'smartcase' are set and the
+ * command line has no uppercase characters, convert
+ * the character to lowercase */
+ if (p_ic && p_scs && !has_uppercase(ccline.cmdbuff))
+    c = MB_TOLOWER(c);
  if (c != NUL)
  {
     if (c == firstc || vim_strchr((char_u *)(
diff -rc vim.63157185aea5/src/misc1.c vim/src/misc1.c
*** vim.63157185aea5/src/misc1.c Tue Jun  8 23:33:29 2010
--- vim/src/misc1.c Tue Jun  8 23:33:29 2010
***************
*** 9575,9581 ****
  }
 
  /*
!  * return TRUE when need to go to Insert mode because of 'insertmode'.
   * Don't do this when still processing a command or a mapping.
   * Don't do this when inside a ":normal" command.
   */
--- 9575,9581 ----
  }
 
  /*
!  * Return TRUE when need to go to Insert mode because of 'insertmode'.
   * Don't do this when still processing a command or a mapping.
   * Don't do this when inside a ":normal" command.
   */
***************
*** 9583,9586 ****
--- 9583,9632 ----
  goto_im()
  {
      return (p_im && stuff_empty() && typebuf_typed());
+ }
+
+ /*
+  * Return TRUE when pattern "pat" has an uppercase character.
+  */
+     int
+ has_uppercase(pat)
+     char_u *pat;
+ {
+     while (*pat)
+     {
+ #ifdef FEAT_MBYTE
+ int l;
+
+ if (has_mbyte && (l = (*mb_ptr2len)(pat)) > 1)
+ {
+    if (enc_utf8 && utf_isupper(utf_ptr2char(pat)))
+    {
+ return TRUE;
+ break;
+    }
+    pat += l;
+ }
+ else
+ #endif
+    if (*pat == '\\')
+    {
+ if (pat[1] == '_' && pat[2] != NUL)  /* skip "\_X" */
+    pat += 3;
+ else if (pat[1] == '%' && pat[2] != NUL)  /* skip "\%X" */
+    pat += 3;
+ else if (pat[1] != NUL)  /* skip "\X" */
+    pat += 2;
+ else
+    pat += 1;
+    }
+    else if (MB_ISUPPER(*pat))
+    {
+ return TRUE;
+ break;
+    }
+    else
+ ++pat;
+     }
+
+     return FALSE;
  }
diff -rc vim.63157185aea5/src/search.c vim/src/search.c
*** vim.63157185aea5/src/search.c Tue Jun  8 23:33:29 2010
--- vim/src/search.c Tue Jun  8 23:33:29 2010
***************
*** 365,420 ****
  ignorecase(pat)
      char_u *pat;
  {
!     char_u *p;
!     int ic;
!
!     ic = p_ic;
!     if (ic && !no_smartcase && p_scs
  #ifdef FEAT_INS_EXPAND
  && !(ctrl_x_mode && curbuf->b_p_inf)
  #endif
     )
!     {
! /* don't ignore case if pattern has uppercase */
! for (p = pat; *p; )
! {
! #ifdef FEAT_MBYTE
!    int l;
 
-    if (has_mbyte && (l = (*mb_ptr2len)(p)) > 1)
-    {
- if (enc_utf8 && utf_isupper(utf_ptr2char(p)))
- {
-    ic = FALSE;
-    break;
- }
- p += l;
-    }
-    else
- #endif
-                 if (*p == '\\')
- {
-    if (p[1] == '_' && p[2] != NUL)  /* skip "\_X" */
- p += 3;
-    else if (p[1] == '%' && p[2] != NUL)  /* skip "\%X" */
- p += 3;
-    else if (p[1] != NUL)  /* skip "\X" */
- p += 2;
-    else
- p += 1;
- }
- else if (MB_ISUPPER(*p))
- {
-    ic = FALSE;
-    break;
- }
- else
-    ++p;
- }
-     }
      no_smartcase = FALSE;
!
!     return ic;
  }
 
      char_u *
--- 365,379 ----
  ignorecase(pat)
      char_u *pat;
  {
!     if (p_ic && !no_smartcase && p_scs && !has_uppercase(pat)
  #ifdef FEAT_INS_EXPAND
  && !(ctrl_x_mode && curbuf->b_p_inf)
  #endif
     )
! return TRUE;
 
      no_smartcase = FALSE;
!     return FALSE;
  }
 
      char_u *

--
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
Reply | Threaded
Open this post in threaded view
|

Re: CTRL-L with incsearch, ignorecase and smartcase

Martin Toft
On Tue, Jun 08, 2010 at 11:37:09PM +0200, Martin Toft wrote:
> The diff is made using "hg extdiff -p -o -rc"

Make that "hg extdiff -p diff -o -rc".

--
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
Reply | Threaded
Open this post in threaded view
|

Re: CTRL-L with incsearch, ignorecase and smartcase

Martin Toft
In reply to this post by Martin Toft
Am I going in the wrong direction with this?

I have attached an ordinary Mercual-diff, in case my earlier context
diff was too weird. It is attached as a file this time.

Martin

--
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

incsearch-ctrl-l-patch.txt (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: CTRL-L with incsearch, ignorecase and smartcase

Martin Toft
On Wed, Jun 16, 2010 at 10:22:46PM +0200, Martin Toft wrote:
> Am I going in the wrong direction with this?
>
> I have attached an ordinary Mercual-diff, in case my earlier context
> diff was too weird. It is attached as a file this time.

Bump!

I have attached an updated diff, which includes the prototype for
misc1.c:has_uppercase.

--
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

incsearch-ctrl-l-patch.txt (4K) Download Attachment