summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/buffer.c211
-rw-r--r--src/testdir/test_cmdline.vim19
-rw-r--r--src/version.c2
3 files changed, 120 insertions, 112 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 4a39329c5c..b17ae16521 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2772,17 +2772,19 @@ ExpandBufnames(
char_u ***file,
int options)
{
- int count = 0;
+ int count;
buf_T *buf;
int round;
char_u *p;
- int attempt;
char_u *patc = NULL;
#ifdef FEAT_VIMINFO
bufmatch_T *matches = NULL;
#endif
int fuzzy;
fuzmatch_str_T *fuzmatch = NULL;
+ regmatch_T regmatch;
+ int score = 0;
+ int to_free = FALSE;
*num_file = 0; // return values in case of FAIL
*file = NULL;
@@ -2798,151 +2800,138 @@ ExpandBufnames(
// expression matching)
if (!fuzzy)
{
- if (*pat == '^')
+ if (*pat == '^' && pat[1] != NUL)
{
- patc = alloc(STRLEN(pat) + 11);
+ int len = (int)STRLEN(pat);
+ patc = alloc(len);
if (patc == NULL)
return FAIL;
- STRCPY(patc, "\\(^\\|[\\/]\\)");
- STRCPY(patc + 11, pat + 1);
+ STRNCPY(patc, pat + 1, len - 1);
+ patc[len - 1] = NUL;
+ to_free = TRUE;
}
+ else if (*pat == '^')
+ patc = (char_u *)"";
else
patc = pat;
+ regmatch.regprog = vim_regcomp(patc, RE_MAGIC);
}
- // attempt == 0: try match with '\<', match at start of word
- // attempt == 1: try match without '\<', match anywhere
- for (attempt = 0; attempt <= (fuzzy ? 0 : 1); ++attempt)
+ // round == 1: Count the matches.
+ // round == 2: Build the array to keep the matches.
+ for (round = 1; round <= 2; ++round)
{
- regmatch_T regmatch;
- int score = 0;
-
- if (!fuzzy)
- {
- if (attempt > 0 && patc == pat)
- break; // there was no anchor, no need to try again
- regmatch.regprog = vim_regcomp(patc + attempt * 11, RE_MAGIC);
- }
-
- // round == 1: Count the matches.
- // round == 2: Build the array to keep the matches.
- for (round = 1; round <= 2; ++round)
+ count = 0;
+ FOR_ALL_BUFFERS(buf)
{
- count = 0;
- FOR_ALL_BUFFERS(buf)
- {
- if (!buf->b_p_bl) // skip unlisted buffers
- continue;
+ if (!buf->b_p_bl) // skip unlisted buffers
+ continue;
#ifdef FEAT_DIFF
- if (options & BUF_DIFF_FILTER)
- // Skip buffers not suitable for
- // :diffget or :diffput completion.
- if (buf == curbuf || !diff_mode_buf(buf))
- continue;
+ if (options & BUF_DIFF_FILTER)
+ // Skip buffers not suitable for
+ // :diffget or :diffput completion.
+ if (buf == curbuf || !diff_mode_buf(buf))
+ continue;
#endif
- if (!fuzzy)
+ if (!fuzzy)
+ {
+ if (regmatch.regprog == NULL)
{
- if (regmatch.regprog == NULL)
- {
- // invalid pattern, possibly after recompiling
- if (patc != pat)
- vim_free(patc);
- return FAIL;
- }
- p = buflist_match(&regmatch, buf, p_wic);
+ // invalid pattern, possibly after recompiling
+ if (to_free)
+ vim_free(patc);
+ return FAIL;
}
- else
+ p = buflist_match(&regmatch, buf, p_wic);
+ }
+ else
+ {
+ p = NULL;
+ // first try matching with the short file name
+ if ((score = fuzzy_match_str(buf->b_sfname, pat)) != 0)
+ p = buf->b_sfname;
+ if (p == NULL)
{
- p = NULL;
- // first try matching with the short file name
- if ((score = fuzzy_match_str(buf->b_sfname, pat)) != 0)
- p = buf->b_sfname;
- if (p == NULL)
- {
- // next try matching with the full path file name
- if ((score = fuzzy_match_str(buf->b_ffname, pat)) != 0)
- p = buf->b_ffname;
- }
+ // next try matching with the full path file name
+ if ((score = fuzzy_match_str(buf->b_ffname, pat)) != 0)
+ p = buf->b_ffname;
}
+ }
- if (p == NULL)
- continue;
+ if (p == NULL)
+ continue;
- if (round == 1)
- {
- ++count;
- continue;
- }
+ if (round == 1)
+ {
+ ++count;
+ continue;
+ }
- if (options & WILD_HOME_REPLACE)
- p = home_replace_save(buf, p);
- else
- p = vim_strsave(p);
+ if (options & WILD_HOME_REPLACE)
+ p = home_replace_save(buf, p);
+ else
+ p = vim_strsave(p);
- if (!fuzzy)
- {
+ if (!fuzzy)
+ {
#ifdef FEAT_VIMINFO
- if (matches != NULL)
- {
- matches[count].buf = buf;
- matches[count].match = p;
- count++;
- }
- else
-#endif
- (*file)[count++] = p;
- }
- else
+ if (matches != NULL)
{
- fuzmatch[count].idx = count;
- fuzmatch[count].str = p;
- fuzmatch[count].score = score;
+ matches[count].buf = buf;
+ matches[count].match = p;
count++;
}
+ else
+#endif
+ (*file)[count++] = p;
}
- if (count == 0) // no match found, break here
- break;
- if (round == 1)
+ else
{
- if (!fuzzy)
+ fuzmatch[count].idx = count;
+ fuzmatch[count].str = p;
+ fuzmatch[count].score = score;
+ count++;
+ }
+ }
+ if (count == 0) // no match found, break here
+ break;
+ if (round == 1)
+ {
+ if (!fuzzy)
+ {
+ *file = ALLOC_MULT(char_u *, count);
+ if (*file == NULL)
{
- *file = ALLOC_MULT(char_u *, count);
- if (*file == NULL)
- {
- vim_regfree(regmatch.regprog);
- if (patc != pat)
- vim_free(patc);
- return FAIL;
- }
+ vim_regfree(regmatch.regprog);
+ if (to_free)
+ vim_free(patc);
+ return FAIL;
+ }
#ifdef FEAT_VIMINFO
- if (options & WILD_BUFLASTUSED)
- matches = ALLOC_MULT(bufmatch_T, count);
+ if (options & WILD_BUFLASTUSED)
+ matches = ALLOC_MULT(bufmatch_T, count);
#endif
- }
- else
+ }
+ else
+ {
+ fuzmatch = ALLOC_MULT(fuzmatch_str_T, count);
+ if (fuzmatch == NULL)
{
- fuzmatch = ALLOC_MULT(fuzmatch_str_T, count);
- if (fuzmatch == NULL)
- {
- *num_file = 0;
- *file = NULL;
- return FAIL;
- }
+ *num_file = 0;
+ *file = NULL;
+ return FAIL;
}
}
}
-
- if (!fuzzy)
- {
- vim_regfree(regmatch.regprog);
- if (count) // match(es) found, break here
- break;
- }
}
- if (!fuzzy && patc != pat)
- vim_free(patc);
+ if (!fuzzy)
+ {
+ vim_regfree(regmatch.regprog);
+ if (to_free)
+ vim_free(patc);
+ }
#ifdef FEAT_VIMINFO
if (!fuzzy)
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index ea95cbfce5..c0d01fb967 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -691,7 +691,7 @@ func Test_getcompletion()
bw Xtest\
endif
- call assert_fails("call getcompletion('\\\\@!\\\\@=', 'buffer')", 'E871:')
+ call assert_fails("call getcompletion('\\\\@!\\\\@=', 'buffer')", 'E866:')
call assert_fails('call getcompletion("", "burp")', 'E475:')
call assert_fails('call getcompletion("abc", [])', 'E1174:')
endfunc
@@ -3755,4 +3755,21 @@ func Test_window_size_stays_same_after_changing_cmdheight()
call assert_equal(expected, winheight(0))
endfunc
+" verify that buffer-completion finds all buffer names matching a pattern
+func Test_buffer_completion()
+ " should return empty list
+ call assert_equal([], getcompletion('', 'buffer'))
+
+ call mkdir('Xbuf_complete', 'R')
+ e Xbuf_complete/Foobar.c
+ e Xbuf_complete/MyFoobar.c
+ e AFoobar.h
+ let expected = ["Xbuf_complete/Foobar.c", "Xbuf_complete/MyFoobar.c", "AFoobar.h"]
+
+ call assert_equal(3, len(getcompletion('Foo', 'buffer')))
+ call assert_equal(expected, getcompletion('Foo', 'buffer'))
+ call feedkeys(":b Foo\<C-A>\<C-B>\"\<CR>", 'xt')
+ call assert_equal("\"b Xbuf_complete/Foobar.c Xbuf_complete/MyFoobar.c AFoobar.h", @:)
+endfunc
+
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index b6e25e665a..a80f2a87b5 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 131,
+/**/
130,
/**/
129,