]> granicus.if.org Git - vim/commitdiff
patch 8.1.1769: 'shellslash' is also used for completion v8.1.1769
authorBram Moolenaar <Bram@vim.org>
Sun, 28 Jul 2019 14:36:39 +0000 (16:36 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 28 Jul 2019 14:36:39 +0000 (16:36 +0200)
Problem:    'shellslash' is also used for completion.
Solution:   Add the 'completeslash' option. (Yasuhiro Matsumoto, closes #3612)

runtime/doc/options.txt
src/ex_getln.c
src/insexpand.c
src/option.c
src/option.h
src/structs.h
src/testdir/test_ins_complete.vim
src/version.c

index 2583780bc3a18cf47a2aaf0dba8eed58ed4e189c..0d5586357d8b62ceb89e2563e0a8ea1714ae7c3a 100644 (file)
@@ -1874,6 +1874,21 @@ A jump table for the options with a short description can be found at |Q_op|.
        This option cannot be set from a |modeline| or in the |sandbox|, for
        security reasons.
 
+                                               *'completeslash'* *'csl'*
+'completeslash' 'csl'  string  (default: "")
+                       local to buffer
+                       {not in Vi}  {only for MS-Windows}
+       When this option is set it overrules 'shellslash' for completion:
+       - When this option is set to "slash", a forward slash is used for path
+         completion in insert mode. This is useful when editing HTML tag, or
+         Makefile with 'noshellslash' on Windows.
+       - When this option is set to "backslash", backslash is used. This is
+         useful when editing a batch file with 'shellslash' set on Windows.
+       - When this option is empty, same character is used as for
+         'shellslash'.
+       For Insert mode completion the buffer-local value is used.  For
+       command line completion the global value is used.
+
                                                *'completeopt'* *'cot'*
 'completeopt' 'cot'    string  (default: "menu,preview")
                        global
@@ -6521,7 +6536,8 @@ A jump table for the options with a short description can be found at |Q_op|.
        'shellslash' only works when a backslash can be used as a path
        separator.  To test if this is so use: >
                if exists('+shellslash')
-<
+<      Also see 'completeslash'.
+
                        *'shelltemp'* *'stmp'* *'noshelltemp'* *'nostmp'*
 'shelltemp' 'stmp'     boolean (Vi default off, Vim default on)
                        global
index 471479c2caa60986e659d7a9bed4bd7dcbdabd87..7ef304ddbd7dc77b54975c2a7dd3bb607268f159 100644 (file)
@@ -5095,6 +5095,26 @@ ExpandFromContext(
        ret = expand_wildcards_eval(&pat, num_file, file, flags);
        if (free_pat)
            vim_free(pat);
+#ifdef BACKSLASH_IN_FILENAME
+       if (p_csl[0] != NUL)
+       {
+           int     i;
+
+           for (i = 0; i < *num_file; ++i)
+           {
+               char_u  *ptr = (*file)[i];
+
+               while (*ptr != NUL)
+               {
+                   if (p_csl[0] == 's' && *ptr == '\\')
+                       *ptr = '/';
+                   else if (p_csl[0] == 'b' && *ptr == '/')
+                       *ptr = '\\';
+                   ptr += (*mb_ptr2len)(ptr);
+               }
+           }
+       }
+#endif
        return ret;
     }
 
index fe475a5da6838d166bf17f1232eaae989d336e26..42458005edea9a6286841c451e48f9eabbc74992 100644 (file)
@@ -2669,6 +2669,26 @@ ins_compl_get_exp(pos_T *ini)
 
                // May change home directory back to "~".
                tilde_replace(compl_pattern, num_matches, matches);
+#ifdef BACKSLASH_IN_FILENAME
+               if (curbuf->b_p_csl[0] != NUL)
+               {
+                   int     i;
+
+                   for (i = 0; i < num_matches; ++i)
+                   {
+                       char_u  *ptr = matches[i];
+
+                       while (*ptr != NUL)
+                       {
+                           if (curbuf->b_p_csl[0] == 's' && *ptr == '\\')
+                               *ptr = '/';
+                           else if (curbuf->b_p_csl[0] == 'b' && *ptr == '/')
+                               *ptr = '\\';
+                           ptr += (*mb_ptr2len)(ptr);
+                       }
+                   }
+               }
+#endif
                ins_compl_add_matches(num_matches, matches, p_fic || p_wic);
            }
            break;
index 3959d47114ff4735d4c2ad71c826db3314357e46..fdad20551816d4bede020f0870fd2cd944cd78e8 100644 (file)
@@ -88,6 +88,7 @@
 # define PV_DICT       OPT_BOTH(OPT_BUF(BV_DICT))
 # define PV_TSR                OPT_BOTH(OPT_BUF(BV_TSR))
 #endif
+#define PV_CSL         OPT_BUF(BV_CSL)
 #ifdef FEAT_COMPL_FUNC
 # define PV_CFU                OPT_BUF(BV_CFU)
 #endif
@@ -890,6 +891,15 @@ static struct vimoption options[] =
 #else
                            (char_u *)NULL, PV_NONE,
                            {(char_u *)0L, (char_u *)0L}
+#endif
+                           SCTX_INIT},
+    {"completeslash",   "csl",  P_STRING|P_VI_DEF|P_VIM,
+#if defined(FEAT_INS_EXPAND) && defined(BACKSLASH_IN_FILENAME)
+                           (char_u *)&p_csl, PV_CSL,
+                           {(char_u *)"", (char_u *)0L}
+#else
+                           (char_u *)NULL, PV_NONE,
+                           {(char_u *)0L, (char_u *)0L}
 #endif
                            SCTX_INIT},
     {"confirm",     "cf",   P_BOOL|P_VI_DEF,
@@ -3238,6 +3248,9 @@ static char *(p_fcl_values[]) = {"all", NULL};
 #endif
 #ifdef FEAT_INS_EXPAND
 static char *(p_cot_values[]) = {"menu", "menuone", "longest", "preview", "noinsert", "noselect", NULL};
+# ifdef BACKSLASH_IN_FILENAME
+static char *(p_csl_values[]) = {"slash", "backslash", NULL};
+# endif
 #endif
 #ifdef FEAT_SIGNS
 static char *(p_scl_values[]) = {"yes", "no", "auto", "number", NULL};
@@ -7409,7 +7422,7 @@ did_set_string_option(
        }
     }
 
