vim-patch:9.1.1341: cannot define completion triggers

Problem:  Cannot define completion triggers and act upon it
Solution: add the new option 'isexpand' and add the complete_match()
          function to return the completion matches according to the
          'isexpand' setting (glepnir)

Currently, completion trigger position is determined solely by the
'iskeyword' pattern (\k\+$), which causes issues when users need
different completion behaviors - such as triggering after '/' for
comments or '.' for methods. Modifying 'iskeyword' to include these
characters has undesirable side effects on other Vim functionality that
relies on keyword definitions.

Introduce a new buffer-local option 'isexpand' that allows specifying
different completion triggers and add the complete_match() function that
finds the appropriate start column for completion based on these
triggers, scanning backwards from cursor position.

This separation of concerns allows customized completion behavior
without affecting iskeyword-dependent features. The option's
buffer-local nature enables per-filetype completion triggers.

closes: vim/vim#16716

bcd5995b40

Co-authored-by: glepnir <glephunter@gmail.com>
This commit is contained in:
glepnir
2025-04-26 13:06:43 +08:00
parent ac8ae1596c
commit fcabbc2283
13 changed files with 434 additions and 0 deletions

View File

@@ -85,6 +85,7 @@ void didset_string_options(void)
check_str_opt(kOptBackupcopy, NULL);
check_str_opt(kOptBelloff, NULL);
check_str_opt(kOptCompletefuzzycollect, NULL);
check_str_opt(kOptIsexpand, NULL);
check_str_opt(kOptCompleteopt, NULL);
check_str_opt(kOptSessionoptions, NULL);
check_str_opt(kOptViewoptions, NULL);
@@ -1316,6 +1317,44 @@ const char *did_set_inccommand(optset_T *args FUNC_ATTR_UNUSED)
return did_set_str_generic(args);
}
/// The 'isexpand' option is changed.
const char *did_set_isexpand(optset_T *args)
{
char *ise = p_ise;
char *p;
bool last_was_comma = false;
if (args->os_flags & OPT_LOCAL) {
ise = curbuf->b_p_ise;
}
for (p = ise; *p != NUL;) {
if (*p == '\\' && p[1] == ',') {
p += 2;
last_was_comma = false;
continue;
}
if (*p == ',') {
if (last_was_comma) {
return e_invarg;
}
last_was_comma = true;
p++;
continue;
}
last_was_comma = false;
MB_PTR_ADV(p);
}
if (last_was_comma) {
return e_invarg;
}
return NULL;
}
/// The 'iskeyword' option is changed.
const char *did_set_iskeyword(optset_T *args)
{