]> Sergey Matveev's repositories - vim-lsp.git/blob - test/clangd_offsetencoding.vim
Add support for UTF-8 and UTF-16 offset encoding
[vim-lsp.git] / test / clangd_offsetencoding.vim
1 vim9script
2 # Unit tests for language server protocol offset encoding using clangd
3
4 source common.vim
5
6 # Start the C language server.  Returns true on success and false on failure.
7 def g:StartLangServer(): bool
8   if has('patch-9.0.1629')
9     return g:StartLangServerWithFile('Xtest.c')
10   endif
11   return false
12 enddef
13
14 if !has('patch-9.0.1629')
15   # Need patch 9.0.1629 to properly encode/decode the UTF-16 offsets
16   finish
17 endif
18
19 var lspOpts = {autoComplete: false, highlightDiagInline: true}
20 g:LspOptionsSet(lspOpts)
21
22 var lspServers = [{
23       filetype: ['c', 'cpp'],
24       path: (exepath('clangd-15') ?? exepath('clangd')),
25       args: ['--background-index',
26              '--clang-tidy',
27              $'--offset-encoding={$LSP_OFFSET_ENCODING}']
28   }]
29 call LspAddServer(lspServers)
30
31 # Test for :LspCodeAction with symbols containing multibyte and composing
32 # characters
33 def g:Test_LspCodeAction_multibyte()
34   silent! edit XLspCodeAction_mb.c
35   sleep 200m
36   var lines =<< trim END
37     #include <stdio.h>
38     void fn(int aVar)
39     {
40         printf("aVar = %d\n", aVar);
41         printf("馃槉馃槉馃槉馃槉 = %d\n", aVar):
42         printf("a虂b虂a虂b虂 = %d\n", aVar):
43         printf("a台虂a台虂a台虂a台虂 = %d\n", aVar):
44     }
45   END
46   setline(1, lines)
47   g:WaitForServerFileLoad(3)
48   :redraw!
49   cursor(5, 5)
50   redraw!
51   :LspCodeAction 1
52   assert_equal('    printf("馃槉馃槉馃槉馃槉 = %d\n", aVar);', getline(5))
53   cursor(6, 5)
54   redraw!
55   :LspCodeAction 1
56   assert_equal('    printf("a虂b虂a虂b虂 = %d\n", aVar);', getline(6))
57   cursor(7, 5)
58   redraw!
59   :LspCodeAction 1
60   assert_equal('    printf("a台虂a台虂a台虂a台虂 = %d\n", aVar);', getline(7))
61
62   :%bw!
63 enddef
64
65 # Test for :LspDiagShow when using multibyte and composing characters
66 def g:Test_LspDiagShow_multibyte()
67   :silent! edit XLspDiagShow_mb.c
68   sleep 200m
69   var lines =<< trim END
70     #include <stdio.h>
71     void fn(int aVar)
72     {
73         printf("aVar = %d\n", aVar);
74         printf("馃槉馃槉馃槉馃槉 = %d\n". aVar);
75         printf("a虂b虂a虂b虂 = %d\n". aVar);
76         printf("a台虂a台虂a台虂a台虂 = %d\n". aVar);
77     }
78   END
79   setline(1, lines)
80   g:WaitForServerFileLoad(3)
81   :redraw!
82   :LspDiagShow
83   var qfl: list<dict<any>> = getloclist(0)
84   assert_equal([5, 37], [qfl[0].lnum, qfl[0].col])
85   assert_equal([6, 33], [qfl[1].lnum, qfl[1].col])
86   assert_equal([7, 41], [qfl[2].lnum, qfl[2].col])
87   :lclose
88   :%bw!
89 enddef
90
91 # Test for :LspFormat when using multibyte and composing characters
92 def g:Test_LspFormat_multibyte()
93   :silent! edit XLspFormat_mb.c
94   sleep 200m
95   var lines =<< trim END
96     void fn(int aVar)
97     {
98         int 馃槉馃槉馃槉馃槉   =   aVar + 1;
99         int a虂b虂a虂b虂   =   aVar + 1;
100         int a台虂a台虂a台虂a台虂   =   aVar + 1;
101     }
102   END
103   setline(1, lines)
104   g:WaitForServerFileLoad(0)
105   :redraw!
106   :LspFormat
107   var expected =<< trim END
108     void fn(int aVar) {
109       int 馃槉馃槉馃槉馃槉 = aVar + 1;
110       int a虂b虂a虂b虂 = aVar + 1;
111       int a台虂a台虂a台虂a台虂 = aVar + 1;
112     }
113   END
114   assert_equal(expected, getline(1, '$'))
115   :%bw!
116 enddef
117
118 # Test for :LspGotoDefinition when using multibyte and composing characters
119 def g:Test_LspGotoDefinition_multibyte()
120   :silent! edit XLspGotoDefinition_mb.c
121   sleep 200m
122   var lines: list<string> =<< trim END
123     #include <stdio.h>
124     void fn(int aVar)
125     {
126         printf("aVar = %d\n", aVar);
127         printf("馃槉馃槉馃槉馃槉 = %d\n", aVar);
128         printf("a虂b虂a虂b虂 = %d\n", aVar);
129         printf("a台虂a台虂a台虂a台虂 = %d\n", aVar);
130     }
131   END
132   setline(1, lines)
133   g:WaitForServerFileLoad(0)
134   redraw!
135
136   for [lnum, colnr] in [[4, 27], [5, 39], [6, 35], [7, 43]]
137     cursor(lnum, colnr)
138     :LspGotoDefinition
139     assert_equal([2, 13], [line('.'), col('.')])
140   endfor
141
142   :%bw!
143 enddef
144
145 # Test for :LspGotoDefinition when using multibyte and composing characters
146 def g:Test_LspGotoDefinition_after_multibyte()
147   :silent! edit XLspGotoDef_after_mb.c
148   sleep 200m
149   var lines =<< trim END
150     void fn(int aVar)
151     {
152         /* 伪尾纬未, 馃槉馃槉馃槉馃槉, a虂b虂a虂b虂, a台虂a台虂a台虂a台虂 */ int 伪尾纬未, bVar;
153         /* 伪尾纬未, 馃槉馃槉馃槉馃槉, a虂b虂a虂b虂, a台虂a台虂a台虂a台虂 */ int 馃槉馃槉馃槉馃槉, cVar;
154         /* 伪尾纬未, 馃槉馃槉馃槉馃槉, a虂b虂a虂b虂, a台虂a台虂a台虂a台虂 */ int a虂b虂a虂b虂, dVar;
155         /* 伪尾纬未, 馃槉馃槉馃槉馃槉, a虂b虂a虂b虂, a台虂a台虂a台虂a台虂 */ int a台虂a台虂a台虂a台虂, eVar;
156         bVar = 1;
157         cVar = 2;
158         dVar = 3;
159         eVar = 4;
160         aVar = 伪尾纬未 + 馃槉馃槉馃槉馃槉 + a虂b虂a虂b虂 + a台虂a台虂a台虂a台虂 + bVar;
161     }
162   END
163   setline(1, lines)
164   g:WaitForServerFileLoad(0)
165   :redraw!
166   cursor(7, 5)
167   :LspGotoDefinition
168   assert_equal([3, 88], [line('.'), col('.')])
169   cursor(8, 5)
170   :LspGotoDefinition
171   assert_equal([4, 96], [line('.'), col('.')])
172   cursor(9, 5)
173   :LspGotoDefinition
174   assert_equal([5, 92], [line('.'), col('.')])
175   cursor(10, 5)
176   :LspGotoDefinition
177   assert_equal([6, 100], [line('.'), col('.')])
178   cursor(11, 12)
179   :LspGotoDefinition
180   assert_equal([3, 78], [line('.'), col('.')])
181   cursor(11, 23)
182   :LspGotoDefinition
183   assert_equal([4, 78], [line('.'), col('.')])
184   cursor(11, 42)
185   :LspGotoDefinition
186   assert_equal([5, 78], [line('.'), col('.')])
187   cursor(11, 57)
188   :LspGotoDefinition
189   assert_equal([6, 78], [line('.'), col('.')])
190
191   :%bw!
192 enddef
193
194 # Test for doing omni completion for symbols with multibyte and composing
195 # characters
196 def g:Test_OmniComplete_multibyte()
197   :silent! edit XOmniComplete_mb.c
198   sleep 200m
199   var lines: list<string> =<< trim END
200     void Func1(void)
201     {
202         int 馃槉馃槉馃槉馃槉, aVar;
203         int a虂b虂a虂b虂, bVar;
204         int a台虂a台虂a台虂a台虂, cVar;
205         
206         
207         
208     }
209   END
210   setline(1, lines)
211   g:WaitForServerFileLoad(0)
212   redraw!
213
214   cursor(6, 4)
215   feedkeys("aaV\<C-X>\<C-O> = 馃槉馃槉\<C-X>\<C-O>;", 'xt')
216   assert_equal('    aVar = 馃槉馃槉馃槉馃槉;', getline('.'))
217   cursor(7, 4)
218   feedkeys("abV\<C-X>\<C-O> = a虂b虂\<C-X>\<C-O>;", 'xt')
219   assert_equal('    bVar = a虂b虂a虂b虂;', getline('.'))
220   cursor(8, 4)
221   feedkeys("acV\<C-X>\<C-O> = a台虂a台虂\<C-X>\<C-O>;", 'xt')
222   assert_equal('    cVar = a台虂a台虂a台虂a台虂;', getline('.'))
223   feedkeys("oa虂b虂\<C-X>\<C-O> = a台虂a台虂\<C-X>\<C-O>;", 'xt')
224   assert_equal('    a虂b虂a虂b虂 = a台虂a台虂a台虂a台虂;', getline('.'))
225   feedkeys("oa台虂a台虂\<C-X>\<C-O> = a虂b虂\<C-X>\<C-O>;", 'xt')
226   assert_equal('    a台虂a台虂a台虂a台虂 = a虂b虂a虂b虂;', getline('.'))
227   :%bw!
228 enddef
229
230 # Test for :LspOutline with multibyte and composing characters
231 def g:Test_Outline_multibyte()
232   silent! edit XLspOutline_mb.c
233   sleep 200m
234   var lines: list<string> =<< trim END
235     typedef void 馃槉馃槉馃槉馃槉;
236     typedef void a虂b虂a虂b虂;
237     typedef void a台虂a台虂a台虂a台虂;
238     
239     馃槉馃槉馃槉馃槉 Func1()
240     {
241     }
242     
243     a虂b虂a虂b虂 Func2()
244     {
245     }
246     
247     a台虂a台虂a台虂a台虂 Func3()
248     {
249     }
250   END
251   setline(1, lines)
252   g:WaitForServerFileLoad(0)
253   redraw!
254
255   cursor(1, 1)
256   :LspOutline
257   assert_equal(2, winnr('$'))
258
259   :wincmd w
260   cursor(5, 1)
261   feedkeys("\<CR>", 'xt')
262   assert_equal([2, 5, 18], [winnr(), line('.'), col('.')])
263
264   :wincmd w
265   cursor(6, 1)
266   feedkeys("\<CR>", 'xt')
267   assert_equal([2, 9, 14], [winnr(), line('.'), col('.')])
268
269   :wincmd w
270   cursor(7, 1)
271   feedkeys("\<CR>", 'xt')
272   assert_equal([2, 13, 22], [winnr(), line('.'), col('.')])
273
274   :wincmd w
275   cursor(10, 1)
276   feedkeys("\<CR>", 'xt')
277   assert_equal([2, 1, 14], [winnr(), line('.'), col('.')])
278
279   :wincmd w
280   cursor(11, 1)
281   feedkeys("\<CR>", 'xt')
282   assert_equal([2, 2, 14], [winnr(), line('.'), col('.')])
283
284   :wincmd w
285   cursor(12, 1)
286   feedkeys("\<CR>", 'xt')
287   assert_equal([2, 3, 14], [winnr(), line('.'), col('.')])
288
289   :%bw!
290 enddef
291
292 # Test for :LspRename with multibyte and composing characters
293 def g:Test_LspRename_multibyte()
294   silent! edit XLspRename_mb.c
295   sleep 200m
296   var lines: list<string> =<< trim END
297     #include <stdio.h>
298     void fn(int aVar)
299     {
300         printf("aVar = %d\n", aVar);
301         printf("馃槉馃槉馃槉馃槉 = %d\n", aVar);
302         printf("a虂b虂a虂b虂 = %d\n", aVar);
303         printf("a台虂a台虂a台虂a台虂 = %d\n", aVar);
304     }
305   END
306   setline(1, lines)
307   g:WaitForServerFileLoad(0)
308   redraw!
309   cursor(2, 12)
310   :LspRename bVar
311   redraw!
312   var expected: list<string> =<< trim END
313     #include <stdio.h>
314     void fn(int bVar)
315     {
316         printf("aVar = %d\n", bVar);
317         printf("馃槉馃槉馃槉馃槉 = %d\n", bVar);
318         printf("a虂b虂a虂b虂 = %d\n", bVar);
319         printf("a台虂a台虂a台虂a台虂 = %d\n", bVar);
320     }
321   END
322   assert_equal(expected, getline(1, '$'))
323   :%bw!
324 enddef
325
326 # Test for :LspShowReferences when using multibyte and composing characters
327 def g:Test_LspShowReferences_multibyte()
328   :silent! edit XLspShowReferences_mb.c
329   sleep 200m
330   var lines: list<string> =<< trim END
331     #include <stdio.h>
332     void fn(int aVar)
333     {
334         printf("aVar = %d\n", aVar);
335         printf("馃槉馃槉馃槉馃槉 = %d\n", aVar);
336         printf("a虂b虂a虂b虂 = %d\n", aVar);
337         printf("a台虂a台虂a台虂a台虂 = %d\n", aVar);
338     }
339   END
340   setline(1, lines)
341   g:WaitForServerFileLoad(0)
342   redraw!
343   cursor(4, 27)
344   :LspShowReferences
345   var qfl: list<dict<any>> = getloclist(0)
346   assert_equal([2, 13], [qfl[0].lnum, qfl[0].col])
347   assert_equal([4, 27], [qfl[1].lnum, qfl[1].col])
348   assert_equal([5, 39], [qfl[2].lnum, qfl[2].col])
349   assert_equal([6, 35], [qfl[3].lnum, qfl[3].col])
350   assert_equal([7, 43], [qfl[4].lnum, qfl[4].col])
351   :lclose
352
353   :%bw!
354 enddef
355
356 # Test for :LspSymbolSearch when using multibyte and composing characters
357 def g:Test_LspSymbolSearch_multibyte()
358   silent! edit XLspSymbolSearch_mb.c
359   sleep 200m
360   var lines: list<string> =<< trim END
361     typedef void 馃槉馃槉馃槉馃槉;
362     typedef void a虂b虂a虂b虂;
363     typedef void a台虂a台虂a台虂a台虂;
364
365     馃槉馃槉馃槉馃槉 Func1()
366     {
367     }
368
369     a虂b虂a虂b虂 Func2()
370     {
371     }
372
373     a台虂a台虂a台虂a台虂 Func3()
374     {
375     }
376   END
377   setline(1, lines)
378   g:WaitForServerFileLoad(0)
379
380   cursor(1, 1)
381   feedkeys(":LspSymbolSearch Func1\<CR>\<CR>", "xt")
382   assert_equal([5, 18], [line('.'), col('.')])
383   cursor(1, 1)
384   feedkeys(":LspSymbolSearch Func2\<CR>\<CR>", "xt")
385   assert_equal([9, 14], [line('.'), col('.')])
386   cursor(1, 1)
387   feedkeys(":LspSymbolSearch Func3\<CR>\<CR>", "xt")
388   assert_equal([13, 22], [line('.'), col('.')])
389
390   :%bw!
391 enddef
392
393 # Test for setting the 'tagfunc' with multibyte and composing characters in
394 # symbols
395 def g:Test_LspTagFunc_multibyte()
396   var lines =<< trim END
397     void fn(int aVar)
398     {
399         int 馃槉馃槉馃槉馃槉, bVar;
400         int a虂b虂a虂b虂, cVar;
401         int a台虂a台虂a台虂a台虂, dVar;
402         bVar = 10;
403         cVar = 10;
404         dVar = 10;
405     }
406   END
407   writefile(lines, 'Xtagfunc_mb.c')
408   :silent! edit! Xtagfunc_mb.c
409   g:WaitForServerFileLoad(0)
410   :setlocal tagfunc=lsp#lsp#TagFunc
411   cursor(6, 5)
412   :exe "normal \<C-]>"
413   assert_equal([3, 27], [line('.'), col('.')])
414   cursor(7, 5)
415   :exe "normal \<C-]>"
416   assert_equal([4, 23], [line('.'), col('.')])
417   cursor(8, 5)
418   :exe "normal \<C-]>"
419   assert_equal([5, 31], [line('.'), col('.')])
420   :set tagfunc&
421
422   :%bw!
423   delete('Xtagfunc_mb.c')
424 enddef
425
426 # Test for the :LspSuperTypeHierarchy and :LspSubTypeHierarchy commands with
427 # multibyte and composing characters
428 def g:Test_LspTypeHier_multibyte()
429   silent! edit XLspTypeHier_mb.cpp
430   sleep 200m
431   var lines =<< trim END
432     /* 伪尾馃槉馃槉a虂a虂a台虂a台虂 */ class parent {
433     };
434
435     /* 伪尾馃槉馃槉a虂a虂a台虂a台虂 */ class child : public parent {
436     };
437
438     /* 伪尾馃槉馃槉a虂a虂a台虂a台虂 */ class grandchild : public child {
439     };
440   END
441   setline(1, lines)
442   g:WaitForServerFileLoad(0)
443   redraw!
444
445   cursor(1, 42)
446   :LspSubTypeHierarchy
447   call feedkeys("\<CR>", 'xt')
448   assert_equal([1, 36], [line('.'), col('.')])
449   cursor(1, 42)
450
451   :LspSubTypeHierarchy
452   call feedkeys("\<Down>\<CR>", 'xt')
453   assert_equal([4, 42], [line('.'), col('.')])
454
455   cursor(1, 42)
456   :LspSubTypeHierarchy
457   call feedkeys("\<Down>\<Down>\<CR>", 'xt')
458   assert_equal([7, 42], [line('.'), col('.')])
459
460   cursor(7, 42)
461   :LspSuperTypeHierarchy
462   call feedkeys("\<CR>", 'xt')
463   assert_equal([7, 36], [line('.'), col('.')])
464
465   cursor(7, 42)
466   :LspSuperTypeHierarchy
467   call feedkeys("\<Down>\<CR>", 'xt')
468   assert_equal([4, 36], [line('.'), col('.')])
469
470   cursor(7, 42)
471   :LspSuperTypeHierarchy
472   call feedkeys("\<Down>\<Down>\<CR>", 'xt')
473   assert_equal([1, 36], [line('.'), col('.')])
474
475   :%bw!
476 enddef
477
478 # vim: shiftwidth=2 softtabstop=2 noexpandtab