Support show message notification by handling window/showMessage response (#1120)

* support window/showMessage

* describe g:lsp_show_message_log_level in documentation

* add tests for window/showMessage support

Co-authored-by: mattn <mattn.jp@gmail.com>
This commit is contained in:
Linda_pp
2021-03-28 21:58:20 +09:00
committed by GitHub
parent 7d7ded98dd
commit 800c878209
5 changed files with 181 additions and 0 deletions

View File

@@ -63,6 +63,7 @@ function! lsp#enable() abort
call lsp#internal#diagnostics#_enable()
call lsp#internal#document_code_action#signs#_enable()
call lsp#internal#show_message_request#_enable()
call lsp#internal#show_message#_enable()
call lsp#internal#work_done_progress#_enable()
call lsp#internal#completion#documentation#_enable()
call s:register_events()
@@ -78,6 +79,7 @@ function! lsp#disable() abort
call lsp#internal#diagnostics#_disable()
call lsp#internal#document_code_action#signs#_disable()
call lsp#internal#show_message_request#_disable()
call lsp#internal#show_message#_disable()
call lsp#internal#work_done_progress#_disable()
call lsp#internal#completion#documentation#_disable()
call s:unregister_events()

View File

@@ -0,0 +1,74 @@
let s:ErrorType = 1
let s:WarningType = 2
let s:InfoType = 3
let s:LogType = 4
function! lsp#internal#show_message#_enable() abort
if g:lsp_show_message_log_level ==# 'none' | return | endif
let s:Dispose = lsp#callbag#pipe(
\ lsp#stream(),
\ lsp#callbag#filter({x->
\ g:lsp_show_message_log_level !=# 'none' &&
\ has_key(x, 'response') && has_key(x['response'], 'method')
\ && x['response']['method'] ==# 'window/showMessage'
\ }),
\ lsp#callbag#tap({x->s:handle_show_message(x['server'], x['response']['params'])}),
\ lsp#callbag#subscribe({ 'error': function('s:on_error') }),
\ )
endfunction
function! lsp#internal#show_message#_disable() abort
if exists('s:Dispose')
call s:Dispose()
unlet s:Dispose
endif
endfunction
function! s:on_error(e) abort
call lsp#log('lsp#internal#show_message error', a:e)
if exists('s:Dispose')
call s:Dispose()
unlet s:Dispose
endif
endfunction
function! s:handle_show_message(server, params) abort
let l:level = s:name_to_level(g:lsp_show_message_log_level)
let l:type = a:params['type']
if l:level < l:type
return
endif
let l:message = a:params['message']
try
if l:type == s:ErrorType
echohl ErrorMsg
elseif l:type == s:WarningType
echohl WarningMsg
endif
echom printf('%s: %s: %s', a:server, s:type_to_name(l:type), l:message)
finally
echohl None
endtry
endfunction
function! s:name_to_level(name) abort
if a:name ==# 'none'
return 0
elseif a:name ==# 'error'
return s:ErrorType
elseif a:name ==# 'warn' || a:name ==# 'warning'
return s:WarningType
elseif a:name ==# 'info'
return s:InfoType
elseif a:name ==# 'log'
return s:LogType
else
return 0
endif
endfunction
function! s:type_to_name(type) abort
return get(['unknown', 'error', 'warning', 'info', 'log'], a:type, 'unknown')
endfunction

View File

@@ -73,6 +73,7 @@ CONTENTS *vim-lsp-contents*
g:lsp_tagfunc_source_methods |g:lsp_tagfunc_source_methods|
g:lsp_show_message_request_enabled |g:lsp_show_message_request_enabled|
g:lsp_work_done_progress_enabled |g:lsp_work_done_progress_enabled|
g:lsp_show_message_log_level |g:lsp_show_message_log_level|
Functions |vim-lsp-functions|
lsp#enable |lsp#enable()|
lsp#disable |lsp#disable()|
@@ -913,6 +914,17 @@ g:lsp_work_done_progress_enabled *g:lsp_work_done_progress_enabled*
notifications. This can be intercepted by listening to |lsp#stream()|.
Set to `1` to enable.
g:lsp_show_message_log_level *g:lsp_show_message_log_level*
Type: |String|
Default: `'warning'`
Determines log level of messages sent from LSP servers. Possible values
are one of `'none'`, `'error'`, `'warning'`, `'info'`, `'log'`. Messages
are filtered by the value set to this variable. For example, when
`'warning'` is set, `'error'` level and `'warning'` level messages are
shown but `'info'` level and `'log'` level messages are not shown. Setting
`'none'` disables to show messages completely.
==============================================================================
FUNCTIONS *vim-lsp-functions*

