Skip to content

Commit efff126

Browse files
clktmrthomasfaingnaert
authored andcommitted
Add lsp#formatexpr() (#528)
* Add <plug>(lsp-document-range-format) This binding defines an operator and can be used with a motion. Because s:document_format_range() did only format based on the visual selection markers, a new type parameter was added to pass the selection type according to 'opfunc'. * Denote mapmode for plug mappings and add missing
1 parent 19e5b08 commit efff126

File tree

3 files changed

+62
-41
lines changed

3 files changed

+62
-41
lines changed

autoload/lsp/ui/vim.vim

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -224,22 +224,34 @@ function! lsp#ui#vim#document_format() abort
224224
return s:document_format(0)
225225
endfunction
226226

227-
function! s:get_visual_selection_pos() abort
228-
" https://groups.google.com/d/msg/vim_dev/oCUQzO3y8XE/vfIMJiHCHtEJ
229-
" https://stackoverflow.com/a/6271254
230-
" getpos("'>'") doesn't give the right column so need to do extra processing
231-
let [line_start, column_start] = getpos("'<")[1:2]
232-
let [line_end, column_end] = getpos("'>")[1:2]
233-
let lines = getline(line_start, line_end)
234-
if len(lines) == 0
235-
return [0, 0, 0, 0]
236-
endif
237-
let lines[-1] = lines[-1][: column_end - (&selection ==# 'inclusive' ? 1 : 2)]
238-
let lines[0] = lines[0][column_start - 1:]
239-
return [line_start, column_start, line_end, len(lines[-1])]
227+
function! s:get_selection_pos(type) abort
228+
if a:type ==? 'v'
229+
let l:start_pos = getpos("'<")[1:2]
230+
let l:end_pos = getpos("'>")[1:2]
231+
" fix end_pos column (see :h getpos() and :h 'selection')
232+
let l:end_line = getline(l:end_pos[0])
233+
let l:offset = (&selection ==# 'inclusive' ? 1 : 2)
234+
let l:end_pos[1] = len(l:end_line[:l:end_pos[1]-l:offset])
235+
" edge case: single character selected with selection=exclusive
236+
if l:start_pos[0] == l:end_pos[0] && l:start_pos[1] > l:end_pos[1]
237+
let l:end_pos[1] = l:start_pos[1]
238+
endif
239+
elseif a:type ==? 'line'
240+
let l:start_pos = [line("'["), 1]
241+
let l:end_lnum = line("']")
242+
let l:end_pos = [line("']"), len(getline(l:end_lnum))]
243+
elseif a:type ==? 'char'
244+
let l:start_pos = getpos("'[")[1:2]
245+
let l:end_pos = getpos("']")[1:2]
246+
else
247+
let l:start_pos = [0, 0]
248+
let l:end_pos = [0, 0]
249+
endif
250+
251+
return l:start_pos + l:end_pos
240252
endfunction
241253

242-
function! s:document_format_range(sync) abort
254+
function! s:document_format_range(sync, type) abort
243255
let l:servers = filter(lsp#get_whitelisted_servers(), 'lsp#capabilities#has_document_range_formatting_provider(v:val)')
244256
let s:last_req_id = s:last_req_id + 1
245257

@@ -251,7 +263,7 @@ function! s:document_format_range(sync) abort
251263
" TODO: ask user to select server for formatting
252264
let l:server = l:servers[0]
253265

254-
let [l:start_lnum, l:start_col, l:end_lnum, l:end_col] = s:get_visual_selection_pos()
266+
let [l:start_lnum, l:start_col, l:end_lnum, l:end_col] = s:get_selection_pos(a:type)
255267
let l:start_char = lsp#utils#to_char('%', l:start_lnum, l:start_col)
256268
let l:end_char = lsp#utils#to_char('%', l:end_lnum, l:end_col)
257269
redraw | echo 'Formatting document range ...'
@@ -274,11 +286,15 @@ function! s:document_format_range(sync) abort
274286
endfunction
275287

276288
function! lsp#ui#vim#document_range_format_sync() abort
277-
return s:document_format_range(1)
289+
return s:document_format_range(1, visualmode())
278290
endfunction
279291

280292
function! lsp#ui#vim#document_range_format() abort
281-
return s:document_format_range(0)
293+
return s:document_format_range(0, visualmode())
294+
endfunction
295+
296+
function! lsp#ui#vim#document_range_format_opfunc(type) abort
297+
return s:document_format_range(1, a:type)
282298
endfunction
283299

284300
function! lsp#ui#vim#workspace_symbol() abort

doc/vim-lsp.txt

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -931,30 +931,33 @@ To map keys to the feature of vim-lsp, use <plug> mappings:
931931
<
932932
Available plug mappings are following:
933933

934-
(lsp-code-action)
935-
(lsp-declaration)
936-
(lsp-peek-declaration)
937-
(lsp-definition)
938-
(lsp-peek-definition)
939-
(lsp-document-symbol)
940-
(lsp-document-diagnostics)
941-
(lsp-hover)
942-
(lsp-next-error)
943-
(lsp-next-reference)
944-
(lsp-preview-close)
945-
(lsp-preview-focus)
946-
(lsp-previous-error)
947-
(lsp-previous-reference)
948-
(lsp-references)
949-
(lsp-rename)
950-
(lsp-workspace-symbol)
951-
(lsp-document-format)
952-
(lsp-document-format)
953-
(lsp-implementation)
954-
(lsp-peek-implementation)
955-
(lsp-type-definition)
956-
(lsp-peek-type-definition)
957-
(lsp-status)
934+
nnoremap <plug>(lsp-code-action)
935+
nnoremap <plug>(lsp-declaration)
936+
nnoremap <plug>(lsp-peek-declaration)
937+
nnoremap <plug>(lsp-definition)
938+
nnoremap <plug>(lsp-peek-definition)
939+
nnoremap <plug>(lsp-document-symbol)
940+
nnoremap <plug>(lsp-document-diagnostics)
941+
nnoremap <plug>(lsp-hover)
942+
nnoremap <plug>(lsp-next-error)
943+
nnoremap <plug>(lsp-next-reference)
944+
nnoremap <plug>(lsp-preview-close)
945+
nnoremap <plug>(lsp-preview-focus)
946+
nnoremap <plug>(lsp-previous-error)
947+
nnoremap <plug>(lsp-previous-reference)
948+
nnoremap <plug>(lsp-references)
949+
nnoremap <plug>(lsp-rename)
950+
nnoremap <plug>(lsp-workspace-symbol)
951+
nnoremap <plug>(lsp-document-format)
952+
vnoremap <plug>(lsp-document-format)
953+
nnoremap <plug>(lsp-document-range-format)
954+
xnoremap <plug>(lsp-document-range-format)
955+
nnoremap <plug>(lsp-implementation)
956+
nnoremap <plug>(lsp-peek-implementation)
957+
nnoremap <plug>(lsp-type-definition)
958+
nnoremap <plug>(lsp-peek-type-definition)
959+
nnoremap <plug>(lsp-status)
960+
nnoremap <plug>(lsp-signature-help)
958961

959962
See also |vim-lsp-commands|
960963

plugin/lsp.vim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ nnoremap <plug>(lsp-peek-type-definition) :<c-u>call lsp#ui#vim#type_definition(
9696
nnoremap <plug>(lsp-workspace-symbol) :<c-u>call lsp#ui#vim#workspace_symbol()<cr>
9797
nnoremap <plug>(lsp-document-format) :<c-u>call lsp#ui#vim#document_format()<cr>
9898
vnoremap <plug>(lsp-document-format) :<Home>silent <End>call lsp#ui#vim#document_range_format()<cr>
99+
nnoremap <plug>(lsp-document-range-format) :<c-u>set opfunc=lsp#ui#vim#document_range_format_opfunc<cr>g@
100+
xnoremap <plug>(lsp-document-range-format) :<Home>silent <End>call lsp#ui#vim#document_range_format()<cr>
99101
nnoremap <plug>(lsp-implementation) :<c-u>call lsp#ui#vim#implementation(0)<cr>
100102
nnoremap <plug>(lsp-peek-implementation) :<c-u>call lsp#ui#vim#implementation(1)<cr>
101103
nnoremap <plug>(lsp-status) :<c-u>echo lsp#get_server_status()<cr>

0 commit comments

Comments
 (0)