Skip to content

Commit 90d568d

Browse files
committed
Merge branch 'master' into fix-textedit
2 parents 3a6def0 + e748025 commit 90d568d

20 files changed

+530
-60
lines changed

README.md

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,24 @@ At the moment, you have two options:
5353

5454
For more information, refer to the readme and documentation of the respective plugins.
5555

56+
## Folding
57+
58+
You can let the language server automatically handle folding for you. To enable this, you have to set `'foldmethod'`, `'foldexpr'` and (optionally) `'foldtext'`:
59+
60+
```vim
61+
set foldmethod=expr
62+
\ foldexpr=lsp#ui#vim#folding#foldexpr()
63+
\ foldtext=lsp#ui#vim#folding#foldtext()
64+
```
65+
66+
If you would like to disable folding globally, you can add this to your configuration:
67+
68+
```vim
69+
let g:lsp_fold_enabled = 0
70+
```
71+
72+
Also see `:h vim-lsp-folding`.
73+
5674
## Supported commands
5775

5876
**Note:**
@@ -146,11 +164,11 @@ Virtual text will use the same highlight groups as signs feature.
146164

147165
### Highlight references
148166

149-
References to the symbol under the cursor are highlighted by default. To
150-
disable, set in your configuration:
167+
Highlight references to the symbol under the cursor. To enable, set in your
168+
configuration:
151169

152170
```viml
153-
let g:lsp_highlight_references_enabled = 0
171+
let g:lsp_highlight_references_enabled = 1
154172
```
155173

156174
To change the style of the highlighting, you can set or link the `lspReference`

autoload/lsp.vim

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,10 @@ function! s:on_text_document_did_save() abort
191191
if getbufvar(l:buf, '&buftype') ==# 'terminal' | return | endif
192192
call lsp#log('s:on_text_document_did_save()', l:buf)
193193
for l:server_name in lsp#get_whitelisted_servers(l:buf)
194-
call s:ensure_flush(l:buf, l:server_name, {result->s:call_did_save(l:buf, l:server_name, result, function('s:Noop'))})
194+
" We delay the callback by one loop iteration as calls to ensure_flush
195+
" can introduce mmap'd file locks that linger on Windows and collide
196+
" with the second lang server call preventing saves (see #455)
197+
call s:ensure_flush(l:buf, l:server_name, {result->timer_start(0, {result->s:call_did_save(l:buf, l:server_name, result, function('s:Noop'))})})
195198
endfor
196199
endfunction
197200

@@ -380,6 +383,21 @@ function! lsp#default_get_supported_capabilities(server_info) abort
380383
\ 'workspace': {
381384
\ 'applyEdit': v:true,
382385
\ 'configuration': v:true
386+
\ },
387+
\ 'textDocument': {
388+
\ 'completion': {
389+
\ 'completionItemKind': {
390+
\ 'valueSet': lsp#omni#get_completion_item_kinds()
391+
\ }
392+
\ },
393+
\ 'documentSymbol': {
394+
\ 'symbolKind': {
395+
\ 'valueSet': lsp#ui#vim#utils#get_symbol_kinds()
396+
\ }
397+
\ },
398+
\ 'foldingRange': {
399+
\ 'lineFoldingOnly': v:true
400+
\ }
383401
\ }
384402
\ }
385403
endfunction
@@ -514,6 +532,7 @@ function! s:ensure_changed(buf, server_name, cb) abort
514532
\ 'contentChanges': s:text_changes(a:buf, a:server_name),
515533
\ }
516534
\ })
535+
call lsp#ui#vim#folding#send_request(a:server_name, a:buf, 0)
517536

518537
let l:msg = s:new_rpc_success('textDocument/didChange sent', { 'server_name': a:server_name, 'path': l:path })
519538
call lsp#log(l:msg)
@@ -552,6 +571,8 @@ function! s:ensure_open(buf, server_name, cb) abort
552571
\ },
553572
\ })
554573

574+
call lsp#ui#vim#folding#send_request(a:server_name, a:buf, 0)
575+
555576
let l:msg = s:new_rpc_success('textDocument/open sent', { 'server_name': a:server_name, 'path': l:path, 'filetype': getbufvar(a:buf, '&filetype') })
556577
call lsp#log(l:msg)
557578
call a:cb(l:msg)
@@ -732,7 +753,9 @@ function! lsp#get_text_document_identifier(...) abort
732753
endfunction
733754

734755
function! lsp#get_position(...) abort
735-
return { 'line': line('.') - 1, 'character': col('.') -1 }
756+
let l:line = line('.')
757+
let l:char = lsp#utils#to_char('%', l:line, col('.'))
758+
return { 'line': l:line - 1, 'character': l:char }
736759
endfunction
737760

738761
function! s:get_text_document_identifier(buf) abort

autoload/lsp/capabilities.vim

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ function! lsp#capabilities#has_implementation_provider(server_name) abort
5454
endfunction
5555

