summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Parise <jon@indelible.org>2021-09-04 18:07:53 -0700
committerGitHub <noreply@github.com>2021-09-05 10:07:53 +0900
commit8fd23f4b716a36a0a4b56ae34f6e6a4ab8979045 (patch)
treee8ed6b3272a0475469fc9be8f01cadf9a2bfebbb
parentb9fdb91e9294b091a56a9da0b8ae705490cd95c6 (diff)
downloadale-8fd23f4b716a36a0a4b56ae34f6e6a4ab8979045.zip
Introduce an ALELSPStarted autocommand (#3878)
This User autocommand is trigged immediately after an LSP process is successfully initialized. This provides a way to perform any additional initialization work, such as setting up buffer-level mappings.
-rw-r--r--autoload/ale/lsp_linter.vim24
-rw-r--r--doc/ale.txt7
-rw-r--r--test/lsp/test_lsp_startup.vader93
3 files changed, 102 insertions, 22 deletions
diff --git a/autoload/ale/lsp_linter.vim b/autoload/ale/lsp_linter.vim
index b8885f31..ad181912 100644
--- a/autoload/ale/lsp_linter.vim
+++ b/autoload/ale/lsp_linter.vim
@@ -271,6 +271,30 @@ function! ale#lsp_linter#OnInit(linter, details, Callback) abort
call ale#lsp#NotifyForChanges(l:conn_id, l:buffer)
endif
+ " Tell the relevant buffer that the LSP has started via an autocmd.
+ if l:buffer > 0
+ if l:buffer == bufnr('')
+ silent doautocmd <nomodeline> User ALELSPStarted
+ else
+ execute 'augroup ALELSPStartedGroup' . l:buffer
+ autocmd!
+
+ execute printf(
+ \ 'autocmd BufEnter <buffer=%d>'
+ \ . ' doautocmd <nomodeline> User ALELSPStarted',
+ \ l:buffer
+ \)
+
+ " Replicate ++once behavior for backwards compatibility.
+ execute printf(
+ \ 'autocmd BufEnter <buffer=%d>'
+ \ . ' autocmd! ALELSPStartedGroup%d',
+ \ l:buffer, l:buffer
+ \)
+ augroup END
+ endif
+ endif
+
call a:Callback(a:linter, a:details)
endfunction
diff --git a/doc/ale.txt b/doc/ale.txt
index 351c34ce..ddcc9d3f 100644
--- a/doc/ale.txt
+++ b/doc/ale.txt
@@ -4308,6 +4308,13 @@ ALEJobStarted *ALEJobStarted-autocmd*
|ale#engine#IsCheckingBuffer()| over |ALELintPre-autocmd|, which is actually
triggered before any linters are executed.
+ALELSPStarted *ALELSPStarted-autocmd*
+ *ALELSPStarted*
+
+ This |User| autocommand is trigged immediately after an LSP connection is
+ successfully initialized. This provides a way to perform any additional
+ initialization work, such as setting up buffer-level mappings.
+
ALEWantResults *ALEWantResults-autocmd*
*ALEWantResults*
diff --git a/test/lsp/test_lsp_startup.vader b/test/lsp/test_lsp_startup.vader
index cd9b59dd..f0afe39c 100644
--- a/test/lsp/test_lsp_startup.vader
+++ b/test/lsp/test_lsp_startup.vader
@@ -14,6 +14,7 @@ Before:
let g:job_map = {}
let g:emulate_job_failure = 0
let g:next_job_id = 1
+ let g:lsp_started = 0
let g:socket_map = {}
let g:emulate_socket_failure = 0
@@ -102,17 +103,17 @@ Before:
call ale#lsp#HandleMessage(l:conn_id, l:data)
endfunction
- function! Start() abort
+ function! Start(buffer) abort
let l:linter = values(ale#linter#GetLintersLoaded())[0][0]
return ale#lsp_linter#StartLSP(
- \ bufnr(''),
+ \ a:buffer,
\ l:linter,
\ {linter, details -> add(g:calls, [linter.name, details])},
\)
endfunction
- function! AssertInitSuccess(linter_name, conn_prefix, language, root, command) abort
+ function! AssertInitSuccess(linter_name, conn_prefix, language, root, command, buffer) abort
let l:messages = PopMessages()
if a:linter_name is# 'tsserver'
@@ -121,7 +122,7 @@ Before:
\ {
\ 'seq': v:null,
\ 'arguments': {
- \ 'file': expand('%:p'),
+ \ 'file': expand('#' . a:buffer . ':p'),
\ },
\ 'type': 'request',
\ 'command': 'open',
@@ -252,7 +253,7 @@ Before:
\ 'jsonrpc': '2.0',
\ 'params': {
\ 'textDocument': {
- \ 'uri': ale#path#ToURI(expand('%:p')),
+ \ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ 'version': ale#lsp#message#GetNextVersionID() - 1,
\ 'languageId': a:language,
\ 'text': "\n",
@@ -270,8 +271,8 @@ Before:
\ {
\ 'connection_id': a:conn_prefix . ':' . a:root,
\ 'project_root': a:root,
- \ 'buffer': bufnr(''),
- \ 'command': !empty(a:command) ? ale#job#PrepareCommand(bufnr(''), a:command) : '',
+ \ 'buffer': a:buffer,
+ \ 'command': !empty(a:command) ? ale#job#PrepareCommand(a:buffer, a:command) : '',
\ },
\ ],
\ ],
@@ -297,6 +298,7 @@ After:
unlet! g:job_map
unlet! g:emulate_job_failure
unlet! g:next_job_id
+ unlet! g:lsp_started
unlet! g:socket_map
unlet! g:emulate_socket_failure
@@ -305,6 +307,12 @@ After:
unlet! g:message_buffer
unlet! g:calls
+ augroup VaderTest
+ autocmd!
+ augroup END
+
+ augroup! VaderTest
+
delfunction PopMessages
delfunction Start
delfunction AssertInitSuccess
@@ -317,15 +325,15 @@ After:
Execute(tsserver should be started correctly):
runtime ale_linters/typescript/tsserver.vim
- Assert Start()
- call AssertInitSuccess('tsserver', 'tsserver', '', '', ale#Escape('tsserver'))
+ Assert Start(bufnr(''))
+ call AssertInitSuccess('tsserver', 'tsserver', '', '', ale#Escape('tsserver'), bufnr(''))
Execute(tsserver failures should be handled appropriately):
runtime ale_linters/typescript/tsserver.vim
let g:emulate_job_failure = 1
- Assert !Start()
+ Assert !Start(bufnr(''))
call AssertInitFailure()
Execute(LSP jobs should start correctly):
@@ -338,8 +346,8 @@ Execute(LSP jobs should start correctly):
\ 'initialization_options': {},
\})
- Assert Start()
- call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', 'foo')
+ Assert Start(bufnr(''))
+ call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', 'foo', bufnr(''))
Execute(LSP job failures should be handled):
call ale#linter#Define('foobar', {
@@ -353,7 +361,7 @@ Execute(LSP job failures should be handled):
let g:emulate_job_failure = 1
- Assert !Start()
+ Assert !Start(bufnr(''))
call AssertInitFailure()
Execute(LSP TCP connections should start correctly):
@@ -365,8 +373,8 @@ Execute(LSP TCP connections should start correctly):
\ 'initialization_options': {},
\})
- Assert Start()
- call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', '')
+ Assert Start(bufnr(''))
+ call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', '', bufnr(''))
Execute(LSP TCP connection failures should be handled):
call ale#linter#Define('foobar', {
@@ -379,7 +387,7 @@ Execute(LSP TCP connection failures should be handled):
let g:emulate_socket_failure = 1
- Assert !Start()
+ Assert !Start(bufnr(''))
call AssertInitFailure()
Execute(Deferred executables should be handled correctly):
@@ -392,9 +400,9 @@ Execute(Deferred executables should be handled correctly):
\ 'initialization_options': {},
\})
- Assert Start()
+ Assert Start(bufnr(''))
call ale#test#FlushJobs()
- call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', ale#Escape('foo') . ' -c')
+ call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', ale#Escape('foo') . ' -c', bufnr(''))
Execute(Deferred commands should be handled correctly):
call ale#linter#Define('foobar', {
@@ -406,9 +414,9 @@ Execute(Deferred commands should be handled correctly):
\ 'initialization_options': {},
\})
- Assert Start()
+ Assert Start(bufnr(''))
call ale#test#FlushJobs()
- call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', ale#Escape('foo') . ' -c')
+ call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', ale#Escape('foo') . ' -c', bufnr(''))
Execute(Deferred addresses should be handled correctly):
call ale#linter#Define('foobar', {
@@ -419,9 +427,9 @@ Execute(Deferred addresses should be handled correctly):
\ 'initialization_options': {},
\})
- Assert Start()
+ Assert Start(bufnr(''))
call ale#test#FlushJobs()
- call AssertInitSuccess('foo', 'localhost:1234', 'foobar', '/foo/bar', '')
+ call AssertInitSuccess('foo', 'localhost:1234', 'foobar', '/foo/bar', '', bufnr(''))
Execute(Servers that have crashed should be restarted):
call ale#lsp#Register('foo', '/foo/bar', {})
@@ -432,3 +440,44 @@ Execute(Servers that have crashed should be restarted):
AssertEqual 0, ale#lsp#GetConnections()['foo:/foo/bar']['initialized']
AssertEqual ['initialize'], map(PopMessages(), 'v:val[''method'']')
+
+Execute(Current LSP buffer should receive ALELSPStarted):
+ call ale#linter#Define('foobar', {
+ \ 'name': 'foo',
+ \ 'lsp': 'socket',
+ \ 'address': 'foo',
+ \ 'project_root': '/foo/bar',
+ \ 'initialization_options': {},
+ \})
+
+ augroup VaderTest
+ autocmd!
+ autocmd User ALELSPStarted let g:lsp_started = 1
+ augroup END
+
+ Assert Start(bufnr(''))
+ call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', '', bufnr(''))
+ AssertEqual g:lsp_started, 1
+
+Execute(Target LSP buffer should receive ALELSPStarted):
+ call ale#linter#Define('foobar', {
+ \ 'name': 'foo',
+ \ 'lsp': 'socket',
+ \ 'address': 'foo',
+ \ 'project_root': '/foo/bar',
+ \ 'initialization_options': {},
+ \})
+
+ augroup VaderTest
+ autocmd!
+ autocmd User ALELSPStarted let g:lsp_started = 1
+ augroup END
+
+ let buffer = bufnr('')
+
+ enew!
+ Assert Start(buffer)
+ call AssertInitSuccess('foo', 'foo', 'foobar', '/foo/bar', '', buffer)
+ execute 'buffer' . buffer
+
+ AssertEqual g:lsp_started, 1