I broke up with neovim....vim is my best friend now

This commit is contained in:
LinlyBoi
2023-04-30 08:14:07 +03:00
parent 0d185449c5
commit 4a4a6b1e81
5245 changed files with 468325 additions and 25 deletions

View File

@@ -0,0 +1,101 @@
Describe lsp#utils#buffer
Before each
% delete _
0put ='foo'
1put ='bar'
3delete _
End
After all
% delete _
End
Describe lsp#utils#buffer#_get_lines
It adds a blank line when nobinary and fixendofline are set
if !exists('+fixendofline')
Skip This test requires 'fixendofline'
endif
setl nobinary
setl fixendofline
Assert Equals(lsp#utils#buffer#_get_lines(bufnr('$')), ['foo', 'bar', ''])
End
It adds a blank line when nobinary, nofixendofline, and endofline are set
if !exists('+fixendofline')
Skip This test requires 'fixendofline'
endif
setl nobinary
setl nofixendofline
setl endofline
Assert Equals(lsp#utils#buffer#_get_lines(bufnr('$')), ['foo', 'bar', ''])
End
It adds a blank line when binary and endofline are set
if !exists('+fixendofline')
Skip This test requires 'fixendofline'
endif
setl binary
setl endofline
Assert Equals(lsp#utils#buffer#_get_lines(bufnr('$')), ['foo', 'bar', ''])
End
It does not add a blank line when nobinary, nofixendofline, and noendofline are set
if !exists('+fixendofline')
Skip This test requires 'fixendofline'
endif
setl nobinary
setl nofixendofline
setl noendofline
Assert Equals(lsp#utils#buffer#_get_lines(bufnr('$')), ['foo', 'bar'])
End
It does not add a blank line when binary and noendofline are set
if !exists('+fixendofline')
Skip This test requires 'fixendofline'
endif
setl binary
setl noendofline
Assert Equals(lsp#utils#buffer#_get_lines(bufnr('$')), ['foo', 'bar'])
End
It adds a blank line when nobinary is set
if exists('+fixendofline')
Skip This test is not for 'fixendofline'
endif
setl nobinary
Assert Equals(lsp#utils#buffer#_get_lines(bufnr('$')), ['foo', 'bar', ''])
End
It adds a blank line when binary and endofline are set
if exists('+fixendofline')
Skip This test is not for 'fixendofline'
endif
setl binary
setl endofline
Assert Equals(lsp#utils#buffer#_get_lines(bufnr('$')), ['foo', 'bar', ''])
End
It does not add a blank line when binary and noendofline are set
if exists('+fixendofline')
Skip This test is not for 'fixendofline'
endif
setl binary
setl noendofline
Assert Equals(lsp#utils#buffer#_get_lines(bufnr('$')), ['foo', 'bar'])
End
End
Describe lsp#utils#buffer#get_indent_size
It gets shiftwidth if set
setl shiftwidth=4
setl tabstop=8
Assert Equals(lsp#utils#buffer#get_indent_size(bufnr('$')), 4)
End
It gets tabstop if shiftwidth not set
setl shiftwidth=0
setl tabstop=12
Assert Equals(lsp#utils#buffer#get_indent_size(bufnr('$')), 12)
End
End
End

View File

@@ -0,0 +1,86 @@
Describe lsp#utils#diff
Describe lsp#utils#diff#compute
It should return diff of one letter
let lines1 = [
\ 'foo',
\ 'bar',
\ 'baz',
\]
let lines2 = [
\ 'foo',
\ 'baR',
\ 'baz',
\]
let want = {
\ 'range': {
\ 'start': { 'line': 1, 'character': 2 },
\ 'end': { 'line': 1, 'character': 3 },
\ },
\ 'text': 'R',
\ 'rangeLength': 1
\}
let got = lsp#utils#diff#compute(lines1, lines2)
Assert Equals(got, want)
End
It should return diff of multi-lines
let lines1 = [
\ 'foo',
\ 'bar',
\ 'baz',
\]
let lines2 = [
\ 'Foo',
\ 'baR',
\ 'baz',
\]
let want = {
\ 'range': {
\ 'start': { 'line': 0, 'character': 0 },
\ 'end': { 'line': 1, 'character': 3, }
\ },
\ 'text': "Foo\nbaR",
\ "rangeLength": 7
\}
let got = lsp#utils#diff#compute(lines1, lines2)
Assert Equals(got, want)
End
It should return diff for empty list
let lines1 = []
let lines2 = [
\ 'foo',
\ 'bar',
\ 'baz',
\]
let want = {
\ 'range': {
\ 'start': { 'line': 0, 'character': 0 },
\ 'end': { 'line': 0, 'character': 0, }
\ },
\ 'text': "foo\nbar\nbaz\n",
\ "rangeLength": 0
\}
let got = lsp#utils#diff#compute(lines1, lines2)
Assert Equals(got, want)
let lines1 = [
\ 'foo',
\ 'bar',
\ 'baz',
\]
let lines2 = []
let want = {
\ 'range': {
\ 'start': { 'line': 0, 'character': 0 },
\ 'end': { 'line': 3, 'character': 0, }
\ },
\ 'text': '',
\ "rangeLength": 12
\}
let got = lsp#utils#diff#compute(lines1, lines2)
Assert Equals(got, want)
End
End
End

View File

@@ -0,0 +1,65 @@
Describe lsp#utils#position
Before each
% delete _
End
After all
% delete _
End
Describe lsp#utils#position#lsp_to_vim
It should return the byte-index from the given character-index on a buffer
call setline(1, ['a β c', 'δ', ''])
Assert Equals(lsp#utils#position#lsp_to_vim('%', { 'line': 0, 'character': 0 }), [1, 1])
Assert Equals(lsp#utils#position#lsp_to_vim('%', { 'line': 0, 'character': 1 }), [1, 2])
Assert Equals(lsp#utils#position#lsp_to_vim('%', { 'line': 0, 'character': 2 }), [1, 3])
Assert Equals(lsp#utils#position#lsp_to_vim('%', { 'line': 0, 'character': 3 }), [1, 5])
Assert Equals(lsp#utils#position#lsp_to_vim('%', { 'line': 0, 'character': 4 }), [1, 6])
Assert Equals(lsp#utils#position#lsp_to_vim('%', { 'line': 1, 'character': 0 }), [2, 1])
Assert Equals(lsp#utils#position#lsp_to_vim('%', { 'line': 1, 'character': 1 }), [2, 3])
Assert Equals(lsp#utils#position#lsp_to_vim('%', { 'line': 2, 'character': 0 }), [3, 1])
End
It should return the byte-index from the given character-index in an unloaded file
Assert Equals(lsp#utils#position#lsp_to_vim('./test/testfiles/multibyte.txt', { 'line': 0, 'character': 0 }), [1, 1])
Assert Equals(lsp#utils#position#lsp_to_vim('./test/testfiles/multibyte.txt', { 'line': 0, 'character': 1 }), [1, 2])
Assert Equals(lsp#utils#position#lsp_to_vim('./test/testfiles/multibyte.txt', { 'line': 0, 'character': 2 }), [1, 3])
Assert Equals(lsp#utils#position#lsp_to_vim('./test/testfiles/multibyte.txt', { 'line': 0, 'character': 3 }), [1, 5])
Assert Equals(lsp#utils#position#lsp_to_vim('./test/testfiles/multibyte.txt', { 'line': 0, 'character': 4 }), [1, 6])
Assert Equals(lsp#utils#position#lsp_to_vim('./test/testfiles/multibyte.txt', { 'line': 1, 'character': 0 }), [2, 1])
Assert Equals(lsp#utils#position#lsp_to_vim('./test/testfiles/multibyte.txt', { 'line': 1, 'character': 1 }), [2, 3])
Assert Equals(lsp#utils#position#lsp_to_vim('./test/testfiles/multibyte.txt', { 'line': 2, 'character': 0 }), [3, 1])
End
End
Describe lsp#utils#position#vim_to_lsp
It should return the character-index from the given byte-index on a buffer
call setline(1, ['a β c', 'δ', ''])
Assert Equals({ 'line': 0, 'character': 0 }, lsp#utils#position#vim_to_lsp('%', [1, 1]))
Assert Equals({ 'line': 0, 'character': 1 }, lsp#utils#position#vim_to_lsp('%', [1, 2]))
Assert Equals({ 'line': 0, 'character': 2 }, lsp#utils#position#vim_to_lsp('%', [1, 3]))
Assert Equals({ 'line': 0, 'character': 3 }, lsp#utils#position#vim_to_lsp('%', [1, 5]))
Assert Equals({ 'line': 0, 'character': 4 }, lsp#utils#position#vim_to_lsp('%', [1, 6]))
Assert Equals({ 'line': 1, 'character': 0 }, lsp#utils#position#vim_to_lsp('%', [2, 1]))
Assert Equals({ 'line': 1, 'character': 1 }, lsp#utils#position#vim_to_lsp('%', [2, 3]))
Assert Equals({ 'line': 2, 'character': 0 }, lsp#utils#position#vim_to_lsp('%', [3, 1]))
End
It should return the character-index from the given byte-index in an unloaded file
Assert Equals({ 'line': 0, 'character': 0 }, lsp#utils#position#vim_to_lsp('./test/testfiles/multibyte.txt', [1, 1]))
Assert Equals({ 'line': 0, 'character': 1 }, lsp#utils#position#vim_to_lsp('./test/testfiles/multibyte.txt', [1, 2]))
Assert Equals({ 'line': 0, 'character': 2 }, lsp#utils#position#vim_to_lsp('./test/testfiles/multibyte.txt', [1, 3]))
Assert Equals({ 'line': 0, 'character': 3 }, lsp#utils#position#vim_to_lsp('./test/testfiles/multibyte.txt', [1, 5]))
Assert Equals({ 'line': 0, 'character': 4 }, lsp#utils#position#vim_to_lsp('./test/testfiles/multibyte.txt', [1, 6]))
Assert Equals({ 'line': 1, 'character': 0 }, lsp#utils#position#vim_to_lsp('./test/testfiles/multibyte.txt', [2, 1]))
Assert Equals({ 'line': 1, 'character': 1 }, lsp#utils#position#vim_to_lsp('./test/testfiles/multibyte.txt', [2, 3]))
Assert Equals({ 'line': 2, 'character': 0 }, lsp#utils#position#vim_to_lsp('./test/testfiles/multibyte.txt', [3, 1]))
End
End
End

View File

@@ -0,0 +1,61 @@
Describe lsp#utils#range
Before each
% delete _
End
Describe lsp#utils#range#_get_recent_visual_range
It should return single line visual selection
call setline(1, ['あいうえお'])
normal! gg0llvly
Assert Equals(lsp#utils#range#_get_recent_visual_range(), {
\ 'start': {
\ 'line': 0,
\ 'character': 2
\ },
\ 'end': {
\ 'line': 0,
\ 'character': 4
\ }
\ })
End
It should return multi line visual selection
call setline(1, ['あいうえお', 'かきくけこ'])
normal! gg0llvjly
Assert Equals(lsp#utils#range#_get_recent_visual_range(), {
\ 'start': {
\ 'line': 0,
\ 'character': 2
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 4
\ }
\ })
End
End
Describe lsp#utils#range#_get_current_line_range
It should return current line range
call setline(1, ['あいうえお', 'かきくけこ', 'さしすせそ'])
call cursor(2, 1)
Assert Equals(lsp#utils#range#_get_current_line_range(), {
\ 'start': {
\ 'line': 1,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 5
\ }
\ })
End
End
End

View File

@@ -0,0 +1,75 @@
Describe lsp#utils#tagstack
Before each
% delete _
if exists('*settagstack')
call settagstack(1, {'items' : []})
endif
End
After all
% delete _
End
Describe lsp#utils#tagstack#_update()
It should correctly preserve the tag stack
let l:bufnr = bufnr('%')
0put = 'foo'
1put = 'bar'
2put = 'baz'
call cursor(1, 1)
call lsp#utils#tagstack#_update()
call cursor(1, 2)
call lsp#utils#tagstack#_update()
call cursor(3, 3)
call lsp#utils#tagstack#_update()
call cursor(2, 1)
call lsp#utils#tagstack#_update()
if !exists('*gettagstack') || !exists('*settagstack')
" calling lsp#utils#tagstack#_update() should be safe if
" gettagstack and settagstack doesn't exist
return
endif
let l:tagstack = gettagstack()
Assert Equals(l:tagstack['length'], 4)
Assert Equals(l:tagstack['curidx'], 5)
Assert Equals(l:tagstack['items'][0], {
\ 'bufnr': l:bufnr,
\ 'tagname': 'foo',
\ 'from': [l:bufnr, 1, 1, 0],
\ 'matchnr': 1,
\ })
Assert Equals(l:tagstack['items'][1], {
\ 'bufnr': l:bufnr,
\ 'tagname': 'foo',
\ 'from': [l:bufnr, 1, 2, 0],
\ 'matchnr': 1,
\ })
Assert Equals(l:tagstack['items'][2], {
\ 'bufnr': l:bufnr,
\ 'tagname': 'baz',
\ 'from': [l:bufnr, 3, 3, 0],
\ 'matchnr': 1,
\ })
Assert Equals(l:tagstack['items'][3], {
\ 'bufnr': l:bufnr,
\ 'tagname': 'bar',
\ 'from': [l:bufnr, 2, 1, 0],
\ 'matchnr': 1,
\ })
End
End
End

View File

@@ -0,0 +1,647 @@
function! s:set_text(lines)
% delete _
put =a:lines
execute 'normal ggdd'
endfunction
function! s:get_text()
return lsp#utils#buffer#_get_lines(bufnr('$'))
endfunction
Describe lsp#utils#text_edit
Before all
let s:endofline_backup = &endofline
set endofline
End
After all
let &endofline = s:endofline_backup
End
Before each
enew!
End
Describe lsp#utils#text_edit#apply_text_edits
It insert newText
call s:set_text(['foo', 'bar'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 1,
\ 'character': 1
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 1
\ }
\ },
\ 'newText': 'baz'
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['foo', 'bbazar', ''])
End
It insert empty newText
call s:set_text(['foo', 'bar'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 1,
\ 'character': 1
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 1
\ }
\ },
\ 'newText': ''
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['foo', 'bar', ''])
End
It replace range string to newText
call s:set_text(['foo', 'bar'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 1,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 1
\ }
\ },
\ 'newText': 'replaced'
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['foo', 'replacedar', ''])
End
It replace range string to empty newText
call s:set_text(['foo', 'bar'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 1,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 1
\ }
\ },
\ 'newText': ''
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['foo', 'ar', ''])
End
It single line start character is -1
call s:set_text(['foo', 'bar'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 1,
\ 'character': -1
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 3
\ }
\ },
\ 'newText': ''
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['foo', '', ''])
End
It single line start character is 0
call s:set_text(['foo', 'bar'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 1,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 3
\ }
\ },
\ 'newText': ''
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['foo', '', ''])
End
It single line start character is 1
call s:set_text(['foo', 'bar'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 1,
\ 'character': 1
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 3
\ }
\ },
\ 'newText': ''
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['foo', 'b', ''])
End
It single line end character is `len(getline('.')) - 1`
call s:set_text(['foo', 'bar'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 1,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 2
\ }
\ },
\ 'newText': ''
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['foo', 'r', ''])
End
It single line end character is `len(getline('.'))`
call s:set_text(['foo', 'bar'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 1,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 3
\ }
\ },
\ 'newText': ''
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['foo', '', ''])
End
It single line end character is `len(getline('.')) + 1`
call s:set_text(['foo', 'bar'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 1,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 4
\ }
\ },
\ 'newText': ''
\ }])
" if newline character deleting, need end position is next line zero character.
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['foo', '', ''])
End
It replace range string to empty newText, multiline top to top
call s:set_text(['foo', 'bar', 'baz'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 0,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 0
\ }
\ },
\ 'newText': ''
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['bar', 'baz', ''])
End
It replace range string to empty newText, multiline top to tail
call s:set_text(['foo', 'bar', 'baz'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 0,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 2
\ }
\ },
\ 'newText': ''
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['r', 'baz', ''])
call s:set_text(['foo', 'bar', 'baz'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 0,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 3
\ }
\ },
\ 'newText': ''
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['', 'baz', ''])
call s:set_text(['foo', 'bar', 'baz'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 0,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 4
\ }
\ },
\ 'newText': ''
\ }])
" if newline character deleting, need end position is next line zero character.
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['', 'baz', ''])
End
It replace range string to empty newText, multiline middle to middle
call s:set_text(['foo', 'bar', 'baz'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 0,
\ 'character': 1
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 2
\ }
\ },
\ 'newText': ''
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['fr', 'baz', ''])
End
It replaces entire buffer correctly
call s:set_text(['foo', 'bar', 'baz'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 0,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 3,
\ 'character': 0
\ }
\ },
\ 'newText': "x\ny\nz\n"
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['x', 'y', 'z', ''])
End
It multiple textEdit with inserting \r.
" Add some text to buffer
call s:set_text(['class ABC {', ' private:', ' ', 'int a;};', ])
" Format
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [
\ {
\ "range": {
\ "end": {
\ "character": 2,
\ "line": 1
\ },
\ "start": {
\ "character": 11,
\ "line": 0
\ }
\ },
\ "newText": "\n"
\ },
\ {
\ "range": {
\ "end": {
\ "character": 0,
\ "line": 3
\ },
\ "start": {
\ "character": 10,
\ "line": 1
\ }
\ },
\ "newText": "\n "
\ },
\ {
\ "range": {
\ "end": {
\ "character": 6,
\ "line": 3
\ },
\ "start": {
\ "character": 6,
\ "line": 3
\ }
\ },
\ "newText": "\n"
\ }
\ ])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['class ABC {', 'private:', ' int a;', '};', ''])
End
It preserves v:completed_item
" Add some text to buffer
call s:set_text(['foo', 'bar'])
" Go to end of file and invoke completion
execute "normal Gof\<C-p>\<Esc>"
" Make sure that v:completed_item is set
Assert Equals(v:completed_item["word"], "foo")
let l:old_completed_item = v:completed_item
" Perform some text edits
" Insert
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 1,
\ 'character': 1
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 1
\ }
\ },
\ 'newText': 'baz'
\ }])
" Insert empty
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 1,
\ 'character': 1
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 1
\ }
\ },
\ 'newText': ''
\ }])
" Replace
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 1,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 1
\ }
\ },
\ 'newText': 'replaced'
\ }])
" Delete
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 1,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 1
\ }
\ },
\ 'newText': ''
\ }])
" Make sure v:completed_item is not changed
Assert Equals(v:completed_item, l:old_completed_item)
End
It replaces entire buffer correctly when end column is 1
call s:set_text(['foo', 'b'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 0,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 1
\ }
\ },
\ 'newText': "x\ny\nz\n"
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['x', 'y', 'z', '', ''])
End
It should apply edit that contains \r\n
call s:set_text(['foo', 'b'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ 'range': {
\ 'start': {
\ 'line': 0,
\ 'character': 0
\ },
\ 'end': {
\ 'line': 1,
\ 'character': 1
\ }
\ },
\ 'newText': "x\r\ny\r\nz\r\n"
\ }])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['x', 'y', 'z', '', ''])
End
It adds imports correctly
call s:set_text(['package main', '', 'import java.util.ArrayList;', '', 'public class Main {}'])
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ [{
\ "range": {
\ "start": {
\ "character": 0,
\ "line": 2
\ },
\ "end": {
\ "character": 0,
\ "line": 3
\ }
\ },
\ "newText": ""
\ },
\ {
\ "range": {
\ "start": {
\ "character": 0,
\ "line": 2
\ },
\ "end": {
\ "character": 0,
\ "line": 2
\ }
\ },
\ "newText": "import java.util.ArrayList;\n"
\ }
\ ])
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, ['package main', '', 'import java.util.ArrayList;', '', 'public class Main {}', ''])
End
It adds null
let l:text = ['package main', '', 'import java.util.ArrayList;', '', 'public class Main {}']
call s:set_text(l:text)
call lsp#utils#text_edit#apply_text_edits(
\ expand('%'),
\ v:null)
let l:buffer_text = s:get_text()
Assert Equals(l:buffer_text, l:text + [''])
End
It should apply edits to unloaded file
let l:target = globpath(&runtimepath, 'test/lsp/utils/text_edit.vimspec')
call themis#log(l:target)
call lsp#utils#text_edit#apply_text_edits(lsp#utils#path_to_uri(l:target), [{
\ 'range': {
\ 'start': {
\ 'line': 0,
\ 'character': 0,
\ },
\ 'end': {
\ 'line': 0,
\ 'character': 0,
\ }
\ },
\ 'newText': "aiueo\n"
\ }])
Assert Equals(getbufline(l:target, 1), ['aiueo'])
End
End
End