5656
function! lsp#capabilities#has_code_action_provider(server_name) abort
57+
let l:capabilities = lsp#get_server_capabilities(a:server_name)
58+
if !empty(l:capabilities) && has_key(l:capabilities, 'codeActionProvider')
59+
if type(l:capabilities['codeActionProvider']) == type({})
60+
if has_key(l:capabilities['codeActionProvider'], 'codeActionKinds') && type(l:capabilities['codeActionProvider']['codeActionKinds']) == type([])
61+
return len(l:capabilities['codeActionProvider']['codeActionKinds']) != 0
62+
endif
63+
endif
64+
endif
5765
return s:has_bool_provider(a:server_name, 'codeActionProvider')
5866
endfunction
5967

@@ -65,6 +73,10 @@ function! lsp#capabilities#has_document_highlight_provider(server_name) abort
6573
return s:has_bool_provider(a:server_name, 'documentHighlightProvider')
6674
endfunction
6775

76+
function! lsp#capabilities#has_folding_range_provider(server_name) abort
77+
return s:has_bool_provider(a:server_name, 'foldingRangeProvider')
78+
endfunction
79+
6880
" [supports_did_save (boolean), { 'includeText': boolean }]
6981
function! lsp#capabilities#get_text_document_save_registration_options(server_name) abort
7082
let l:capabilities = lsp#get_server_capabilities(a:server_name)

autoload/lsp/omni.vim

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ function! s:apply_text_edits() abort
318318
" expand textEdit range, for omni complet inserted text.
319319
let l:text_edit = get(l:user_data, s:user_data_key, {})
320320
if !empty(l:text_edit)
321-
let l:expanded_text_edit = s:expand_range(l:text_edit, len(v:completed_item['word']))
321+
let l:expanded_text_edit = s:expand_range(l:text_edit, strchars(v:completed_item['word']))
322322
call add(l:all_text_edits, l:expanded_text_edit)
323323
endif
324324

@@ -369,4 +369,8 @@ function! s:get_cursor_pos_and_edit_length(text_edit) abort
369369
return [l:pos, l:length]
370370
endfunction
371371

372+
function! lsp#omni#get_completion_item_kinds() abort
373+
return map(keys(s:kind_text_mappings), {idx, key -> str2nr(key)})
374+
endfunction
375+
372376
" }}}

autoload/lsp/ui/vim.vim

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ function! s:document_format(sync) abort
193193

194194
" TODO: ask user to select server for formatting
195195
let l:server = l:servers[0]
196+
redraw | echo 'Formatting document ...'
196197
call lsp#send_request(l:server, {
197198
\ 'method': 'textDocument/formatting',
198199
\ 'params': {
@@ -205,8 +206,6 @@ function! s:document_format(sync) abort
205206
\ 'sync': a:sync,
206207
\ 'on_notification': function('s:handle_text_edit', [l:server, s:last_req_id, 'document format']),
207208
\ })
208-
209-
echo 'Formatting document ...'
210209
endfunction
211210

212211
function! lsp#ui#vim#document_format_sync() abort
@@ -253,13 +252,16 @@ function! s:document_format_range(sync) abort
253252
let l:server = l:servers[0]
254253

255254
let [l:start_lnum, l:start_col, l:end_lnum, l:end_col] = s:get_visual_selection_pos()
255+
let l:start_char = lsp#utils#to_char('%', l:start_lnum, l:start_col)
256+
let l:end_char = lsp#utils#to_char('%', l:end_lnum, l:end_col)
257+
redraw | echo 'Formatting document range ...'
256258
call lsp#send_request(l:server, {
257259
\ 'method': 'textDocument/rangeFormatting',
258260
\ 'params': {
259261
\ 'textDocument': lsp#get_text_document_identifier(),
260262
\ 'range': {
261-
\ 'start': { 'line': l:start_lnum - 1, 'character': l:start_col - 1 },
262-
\ 'end': { 'line': l:end_lnum - 1, 'character': l:end_col - 1 },
263+
\ 'start': { 'line': l:start_lnum - 1, 'character': l:start_char },
264+
\ 'end': { 'line': l:end_lnum - 1, 'character': l:end_char },
263265
\ },
264266
\ 'options': {
265267
\ 'tabSize': getbufvar(bufnr('%'), '&shiftwidth'),
@@ -269,8 +271,6 @@ function! s:document_format_range(sync) abort
269271
\ 'sync': a:sync,
270272
\ 'on_notification': function('s:handle_text_edit', [l:server, s:last_req_id, 'range format']),
271273
\ })
272-
273-
echo 'Formatting document range ...'
274274
endfunction
275275

276276
function! lsp#ui#vim#document_range_format_sync() abort
@@ -349,9 +349,11 @@ function! s:get_visual_selection_range() abort
349349
if l:column_end - 1 > len(getline(l:line_end))
350350
let l:column_end = len(getline(l:line_end)) + 1
351351
endif
352+
let l:char_start = lsp#utils#to_char('%', l:line_start, l:column_start)
353+
let l:char_end = lsp#utils#to_char('%', l:line_end, l:column_end)
352354
return {
353-
\ 'start': { 'line': l:line_start - 1, 'character': l:column_start - 1 },
354-
\ 'end': { 'line': l:line_end - 1, 'character': l:column_end - 1 },
355+
\ 'start': { 'line': l:line_start - 1, 'character': l:char_start },
356+
\ 'end': { 'line': l:line_end - 1, 'character': l:char_end },
355357
\}
356358
endfunction
357359

