Patch 8.2.4479
Problem:    No fuzzy completieon for maps and abbreviations.
Solution:   Fuzzy complete maps and abbreviations. (Yegappan Lakshmanan,
            closes #9856)
Files:      src/cmdexpand.c, src/map.c, src/proto/map.pro, src/search.c,
            src/testdir/test_cmdline.vim


*** ../vim-8.2.4478/src/cmdexpand.c     2022-02-26 16:05:05.030403209 +0000
--- src/cmdexpand.c     2022-02-27 12:01:28.427935734 +0000
***************
*** 56,62 ****
            && xp->xp_context != EXPAND_FILES_IN_PATH
            && xp->xp_context != EXPAND_FILETYPE
            && xp->xp_context != EXPAND_HELP
-           && xp->xp_context != EXPAND_MAPPINGS
            && xp->xp_context != EXPAND_OLD_SETTING
            && xp->xp_context != EXPAND_OWNSYNTAX
            && xp->xp_context != EXPAND_PACKADD
--- 56,61 ----
***************
*** 1216,1225 ****
  
      // Isolate the command and search for it in the command table.
      // Exceptions:
!     // - the 'k' command can directly be followed by any character, but
!     //   do accept "keepmarks", "keepalt" and "keepjumps".
      // - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
!     if (*cmd == 'k' && cmd[1] != 'e')
      {
        eap->cmdidx = CMD_k;
        p = cmd + 1;
--- 1215,1226 ----
  
      // Isolate the command and search for it in the command table.
      // Exceptions:
!     // - the 'k' command can directly be followed by any character, but do
!     // accept "keepmarks", "keepalt" and "keepjumps". As fuzzy matching can
!     // find matches anywhere in the command name, do this only for command
!     // expansion based on regular expression and not for fuzzy matching.
      // - the 's' command can be followed directly by 'c', 'g', 'i', 'I' or 'r'
!     if (!fuzzy && (*cmd == 'k' && cmd[1] != 'e'))
      {
        eap->cmdidx = CMD_k;
        p = cmd + 1;
***************
*** 2596,2602 ****
            || xp->xp_context == EXPAND_BOOL_SETTINGS)
        ret = ExpandSettings(xp, &regmatch, pat, numMatches, matches);
      else if (xp->xp_context == EXPAND_MAPPINGS)
!       ret = ExpandMappings(&regmatch, numMatches, matches);
  # if defined(FEAT_EVAL)
      else if (xp->xp_context == EXPAND_USER_DEFINED)
        ret = ExpandUserDefined(xp, &regmatch, matches, numMatches);
--- 2597,2603 ----
            || xp->xp_context == EXPAND_BOOL_SETTINGS)
        ret = ExpandSettings(xp, &regmatch, pat, numMatches, matches);
      else if (xp->xp_context == EXPAND_MAPPINGS)
!       ret = ExpandMappings(pat, &regmatch, numMatches, matches);
  # if defined(FEAT_EVAL)
      else if (xp->xp_context == EXPAND_USER_DEFINED)
        ret = ExpandUserDefined(xp, &regmatch, matches, numMatches);
***************
*** 2712,2718 ****
                fuzmatch = ALLOC_MULT(fuzmatch_str_T, count);
            else
                *matches = ALLOC_MULT(char_u *, count);
!           if ((fuzzy && (fuzmatch == NULL)) || (*matches == NULL))
            {
                *numMatches = 0;
                *matches = NULL;
--- 2713,2720 ----
                fuzmatch = ALLOC_MULT(fuzmatch_str_T, count);
            else
                *matches = ALLOC_MULT(char_u *, count);
!           if ((!fuzzy && (*matches == NULL))
!                                       || (fuzzy && (fuzmatch == NULL)))
            {
                *numMatches = 0;
                *matches = NULL;
*** ../vim-8.2.4478/src/map.c   2022-02-16 18:27:32.583437344 +0000
--- src/map.c   2022-02-27 12:01:28.427935734 +0000
***************
*** 1257,1265 ****
   */
      int
  ExpandMappings(
      regmatch_T        *regmatch,
!     int               *num_file,
!     char_u    ***file)
  {
      mapblock_T        *mp;
      int               hash;
--- 1257,1266 ----
   */
      int
  ExpandMappings(
+     char_u    *pat,
      regmatch_T        *regmatch,
!     int               *numMatches,
!     char_u    ***matches)
  {
      mapblock_T        *mp;
      int               hash;
***************
*** 1267,1277 ****
      int               round;
      char_u    *p;
      int               i;
  
      validate_maphash();
  
!     *num_file = 0;                // return values in case of FAIL
!     *file = NULL;
  
      // round == 1: Count the matches.
      // round == 2: Build the array to keep the matches.
--- 1268,1284 ----
      int               round;
      char_u    *p;
      int               i;
+     int               fuzzy;
+     int               match;
+     int               score;
+     fuzmatch_str_T  *fuzmatch = NULL;
+ 
+     fuzzy = cmdline_fuzzy_complete(pat);
  
      validate_maphash();
  
!     *numMatches = 0;              // return values in case of FAIL
!     *matches = NULL;
  
      // round == 1: Count the matches.
      // round == 2: Build the array to keep the matches.
***************
*** 1279,1284 ****
--- 1286,1292 ----
      {
        count = 0;
  
+       // First search in map modifier arguments
        for (i = 0; i < 7; ++i)
        {
            if (i == 0)
***************
*** 1300,1312 ****
            else
                continue;
  
!           if (vim_regexec(regmatch, p, (colnr_T)0))
            {
!               if (round == 1)
!                   ++count;
                else
!                   (*file)[count++] = vim_strsave(p);
            }
        }
  
        for (hash = 0; hash < 256; ++hash)
--- 1308,1336 ----
            else
                continue;
  
!           if (!fuzzy)
!               match = vim_regexec(regmatch, p, (colnr_T)0);
!           else
!           {
!               score = fuzzy_match_str(p, pat);
!               match = (score != 0);
!           }
! 
!           if (!match)
!               continue;
! 
!           if (round == 2)
            {
!               if (fuzzy)
!               {
!                   fuzmatch[count].idx = count;
!                   fuzmatch[count].str = vim_strsave(p);
!                   fuzmatch[count].score = score;
!               }
                else
!                   (*matches)[count] = vim_strsave(p);
            }
+           ++count;
        }
  
        for (hash = 0; hash < 256; ++hash)
***************
*** 1326,1339 ****
                if (mp->m_mode & expand_mapmodes)
                {
                    p = translate_mapping(mp->m_keys);
!                   if (p != NULL && vim_regexec(regmatch, p, (colnr_T)0))
                    {
!                       if (round == 1)
!                           ++count;
                        else
                        {
!                           (*file)[count++] = p;
!                           p = NULL;
                        }
                    }
                    vim_free(p);
--- 1350,1380 ----
                if (mp->m_mode & expand_mapmodes)
                {
                    p = translate_mapping(mp->m_keys);
!                   if (p != NULL)
                    {
!                       if (!fuzzy)
!                           match = vim_regexec(regmatch, p, (colnr_T)0);
                        else
                        {
!                           score = fuzzy_match_str(p, pat);
!                           match = (score != 0);
!                       }
! 
!                       if (match)
!                       {
!                           if (round == 2)
!                           {
!                               if (fuzzy)
!                               {
!                                   fuzmatch[count].idx = count;
!                                   fuzmatch[count].str = p;
!                                   fuzmatch[count].score = score;
!                               }
!                               else
!                                   (*matches)[count] = p;
!                               p = NULL;
!                           }
!                           ++count;
                        }
                    }
                    vim_free(p);
***************
*** 1346,1357 ****
  
        if (round == 1)
        {
!           *file = ALLOC_MULT(char_u *, count);
!           if (*file == NULL)
!               return FAIL;
        }
      } // for (round)
  
      if (count > 1)
      {
        char_u  **ptr1;
--- 1387,1411 ----
  
        if (round == 1)
        {
!           if (fuzzy)
!           {
!               fuzmatch = ALLOC_MULT(fuzmatch_str_T, count);
!               if (fuzmatch == NULL)
!                   return FAIL;
!           }
!           else
!           {
!               *matches = ALLOC_MULT(char_u *, count);
!               if (*matches == NULL)
!                   return FAIL;
!           }
        }
      } // for (round)
  
+     if (fuzzy && fuzzymatches_to_strmatches(fuzmatch, matches, count,
+                                                       FALSE) == FAIL)
+       return FAIL;
+ 
      if (count > 1)
      {
        char_u  **ptr1;
***************
*** 1359,1368 ****
        char_u  **ptr3;
  
        // Sort the matches
!       sort_strings(*file, count);
  
        // Remove multiple entries
!       ptr1 = *file;
        ptr2 = ptr1 + 1;
        ptr3 = ptr1 + count;
  
--- 1413,1424 ----
        char_u  **ptr3;
  
        // Sort the matches
!       // Fuzzy matching already sorts the matches
!       if (!fuzzy)
!           sort_strings(*matches, count);
  
        // Remove multiple entries
!       ptr1 = *matches;
        ptr2 = ptr1 + 1;
        ptr3 = ptr1 + count;
  
***************
*** 1378,1384 ****
        }
      }
  
!     *num_file = count;
      return (count == 0 ? FAIL : OK);
  }
  
--- 1434,1440 ----
        }
      }
  
!     *numMatches = count;
      return (count == 0 ? FAIL : OK);
  }
  
*** ../vim-8.2.4478/src/proto/map.pro   2022-01-11 11:58:14.920745981 +0000
--- src/proto/map.pro   2022-02-27 12:01:28.431935722 +0000
***************
*** 8,14 ****
  int map_to_exists(char_u *str, char_u *modechars, int abbr);
  int map_to_exists_mode(char_u *rhs, int mode, int abbr);
  char_u *set_context_in_map_cmd(expand_T *xp, char_u *cmd, char_u *arg, int 
forceit, int isabbrev, int isunmap, cmdidx_T cmdidx);
! int ExpandMappings(regmatch_T *regmatch, int *num_file, char_u ***file);
  int check_abbr(int c, char_u *ptr, int col, int mincol);
  char_u *eval_map_expr(mapblock_T *mp, int c);
  char_u *vim_strsave_escape_csi(char_u *p);
--- 8,14 ----
  int map_to_exists(char_u *str, char_u *modechars, int abbr);
  int map_to_exists_mode(char_u *rhs, int mode, int abbr);
  char_u *set_context_in_map_cmd(expand_T *xp, char_u *cmd, char_u *arg, int 
forceit, int isabbrev, int isunmap, cmdidx_T cmdidx);
! int ExpandMappings(char_u *pat, regmatch_T *regmatch, int *num_file, char_u 
***file);
  int check_abbr(int c, char_u *ptr, int col, int mincol);
  char_u *eval_map_expr(mapblock_T *mp, int c);
  char_u *vim_strsave_escape_csi(char_u *p);
*** ../vim-8.2.4478/src/search.c        2022-02-25 15:24:21.049157319 +0000
--- src/search.c        2022-02-27 12:01:28.431935722 +0000
***************
*** 5006,5012 ****
      if (str == NULL || pat == NULL)
        return 0;
  
!     fuzzy_match(str, pat, FALSE, &score, matchpos,
                                sizeof(matchpos) / sizeof(matchpos[0]));
  
      return score;
--- 5006,5012 ----
      if (str == NULL || pat == NULL)
        return 0;
  
!     fuzzy_match(str, pat, TRUE, &score, matchpos,
                                sizeof(matchpos) / sizeof(matchpos[0]));
  
      return score;
*** ../vim-8.2.4478/src/testdir/test_cmdline.vim        2022-02-26 
16:05:05.030403209 +0000
--- src/testdir/test_cmdline.vim        2022-02-27 12:01:28.431935722 +0000
***************
*** 2658,2668 ****
    call feedkeys(":mapclear buf\<Tab>\<C-B>\"\<CR>", 'tx')
    call assert_equal('"mapclear <buffer>', @:)
  
!   " map name fuzzy completion - NOT supported
    " test regex completion works
    set wildoptions=fuzzy
    call feedkeys(":cnoremap <ex\<Tab> <esc> \<Tab>\<C-B>\"\<CR>", 'tx')
    call assert_equal("\"cnoremap <expr> <esc> \<Tab>", @:)
  
    " menu name fuzzy completion
    if has('gui_running')
--- 2658,2709 ----
    call feedkeys(":mapclear buf\<Tab>\<C-B>\"\<CR>", 'tx')
    call assert_equal('"mapclear <buffer>', @:)
  
!   " map name fuzzy completion
    " test regex completion works
    set wildoptions=fuzzy
    call feedkeys(":cnoremap <ex\<Tab> <esc> \<Tab>\<C-B>\"\<CR>", 'tx')
    call assert_equal("\"cnoremap <expr> <esc> \<Tab>", @:)
+   nmap <plug>MyLongMap :p<CR>
+   call feedkeys(":nmap MLM\<Tab>\<C-B>\"\<CR>", 'tx')
+   call assert_equal("\"nmap <Plug>MyLongMap", @:)
+   call feedkeys(":nmap MLM \<Tab>\<C-B>\"\<CR>", 'tx')
+   call assert_equal("\"nmap MLM \t", @:)
+   call feedkeys(":nmap <F2> one two \<Tab>\<C-B>\"\<CR>", 'tx')
+   call assert_equal("\"nmap <F2> one two \t", @:)
+   " duplicate entries should be removed
+   vmap <plug>MyLongMap :<C-U>#<CR>
+   call feedkeys(":nmap MLM\<Tab>\<C-B>\"\<CR>", 'tx')
+   call assert_equal("\"nmap <Plug>MyLongMap", @:)
+   nunmap <plug>MyLongMap
+   vunmap <plug>MyLongMap
+   call feedkeys(":nmap ABC\<Tab>\<C-B>\"\<CR>", 'tx')
+   call assert_equal("\"nmap ABC\t", @:)
+   " results should be sorted by best match
+   nmap <Plug>format :
+   nmap <Plug>goformat :
+   nmap <Plug>TestFOrmat :
+   nmap <Plug>fendoff :
+   nmap <Plug>state :
+   nmap <Plug>FendingOff :
+   call feedkeys(":nmap <Plug>fo\<C-A>\<C-B>\"\<CR>", 'tx')
+   call assert_equal("\"nmap <Plug>format <Plug>TestFOrmat <Plug>FendingOff 
<Plug>goformat <Plug>fendoff", @:)
+   nunmap <Plug>format
+   nunmap <Plug>goformat
+   nunmap <Plug>TestFOrmat
+   nunmap <Plug>fendoff
+   nunmap <Plug>state
+   nunmap <Plug>FendingOff
+ 
+   " abbreviation fuzzy completion
+   set wildoptions=fuzzy
+   call feedkeys(":iabbr wait\<Tab>\<C-B>\"\<CR>", 'tx')
+   call assert_equal("\"iabbr <nowait>", @:)
+   iabbr WaitForCompletion WFC
+   call feedkeys(":iabbr fcl\<Tab>\<C-B>\"\<CR>", 'tx')
+   call assert_equal("\"iabbr WaitForCompletion", @:)
+   call feedkeys(":iabbr a1z\<Tab>\<C-B>\"\<CR>", 'tx')
+   call assert_equal("\"iabbr a1z\t", @:)
+   iunabbrev WaitForCompletion
  
    " menu name fuzzy completion
    if has('gui_running')
***************
*** 2792,2797 ****
--- 2833,2848 ----
    call assert_equal('"Foo2Bar', @:)
    delcommand Foo2Bar
  
+   " Test for command completion for a command starting with 'k'
+   command KillKillKill :
+   set wildoptions&
+   call feedkeys(":killkill\<Tab>\<C-B>\"\<CR>", 'tx')
+   call assert_equal("\"killkill\<Tab>", @:)
+   set wildoptions=fuzzy
+   call feedkeys(":killkill\<Tab>\<C-B>\"\<CR>", 'tx')
+   call assert_equal('"KillKillKill', @:)
+   delcom KillKillKill
+ 
    set wildoptions&
    %bw!
  endfunc
*** ../vim-8.2.4478/src/version.c       2022-02-26 16:05:05.034403199 +0000
--- src/version.c       2022-02-27 12:04:06.599471869 +0000
***************
*** 756,757 ****
--- 756,759 ----
  {   /* Add new patch number below this line */
+ /**/
+     4479,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
114. You are counting items, you go "0,1,2,3,4,5,6,7,8,9,A,B,C,D...".

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220227120810.C80481C14BE%40moolenaar.net.

Raspunde prin e-mail lui