diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 9643dd86ad..7dad0c4ae3 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1,4 +1,4 @@ -*options.txt* For Vim version 9.1. Last change: 2025 Sep 15 +*options.txt* For Vim version 9.1. Last change: 2025 Sep 20 VIM REFERENCE MANUAL by Bram Moolenaar @@ -913,7 +913,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'autocomplete'* *'ac'* *'noautocomplete'* *'noac'* 'autocomplete' 'ac' boolean (default off) - global + global or local to buffer |global-local| {only available on platforms with timing support} When on, Vim shows a completion menu as you type, similar to using |i_CTRL-N|, but triggered automatically. See |ins-autocompletion|. diff --git a/runtime/optwin.vim b/runtime/optwin.vim index cf743aa7a7..5b5727aa67 100644 --- a/runtime/optwin.vim +++ b/runtime/optwin.vim @@ -1,7 +1,7 @@ " These commands create the option window. " " Maintainer: The Vim Project -" Last Change: 2025 Sep 02 +" Last Change: 2025 Sep 20 " Former Maintainer: Bram Moolenaar " If there already is an option window, jump to that one. @@ -876,6 +876,7 @@ if has("insert_expand") call append("$", "\t" .. s:local_to_buffer) call OptionL("cpt") call AddOption("autocomplete", gettext("automatic completion in insert mode")) + call append("$", "\t" .. s:global_or_local) call BinOptionG("ac", &ac) call AddOption("autocompletetimeout", gettext("initial decay timeout for 'autocomplete' algorithm")) call append("$", " \tset act=" . &act) diff --git a/src/buffer.c b/src/buffer.c index 0feafc590d..29908c4aa8 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -2534,6 +2534,7 @@ free_buf_options( #endif clear_string_option(&buf->b_p_tsr); clear_string_option(&buf->b_p_qe); + buf->b_p_ac = -1; buf->b_p_ar = -1; buf->b_p_ul = NO_LOCAL_UNDOLEVEL; clear_string_option(&buf->b_p_lw); diff --git a/src/edit.c b/src/edit.c index 41e1c00703..400d047b8c 100644 --- a/src/edit.c +++ b/src/edit.c @@ -694,7 +694,7 @@ edit( { ins_compl_delete(); if (ins_compl_has_preinsert() - && ins_compl_has_autocomplete()) + && ins_compl_autocomplete_enabled()) (void)ins_compl_insert(FALSE, TRUE); else (void)ins_compl_insert(FALSE, FALSE); @@ -987,7 +987,7 @@ doESCkey: case Ctrl_H: did_backspace = ins_bs(c, BACKSPACE_CHAR, &inserted_space); auto_format(FALSE, TRUE); - if (did_backspace && p_ac && !char_avail() + if (did_backspace && ins_compl_has_autocomplete() && !char_avail() && curwin->w_cursor.col > 0) { c = char_before_cursor(); @@ -1418,7 +1418,8 @@ normalchar: foldOpenCursor(); #endif // Trigger autocompletion - if (p_ac && !char_avail() && vim_isprintc(c)) + if (ins_compl_has_autocomplete() && !char_avail() + && vim_isprintc(c)) { update_screen(UPD_VALID); // Show character immediately out_flush(); diff --git a/src/insexpand.c b/src/insexpand.c index 0beea079d4..bb814af708 100644 --- a/src/insexpand.c +++ b/src/insexpand.c @@ -2375,7 +2375,7 @@ ins_compl_preinsert_effect(void) * Returns TRUE if autocompletion is active. */ int -ins_compl_has_autocomplete(void) +ins_compl_autocomplete_enabled(void) { return compl_autocomplete; } @@ -2449,6 +2449,16 @@ ins_compl_need_restart(void) && compl_opt_refresh_always); } +/* + * Return TRUE if 'autocomplete' option is set + */ + int +ins_compl_has_autocomplete(void) +{ + // Use buffer-local setting if defined (>= 0), otherwise use global + return curbuf->b_p_ac >= 0 ? curbuf->b_p_ac : p_ac; +} + /* * Called after changing "compl_leader". * Show the popup menu with a different set of matches. @@ -2498,8 +2508,7 @@ ins_compl_new_leader(void) save_w_wrow = curwin->w_wrow; save_w_leftcol = curwin->w_leftcol; compl_restarting = TRUE; - if (p_ac) - compl_autocomplete = TRUE; + compl_autocomplete = ins_compl_has_autocomplete(); if (ins_complete(Ctrl_N, FALSE) == FAIL) compl_cont_status = 0; compl_restarting = FALSE; diff --git a/src/option.c b/src/option.c index f258836ec4..4f74de5142 100644 --- a/src/option.c +++ b/src/option.c @@ -695,6 +695,7 @@ set_init_1(int clean_arg) #endif curbuf->b_p_initialized = TRUE; + curbuf->b_p_ac = -1; curbuf->b_p_ar = -1; // no local 'autoread' value curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL; check_buf_options(curbuf); @@ -2207,6 +2208,8 @@ do_set_option_bool( // For 'autoread' -1 means to use global value. if ((int *)varp == &curbuf->b_p_ar && opt_flags == OPT_LOCAL) value = -1; + else if ((int *)varp == &curbuf->b_p_ac && opt_flags == OPT_LOCAL) + value = -1; else value = *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL); } @@ -6441,6 +6444,9 @@ unset_global_local_option(char_u *name, void *from) case PV_PATH: clear_string_option(&buf->b_p_path); break; + case PV_AC: + buf->b_p_ac = -1; + break; case PV_AR: buf->b_p_ar = -1; break; @@ -6593,6 +6599,7 @@ get_varp_scope(struct vimoption *p, int scope) case PV_EP: return (char_u *)&(curbuf->b_p_ep); case PV_KP: return (char_u *)&(curbuf->b_p_kp); case PV_PATH: return (char_u *)&(curbuf->b_p_path); + case PV_AC: return (char_u *)&(curbuf->b_p_ac); case PV_AR: return (char_u *)&(curbuf->b_p_ar); case PV_TAGS: return (char_u *)&(curbuf->b_p_tags); case PV_TC: return (char_u *)&(curbuf->b_p_tc); @@ -6669,6 +6676,8 @@ get_varp(struct vimoption *p) ? (char_u *)&curbuf->b_p_kp : p->var; case PV_PATH: return *curbuf->b_p_path != NUL ? (char_u *)&(curbuf->b_p_path) : p->var; + case PV_AC: return curbuf->b_p_ac >= 0 + ? (char_u *)&(curbuf->b_p_ac) : p->var; case PV_AR: return curbuf->b_p_ar >= 0 ? (char_u *)&(curbuf->b_p_ar) : p->var; case PV_TAGS: return *curbuf->b_p_tags != NUL @@ -7501,6 +7510,7 @@ buf_copy_options(buf_T *buf, int flags) // options that are normally global but also have a local value // are not copied, start using the global value + buf->b_p_ac = -1; buf->b_p_ar = -1; buf->b_p_ul = NO_LOCAL_UNDOLEVEL; buf->b_p_bkc = empty_option; diff --git a/src/option.h b/src/option.h index ce75d6862e..9e6aed3556 100644 --- a/src/option.h +++ b/src/option.h @@ -1168,6 +1168,7 @@ EXTERN int p_xtermcodes; // 'xtermcodes' enum { BV_AI = 0 + , BV_AC , BV_AR , BV_BH , BV_BKC diff --git a/src/optiondefs.h b/src/optiondefs.h index 1db29305e7..572b7aff13 100644 --- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -26,6 +26,7 @@ // Definition of the PV_ values for buffer-local options. // The BV_ values are defined in option.h. +#define PV_AC OPT_BOTH(OPT_BUF(BV_AC)) #define PV_AI OPT_BUF(BV_AI) #define PV_AR OPT_BOTH(OPT_BUF(BV_AR)) #define PV_BKC OPT_BOTH(OPT_BUF(BV_BKC)) @@ -390,7 +391,7 @@ static struct vimoption options[] = SCTX_INIT}, #ifdef ELAPSED_FUNC {"autocomplete", "ac", P_BOOL|P_VI_DEF, - (char_u *)&p_ac, PV_NONE, NULL, + (char_u *)&p_ac, PV_AC, NULL, NULL, {(char_u *)FALSE, (char_u *)0L} SCTX_INIT}, {"autocompletedelay", "acl", P_NUM|P_VI_DEF, (char_u *)&p_acl, PV_NONE, NULL, NULL, diff --git a/src/proto/insexpand.pro b/src/proto/insexpand.pro index b1656dacc3..3dfa9c0194 100644 --- a/src/proto/insexpand.pro +++ b/src/proto/insexpand.pro @@ -49,7 +49,7 @@ colnr_T ins_compl_col(void); int ins_compl_len(void); int ins_compl_has_preinsert(void); int ins_compl_preinsert_effect(void); -int ins_compl_has_autocomplete(void); +int ins_compl_autocomplete_enabled(void); int ins_compl_bs(void); void ins_compl_addleader(int c); void ins_compl_addfrommatch(void); @@ -76,4 +76,5 @@ void ins_compl_check_keys(int frequency, int in_compl_func); int ins_complete(int c, int enable_pum); void ins_compl_enable_autocomplete(void); void free_insexpand_stuff(void); +int ins_compl_has_autocomplete(void); /* vim: set ft=c : */ diff --git a/src/structs.h b/src/structs.h index 0968b3c9a9..3efcabda75 100644 --- a/src/structs.h +++ b/src/structs.h @@ -3285,6 +3285,7 @@ struct file_buffer sctx_T b_p_script_ctx[BV_COUNT]; // SCTXs for buffer-local options #endif + int b_p_ac; // 'autocomplete' int b_p_ai; // 'autoindent' int b_p_ai_nopaste; // b_p_ai saved for paste mode char_u *b_p_bkc; // 'backupcopy' diff --git a/src/testdir/test_ins_complete.vim b/src/testdir/test_ins_complete.vim index b48f0deec6..6f6232f963 100644 --- a/src/testdir/test_ins_complete.vim +++ b/src/testdir/test_ins_complete.vim @@ -5454,7 +5454,7 @@ func Test_scriptlocal_autoload_func() call test_override("char_avail", 1) new inoremap let b:matches = complete_info(["matches"]).matches - set autocomplete + setlocal autocomplete setlocal complete=.,Fcompl#Func call feedkeys("im\\0", 'xt!') @@ -5465,7 +5465,6 @@ func Test_scriptlocal_autoload_func() call assert_equal(['foo', 'foobar'], b:matches->mapnew('v:val.word')) setlocal complete& - set autocomplete& bwipe! call test_override("char_avail", 0) let &rtp = save_rtp @@ -5563,7 +5562,7 @@ func Test_autocompletedelay() let lines =<< trim [SCRIPT] call setline(1, ['foo', 'foobar', 'foobarbaz']) - set autocomplete + setlocal autocomplete [SCRIPT] call writefile(lines, 'XTest_autocomplete_delay', 'D') let buf = RunVimInTerminal('-S XTest_autocomplete_delay', {'rows': 10}) diff --git a/src/version.c b/src/version.c index 53fef7dd9e..2246dcf1f2 100644 --- a/src/version.c +++ b/src/version.c @@ -724,6 +724,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1779, /**/ 1778, /**/