From: Yegappan Lakshmanan Date: Thu, 30 Mar 2023 03:21:34 +0000 (-0700) Subject: Completion doesn't properly work with multibyte characters X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=498680aef108f44916186c18ab75f5b4f88c790c;p=vim-lsp.git Completion doesn't properly work with multibyte characters --- diff --git a/autoload/lsp/completion.vim b/autoload/lsp/completion.vim index cb84cf0..02f2ed5 100644 --- a/autoload/lsp/completion.vim +++ b/autoload/lsp/completion.vim @@ -320,7 +320,7 @@ def g:LspOmniFunc(findstart: number, base: string): any 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 @@ def LspComplete() 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 @@ def LspComplete() # 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 223f0bb..14bbc14 100644 --- a/test/clangd_tests.vim +++ b/test/clangd_tests.vim @@ -977,6 +977,59 @@ def g:Test_OmniComplete_FirstColumn() :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 36a1aa3..484a865 100644 --- a/test/runner.vim +++ b/test/runner.vim @@ -16,6 +16,7 @@ def LspRunTests() var fns: list = execute('function /^Test_') ->split("\n") ->map("v:val->substitute('^def ', '', '')") + ->sort() for f in fns v:errors = [] v:errmsg = ''