-    /* 'completeopt' */
+    // 'completeopt'
     else if (varp == &p_cot)
     {
        if (check_opt_strings(p_cot, p_cot_values, TRUE) != OK)
@@ -7417,7 +7430,16 @@ did_set_string_option(
        else
            completeopt_was_set();
     }
-#endif /* FEAT_INS_EXPAND */
+
+# ifdef BACKSLASH_IN_FILENAME
+    // 'completeslash'
+    else if (varp == &curbuf->b_p_csl)
+    {
+       if (check_opt_strings(p_csl, p_csl_values, FALSE) != OK)
+           errmsg = e_invarg;
+    }
+# endif
+#endif // FEAT_INS_EXPAND
 
 #ifdef FEAT_SIGNS
     // 'signcolumn'
@@ -11110,7 +11132,6 @@ get_varp(struct vimoption *p)
 #endif
        case PV_MENC:   return *curbuf->b_p_menc != NUL
                                    ? (char_u *)&(curbuf->b_p_menc) : p->var;
-
 #ifdef FEAT_ARABIC
        case PV_ARAB:   return (char_u *)&(curwin->w_p_arab);
 #endif
@@ -11197,6 +11218,9 @@ get_varp(struct vimoption *p)
 #endif
 #ifdef FEAT_INS_EXPAND
        case PV_CPT:    return (char_u *)&(curbuf->b_p_cpt);
+# ifdef BACKSLASH_IN_FILENAME
+       case PV_CSL:    return (char_u *)&(curbuf->b_p_csl);
+# endif
 #endif
 #ifdef FEAT_COMPL_FUNC
        case PV_CFU:    return (char_u *)&(curbuf->b_p_cfu);
@@ -11591,6 +11615,9 @@ buf_copy_options(buf_T *buf, int flags)
            buf->b_p_swf = cmdmod.noswapfile ? FALSE : p_swf;
 #ifdef FEAT_INS_EXPAND
            buf->b_p_cpt = vim_strsave(p_cpt);
+# ifdef BACKSLASH_IN_FILENAME
+           buf->b_p_csl = vim_strsave(p_csl);
+# endif
 #endif
 #ifdef FEAT_COMPL_FUNC
            buf->b_p_cfu = vim_strsave(p_cfu);
index 06546678c9a2821d452b64f6d35e8ad8cdba5284..29ecd8ac3e327b066d74c7a6f4a38c7df9c540e7 100644 (file)
@@ -412,6 +412,9 @@ EXTERN int  p_confirm;      // 'confirm'
 EXTERN int     p_cp;           // 'compatible'
 #ifdef FEAT_INS_EXPAND
 EXTERN char_u  *p_cot;         // 'completeopt'
+# ifdef BACKSLASH_IN_FILENAME
+EXTERN char_u  *p_csl;         // 'completeslash'
+# endif
 EXTERN long    p_ph;           // 'pumheight'
 EXTERN long    p_pw;           // 'pumwidth'
 #endif
@@ -997,6 +1000,9 @@ enum
     , BV_DICT
     , BV_TSR
 #endif
+#ifdef BACKSLASH_IN_FILENAME
+    , BV_CSL
+#endif
 #ifdef FEAT_COMPL_FUNC
     , BV_CFU
 #endif
index 584117633010c816306256b9b8dbe6ac86068e85..122e47503820fb88d0caec92bba12672bb5dd66b 100644 (file)
@@ -1198,6 +1198,7 @@ typedef struct hashitem_S
 
 // Initial size for a hashtable.  Our items are relatively small and growing
 // is expensive, thus use 16 as a start.  Must be a power of 2.
+// This allows for storing 10 items (2/3 of 16) before a resize is needed.
 #define HT_INIT_SIZE 16
 
 typedef struct hashtable_S
@@ -2395,6 +2396,9 @@ struct file_buffer
 #ifdef FEAT_INS_EXPAND
     char_u     *b_p_cpt;       // 'complete'
 #endif
+#ifdef BACKSLASH_IN_FILENAME
+    char_u     *b_p_csl;       // 'completeslash'
+#endif
 #ifdef FEAT_COMPL_FUNC
     char_u     *b_p_cfu;       // 'completefunc'
     char_u     *b_p_ofu;       // 'omnifunc'
index c028df3e3e7a3c6ac6ed4fc58fa39a3819589994..29f4050f947bc8610c499aff576a6d0303292035 100644 (file)
@@ -331,3 +331,50 @@ func Test_compl_in_cmdwin()
   delcom GetInput
   set wildmenu& wildchar&
 endfunc
+
+" Test for insert path completion with completeslash option
+func Test_ins_completeslash()
+  if !has('win32')
+    return
+  endif
+  
+  call mkdir('Xdir')
+
+  let orig_shellslash = &shellslash
+  set cpt&
+
+  new
+  
+  set noshellslash
+
+  set completeslash=
+  exe "normal oXd\<C-X>\<C-F>"
+  call assert_equal('Xdir\', getline('.'))
+
+  set completeslash=backslash
+  exe "normal oXd\<C-X>\<C-F>"
+  call assert_equal('Xdir\', getline('.'))
+
+  set completeslash=slash
+  exe "normal oXd\<C-X>\<C-F>"
+  call assert_equal('Xdir/', getline('.'))
+
+  set shellslash
+
+  set completeslash=
+  exe "normal oXd\<C-X>\<C-F>"
+  call assert_equal('Xdir/', getline('.'))
+
+  set completeslash=backslash
+  exe "normal oXd\<C-X>\<C-F>"
+  call assert_equal('Xdir\', getline('.'))
+
+  set completeslash=slash
+  exe "normal oXd\<C-X>\<C-F>"
+  call assert_equal('Xdir/', getline('.'))
+  %bw!
+  call delete('Xdir', 'rf')
+
+  let &shellslash = orig_shellslash
+endfunc
+
index 166b17c96e8361b574ab415205c620cfde22db56..2db2ee1303f6efd35212a5df65097059f2917858 100644 (file)
@@ -777,6 +777,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1769,
 /**/
     1768,
 /**/