]> Sergey Matveev's repositories - vim-lsp.git/commitdiff
Completion doesn't properly work with multibyte characters
authorYegappan Lakshmanan <yegappan@yahoo.com>
Thu, 30 Mar 2023 03:21:34 +0000 (20:21 -0700)
committerYegappan Lakshmanan <yegappan@yahoo.com>
Thu, 30 Mar 2023 03:21:34 +0000 (20:21 -0700)
autoload/lsp/completion.vim
test/clangd_tests.vim
test/runner.vim

index cb84cf0fb41336d4cc9a730055e34fd96b6e69d6..02f2ed5f5aae2f1edf55e073aa839d8bb4e8104c 100644 (file)
@@ -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
index 223f0bbc55b4d61a947a75a5477412a345c1ab09..14bbc14ad3fef499522adeb2469d4cd71859090f 100644 (file)
@@ -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<string> =<< trim END
+    #include <string.h>
+    void Fn(void)
+    {
+      int thisVar = 1;
+      int len = strlen("©©©©©") + thisVar;
+    }
+  END
+  setline(1, lines)
+  g:WaitForServerFileLoad(0)
+  redraw!
+
+  cursor(5, 36)
+  feedkeys("cwthis\<C-X>\<C-O>", '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<string> =<< 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\<C-X>\<C-O>\<C-N>\<C-Y>", 'xt')
+  assert_equal('    myTest.baz = 10;', getline('.'))
+  cursor(11, 12)
+  feedkeys("cw\<C-X>\<C-O>\<C-N>\<C-N>\<C-Y>", '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
index 36a1aa36365fc326ca4372c005dfa3af791815a3..484a865f1c6db9cf6d170f7e087b223cbe611a10 100644 (file)
@@ -16,6 +16,7 @@ def LspRunTests()
   var fns: list<string> = execute('function /^Test_')
                    ->split("\n")
                    ->map("v:val->substitute('^def ', '', '')")
+                   ->sort()
   for f in fns
     v:errors = []
     v:errmsg = ''