summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ale_linters/javascript/eslint.vim18
-rw-r--r--autoload/ale/engine.vim5
-rw-r--r--autoload/ale/highlight.vim2
-rw-r--r--autoload/ale/job.vim2
-rw-r--r--autoload/ale/lsp.vim32
-rw-r--r--test/handler/test_eslint_handler.vader58
-rw-r--r--test/test_highlight_placement.vader13
-rw-r--r--test/test_loclist_corrections.vader36
8 files changed, 143 insertions, 23 deletions
diff --git a/ale_linters/javascript/eslint.vim b/ale_linters/javascript/eslint.vim
index d5e51acb..f1c3bb01 100644
--- a/ale_linters/javascript/eslint.vim
+++ b/ale_linters/javascript/eslint.vim
@@ -39,6 +39,13 @@ function! ale_linters#javascript#eslint#GetCommand(buffer) abort
\ . ' -f unix --stdin --stdin-filename %s'
endfunction
+let s:col_end_patterns = [
+\ '\vParsing error: Unexpected token (.+) ',
+\ '\v''(.+)'' is not defined.',
+\ '\v%(Unexpected|Redundant use of) [''`](.+)[''`]',
+\ '\vUnexpected (console) statement',
+\]
+
function! ale_linters#javascript#eslint#Handle(buffer, lines) abort
let l:config_error_pattern = '\v^ESLint couldn''t find a configuration file'
\ . '|^Cannot read config file'
@@ -77,13 +84,18 @@ function! ale_linters#javascript#eslint#Handle(buffer, lines) abort
let l:text .= ' [' . l:match[4] . ']'
endif
- call add(l:output, {
- \ 'bufnr': a:buffer,
+ let l:obj = {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:text,
\ 'type': l:type ==# 'Warning' ? 'W' : 'E',
- \})
+ \}
+
+ for l:col_match in ale#util#GetMatches(l:text, s:col_end_patterns)
+ let l:obj.end_col = l:obj.col + len(l:col_match[1]) - 1
+ endfor
+
+ call add(l:output, l:obj)
endfor
return l:output
diff --git a/autoload/ale/engine.vim b/autoload/ale/engine.vim
index c778f253..49cc2a9a 100644
--- a/autoload/ale/engine.vim
+++ b/autoload/ale/engine.vim
@@ -288,6 +288,11 @@ function! ale#engine#FixLocList(buffer, linter, loclist) abort
let l:item.detail = l:old_item.detail
endif
+ " Pass on a col_length key if set, used for highlights.
+ if has_key(l:old_item, 'end_col')
+ let l:item.end_col = str2nr(l:old_item.end_col)
+ endif
+
if l:item.lnum == 0
" When errors appear at line 0, put them at line 1 instead.
let l:item.lnum = 1
diff --git a/autoload/ale/highlight.vim b/autoload/ale/highlight.vim
index f3a479e3..4ac1d1e4 100644
--- a/autoload/ale/highlight.vim
+++ b/autoload/ale/highlight.vim
@@ -86,7 +86,7 @@ function! ale#highlight#UpdateHighlights() abort
let l:col = l:item.col
let l:group = l:item.type ==# 'E' ? 'ALEError' : 'ALEWarning'
let l:line = l:item.lnum
- let l:size = 1
+ let l:size = has_key(l:item, 'end_col') ? l:item.end_col - l:col + 1 : 1
" Rememeber the match ID for the item.
" This ID will be used to preserve loclist items which are set
diff --git a/autoload/ale/job.vim b/autoload/ale/job.vim
index d0572f51..11a36045 100644
--- a/autoload/ale/job.vim
+++ b/autoload/ale/job.vim
@@ -220,7 +220,7 @@ function! ale#job#SendRaw(job_id, string) abort
if has('nvim')
call jobsend(a:job_id, a:string)
else
- call ch_sendraw(job_getchannel(s:job_map[a:job_id]), a:string)
+ call ch_sendraw(job_getchannel(s:job_map[a:job_id].job), a:string)
endif
endfunction
diff --git a/autoload/ale/lsp.vim b/autoload/ale/lsp.vim
index acf47408..36620228 100644
--- a/autoload/ale/lsp.vim
+++ b/autoload/ale/lsp.vim
@@ -160,22 +160,28 @@ function! ale#lsp#SendMessageToProgram(executable, command, message, ...) abort
let [l:id, l:data] = ale#lsp#CreateMessageData(a:message)
let l:matches = filter(s:connections[:], 'v:val.executable ==# a:executable')
-
- if empty(l:matches)
- " We haven't looked at this executable before.
- " Create a new connection.
- let l:conn = NewConnection()
- endif
+ " Get the current connection or a new one.
+ let l:conn = !empty(l:matches) ? l:matches[0] : s:NewConnection()
if !ale#job#IsRunning(l:conn.job_id)
- let l:options = {'mode': 'raw', 'out_cb': 's:HandleCommandMessage'}
+ let l:options = {
+ \ 'mode': 'raw',
+ \ 'out_cb': function('s:HandleCommandMessage'),
+ \}
let l:job_id = ale#job#Start(ale#job#PrepareCommand(a:command), l:options)
endif
- if l:job_id > 0
+ if l:job_id <= 0
return 0
endif
+ " The ID is 0 when the message is a Notification, which is a JSON-RPC
+ " request for which the server must not return a response.
+ if l:id != 0
+ " Add the callback, which the server will respond to later.
+ let l:conn.callback_map[l:id] = a:1
+ endif
+
call ale#job#SendRaw(l:job_id, l:data)
let l:conn.job_id = l:job_id
@@ -201,18 +207,14 @@ function! ale#lsp#SendMessageToAddress(address, message, ...) abort
let [l:id, l:data] = ale#lsp#CreateMessageData(a:message)
let l:matches = filter(s:connections[:], 'v:val.address ==# a:address')
-
- if empty(l:matches)
- " We haven't looked at this address before.
- " Create a new connection.
- let l:conn = NewConnection()
- endif
+ " Get the current connection or a new one.
+ let l:conn = !empty(l:matches) ? l:matches[0] : s:NewConnection()
if !has_key(l:conn, 'channel') || ch_status(l:conn.channel) !=# 'open'
let l:conn.channnel = ch_open(a:address, {
\ 'mode': 'raw',
\ 'waittime': 0,
- \ 'callback': 's:HandleChannelMessage',
+ \ 'callback': function('s:HandleChannelMessage'),
\})
endif
diff --git a/test/handler/test_eslint_handler.vader b/test/handler/test_eslint_handler.vader
index 6d84ff7e..9d5e98fc 100644
--- a/test/handler/test_eslint_handler.vader
+++ b/test/handler/test_eslint_handler.vader
@@ -5,21 +5,18 @@ Execute(The eslint handler should parse lines correctly):
AssertEqual
\ [
\ {
- \ 'bufnr': 347,
\ 'lnum': 47,
\ 'col': 14,
\ 'text': 'Missing trailing comma. [Warning/comma-dangle]',
\ 'type': 'W',
\ },
\ {
- \ 'bufnr': 347,
\ 'lnum': 56,
\ 'col': 41,
\ 'text': 'Missing semicolon. [Error/semi]',
\ 'type': 'E',
\ },
\ {
- \ 'bufnr': 347,
\ 'lnum': 13,
\ 'col': 3,
\ 'text': 'Parsing error: Unexpected token',
@@ -117,3 +114,58 @@ Execute(The eslint handler should print a message for invalid configuration sett
\ 'detail': join(g:config_error_lines, "\n"),
\ }],
\ ale_linters#javascript#eslint#Handle(347, g:config_error_lines[:])
+
+Execute(The eslint handler should output end_col values where appropriate):
+ AssertEqual
+ \ [
+ \ {
+ \ 'lnum': 4,
+ \ 'col': 3,
+ \ 'end_col': 15,
+ \ 'text': 'Parsing error: Unexpected token ''some string'' [Error]',
+ \ 'type': 'E',
+ \ },
+ \ {
+ \ 'lnum': 70,
+ \ 'col': 3,
+ \ 'end_col': 5,
+ \ 'text': '''foo'' is not defined. [Error/no-undef]',
+ \ 'type': 'E',
+ \ },
+ \ {
+ \ 'lnum': 71,
+ \ 'col': 2,
+ \ 'end_col': 6,
+ \ 'text': 'Unexpected `await` inside a loop. [Error/no-await-in-loop]',
+ \ 'type': 'E',
+ \ },
+ \ {
+ \ 'lnum': 72,
+ \ 'col': 6,
+ \ 'end_col': 10,
+ \ 'text': 'Redundant use of `await` on a return value. [Error/no-return-await]',
+ \ 'type': 'E',
+ \ },
+ \ {
+ \ 'lnum': 73,
+ \ 'col': 4,
+ \ 'end_col': 10,
+ \ 'text': 'Unexpected console statement [Error/no-console]',
+ \ 'type': 'E',
+ \ },
+ \ {
+ \ 'lnum': 74,
+ \ 'col': 4,
+ \ 'end_col': 11,
+ \ 'text': 'Unexpected ''debugger'' statement. [Error/no-debugger]',
+ \ 'type': 'E',
+ \ },
+ \ ],
+ \ ale_linters#javascript#eslint#Handle(347, [
+ \ 'app.js:4:3: Parsing error: Unexpected token ''some string'' [Error]',
+ \ 'app.js:70:3: ''foo'' is not defined. [Error/no-undef]',
+ \ 'app.js:71:2: Unexpected `await` inside a loop. [Error/no-await-in-loop]',
+ \ 'app.js:72:6: Redundant use of `await` on a return value. [Error/no-return-await]',
+ \ 'app.js:73:4: Unexpected console statement [Error/no-console]',
+ \ 'app.js:74:4: Unexpected ''debugger'' statement. [Error/no-debugger]',
+ \ ])
diff --git a/test/test_highlight_placement.vader b/test/test_highlight_placement.vader
index 25c98784..b5878922 100644
--- a/test/test_highlight_placement.vader
+++ b/test/test_highlight_placement.vader
@@ -137,3 +137,16 @@ Execute(Only ALE highlights should be restored when buffers are restored):
" Only our matches should appear again.
AssertEqual 1, len(getmatches()), 'The highlights weren''t set again!'
+
+Execute(Higlight end columns should set an appropriate size):
+ call ale#highlight#SetHighlights(bufnr('%'), [
+ \ {'bufnr': bufnr('%'), 'type': 'E', 'lnum': 3, 'col': 2, 'end_col': 5},
+ \ {'bufnr': bufnr('%'), 'type': 'W', 'lnum': 4, 'col': 1, 'end_col': 5},
+ \])
+
+ AssertEqual
+ \ [
+ \ {'group': 'ALEError', 'id': 15, 'priority': 10, 'pos1': [3, 2, 4]},
+ \ {'group': 'ALEWarning', 'id': 16, 'priority': 10, 'pos1': [4, 1, 5]},
+ \ ],
+ \ getmatches()
diff --git a/test/test_loclist_corrections.vader b/test/test_loclist_corrections.vader
index 281f6787..8e01dfbc 100644
--- a/test/test_loclist_corrections.vader
+++ b/test/test_loclist_corrections.vader
@@ -128,3 +128,39 @@ Execute(FixLocList should convert line and column numbers correctly):
\ {'name': 'foobar'},
\ [{'text': 'a', 'lnum': '010', 'col': '010'}],
\ )
+
+Execute(FixLocList should pass on col_length values):
+ " The numbers should be 10, not 8 as octals.
+ AssertEqual
+ \ [
+ \ {
+ \ 'text': 'a',
+ \ 'lnum': 10,
+ \ 'col': 10,
+ \ 'end_col': 12,
+ \ 'bufnr': bufnr('%'),
+ \ 'vcol': 0,
+ \ 'type': 'E',
+ \ 'nr': -1,
+ \ 'linter_name': 'foobar',
+ \ },
+ \ {
+ \ 'text': 'a',
+ \ 'lnum': 10,
+ \ 'col': 11,
+ \ 'end_col': 12,
+ \ 'bufnr': bufnr('%'),
+ \ 'vcol': 0,
+ \ 'type': 'E',
+ \ 'nr': -1,
+ \ 'linter_name': 'foobar',
+ \ },
+ \],
+ \ ale#engine#FixLocList(
+ \ bufnr('%'),
+ \ {'name': 'foobar'},
+ \ [
+ \ {'text': 'a', 'lnum': '010', 'col': '010', 'end_col': '012'},
+ \ {'text': 'a', 'lnum': '010', 'col': '011', 'end_col': 12},
+ \ ],
+ \ )