diff options
| -rw-r--r-- | runtime/doc/options.txt | 18 | ||||
| -rw-r--r-- | src/nvim/buffer_defs.h | 3 | ||||
| -rw-r--r-- | src/nvim/edit.c | 15 | ||||
| -rw-r--r-- | src/nvim/ex_getln.c | 15 | ||||
| -rw-r--r-- | src/nvim/hashtab.h | 1 | ||||
| -rw-r--r-- | src/nvim/option.c | 15 | ||||
| -rw-r--r-- | src/nvim/option_defs.h | 4 | ||||
| -rw-r--r-- | src/nvim/options.lua | 9 | ||||
| -rw-r--r-- | src/nvim/testdir/test_ins_complete.vim | 46 | 
9 files changed, 125 insertions, 1 deletions
| diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index beb5e9f4c2..448df31798 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1386,6 +1386,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 @@ -5289,7 +5304,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	(Vim default on, Vi default off)  			global diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 1223f2bdab..8e855cb644 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -661,6 +661,9 @@ struct file_buffer {    char_u *b_p_com;              ///< 'comments'    char_u *b_p_cms;              ///< 'commentstring'    char_u *b_p_cpt;              ///< 'complete' +#ifdef BACKSLASH_IN_FILENAME +  char_u *b_p_csl;              ///< 'completeslash' +#endif    char_u *b_p_cfu;              ///< 'completefunc'    char_u *b_p_ofu;              ///< 'omnifunc'    char_u *b_p_tfu;              ///< 'tagfunc' diff --git a/src/nvim/edit.c b/src/nvim/edit.c index b3261cfce6..ac0e6cc9f6 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -4171,6 +4171,21 @@ static int ins_compl_get_exp(pos_T *ini)                             EW_FILE|EW_DIR|EW_ADDSLASH|EW_SILENT) == OK) {          // May change home directory back to "~".          tilde_replace(compl_pattern, num_matches, matches); +#ifdef BACKSLASH_IN_FILENAME +        if (curbuf->b_p_csl[0] != NUL) { +          for (int 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 += utfc_ptr2len(ptr); +            } +          } +        } +#endif          ins_compl_add_matches(num_matches, matches, p_fic || p_wic);        }        break; diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 940f446a7b..c56adc8bd4 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -5052,6 +5052,21 @@ ExpandFromContext (      ret = expand_wildcards_eval(&pat, num_file, file, flags);      if (free_pat)        xfree(pat); +#ifdef BACKSLASH_IN_FILENAME +    if (p_csl[0] != NUL) { +      for (int 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 += utfc_ptr2len(ptr); +        } +      } +    } +#endif      return ret;    } diff --git a/src/nvim/hashtab.h b/src/nvim/hashtab.h index 19633d455f..c82a6cc121 100644 --- a/src/nvim/hashtab.h +++ b/src/nvim/hashtab.h @@ -51,6 +51,7 @@ typedef struct hashitem_S {  /// Initial size for a hashtable.  /// Our items are relatively small and growing is expensive, thus start with 16.  /// 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  /// An array-based hashtable. diff --git a/src/nvim/option.c b/src/nvim/option.c index 4569eb1dda..5faf67febf 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -312,6 +312,9 @@ static char *(p_fdm_values[]) =       { "manual", "expr", "marker", "indent",  static char *(p_fcl_values[]) =       { "all", NULL };  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  static char *(p_icm_values[]) =       { "nosplit", "split", NULL };  static char *(p_scl_values[]) =       { "yes", "no", "auto", "auto:1", "auto:2",    "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8", "auto:9", @@ -3188,6 +3191,12 @@ ambw_end:      } else {        completeopt_was_set();      } +#ifdef BACKSLASH_IN_FILENAME +  } else if (varp == &curbuf->b_p_csl) {  // 'completeslash' +    if (check_opt_strings(p_csl, p_csl_values, false) != OK) { +      errmsg = e_invarg; +    } +#endif    } else if (varp == &curwin->w_p_scl) {      // 'signcolumn'      if (check_opt_strings(*varp, p_scl_values, false) != OK) { @@ -5866,6 +5875,9 @@ static char_u *get_varp(vimoption_T *p)    case PV_COM:    return (char_u *)&(curbuf->b_p_com);    case PV_CMS:    return (char_u *)&(curbuf->b_p_cms);    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    case PV_CFU:    return (char_u *)&(curbuf->b_p_cfu);    case PV_OFU:    return (char_u *)&(curbuf->b_p_ofu);    case PV_EOL:    return (char_u *)&(curbuf->b_p_eol); @@ -6153,6 +6165,9 @@ void buf_copy_options(buf_T *buf, int flags)        buf->b_p_inf = p_inf;        buf->b_p_swf = cmdmod.noswapfile ? false : p_swf;        buf->b_p_cpt = vim_strsave(p_cpt); +# ifdef BACKSLASH_IN_FILENAME +      buf->b_p_csl = vim_strsave(p_csl); +# endif        buf->b_p_cfu = vim_strsave(p_cfu);        buf->b_p_ofu = vim_strsave(p_ofu);        buf->b_p_tfu = vim_strsave(p_tfu); diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 6630bda710..4042b79262 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -373,6 +373,9 @@ EXTERN long p_columns;          // 'columns'  EXTERN int p_confirm;           // 'confirm'  EXTERN int p_cp;                // 'compatible'  EXTERN char_u   *p_cot;         // 'completeopt' +# ifdef BACKSLASH_IN_FILENAME +EXTERN char_u   *p_csl;         // 'completeslash' +# endif  EXTERN long p_pb;               // 'pumblend'  EXTERN long p_ph;               // 'pumheight'  EXTERN long p_pw;               // 'pumwidth' @@ -744,6 +747,7 @@ enum {    , BV_CPT    , BV_DICT    , BV_TSR +  , BV_CSL    , BV_CFU    , BV_DEF    , BV_INC diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 02df0ab276..65ef7a4527 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -453,6 +453,15 @@ return {        defaults={if_true={vi="menu,preview"}}      },      { +      full_name='completeslash', abbreviation='csl', +      type='string', scope={'buffer'}, +      vi_def=true, +      vim=true, +      varname='p_csl', +      enable_if='BACKSLASH_IN_FILENAME', +      defaults={if_true={vi=""}} +    }, +    {        full_name='confirm', abbreviation='cf',        type='bool', scope={'global'},        vi_def=true, diff --git a/src/nvim/testdir/test_ins_complete.vim b/src/nvim/testdir/test_ins_complete.vim index b8632b9595..45b0d159d4 100644 --- a/src/nvim/testdir/test_ins_complete.vim +++ b/src/nvim/testdir/test_ins_complete.vim @@ -365,6 +365,52 @@ func Test_compl_in_cmdwin()    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 +  func Test_pum_with_folds_two_tabs()    CheckScreendump | 