View File

@@ -0,0 +1,92 @@
Describe lsp#internal#work_done_progress
Before each
let g:lsp_work_done_progress_enabled = 1
call lsp#internal#work_done_progress#_enable()
End
After each
let g:lsp_work_done_progress_enabled = 0
call lsp#internal#work_done_progress#_disable()
End
It should be able to subscribe to $progress stream
let l:server1_response1 = {'method': '$/progress', 'params':{'token':'token text','value':{'kind':'begin', 'title':'title'}}}
let l:server1_response2 = {'method': '$/progress', 'params':{'token':'token text','value':{'percentage':50,'message':'test message','kind':'report'}}}
let l:server1_response3 = {'method': '$/progress', 'params':{'token':'token text','value':{'kind':'end'}}}
Assert Equals(lsp#internal#work_done_progress#get_progress(), [])
call lsp#stream(1, { 'server': 'server1', 'response': l:server1_response1 })
Assert Equals(lsp#internal#work_done_progress#get_progress(),
\ [{'message': '', 'token': 'token text', 'title': 'title', 'server': 'server1'}])
call lsp#stream(1, { 'server': 'server1', 'response': l:server1_response2 })
Assert Equals(lsp#internal#work_done_progress#get_progress(),
\ [{'message': 'test message', 'token': 'token text', 'percentage': 50, 'title': 'title', 'server': 'server1'}])
call lsp#stream(1, { 'server': 'server1', 'response': l:server1_response3 })
Assert Equals(lsp#internal#work_done_progress#get_progress(), [])
End
It should be able to subscribe to multi $progress stream
let l:server1_response1 = {'method': '$/progress', 'params':{'token':'token text','value':{'kind':'begin', 'title':'title1'}}}
let l:server1_response2 = {'method': '$/progress', 'params':{'token':'token text','value':{'percentage':50,'message':'msg1','kind':'report'}}}
let l:server1_response3 = {'method': '$/progress', 'params':{'token':'token text','value':{'percentage':90,'message':'msg1','kind':'report'}}}
let l:server1_response4 = {'method': '$/progress', 'params':{'token':'token text','value':{'kind':'end'}}}
let l:server2_response1 = {'method': '$/progress', 'params':{'token':'server2_token','value':{'kind':'begin', 'title':'title2'}}}
let l:server2_response2 = {'method': '$/progress', 'params':{'token':'server2_token','value':{'percentage':0,'message':'msg2','kind':'report'}}}
let l:server2_response3 = {'method': '$/progress', 'params':{'token':'server2_token','value':{'kind':'end'}}}
Assert Equals(lsp#internal#work_done_progress#get_progress(), [])
call lsp#stream(1, { 'server': 'server1', 'response': l:server1_response1 })
Assert Equals(lsp#internal#work_done_progress#get_progress(),
\ [{'message': '', 'token': 'token text', 'title': 'title1', 'server': 'server1'}])
call lsp#stream(1, { 'server': 'server2', 'response': l:server2_response1 })
Assert Equals(lsp#internal#work_done_progress#get_progress(),
\ [{'message': '', 'token': 'server2_token', 'title': 'title2', 'server': 'server2'},
\ {'message': '', 'token': 'token text', 'title': 'title1', 'server': 'server1'}])
call lsp#stream(1, { 'server': 'server2', 'response': l:server2_response2 })
Assert Equals(lsp#internal#work_done_progress#get_progress(),
\ [{'message': 'msg2', 'token': 'server2_token', 'percentage':0, 'title': 'title2', 'server': 'server2'},
\ {'message': '', 'token': 'token text', 'title': 'title1', 'server': 'server1'}])
call lsp#stream(1, { 'server': 'server1', 'response': l:server1_response2 })
Assert Equals(lsp#internal#work_done_progress#get_progress(),
\ [{'message': 'msg1', 'token': 'token text', 'percentage':50, 'title': 'title1', 'server': 'server1'},
\ {'message': 'msg2', 'token': 'server2_token', 'percentage':0, 'title': 'title2', 'server': 'server2'}])
call lsp#stream(1, { 'server': 'server1', 'response': l:server1_response3 })
Assert Equals(lsp#internal#work_done_progress#get_progress(),
\ [{'message': 'msg1', 'token': 'token text', 'percentage':90, 'title': 'title1', 'server': 'server1'},
\ {'message': 'msg2', 'token': 'server2_token', 'percentage':0, 'title': 'title2', 'server': 'server2'}])
call lsp#stream(1, { 'server': 'server1', 'response': l:server1_response4 })
Assert Equals(lsp#internal#work_done_progress#get_progress(),
\ [{'message': 'msg2', 'token': 'server2_token', 'percentage':0, 'title': 'title2', 'server': 'server2'}])
call lsp#stream(1, { 'server': 'server2', 'response': l:server2_response3 })
Assert Equals(lsp#internal#work_done_progress#get_progress(), [])
End
It should be returned correctly even if percentage and message do not exist.
let l:server1_response1 = {'method': '$/progress', 'params':{'token':'token text','value':{'kind':'begin', 'title':'title'}}}
let l:server1_response2 = {'method': '$/progress', 'params':{'token':'token text','value':{'kind':'report'}}}
let l:server1_response3 = {'method': '$/progress', 'params':{'token':'token text','value':{'kind':'end'}}}
Assert Equals(lsp#internal#work_done_progress#get_progress(), [])
call lsp#stream(1, { 'server': 'server1', 'response': l:server1_response1 })
Assert Equals(lsp#internal#work_done_progress#get_progress(),
\ [{'message': '', 'token': 'token text', 'title': 'title', 'server': 'server1'}])
call lsp#stream(1, { 'server': 'server1', 'response': l:server1_response2 })
Assert Equals(lsp#internal#work_done_progress#get_progress(),
\ [{'message': '', 'token': 'token text', 'title': 'title', 'server': 'server1'}])
call lsp#stream(1, { 'server': 'server1', 'response': l:server1_response3 })
Assert Equals(lsp#internal#work_done_progress#get_progress(), [])
End
End

View File

@@ -0,0 +1,81 @@
Describe lsp#utils#workspace_edit
Describe lsp#utils#text_edit#apply_workspace_edit
It populates location list with changes
let g:lsp_show_workspace_edits = 1
call lsp#utils#workspace_edit#apply_workspace_edit({
\ 'documentChanges': [{
\ 'textDocument': { 'uri': 'file:///path/to/file' },
\ 'edits': [
\ {
\ "range": {
\ "start": {
\ "character": 0,
\ "line": 1
\ },
\ "end": {
\ "character": 0,
\ "line": 1
\ }
\ },
\ "newText": "import java.util.LinkedList;"
\ },
\ {
\ "range": {
\ "start": {
\ "character": 0,
\ "line": 0
\ },
\ "end": {
\ "character": 0,
\ "line": 0
\ }
\ },
\ "newText": "import java.util.ArrayList;"
\ }
\ ]
\ }]})
let l:loclist = getloclist(0)
Assert Equals(len(l:loclist), 2)
Assert Equals(l:loclist[0]['lnum'], 2)
Assert Equals(l:loclist[0]['col'], 1)
Assert Equals(l:loclist[0]['text'], 'import java.util.LinkedList;')
Assert Equals(l:loclist[1]['lnum'], 1)
Assert Equals(l:loclist[1]['col'], 1)
Assert Equals(l:loclist[1]['text'], 'import java.util.ArrayList;')
end
It should not set location list if not enabled
let g:lsp_show_workspace_edits = 0
call lsp#utils#workspace_edit#apply_workspace_edit({
\ 'documentChanges': [{
\ 'textDocument': { 'uri': 'file:///path/to/file' },
\ 'edits': [
\ {
\ "range": {
\ "start": {
\ "character": 0,
\ "line": 3
\ },
\ "end": {
\ "character": 0,
\ "line": 3
\ }
\ },
\ "newText": "import java.util.LinkedList;"
\ }
\ ]
\ }]})
Assert Equals(len(getloclist(0)), 0)
End
End
End