Skip to content

Commit

Permalink
Print workspace_config with :verbose LspStatus (#1279)
Browse files Browse the repository at this point in the history
* Make verbose LspStatus show workspace config

Need the trailing echo to ensure the next lsp server is on a new line.

* Use pretty printing if available

* checkhealth: Print server status and config

Add initial checkhealth support.
See https://github.com/rhysd/vim-healthcheck

Lists server status, advice for failure, and lists workspace config to
help debug issues or understand server state. Doesn't do much error
detecting.

* checkhealth: Print each server config as a section

checkhealth doesn't allow a lot of formatting (no indentation), so it's
hard to make the config output readable. Output each server as a
separate section instead of one giant config block to make the start of
each server easier to see.
  • Loading branch information
idbrii committed Oct 29, 2022
1 parent 9d4dbf7 commit 0c8fda7
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 2 deletions.
7 changes: 7 additions & 0 deletions README.md
Expand Up @@ -183,6 +183,13 @@ let g:lsp_log_file = expand('~/vim-lsp.log')
let g:asyncomplete_log_file = expand('~/asyncomplete.log')
```

You can get detailed status on your servers using `:CheckHealth` -- built into neovim or in a plugin on vim:

```vim
if !has('nvim') | Plug 'rhysd/vim-healthcheck' | endif
CheckHealth
```

## Tests

[vim-themis](https://github.com/thinca/vim-themis) is used for testing. To run
Expand Down
57 changes: 57 additions & 0 deletions autoload/health/lsp.vim
@@ -0,0 +1,57 @@
function! s:BuildConfigBlock(section, info) abort
let l:block = get(a:info, a:section, '')
if !empty(l:block)
return printf("### %s\n%s\n", a:section, l:block)
endif
return ''
endf


function! health#lsp#check() abort
call health#report_start('server status')
let l:server_status = lsp#collect_server_status()

let l:has_printed = v:false
for l:k in sort(keys(l:server_status))
let l:report = l:server_status[l:k]

let l:status_msg = printf('%s: %s', l:k, l:report.status)
if l:report.status == 'running'
call health#report_ok(l:status_msg)
elseif l:report.status == 'failed'
call health#report_error(l:status_msg, 'See :help g:lsp_log_verbose to debug server failure.')
else
call health#report_warn(l:status_msg)
endif
let l:has_printed = v:true
endfor

if !l:has_printed
call health#report_warn('no servers connected')
endif

for l:k in sort(keys(l:server_status))
call health#report_start(printf('server configuration: %s', l:k))
let l:report = l:server_status[l:k]

let l:msg = "\t\n"
let l:msg .= s:BuildConfigBlock('allowlist', l:report.info)
let l:msg .= s:BuildConfigBlock('blocklist', l:report.info)
let l:cfg = get(l:report.info, 'workspace_config', '')
if !empty(l:cfg)
if get(g:, 'loaded_scriptease', 0)
let l:cfg = scriptease#dump(l:cfg, {'width': &columns-1})
else
let l:cfg = json_encode(l:cfg)
" Add some whitespace to make it readable.
let l:cfg = substitute(l:cfg, '[,{(\[]', "&\n\t", 'g')
let l:cfg = substitute(l:cfg, '":', '& ', 'g')
let l:cfg = substitute(l:cfg, '\v[})\]]+', "\n&", 'g')
let l:cfg = substitute(l:cfg, '\n\s*\n', "\n", 'g')
endif
let l:msg .= printf("### workspace_config\n```json\n%s\n```", l:cfg)
endif
call health#report_info(l:msg)
endfor
endf

26 changes: 25 additions & 1 deletion autoload/lsp.vim
Expand Up @@ -148,7 +148,22 @@ let s:color_map = {
\ 'not running': 'Comment'
\}

" Print the current status of all servers (if called with no arguments)
" Collect the current status of all servers
function! lsp#collect_server_status() abort
let l:results = {}
for l:k in keys(s:servers)
let l:status = s:server_status(l:k)
" Copy to prevent callers from corrupting our config.
let l:info = deepcopy(s:servers[l:k].server_info)
let l:results[l:k] = {
\ 'status': l:status,
\ 'info': l:info,
\ }
endfor
return l:results
endfunction

" Print the current status of all servers
function! lsp#print_server_status() abort
for l:k in sort(keys(s:servers))
let l:status = s:server_status(l:k)
Expand All @@ -157,6 +172,15 @@ function! lsp#print_server_status() abort
echon l:status
echohl None
echo ''
if &verbose
let l:cfg = { 'workspace_config': s:servers[l:k].server_info.workspace_config }
if get(g:, 'loaded_scriptease', 0)
call scriptease#pp_command(0, -1, l:cfg)
else
echo json_encode(l:cfg)
endif
echo ''
endif
endfor
endfunction

Expand Down
12 changes: 11 additions & 1 deletion doc/vim-lsp.txt
Expand Up @@ -11,6 +11,7 @@ CONTENTS *vim-lsp-contents*
Configure |vim-lsp-configure|
vim-lsp-settings |vim-lsp-settings_plugin|
Wiki |vim-lsp-configure-wiki|
Health Check |vim-lsp-healthcheck|
Options |vim-lsp-options|
g:lsp_auto_enable |g:lsp_auto_enable|
g:lsp_preview_keep_focus |g:lsp_preview_keep_focus|
Expand Down Expand Up @@ -270,6 +271,13 @@ to automatically register various language servers.
Plug 'prabirshrestha/vim-lsp'
Plug 'mattn/vim-lsp-settings'
HEALTH CHECK *vim-lsp-healthcheck*
vim-lsp supports the |:CheckHealth| command which can be useful when debugging
lsp configuration issues.

This command is included in neovim and implemented in vim with the
[vim-healthcheck](https://github.com/rhysd/vim-healthcheck) plugin.

WIKI *vim-lsp-configure-wiki*
For documentation on how to configure other language servers refer
to https://github.com/prabirshrestha/vim-lsp/wiki/Servers
Expand Down Expand Up @@ -1778,7 +1786,9 @@ Servers may choose to return empty results if the search query is empty.

LspStatus *:LspStatus*

Prints the status of all registered servers.
Prints the status of all registered servers. Use `:verbose LspStatus` to
additionally show each server's workspace_config.
See also |vim-lsp-healthcheck|.

LspStopServer *:LspStopServer*

Expand Down

0 comments on commit 0c8fda7

Please sign in to comment.