-*options.txt* For Vim version 9.1. Last change: 2024 Jun 04
+*options.txt* For Vim version 9.1. Last change: 2024 Jun 05
VIM REFERENCE MANUAL by Bram Moolenaar
*'completeopt'* *'cot'*
'completeopt' 'cot' string (default: "menu,preview")
- global
+ global or local to buffer |global-local|
A comma-separated list of options for Insert mode completion
|ins-completion|. The supported values are:
-*version9.txt* For Vim version 9.1. Last change: 2024 Jun 03
+*version9.txt* For Vim version 9.1. Last change: 2024 Jun 05
VIM REFERENCE MANUAL by Bram Moolenaar
- use 'smoothscroll' logic for CTRL-D and CTRL-U for half-pagewise scrolling
- the default for 'commentstring' contains whitespace padding to have
automatic comments look nicer |comment-install|
+- 'completeopt' is now a |global-local| option.
*added-9.2*
Added ~
" These commands create the option window.
"
" Maintainer: The Vim Project <https://github.com/vim/vim>
-" Last Change: 2023 Aug 31
+" Last Change: 2024 Jun 05
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
" If there already is an option window, jump to that one.
call append("$", "\t" .. s:local_to_buffer)
call <SID>OptionL("cpt")
call <SID>AddOption("completeopt", gettext("whether to use a popup menu for Insert mode completion"))
- call <SID>OptionG("cot", &cot)
+ call <SID>OptionL("cot")
if exists("+completepopup")
call <SID>AddOption("completepopup", gettext("options for the Insert mode completion info popup"))
call <SID>OptionG("cpp", &cpp)
clear_string_option(&buf->b_p_lop);
clear_string_option(&buf->b_p_cinsd);
clear_string_option(&buf->b_p_cinw);
+ clear_string_option(&buf->b_p_cot);
clear_string_option(&buf->b_p_cpt);
#ifdef FEAT_COMPL_FUNC
clear_string_option(&buf->b_p_cfu);
static int compl_get_longest = FALSE; // put longest common string
// in compl_leader
-static int compl_no_insert = FALSE; // FALSE: select & insert
- // TRUE: noinsert
-static int compl_no_select = FALSE; // FALSE: select & insert
- // TRUE: noselect
-static int compl_longest = FALSE; // FALSE: insert full match
- // TRUE: insert longest prefix
-static int compl_fuzzy_match = FALSE; // True: fuzzy match enabled
-
// Selected one of the matches. When FALSE the match was edited or using the
// longest common string.
static int compl_used_match;
}
/*
- * Set variables that store noselect and noinsert behavior from the
- * 'completeopt' value.
+ * Get the local or global value of 'completeopt' flags.
*/
- void
-completeopt_was_set(void)
+ unsigned int
+get_cot_flags(void)
{
- compl_no_insert = FALSE;
- compl_no_select = FALSE;
- compl_longest = FALSE;
- compl_fuzzy_match = FALSE;
- if (strstr((char *)p_cot, "noselect") != NULL)
- compl_no_select = TRUE;
- if (strstr((char *)p_cot, "noinsert") != NULL)
- compl_no_insert = TRUE;
- if (strstr((char *)p_cot, "longest") != NULL)
- compl_longest = TRUE;
- if (strstr((char *)p_cot, "fuzzy") != NULL)
- compl_fuzzy_match = TRUE;
+ return curbuf->b_cot_flags != 0 ? curbuf->b_cot_flags : cot_flags;
}
pum_wanted(void)
{
// 'completeopt' must contain "menu" or "menuone"
- if (vim_strchr(p_cot, 'm') == NULL)
+ if ((get_cot_flags() & COT_ANY_MENU) == 0)
return FALSE;
// The display looks bad on a B&W display.
compl = compl->cp_next;
} while (!is_first_match(compl));
- if (strstr((char *)p_cot, "menuone") != NULL)
+ if (get_cot_flags() & COT_MENUONE)
return (i >= 1);
return (i >= 2);
}
int cur = -1;
int lead_len = 0;
int max_fuzzy_score = 0;
+ int cur_cot_flags = get_cot_flags();
+ int compl_no_select = (cur_cot_flags & COT_NOSELECT) != 0;
+ int compl_fuzzy_match = (cur_cot_flags & COT_FUZZY) != 0;
// Need to build the popup menu list.
compl_match_arraysize = 0;
if (ctrl_x_mode_not_defined_yet()
|| (ctrl_x_mode_normal() && !compl_started))
{
- compl_get_longest = compl_longest;
+ compl_get_longest = (get_cot_flags() & COT_LONGEST) != 0;
compl_used_match = TRUE;
-
}
if (ctrl_x_mode_not_defined_yet())
int save_w_wrow = curwin->w_wrow;
int save_w_leftcol = curwin->w_leftcol;
int flags = CP_ORIGINAL_TEXT;
+ int cur_cot_flags = get_cot_flags();
+ int compl_longest = (cur_cot_flags & COT_LONGEST) != 0;
+ int compl_no_insert = (cur_cot_flags & COT_NOINSERT) != 0;
+ int compl_no_select = (cur_cot_flags & COT_NOSELECT) != 0;
// If already doing completions stop it.
if (ctrl_x_mode_not_default())
{
int found_end = FALSE;
compl_T *found_compl = NULL;
+ int cur_cot_flags = get_cot_flags();
+ int compl_no_select = (cur_cot_flags & COT_NOSELECT) != 0;
+ int compl_fuzzy_match = (cur_cot_flags & COT_FUZZY) != 0;
while (--todo >= 0)
{
int advance;
int started = compl_started;
buf_T *orig_curbuf = curbuf;
+ int cur_cot_flags = get_cot_flags();
+ int compl_no_insert = (cur_cot_flags & COT_NOINSERT) != 0;
+ int compl_fuzzy_match = (cur_cot_flags & COT_FUZZY) != 0;
// When user complete function return -1 for findstart which is next
// time of 'always', compl_shown_match become NULL.
}
}
}
- if (compl_pending != 0 && !got_int && !compl_no_insert)
+ if (compl_pending != 0 && !got_int && !(cot_flags & COT_NOINSERT))
{
int todo = compl_pending > 0 ? compl_pending : -compl_pending;
clear_string_option(&buf->b_p_inc);
break;
# endif
+ case PV_COT:
+ clear_string_option(&buf->b_p_cot);
+ buf->b_cot_flags = 0;
+ break;
case PV_DICT:
clear_string_option(&buf->b_p_dict);
break;
case PV_DEF: return (char_u *)&(curbuf->b_p_def);
case PV_INC: return (char_u *)&(curbuf->b_p_inc);
#endif
+ case PV_COT: return (char_u *)&(curbuf->b_p_cot);
case PV_DICT: return (char_u *)&(curbuf->b_p_dict);
case PV_TSR: return (char_u *)&(curbuf->b_p_tsr);
#ifdef FEAT_COMPL_FUNC
case PV_INC: return *curbuf->b_p_inc != NUL
? (char_u *)&(curbuf->b_p_inc) : p->var;
#endif
+ case PV_COT: return *curbuf->b_p_cot != NUL
+ ? (char_u *)&(curbuf->b_p_cot) : p->var;
case PV_DICT: return *curbuf->b_p_dict != NUL
? (char_u *)&(curbuf->b_p_dict) : p->var;
case PV_TSR: return *curbuf->b_p_tsr != NUL
COPY_OPT_SCTX(buf, BV_INEX);
# endif
#endif
+ buf->b_p_cot = empty_option;
+ buf->b_cot_flags = 0;
buf->b_p_dict = empty_option;
buf->b_p_tsr = empty_option;
#ifdef FEAT_COMPL_FUNC
#endif
EXTERN int p_cp; // 'compatible'
EXTERN char_u *p_cot; // 'completeopt'
+EXTERN unsigned cot_flags; // flags from 'completeopt'
+// Keep in sync with p_cot_values in optionstr.c
+#define COT_MENU 0x001
+#define COT_MENUONE 0x002
+#define COT_ANY_MENU 0x003 // combination of menu flags
+#define COT_LONGEST 0x004 // FALSE: insert full match,
+ // TRUE: insert longest prefix
+#define COT_PREVIEW 0x008
+#define COT_POPUP 0x010
+#define COT_POPUPHIDDEN 0x020
+#define COT_ANY_PREVIEW 0x038 // combination of preview flags
+#define COT_NOINSERT 0x040 // FALSE: select & insert, TRUE: noinsert
+#define COT_NOSELECT 0x080 // FALSE: select & insert, TRUE: noselect
+#define COT_FUZZY 0x100 // TRUE: fuzzy match enabled
#ifdef BACKSLASH_IN_FILENAME
EXTERN char_u *p_csl; // 'completeslash'
#endif
, BV_CMS
#endif
, BV_COM
+ , BV_COT
, BV_CPT
, BV_DICT
, BV_TSR
# define PV_CMS OPT_BUF(BV_CMS)
#endif
#define PV_COM OPT_BUF(BV_COM)
+#define PV_COT OPT_BOTH(OPT_BUF(BV_COT))
#define PV_CPT OPT_BUF(BV_CPT)
#define PV_DICT OPT_BOTH(OPT_BUF(BV_DICT))
#define PV_TSR OPT_BOTH(OPT_BUF(BV_TSR))
#endif
SCTX_INIT},
{"completeopt", "cot", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP,
- (char_u *)&p_cot, PV_NONE, did_set_completeopt, expand_set_completeopt,
+ (char_u *)&p_cot, PV_COT, did_set_completeopt, expand_set_completeopt,
{(char_u *)"menu,preview", (char_u *)0L}
SCTX_INIT},
{"completepopup", "cpp", P_STRING|P_VI_DEF|P_COMMA|P_NODUP|P_COLON,
(void)opt_strings_flags(p_cmp, p_cmp_values, &cmp_flags, TRUE);
(void)opt_strings_flags(p_bkc, p_bkc_values, &bkc_flags, TRUE);
(void)opt_strings_flags(p_bo, p_bo_values, &bo_flags, TRUE);
+ (void)opt_strings_flags(p_cot, p_cot_values, &cot_flags, TRUE);
#ifdef FEAT_SESSION
(void)opt_strings_flags(p_ssop, p_ssop_values, &ssop_flags, TRUE);
(void)opt_strings_flags(p_vop, p_ssop_values, &vop_flags, TRUE);
check_string_option(&buf->b_p_lop);
check_string_option(&buf->b_p_ft);
check_string_option(&buf->b_p_cinw);
+ check_string_option(&buf->b_p_cot);
check_string_option(&buf->b_p_cpt);
#ifdef FEAT_COMPL_FUNC
check_string_option(&buf->b_p_cfu);
char *
did_set_completeopt(optset_T *args UNUSED)
{
- if (check_opt_strings(p_cot, p_cot_values, TRUE) != OK)
+ char_u *cot = p_cot;
+ unsigned *flags = &cot_flags;
+
+ if (args->os_flags & OPT_LOCAL)
+ {
+ cot = curbuf->b_p_cot;
+ flags = &curbuf->b_cot_flags;
+ }
+
+ if (check_opt_strings(cot, p_cot_values, TRUE) != OK)
+ return e_invalid_argument;
+
+ if (opt_strings_flags(cot, p_cot_values, flags, TRUE) != OK)
return e_invalid_argument;
- completeopt_was_set();
return NULL;
}
int context = pum_height / 2;
#ifdef FEAT_QUICKFIX
int prev_selected = pum_selected;
+ unsigned cur_cot_flags = get_cot_flags();
#endif
#if defined(FEAT_PROP_POPUP) && defined(FEAT_QUICKFIX)
int has_info = FALSE;
if (pum_array[pum_selected].pum_info != NULL
&& Rows > 10
&& repeat <= 1
- && vim_strchr(p_cot, 'p') != NULL)
+ && (cur_cot_flags & COT_ANY_PREVIEW))
{
win_T *curwin_save = curwin;
tabpage_T *curtab_save = curtab;
# endif
# ifdef FEAT_PROP_POPUP
has_info = TRUE;
- if (strstr((char *)p_cot, "popuphidden") != NULL)
+ if (cur_cot_flags & COT_POPUPHIDDEN)
use_popup = USEPOPUP_HIDDEN;
- else if (strstr((char *)p_cot, "popup") != NULL)
+ else if (cur_cot_flags & COT_POPUP)
use_popup = USEPOPUP_NORMAL;
else
use_popup = USEPOPUP_NONE;
int ins_compl_add_infercase(char_u *str_arg, int len, int icase, char_u *fname, int dir, int cont_s_ipos);
int ins_compl_has_shown_match(void);
int ins_compl_long_shown_match(void);
-void completeopt_was_set(void);
+unsigned get_cot_flags(void);
int pum_wanted(void);
void ins_compl_show_pum(void);
char_u *find_word_start(char_u *ptr);
#ifdef FEAT_FOLDING
char_u *b_p_cms; // 'commentstring'
#endif
+ char_u *b_p_cot; // 'completeopt' local value
+ unsigned b_cot_flags; // flags for 'completeopt'
char_u *b_p_cpt; // 'complete'
#ifdef BACKSLASH_IN_FILENAME
char_u *b_p_csl; // 'completeslash'
bwipe!
endfunc
+" Test for buffer-local value of 'completeopt'
+func Test_completeopt_buffer_local()
+ set completeopt=menu
+ new
+ call setline(1, ['foofoo', 'foobar', 'foobaz', ''])
+ call assert_equal('', &l:completeopt)
+ call assert_equal('menu', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+
+ setlocal bufhidden=hide
+ enew
+ call setline(1, ['foofoo', 'foobar', 'foobaz', ''])
+ call assert_equal('', &l:completeopt)
+ call assert_equal('menu', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+
+ setlocal completeopt+=fuzzy,noinsert
+ call assert_equal('menu,fuzzy,noinsert', &l:completeopt)
+ call assert_equal('menu,fuzzy,noinsert', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+ call feedkeys("Gccf\<C-X>\<C-N>bz\<C-Y>", 'tnix')
+ call assert_equal('foobaz', getline('.'))
+
+ setlocal completeopt=
+ call assert_equal('', &l:completeopt)
+ call assert_equal('menu', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+ call feedkeys("Gccf\<C-X>\<C-N>\<C-Y>", 'tnix')
+ call assert_equal('foofoo', getline('.'))
+
+ setlocal completeopt+=longest
+ call assert_equal('menu,longest', &l:completeopt)
+ call assert_equal('menu,longest', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+ call feedkeys("Gccf\<C-X>\<C-N>\<C-X>\<C-Z>", 'tnix')
+ call assert_equal('foo', getline('.'))
+
+ setlocal bufhidden=hide
+ buffer #
+ call assert_equal('', &l:completeopt)
+ call assert_equal('menu', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+ call feedkeys("Gccf\<C-X>\<C-N>\<C-Y>", 'tnix')
+ call assert_equal('foofoo', getline('.'))
+
+ setlocal completeopt+=fuzzy,noinsert
+ call assert_equal('menu,fuzzy,noinsert', &l:completeopt)
+ call assert_equal('menu,fuzzy,noinsert', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+ call feedkeys("Gccf\<C-X>\<C-N>bz\<C-Y>", 'tnix')
+ call assert_equal('foobaz', getline('.'))
+
+ buffer #
+ call assert_equal('menu,longest', &l:completeopt)
+ call assert_equal('menu,longest', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+ call feedkeys("Gccf\<C-X>\<C-N>\<C-X>\<C-Z>", 'tnix')
+ call assert_equal('foo', getline('.'))
+
+ setlocal bufhidden=wipe
+ buffer! #
+ bwipe!
+ call assert_equal('', &l:completeopt)
+ call assert_equal('menu', &completeopt)
+ call assert_equal('menu', &g:completeopt)
+
+ set completeopt&
+endfunc
" Test for completing words following a completed word in a line
func Test_complete_wrapscan()
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 469,
/**/
468,
/**/