Skip to content
Permalink
Browse files

patch 8.1.1769: 'shellslash' is also used for completion

Problem:    'shellslash' is also used for completion.
Solution:   Add the 'completeslash' option. (Yasuhiro Matsumoto, closes #3612)
  • Loading branch information...
brammool committed Jul 28, 2019
1 parent bca9c30 commit ac3150d385e6e3f3fe76642aac3cda954d30583f
Showing with 146 additions and 4 deletions.
  1. +17 −1 runtime/doc/options.txt
  2. +20 −0 src/ex_getln.c
  3. +20 −0 src/insexpand.c
  4. +30 −3 src/option.c
  5. +6 −0 src/option.h
  6. +4 −0 src/structs.h
  7. +47 −0 src/testdir/test_ins_complete.vim
  8. +2 −0 src/version.c
@@ -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
@@ -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;
}

@@ -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;
@@ -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,15 +7422,24 @@ did_set_string_option(
}
}

/* 'completeopt' */
// 'completeopt'
else if (varp == &p_cot)
{
if (check_opt_strings(p_cot, p_cot_values, TRUE) != OK)
errmsg = e_invarg;
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);
@@ -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
@@ -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'
@@ -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

This comment has been minimized.

Copy link
@k-takata

k-takata Jul 29, 2019

Member

I think this line should be: throw 'Skipped: not on MS-Windows'.

This comment has been minimized.

Copy link
@brammool

brammool via email Jul 29, 2019

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

@@ -777,6 +777,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1769,
/**/
1768,
/**/

0 comments on commit ac3150d

Please sign in to comment.
You can’t perform that action at this time.