autoload/lsp/completion.vim | 9 +++++---- test/clangd_tests.vim | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ test/runner.vim | 1 + diff --git a/autoload/lsp/completion.vim b/autoload/lsp/completion.vim index cb84cf0fb41336d4cc9a730055e34fd96b6e69d6..02f2ed5f5aae2f1edf55e073aa839d8bb4e8104c 100644 --- a/autoload/lsp/completion.vim +++ b/autoload/lsp/completion.vim @@ -320,7 +320,7 @@ keyword = line[start - 1] .. keyword start -= 1 endwhile lspserver.omniCompleteKeyword = keyword - return start + return line->byteidx(start) else # Wait for the list of matches from the LSP server var count: number = 0 @@ -361,7 +361,7 @@ if lspserver->empty() || !lspserver.running || !lspserver.ready return endif - var cur_col: number = col('.') + var cur_col: number = charcol('.') var line: string = getline('.') if cur_col == 0 || line->empty() @@ -375,13 +375,14 @@ # If the character before the cursor is not a keyword character or is not # one of the LSP completion trigger characters, then do nothing. if line[cur_col - 2] !~ '\k' - var trigidx = lspserver.completionTriggerChars->index(line[cur_col - 2]) + var trigChars = lspserver.completionTriggerChars + var trigidx = trigChars->index(line[cur_col - 2]) if trigidx == -1 return endif # completion triggered by one of the trigger characters triggerKind = 2 - triggerChar = lspserver.completionTriggerChars[trigidx] + triggerChar = trigChars[trigidx] endif # first send all the changes in the current buffer to the LSP server diff --git a/test/clangd_tests.vim b/test/clangd_tests.vim index 223f0bbc55b4d61a947a75a5477412a345c1ab09..14bbc14ad3fef499522adeb2469d4cd71859090f 100644 --- a/test/clangd_tests.vim +++ b/test/clangd_tests.vim @@ -977,6 +977,59 @@ assert_equal('Foo_t#define FOO 1', getline('.')) :bw! enddef +# Test for doing omni completion from the first column +def g:Test_OmniComplete_Multibyte() + :silent! edit Xtest.c + sleep 200m + var lines: list =<< trim END + #include + void Fn(void) + { + int thisVar = 1; + int len = strlen("©©©©©") + thisVar; + } + END + setline(1, lines) + g:WaitForServerFileLoad(0) + redraw! + + cursor(5, 36) + feedkeys("cwthis\\", 'xt') + assert_equal(' int len = strlen("©©©©©") + thisVar;', getline('.')) + :bw! +enddef + +# Test for doing omni completion from the first column +def g:Test_OmniComplete_Struct() + :silent! edit Xtest.c + sleep 200m + var lines: list =<< trim END + struct test_ { + int foo; + int bar; + int baz; + }; + void Fn(void) + { + struct test_ myTest; + struct test_ *pTest; + myTest.bar = 10; + pTest->bar = 20; + } + END + setline(1, lines) + g:WaitForServerFileLoad(0) + redraw! + + cursor(10, 12) + feedkeys("cwb\\\\", 'xt') + assert_equal(' myTest.baz = 10;', getline('.')) + cursor(11, 12) + feedkeys("cw\\\\\", 'xt') + assert_equal(' pTest->foo = 20;', getline('.')) + :bw! +enddef + # TODO: # 1. Add a test for autocompletion with a single match while ignoring case. # After the full matched name is typed, the completion popup should still diff --git a/test/runner.vim b/test/runner.vim index 36a1aa36365fc326ca4372c005dfa3af791815a3..484a865f1c6db9cf6d170f7e087b223cbe611a10 100644 --- a/test/runner.vim +++ b/test/runner.vim @@ -16,6 +16,7 @@ # Get the list of test functions in this file and call them var fns: list = execute('function /^Test_') ->split("\n") ->map("v:val->substitute('^def ', '', '')") + ->sort() for f in fns v:errors = [] v:errmsg = ''