@@ -486,7 +488,7 @@ function! s:handle_location(ctx, server, type, data) abort "ctx = {counter, list
486488
botright copen
487489
else
488490
let l:lines = readfile(fnameescape(l:loc['filename']))
489-
call lsp#ui#vim#output#preview(l:lines, {
491+
call lsp#ui#vim#output#preview(a:server, l:lines, {
490492
\ 'statusline': ' LSP Peek ' . a:type,
491493
\ 'cursor': { 'line': l:loc['lnum'], 'col': l:loc['col'], 'align': g:lsp_peek_alignment },
492494
\ 'filetype': &filetype
@@ -508,14 +510,24 @@ function! s:handle_rename_prepare(server, last_req_id, type, data) abort
508510

509511
let l:range = a:data['response']['result']
510512
let l:lines = getline(1, '$')
511-
if l:range['start']['line'] ==# l:range['end']['line']
512-
let l:name = l:lines[l:range['start']['line']][l:range['start']['character'] : l:range['end']['character']-1]
513+
let l:start_line = l:range['start']['line'] + 1
514+
let l:start_char = l:range['start']['character']
515+
let l:start_col = lsp#utils#to_col('%', l:start_line, l:start_char)
516+
let l:end_line = l:range['end']['line'] + 1
517+
let l:end_char = l:range['end']['character']
518+
let l:end_col = lsp#utils#to_col('%', l:end_line, l:end_char)
519+
if l:start_line ==# l:end_line
520+
let l:name = l:lines[l:start_line - 1][l:start_col - 1 : l:end_col - 2]
513521
else
514-
let l:name = l:lines[l:range['start']['line']][l:range['start']['character'] :]
515-
for l:i in range(l:range['start']['line']+1, l:range['end']['line']-1)
522+
let l:name = l:lines[l:start_line - 1][l:start_col - 1 :]
523+
for l:i in range(l:start_line, l:end_line - 2)
516524
let l:name .= "\n" . l:lines[l:i]
517525
endfor
518-
let l:name .= l:lines[l:range['end']['line']][: l:range['end']['character']-1]
526+
if l:end_col - 2 < 0
527+
let l:name .= "\n"
528+
else
529+
let l:name .= l:lines[l:end_line - 1][: l:end_col - 2]
530+
endif
519531
endif
520532

521533
call timer_start(1, {x->s:rename(a:server, input('new name: ', l:name), l:range['start'])})
@@ -548,7 +560,7 @@ function! s:handle_text_edit(server, last_req_id, type, data) abort
548560

549561
call lsp#utils#text_edit#apply_text_edits(a:data['request']['params']['textDocument']['uri'], a:data['response']['result'])
550562

551-
echo 'Document formatted'
563+
redraw | echo 'Document formatted'
552564
endfunction
553565

554566
function! s:handle_code_action(server, last_req_id, type, data) abort

autoload/lsp/ui/vim/diagnostics.vim

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ function! lsp#ui#vim#diagnostics#document_diagnostics() abort
5151
endif
5252
endfunction
5353

54+
" Returns a diagnostic object, or empty dictionary if no diagnostics are available.
55+
"
56+
" Note: Consider renaming this method (s/diagnostics/diagnostic) to make
57+
" it clear that it returns just one diagnostic, not a list.
5458
function! lsp#ui#vim#diagnostics#get_diagnostics_under_cursor() abort
5559
let l:diagnostics = s:get_all_buffer_diagnostics()
5660
if !len(l:diagnostics)
@@ -60,7 +64,7 @@ function! lsp#ui#vim#diagnostics#get_diagnostics_under_cursor() abort
6064
let l:line = line('.')
6165
let l:col = col('.')
6266

63-
let l:closest_diagnostics = {}
67+
let l:closest_diagnostic = {}
6468
let l:closest_distance = -1
6569

6670
for l:diagnostic in l:diagnostics
@@ -72,13 +76,13 @@ function! lsp#ui#vim#diagnostics#get_diagnostics_under_cursor() abort
7276
if l:line == l:start_line
7377
let l:distance = abs(l:start_col - l:col)
7478
if l:closest_distance < 0 || l:distance < l:closest_distance
75-
let l:closest_diagnostics = l:diagnostic
79+
let l:closest_diagnostic = l:diagnostic
7680
let l:closest_distance = l:distance
7781
endif
7882
endif
7983
endfor
8084

81-
return l:closest_diagnostics
85+
return l:closest_diagnostic
8286
endfunction
8387

8488
function! lsp#ui#vim#diagnostics#next_error() abort

0 commit comments

Comments
 (0)