View File

@@ -64,6 +64,7 @@ let g:lsp_text_document_did_save_delay = get(g:, 'lsp_text_document_did_save_del
let g:lsp_completion_resolve_timeout = get(g:, 'lsp_completion_resolve_timeout', 200)
let g:lsp_tagfunc_source_methods = get(g:, 'lsp_tagfunc_source_methods', ['definition', 'declaration', 'implementation', 'typeDefinition'])
let g:lsp_show_message_request_enabled = get(g:, 'lsp_show_message_request_enabled', 1)
let g:lsp_show_message_log_level = get(g:, 'lsp_show_message_log_level', 'warning')
let g:lsp_work_done_progress_enabled = get(g:, 'lsp_work_done_progress_enabled', 0)
let g:lsp_get_supported_capabilities = get(g:, 'lsp_get_supported_capabilities', [function('lsp#default_get_supported_capabilities')])

View File

@@ -0,0 +1,92 @@
let s:Error = 1
let s:Warn = 2
let s:Info = 3
let s:Log = 4
function! s:response(type, message) abort
return {
\ 'server': 'server1',
\ 'response': {
\ 'method': 'window/showMessage',
\ 'params': {
\ 'type': a:type,
\ 'message': a:message
\ }
\ }
\ }
endfunction
Describe lsp#internal#show_message
Before
%bwipeout!
let g:lsp_show_message_log_level = 'warning'
call lsp#internal#show_message#_disable()
call lsp#internal#show_message#_enable()
End
After all
%bwipeout!
let g:lsp_show_message_log_level = 'none'
call lsp#internal#show_message#_disable()
End
It should show all messages when 'log' is set to g:lsp_show_message_log_level
let g:lsp_show_message_log_level = 'log'
redir => message_area
call lsp#stream(1, s:response(s:Error, 'error message'))
call lsp#stream(1, s:response(s:Warn, 'warn message'))
call lsp#stream(1, s:response(s:Info, 'info message'))
call lsp#stream(1, s:response(s:Log, 'log message'))
call lsp#stream(1, s:response(s:Info, 'info message2'))
call lsp#stream(1, s:response(s:Info, 'info message3'))
redir END
Assert Match(message_area, 'server1: error: error message')
Assert Match(message_area, 'server1: warning: warn message')
Assert Match(message_area, 'server1: info: info message')
Assert Match(message_area, 'server1: log: log message')
Assert Match(message_area, 'server1: info: info message2')
Assert Match(message_area, 'server1: info: info message3')
End
It should filter shown messages by log level set to g:lsp_show_message_log_level
let g:lsp_show_message_log_level = 'warning'
redir => message_area
call lsp#stream(1, s:response(s:Error, 'error message'))
call lsp#stream(1, s:response(s:Warn, 'warn message'))
call lsp#stream(1, s:response(s:Info, 'info message'))
call lsp#stream(1, s:response(s:Log, 'log message'))
call lsp#stream(1, s:response(s:Info, 'info message2'))
call lsp#stream(1, s:response(s:Info, 'info message3'))
redir END
Assert Match(message_area, 'server1: error: error message')
Assert Match(message_area, 'server1: warning: warn message')
Assert NotMatch(message_area, 'server1: info: info message')
Assert NotMatch(message_area, 'server1: log: log message')
Assert NotMatch(message_area, 'server1: info: info message2')
Assert NotMatch(message_area, 'server1: info: info message3')
End
It should show no message when 'none' is set to g:lsp_show_message_log_level
let g:lsp_show_message_log_level = 'none'
redir => message_area
call lsp#stream(1, s:response(s:Error, 'error message'))
call lsp#stream(1, s:response(s:Warn, 'warn message'))
call lsp#stream(1, s:response(s:Info, 'info message'))
call lsp#stream(1, s:response(s:Log, 'log message'))
call lsp#stream(1, s:response(s:Info, 'info message2'))
call lsp#stream(1, s:response(s:Info, 'info message3'))
redir END
Assert NotMatch(message_area, 'server1: error: error message')
Assert NotMatch(message_area, 'server1: warning: warn message')
Assert NotMatch(message_area, 'server1: info: info message')
Assert NotMatch(message_area, 'server1: log: log message')
Assert NotMatch(message_area, 'server1: info: info message2')
Assert NotMatch(message_area, 'server1: info: info message3')
End
End