mirror of
https://github.com/amix/vimrc
synced 2025-06-23 15:04:59 +08:00
Updated plugins
This commit is contained in:
@ -5,11 +5,18 @@
|
||||
" Strings used for severity in the echoed message
|
||||
let g:ale_echo_msg_error_str = get(g:, 'ale_echo_msg_error_str', 'Error')
|
||||
let g:ale_echo_msg_info_str = get(g:, 'ale_echo_msg_info_str', 'Info')
|
||||
let g:ale_echo_msg_log_str = get(g:, 'ale_echo_msg_log_str', 'Log')
|
||||
let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
|
||||
" Ignoring linters, for disabling some, or ignoring LSP diagnostics.
|
||||
let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {})
|
||||
let g:ale_disable_lsp = get(g:, 'ale_disable_lsp', 0)
|
||||
|
||||
" LSP window/showMessage format
|
||||
let g:ale_lsp_show_message_format = get(g:, 'ale_lsp_show_message_format', '%severity%:%linter%: %s')
|
||||
" Valid values mimic LSP definitions (error, warning and information; log is
|
||||
" never shown)
|
||||
let g:ale_lsp_show_message_severity = get(g:, 'ale_lsp_show_message_severity', 'error')
|
||||
|
||||
let s:lint_timer = -1
|
||||
let s:getcmdwintype_exists = exists('*getcmdwintype')
|
||||
|
||||
@ -156,7 +163,7 @@ function! ale#Queue(delay, ...) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let s:current_ale_version = [2, 5, 0]
|
||||
let s:current_ale_version = [2, 6, 0]
|
||||
|
||||
" A function used to check for ALE features in files outside of the project.
|
||||
function! ale#Has(feature) abort
|
||||
|
@ -267,14 +267,22 @@ function! ale#assert#TearDownLinterTest() abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#assert#SetUpFixerTest(filetype, name) abort
|
||||
function! ale#assert#SetUpFixerTest(filetype, name, ...) abort
|
||||
" If the suffix of the option names format is different, an additional
|
||||
" argument can be used for that instead.
|
||||
if a:0 > 1
|
||||
throw 'Too many arguments'
|
||||
endif
|
||||
|
||||
" Set up a marker so ALE doesn't create real random temporary filenames.
|
||||
let g:ale_create_dummy_temporary_file = 1
|
||||
|
||||
let l:function_name = ale#fix#registry#GetFunc(a:name)
|
||||
let s:FixerFunction = function(l:function_name)
|
||||
|
||||
let l:prefix = 'ale_' . a:filetype . '_' . a:name
|
||||
let l:option_suffix = get(a:000, 0, a:name)
|
||||
let l:prefix = 'ale_' . a:filetype . '_'
|
||||
\ . substitute(l:option_suffix, '-', '_', 'g')
|
||||
let b:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix'
|
||||
|
||||
for l:key in filter(keys(g:), b:filter_expr)
|
||||
@ -286,7 +294,7 @@ function! ale#assert#SetUpFixerTest(filetype, name) abort
|
||||
unlet b:[l:key]
|
||||
endfor
|
||||
|
||||
execute 'runtime autoload/ale/fixers/' . a:name . '.vim'
|
||||
execute 'runtime autoload/ale/fixers/' . substitute(a:name, '-', '_', 'g') . '.vim'
|
||||
|
||||
if !exists('g:dir')
|
||||
call ale#test#SetDirectory('/testplugin/test/fixers')
|
||||
|
@ -265,6 +265,16 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
|
||||
return l:empty
|
||||
endfunction
|
||||
|
||||
function! ale#c#GetCompileCommand(json_item) abort
|
||||
if has_key(a:json_item, 'command')
|
||||
return a:json_item.command
|
||||
elseif has_key(a:json_item, 'arguments')
|
||||
return join(a:json_item.arguments, ' ')
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
|
||||
" Search for an exact file match first.
|
||||
let l:basename = tolower(expand('#' . a:buffer . ':t'))
|
||||
@ -287,15 +297,14 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
|
||||
for l:item in l:file_list
|
||||
" Load the flags for this file, or for a source file matching the
|
||||
" header file.
|
||||
if has_key(l:item, 'command')
|
||||
\&& (
|
||||
if (
|
||||
\ bufnr(l:item.file) is a:buffer
|
||||
\ || (
|
||||
\ !empty(l:source_file)
|
||||
\ && l:item.file[-len(l:source_file):] is? l:source_file
|
||||
\ )
|
||||
\)
|
||||
return ale#c#ParseCFlags(l:item.directory, l:item.command)
|
||||
return ale#c#ParseCFlags(l:item.directory, ale#c#GetCompileCommand(l:item))
|
||||
endif
|
||||
endfor
|
||||
|
||||
@ -307,8 +316,7 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
|
||||
|
||||
for l:item in l:dir_list
|
||||
if ale#path#Simplify(fnamemodify(l:item.file, ':h')) is? l:dir
|
||||
\&& has_key(l:item, 'command')
|
||||
return ale#c#ParseCFlags(l:item.directory, l:item.command)
|
||||
return ale#c#ParseCFlags(l:item.directory, ale#c#GetCompileCommand(l:item))
|
||||
endif
|
||||
endfor
|
||||
|
||||
|
163
sources_non_forked/ale/autoload/ale/code_action.vim
Normal file
163
sources_non_forked/ale/autoload/ale/code_action.vim
Normal file
@ -0,0 +1,163 @@
|
||||
" Author: Jerko Steiner <jerko.steiner@gmail.com>
|
||||
" Description: Code action support for LSP / tsserver
|
||||
|
||||
function! ale#code_action#HandleCodeAction(code_action) abort
|
||||
let l:current_buffer = bufnr('')
|
||||
let l:changes = a:code_action.changes
|
||||
|
||||
for l:file_code_edit in l:changes
|
||||
let l:buf = bufnr(l:file_code_edit.fileName)
|
||||
|
||||
if l:buf != -1 && l:buf != l:current_buffer && getbufvar(l:buf, '&mod')
|
||||
call ale#util#Execute('echom ''Aborting action, file is unsaved''')
|
||||
|
||||
return
|
||||
endif
|
||||
endfor
|
||||
|
||||
for l:file_code_edit in l:changes
|
||||
call ale#code_action#ApplyChanges(
|
||||
\ l:file_code_edit.fileName, l:file_code_edit.textChanges)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#code_action#ApplyChanges(filename, changes) abort
|
||||
let l:current_buffer = bufnr('')
|
||||
" The buffer is used to determine the fileformat, if available.
|
||||
let l:buffer = bufnr(a:filename)
|
||||
let l:is_current_buffer = l:buffer > 0 && l:buffer == l:current_buffer
|
||||
|
||||
if l:buffer > 0
|
||||
let l:lines = getbufline(l:buffer, 1, '$')
|
||||
else
|
||||
let l:lines = readfile(a:filename, 'b')
|
||||
endif
|
||||
|
||||
if l:is_current_buffer
|
||||
let l:pos = getpos('.')[1:2]
|
||||
else
|
||||
let l:pos = [1, 1]
|
||||
endif
|
||||
|
||||
" We have to keep track of how many lines we have added, and offset
|
||||
" changes accordingly.
|
||||
let l:line_offset = 0
|
||||
let l:column_offset = 0
|
||||
let l:last_end_line = 0
|
||||
|
||||
for l:code_edit in a:changes
|
||||
if l:code_edit.start.line isnot l:last_end_line
|
||||
let l:column_offset = 0
|
||||
endif
|
||||
|
||||
let l:line = l:code_edit.start.line + l:line_offset
|
||||
let l:column = l:code_edit.start.offset + l:column_offset
|
||||
let l:end_line = l:code_edit.end.line + l:line_offset
|
||||
let l:end_column = l:code_edit.end.offset + l:column_offset
|
||||
let l:text = l:code_edit.newText
|
||||
|
||||
let l:cur_line = l:pos[0]
|
||||
let l:cur_column = l:pos[1]
|
||||
|
||||
let l:last_end_line = l:end_line
|
||||
|
||||
" Adjust the ends according to previous edits.
|
||||
if l:end_line > len(l:lines)
|
||||
let l:end_line_len = 0
|
||||
else
|
||||
let l:end_line_len = len(l:lines[l:end_line - 1])
|
||||
endif
|
||||
|
||||
let l:insertions = split(l:text, '\n', 1)
|
||||
|
||||
if l:line is 1
|
||||
" Same logic as for column below. Vimscript's slice [:-1] will not
|
||||
" be an empty list.
|
||||
let l:start = []
|
||||
else
|
||||
let l:start = l:lines[: l:line - 2]
|
||||
endif
|
||||
|
||||
if l:column is 1
|
||||
" We need to handle column 1 specially, because we can't slice an
|
||||
" empty string ending on index 0.
|
||||
let l:middle = [l:insertions[0]]
|
||||
else
|
||||
let l:middle = [l:lines[l:line - 1][: l:column - 2] . l:insertions[0]]
|
||||
endif
|
||||
|
||||
call extend(l:middle, l:insertions[1:])
|
||||
let l:middle[-1] .= l:lines[l:end_line - 1][l:end_column - 1 :]
|
||||
|
||||
let l:lines_before_change = len(l:lines)
|
||||
let l:lines = l:start + l:middle + l:lines[l:end_line :]
|
||||
|
||||
let l:current_line_offset = len(l:lines) - l:lines_before_change
|
||||
let l:line_offset += l:current_line_offset
|
||||
let l:column_offset = len(l:middle[-1]) - l:end_line_len
|
||||
|
||||
let l:pos = s:UpdateCursor(l:pos,
|
||||
\ [l:line, l:column],
|
||||
\ [l:end_line, l:end_column],
|
||||
\ [l:current_line_offset, l:column_offset])
|
||||
endfor
|
||||
|
||||
if l:lines[-1] is# ''
|
||||
call remove(l:lines, -1)
|
||||
endif
|
||||
|
||||
call ale#util#Writefile(l:buffer, l:lines, a:filename)
|
||||
|
||||
if l:is_current_buffer
|
||||
call ale#util#Execute(':e!')
|
||||
call setpos('.', [0, l:pos[0], l:pos[1], 0])
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:UpdateCursor(cursor, start, end, offset) abort
|
||||
let l:cur_line = a:cursor[0]
|
||||
let l:cur_column = a:cursor[1]
|
||||
let l:line = a:start[0]
|
||||
let l:column = a:start[1]
|
||||
let l:end_line = a:end[0]
|
||||
let l:end_column = a:end[1]
|
||||
let l:line_offset = a:offset[0]
|
||||
let l:column_offset = a:offset[1]
|
||||
|
||||
if l:end_line < l:cur_line
|
||||
" both start and end lines are before the cursor. only line offset
|
||||
" needs to be updated
|
||||
let l:cur_line += l:line_offset
|
||||
elseif l:end_line == l:cur_line
|
||||
" end line is at the same location as cursor, which means
|
||||
" l:line <= l:cur_line
|
||||
if l:line < l:cur_line || l:column <= l:cur_column
|
||||
" updates are happening either before or around the cursor
|
||||
if l:end_column < l:cur_column
|
||||
" updates are happening before the cursor, update the
|
||||
" column offset for cursor
|
||||
let l:cur_line += l:line_offset
|
||||
let l:cur_column += l:column_offset
|
||||
else
|
||||
" updates are happening around the cursor, move the cursor
|
||||
" to the end of the changes
|
||||
let l:cur_line += l:line_offset
|
||||
let l:cur_column = l:end_column + l:column_offset
|
||||
endif
|
||||
" else is not necessary, it means modifications are happening
|
||||
" after the cursor so no cursor updates need to be done
|
||||
endif
|
||||
else
|
||||
" end line is after the cursor
|
||||
if l:line < l:cur_line || l:line == l:cur_line && l:column <= l:cur_column
|
||||
" changes are happening around the cursor, move the cursor
|
||||
" to the end of the changes
|
||||
let l:cur_line = l:end_line + l:line_offset
|
||||
let l:cur_column = l:end_column + l:column_offset
|
||||
" else is not necesary, it means modifications are happening
|
||||
" after the cursor so no cursor updates need to be done
|
||||
endif
|
||||
endif
|
||||
|
||||
return [l:cur_line, l:cur_column]
|
||||
endfunction
|
@ -1,5 +1,6 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Completion support for LSP linters
|
||||
scriptencoding utf-8
|
||||
|
||||
" The omnicompletion menu is shown through a special Plug mapping which is
|
||||
" only valid in Insert mode. This way, feedkeys() won't send these keys if you
|
||||
@ -15,29 +16,107 @@ onoremap <silent> <Plug>(ale_show_completion_menu) <Nop>
|
||||
let g:ale_completion_delay = get(g:, 'ale_completion_delay', 100)
|
||||
let g:ale_completion_excluded_words = get(g:, 'ale_completion_excluded_words', [])
|
||||
let g:ale_completion_max_suggestions = get(g:, 'ale_completion_max_suggestions', 50)
|
||||
let g:ale_completion_tsserver_autoimport = get(g:, 'ale_completion_tsserver_autoimport', 0)
|
||||
|
||||
let s:timer_id = -1
|
||||
let s:last_done_pos = []
|
||||
|
||||
" CompletionItemKind values from the LSP protocol.
|
||||
let s:LSP_COMPLETION_TEXT_KIND = 1
|
||||
let s:LSP_COMPLETION_METHOD_KIND = 2
|
||||
let s:LSP_COMPLETION_FUNCTION_KIND = 3
|
||||
let s:LSP_COMPLETION_CONSTRUCTOR_KIND = 4
|
||||
let s:LSP_COMPLETION_FIELD_KIND = 5
|
||||
let s:LSP_COMPLETION_VARIABLE_KIND = 6
|
||||
let s:LSP_COMPLETION_CLASS_KIND = 7
|
||||
let s:LSP_COMPLETION_INTERFACE_KIND = 8
|
||||
let s:LSP_COMPLETION_MODULE_KIND = 9
|
||||
let s:LSP_COMPLETION_PROPERTY_KIND = 10
|
||||
let s:LSP_COMPLETION_UNIT_KIND = 11
|
||||
let s:LSP_COMPLETION_VALUE_KIND = 12
|
||||
let s:LSP_COMPLETION_ENUM_KIND = 13
|
||||
let s:LSP_COMPLETION_KEYWORD_KIND = 14
|
||||
let s:LSP_COMPLETION_SNIPPET_KIND = 15
|
||||
let s:LSP_COMPLETION_COLOR_KIND = 16
|
||||
let s:LSP_COMPLETION_FILE_KIND = 17
|
||||
let s:LSP_COMPLETION_REFERENCE_KIND = 18
|
||||
let g:ale_lsp_types = {
|
||||
\ 1: 'text',
|
||||
\ 2: 'method',
|
||||
\ 3: 'function',
|
||||
\ 4: 'constructor',
|
||||
\ 5: 'field',
|
||||
\ 6: 'variable',
|
||||
\ 7: 'class',
|
||||
\ 8: 'interface',
|
||||
\ 9: 'module',
|
||||
\ 10: 'property',
|
||||
\ 11: 'unit',
|
||||
\ 12: 'value',
|
||||
\ 13: 'enum',
|
||||
\ 14: 'keyword',
|
||||
\ 15: 'snippet',
|
||||
\ 16: 'color',
|
||||
\ 17: 'file',
|
||||
\ 18: 'reference',
|
||||
\ 19: 'folder',
|
||||
\ 20: 'enum_member',
|
||||
\ 21: 'constant',
|
||||
\ 22: 'struct',
|
||||
\ 23: 'event',
|
||||
\ 24: 'operator',
|
||||
\ 25: 'type_parameter',
|
||||
\ }
|
||||
|
||||
" from https://github.com/microsoft/TypeScript/blob/29becf05012bfa7ba20d50b0d16813971e46b8a6/lib/protocol.d.ts#L2472
|
||||
let g:ale_tsserver_types = {
|
||||
\ 'warning': 'text',
|
||||
\ 'keyword': 'keyword',
|
||||
\ 'script': 'file',
|
||||
\ 'module': 'module',
|
||||
\ 'class': 'class',
|
||||
\ 'local class': 'class',
|
||||
\ 'interface': 'interface',
|
||||
\ 'type': 'class',
|
||||
\ 'enum': 'enum',
|
||||
\ 'enum member': 'enum_member',
|
||||
\ 'var': 'variable',
|
||||
\ 'local var': 'variable',
|
||||
\ 'function': 'function',
|
||||
\ 'local function': 'function',
|
||||
\ 'method': 'method',
|
||||
\ 'getter': 'property',
|
||||
\ 'setter': 'method',
|
||||
\ 'property': 'property',
|
||||
\ 'constructor': 'constructor',
|
||||
\ 'call': 'method',
|
||||
\ 'index': 'index',
|
||||
\ 'construct': 'constructor',
|
||||
\ 'parameter': 'parameter',
|
||||
\ 'type parameter': 'type_parameter',
|
||||
\ 'primitive type': 'unit',
|
||||
\ 'label': 'text',
|
||||
\ 'alias': 'class',
|
||||
\ 'const': 'constant',
|
||||
\ 'let': 'variable',
|
||||
\ 'directory': 'folder',
|
||||
\ 'external module name': 'text',
|
||||
\ 'JSX attribute': 'parameter',
|
||||
\ 'string': 'text'
|
||||
\ }
|
||||
|
||||
" For compatibility reasons, we only use built in VIM completion kinds
|
||||
" See :help complete-items for Vim completion kinds
|
||||
let g:ale_completion_symbols = get(g:, 'ale_completion_symbols', {
|
||||
\ 'text': 'v',
|
||||
\ 'method': 'f',
|
||||
\ 'function': 'f',
|
||||
\ 'constructor': 'f',
|
||||
\ 'field': 'm',
|
||||
\ 'variable': 'v',
|
||||
\ 'class': 't',
|
||||
\ 'interface': 't',
|
||||
\ 'module': 'd',
|
||||
\ 'property': 'm',
|
||||
\ 'unit': 'v',
|
||||
\ 'value': 'v',
|
||||
\ 'enum': 't',
|
||||
\ 'keyword': 'v',
|
||||
\ 'snippet': 'v',
|
||||
\ 'color': 'v',
|
||||
\ 'file': 'v',
|
||||
\ 'reference': 'v',
|
||||
\ 'folder': 'v',
|
||||
\ 'enum_member': 'm',
|
||||
\ 'constant': 'm',
|
||||
\ 'struct': 't',
|
||||
\ 'event': 'v',
|
||||
\ 'operator': 'f',
|
||||
\ 'type_parameter': 'p',
|
||||
\ '<default>': 'v'
|
||||
\ })
|
||||
|
||||
let s:LSP_INSERT_TEXT_FORMAT_PLAIN = 1
|
||||
let s:LSP_INSERT_TEXT_FORMAT_SNIPPET = 2
|
||||
@ -277,6 +356,27 @@ function! ale#completion#GetAllTriggers() abort
|
||||
return deepcopy(s:trigger_character_map)
|
||||
endfunction
|
||||
|
||||
function! ale#completion#GetCompletionKind(kind) abort
|
||||
let l:lsp_symbol = get(g:ale_lsp_types, a:kind, '')
|
||||
|
||||
if !empty(l:lsp_symbol)
|
||||
return l:lsp_symbol
|
||||
endif
|
||||
|
||||
return get(g:ale_tsserver_types, a:kind, '')
|
||||
endfunction
|
||||
|
||||
function! ale#completion#GetCompletionSymbols(kind) abort
|
||||
let l:kind = ale#completion#GetCompletionKind(a:kind)
|
||||
let l:symbol = get(g:ale_completion_symbols, l:kind, '')
|
||||
|
||||
if !empty(l:symbol)
|
||||
return l:symbol
|
||||
endif
|
||||
|
||||
return get(g:ale_completion_symbols, '<default>', 'v')
|
||||
endfunction
|
||||
|
||||
function! s:CompletionStillValid(request_id) abort
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
|
||||
@ -296,7 +396,10 @@ function! ale#completion#ParseTSServerCompletions(response) abort
|
||||
let l:names = []
|
||||
|
||||
for l:suggestion in a:response.body
|
||||
call add(l:names, l:suggestion.name)
|
||||
call add(l:names, {
|
||||
\ 'word': l:suggestion.name,
|
||||
\ 'source': get(l:suggestion, 'source', ''),
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:names
|
||||
@ -310,6 +413,10 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
||||
for l:suggestion in a:response.body
|
||||
let l:displayParts = []
|
||||
|
||||
for l:action in get(l:suggestion, 'codeActions', [])
|
||||
call add(l:displayParts, l:action.description . ' ')
|
||||
endfor
|
||||
|
||||
for l:part in l:suggestion.displayParts
|
||||
call add(l:displayParts, l:part.text)
|
||||
endfor
|
||||
@ -321,22 +428,23 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
||||
call add(l:documentationParts, l:part.text)
|
||||
endfor
|
||||
|
||||
if l:suggestion.kind is# 'className'
|
||||
let l:kind = 'f'
|
||||
elseif l:suggestion.kind is# 'parameterName'
|
||||
let l:kind = 'f'
|
||||
else
|
||||
let l:kind = 'v'
|
||||
endif
|
||||
|
||||
" See :help complete-items
|
||||
call add(l:results, {
|
||||
let l:result = {
|
||||
\ 'word': l:suggestion.name,
|
||||
\ 'kind': l:kind,
|
||||
\ 'kind': ale#completion#GetCompletionSymbols(l:suggestion.kind),
|
||||
\ 'icase': 1,
|
||||
\ 'menu': join(l:displayParts, ''),
|
||||
\ 'dup': g:ale_completion_tsserver_autoimport,
|
||||
\ 'info': join(l:documentationParts, ''),
|
||||
\})
|
||||
\}
|
||||
|
||||
if has_key(l:suggestion, 'codeActions')
|
||||
let l:result.user_data = json_encode({
|
||||
\ 'codeActions': l:suggestion.codeActions,
|
||||
\ })
|
||||
endif
|
||||
|
||||
call add(l:results, l:result)
|
||||
endfor
|
||||
|
||||
let l:names = getbufvar(l:buffer, 'ale_tsserver_completion_names', [])
|
||||
@ -345,12 +453,12 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
|
||||
let l:names_with_details = map(copy(l:results), 'v:val.word')
|
||||
let l:missing_names = filter(
|
||||
\ copy(l:names),
|
||||
\ 'index(l:names_with_details, v:val) < 0',
|
||||
\ 'index(l:names_with_details, v:val.word) < 0',
|
||||
\)
|
||||
|
||||
for l:name in l:missing_names
|
||||
call add(l:results, {
|
||||
\ 'word': l:name,
|
||||
\ 'word': l:name.word,
|
||||
\ 'kind': 'v',
|
||||
\ 'icase': 1,
|
||||
\ 'menu': '',
|
||||
@ -408,23 +516,6 @@ function! ale#completion#ParseLSPCompletions(response) abort
|
||||
continue
|
||||
endif
|
||||
|
||||
" See :help complete-items for Vim completion kinds
|
||||
if !has_key(l:item, 'kind')
|
||||
let l:kind = 'v'
|
||||
elseif l:item.kind is s:LSP_COMPLETION_METHOD_KIND
|
||||
let l:kind = 'm'
|
||||
elseif l:item.kind is s:LSP_COMPLETION_CONSTRUCTOR_KIND
|
||||
let l:kind = 'm'
|
||||
elseif l:item.kind is s:LSP_COMPLETION_FUNCTION_KIND
|
||||
let l:kind = 'f'
|
||||
elseif l:item.kind is s:LSP_COMPLETION_CLASS_KIND
|
||||
let l:kind = 'f'
|
||||
elseif l:item.kind is s:LSP_COMPLETION_INTERFACE_KIND
|
||||
let l:kind = 'f'
|
||||
else
|
||||
let l:kind = 'v'
|
||||
endif
|
||||
|
||||
let l:doc = get(l:item, 'documentation', '')
|
||||
|
||||
if type(l:doc) is v:t_dict && has_key(l:doc, 'value')
|
||||
@ -433,7 +524,7 @@ function! ale#completion#ParseLSPCompletions(response) abort
|
||||
|
||||
call add(l:results, {
|
||||
\ 'word': l:word,
|
||||
\ 'kind': l:kind,
|
||||
\ 'kind': ale#completion#GetCompletionSymbols(get(l:item, 'kind', '')),
|
||||
\ 'icase': 1,
|
||||
\ 'menu': get(l:item, 'detail', ''),
|
||||
\ 'info': (type(l:doc) is v:t_string ? l:doc : ''),
|
||||
@ -472,13 +563,29 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
|
||||
call setbufvar(l:buffer, 'ale_tsserver_completion_names', l:names)
|
||||
|
||||
if !empty(l:names)
|
||||
let l:identifiers = []
|
||||
|
||||
for l:name in l:names
|
||||
let l:identifier = {
|
||||
\ 'name': l:name.word,
|
||||
\}
|
||||
let l:source = get(l:name, 'source', '')
|
||||
|
||||
" Empty source results in no details for the completed item
|
||||
if !empty(l:source)
|
||||
call extend(l:identifier, { 'source': l:source })
|
||||
endif
|
||||
|
||||
call add(l:identifiers, l:identifier)
|
||||
endfor
|
||||
|
||||
let b:ale_completion_info.request_id = ale#lsp#Send(
|
||||
\ b:ale_completion_info.conn_id,
|
||||
\ ale#lsp#tsserver_message#CompletionEntryDetails(
|
||||
\ l:buffer,
|
||||
\ b:ale_completion_info.line,
|
||||
\ b:ale_completion_info.column,
|
||||
\ l:names,
|
||||
\ l:identifiers,
|
||||
\ ),
|
||||
\)
|
||||
endif
|
||||
@ -525,6 +632,7 @@ function! s:OnReady(linter, lsp_details) abort
|
||||
\ b:ale_completion_info.line,
|
||||
\ b:ale_completion_info.column,
|
||||
\ b:ale_completion_info.prefix,
|
||||
\ g:ale_completion_tsserver_autoimport,
|
||||
\)
|
||||
else
|
||||
" Send a message saying the buffer has changed first, otherwise
|
||||
@ -692,6 +800,30 @@ function! ale#completion#Queue() abort
|
||||
let s:timer_id = timer_start(g:ale_completion_delay, function('s:TimerHandler'))
|
||||
endfunction
|
||||
|
||||
function! ale#completion#HandleUserData(completed_item) abort
|
||||
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
|
||||
|
||||
if l:source isnot# 'ale-automatic' && l:source isnot# 'ale-manual' && l:source isnot# 'ale-callback'
|
||||
return
|
||||
endif
|
||||
|
||||
let l:user_data_json = get(a:completed_item, 'user_data', '')
|
||||
|
||||
if empty(l:user_data_json)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:user_data = json_decode(l:user_data_json)
|
||||
|
||||
if type(l:user_data) isnot v:t_dict
|
||||
return
|
||||
endif
|
||||
|
||||
for l:code_action in get(l:user_data, 'codeActions', [])
|
||||
call ale#code_action#HandleCodeAction(l:code_action)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#completion#Done() abort
|
||||
silent! pclose
|
||||
|
||||
@ -700,6 +832,10 @@ function! ale#completion#Done() abort
|
||||
let s:last_done_pos = getpos('.')[1:2]
|
||||
endfunction
|
||||
|
||||
augroup ALECompletionActions
|
||||
autocmd CompleteDone * call ale#completion#HandleUserData(v:completed_item)
|
||||
augroup END
|
||||
|
||||
function! s:Setup(enabled) abort
|
||||
augroup ALECompletionGroup
|
||||
autocmd!
|
||||
|
@ -50,6 +50,7 @@ let s:global_variable_list = [
|
||||
\ 'ale_sign_style_error',
|
||||
\ 'ale_sign_style_warning',
|
||||
\ 'ale_sign_warning',
|
||||
\ 'ale_sign_highlight_linenrs',
|
||||
\ 'ale_statusline_format',
|
||||
\ 'ale_type_map',
|
||||
\ 'ale_use_global_executables',
|
||||
|
@ -47,7 +47,7 @@ function! ale#fix#ApplyQueuedFixes(buffer) abort
|
||||
set nomodified
|
||||
endif
|
||||
else
|
||||
call writefile(l:new_lines, expand(a:buffer . ':p')) " no-custom-checks
|
||||
call writefile(l:new_lines, expand('#' . a:buffer . ':p')) " no-custom-checks
|
||||
call setbufvar(a:buffer, '&modified', 0)
|
||||
endif
|
||||
endif
|
||||
@ -74,7 +74,7 @@ endfunction
|
||||
function! ale#fix#ApplyFixes(buffer, output) abort
|
||||
let l:data = g:ale_fix_buffer_data[a:buffer]
|
||||
let l:data.output = a:output
|
||||
let l:data.changes_made = l:data.lines_before != l:data.output
|
||||
let l:data.changes_made = l:data.lines_before !=# l:data.output " no-custom-checks
|
||||
let l:data.done = 1
|
||||
|
||||
call ale#command#RemoveManagedFiles(a:buffer)
|
||||
|
@ -27,6 +27,11 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Fix PEP8 issues with black.',
|
||||
\ },
|
||||
\ 'dfmt': {
|
||||
\ 'function': 'ale#fixers#dfmt#Fix',
|
||||
\ 'suggested_filetypes': ['d'],
|
||||
\ 'description': 'Fix D files with dfmt.',
|
||||
\ },
|
||||
\ 'fecs': {
|
||||
\ 'function': 'ale#fixers#fecs#Fix',
|
||||
\ 'suggested_filetypes': ['javascript', 'css', 'html'],
|
||||
@ -49,6 +54,11 @@ let s:default_registry = {
|
||||
\ 'description': 'Apply elm-format to a file.',
|
||||
\ 'aliases': ['format'],
|
||||
\ },
|
||||
\ 'nimpretty': {
|
||||
\ 'function': 'ale#fixers#nimpretty#Fix',
|
||||
\ 'suggested_filetypes': ['nim'],
|
||||
\ 'description': 'Apply nimpretty to a file.',
|
||||
\ },
|
||||
\ 'eslint': {
|
||||
\ 'function': 'ale#fixers#eslint#Fix',
|
||||
\ 'suggested_filetypes': ['javascript', 'typescript'],
|
||||
@ -230,6 +240,11 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['haskell'],
|
||||
\ 'description': 'Refactor Haskell files with stylish-haskell.',
|
||||
\ },
|
||||
\ 'purty': {
|
||||
\ 'function': 'ale#fixers#purty#Fix',
|
||||
\ 'suggested_filetypes': ['purescript'],
|
||||
\ 'description': 'Format PureScript files with purty.',
|
||||
\ },
|
||||
\ 'ocamlformat': {
|
||||
\ 'function': 'ale#fixers#ocamlformat#Fix',
|
||||
\ 'suggested_filetypes': ['ocaml'],
|
||||
@ -255,6 +270,11 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['sql'],
|
||||
\ 'description': 'Fix SQL files with sqlfmt.',
|
||||
\ },
|
||||
\ 'sqlformat': {
|
||||
\ 'function': 'ale#fixers#sqlformat#Fix',
|
||||
\ 'suggested_filetypes': ['sql'],
|
||||
\ 'description': 'Fix SQL files with sqlformat.',
|
||||
\ },
|
||||
\ 'google_java_format': {
|
||||
\ 'function': 'ale#fixers#google_java_format#Fix',
|
||||
\ 'suggested_filetypes': ['java'],
|
||||
@ -312,7 +332,7 @@ let s:default_registry = {
|
||||
\ },
|
||||
\ 'styler': {
|
||||
\ 'function': 'ale#fixers#styler#Fix',
|
||||
\ 'suggested_filetypes': ['r', 'rmarkdown'],
|
||||
\ 'suggested_filetypes': ['r', 'rmarkdown', 'rmd'],
|
||||
\ 'description': 'Fix R files with styler.',
|
||||
\ },
|
||||
\ 'latexindent': {
|
||||
@ -335,6 +355,16 @@ let s:default_registry = {
|
||||
\ 'suggested_filetypes': ['ada'],
|
||||
\ 'description': 'Format Ada files with gnatpp.',
|
||||
\ },
|
||||
\ 'nixpkgs-fmt': {
|
||||
\ 'function': 'ale#fixers#nixpkgsfmt#Fix',
|
||||
\ 'suggested_filetypes': ['nix'],
|
||||
\ 'description': 'A formatter for Nix code',
|
||||
\ },
|
||||
\ 'html-beautify': {
|
||||
\ 'function': 'ale#fixers#html_beautify#Fix',
|
||||
\ 'suggested_filetypes': ['html', 'htmldjango'],
|
||||
\ 'description': 'Fix HTML files with html-beautify.',
|
||||
\ },
|
||||
\}
|
||||
|
||||
" Reset the function registry to the default entries.
|
||||
|
18
sources_non_forked/ale/autoload/ale/fixers/dfmt.vim
Normal file
18
sources_non_forked/ale/autoload/ale/fixers/dfmt.vim
Normal file
@ -0,0 +1,18 @@
|
||||
" Author: theoldmoon0602
|
||||
" Description: Integration of dfmt with ALE.
|
||||
|
||||
call ale#Set('d_dfmt_executable', 'dfmt')
|
||||
call ale#Set('d_dfmt_options', '')
|
||||
|
||||
function! ale#fixers#dfmt#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'd_dfmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'd_dfmt_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' -i'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
21
sources_non_forked/ale/autoload/ale/fixers/html_beautify.vim
Normal file
21
sources_non_forked/ale/autoload/ale/fixers/html_beautify.vim
Normal file
@ -0,0 +1,21 @@
|
||||
" Author: WhyNotHugo <hugo@barrera.io>
|
||||
" Description: Lint HTML files with html-beautify.
|
||||
"
|
||||
call ale#Set('html_beautify_executable', 'html-beautify')
|
||||
call ale#Set('html_beautify_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('html_beautify_options', '')
|
||||
call ale#Set('html_beautify_change_directory', 1)
|
||||
|
||||
function! ale#fixers#html_beautify#Fix(buffer) abort
|
||||
let l:executable = ale#python#FindExecutable(
|
||||
\ a:buffer,
|
||||
\ 'html_beautify',
|
||||
\ ['html-beautify']
|
||||
\)
|
||||
|
||||
let l:options = ale#Var(a:buffer, 'html_beautify_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable). ' ' . l:options . ' -',
|
||||
\}
|
||||
endfunction
|
15
sources_non_forked/ale/autoload/ale/fixers/nimpretty.vim
Normal file
15
sources_non_forked/ale/autoload/ale/fixers/nimpretty.vim
Normal file
@ -0,0 +1,15 @@
|
||||
" Author: Nhan <hi@imnhan.com>
|
||||
" Description: Integration of nimpretty with ALE.
|
||||
|
||||
call ale#Set('nim_nimpretty_executable', 'nimpretty')
|
||||
call ale#Set('nim_nimpretty_options', '--maxLineLen:80')
|
||||
|
||||
function! ale#fixers#nimpretty#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'nim_nimpretty_executable')
|
||||
let l:options = ale#Var(a:buffer, 'nim_nimpretty_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . ' %t' . ale#Pad(l:options),
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
12
sources_non_forked/ale/autoload/ale/fixers/nixpkgsfmt.vim
Normal file
12
sources_non_forked/ale/autoload/ale/fixers/nixpkgsfmt.vim
Normal file
@ -0,0 +1,12 @@
|
||||
call ale#Set('nix_nixpkgsfmt_executable', 'nixpkgs-fmt')
|
||||
call ale#Set('nix_nixpkgsfmt_options', '')
|
||||
|
||||
function! ale#fixers#nixpkgsfmt#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'nix_nixpkgsfmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'nix_nixpkgsfmt_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options),
|
||||
\}
|
||||
endfunction
|
22
sources_non_forked/ale/autoload/ale/fixers/purty.vim
Normal file
22
sources_non_forked/ale/autoload/ale/fixers/purty.vim
Normal file
@ -0,0 +1,22 @@
|
||||
" Author: iclanzan <sorin@iclanzan.com>
|
||||
" Description: Integration of purty with ALE.
|
||||
|
||||
call ale#Set('purescript_purty_executable', 'purty')
|
||||
|
||||
function! ale#fixers#purty#GetExecutable(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'purescript_purty_executable')
|
||||
|
||||
return ale#Escape(l:executable)
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#purty#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#purty#GetExecutable(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': l:executable
|
||||
\ . ' --write'
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
|
@ -6,7 +6,7 @@ function! ale#fixers#rubocop#GetCommand(buffer) abort
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, '.rubocop.yml')
|
||||
let l:options = ale#Var(a:buffer, 'ruby_rubocop_options')
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rubocop')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'rubocop')
|
||||
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --auto-correct --force-exclusion %t'
|
||||
|
@ -5,7 +5,7 @@ function! ale#fixers#sorbet#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable')
|
||||
let l:options = ale#Var(a:buffer, 'ruby_sorbet_options')
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'srb')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'srb')
|
||||
\ . ' tc'
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --autocorrect --file %t'
|
||||
|
16
sources_non_forked/ale/autoload/ale/fixers/sqlformat.vim
Normal file
16
sources_non_forked/ale/autoload/ale/fixers/sqlformat.vim
Normal file
@ -0,0 +1,16 @@
|
||||
" Author: Cluas <Cluas@live.cn>
|
||||
" Description: Fixing files with sqlformat.
|
||||
|
||||
call ale#Set('sql_sqlformat_executable', 'sqlformat')
|
||||
call ale#Set('sql_sqlformat_options', '')
|
||||
|
||||
function! ale#fixers#sqlformat#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'sql_sqlformat_executable')
|
||||
let l:options = ale#Var(a:buffer, 'sql_sqlformat_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' -'
|
||||
\}
|
||||
endfunction
|
@ -7,6 +7,7 @@ call ale#Set('javascript_standard_options', '')
|
||||
|
||||
function! ale#fixers#standard#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'javascript_standard', [
|
||||
\ 'node_modules/standardx/bin/cmd.js',
|
||||
\ 'node_modules/standard/bin/cmd.js',
|
||||
\ 'node_modules/.bin/standard',
|
||||
\])
|
||||
@ -14,7 +15,14 @@ endfunction
|
||||
|
||||
function! ale#fixers#standard#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#standard#GetExecutable(a:buffer)
|
||||
let l:options = ale#Var(a:buffer, 'javascript_standard_options')
|
||||
let l:filetype = getbufvar(a:buffer, '&filetype')
|
||||
let l:options_type = 'javascript_standard_options'
|
||||
|
||||
if l:filetype =~# 'typescript'
|
||||
let l:options_type = 'typescript_standard_options'
|
||||
endif
|
||||
|
||||
let l:options = ale#Var(a:buffer, l:options_type)
|
||||
|
||||
return {
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
|
@ -9,7 +9,7 @@ function! ale#fixers#standardrb#GetCommand(buffer) abort
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, '.standard.yml')
|
||||
let l:options = ale#Var(a:buffer, 'ruby_standardrb_options')
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'standardrb')
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'standardrb')
|
||||
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --fix --force-exclusion %t'
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
call ale#Set('stylelint_executable', 'stylelint')
|
||||
call ale#Set('stylelint_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('stylelint_options', '')
|
||||
|
||||
function! ale#fixers#stylelint#GetExecutable(buffer) abort
|
||||
return ale#node#FindExecutable(a:buffer, 'stylelint', [
|
||||
@ -13,10 +14,14 @@ endfunction
|
||||
|
||||
function! ale#fixers#stylelint#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#stylelint#GetExecutable(a:buffer)
|
||||
let l:options = ale#Var(a:buffer, 'stylelint_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ' --fix %t',
|
||||
\ 'command': ale#path#BufferCdString(a:buffer)
|
||||
\ . ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ' %t'
|
||||
\ . ale#Pad(l:options)
|
||||
\ . ' --fix',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
|
@ -2,13 +2,13 @@
|
||||
" Description: Fixing R files with styler.
|
||||
|
||||
call ale#Set('r_styler_executable', 'Rscript')
|
||||
call ale#Set('r_styler_options', 'tidyverse_style')
|
||||
call ale#Set('r_styler_options', 'tidyverse_style()')
|
||||
|
||||
function! ale#fixers#styler#Fix(buffer) abort
|
||||
return {
|
||||
\ 'command': 'Rscript --vanilla -e '
|
||||
\ . '"suppressPackageStartupMessages(library(styler));'
|
||||
\ . 'style_file(commandArgs(TRUE), style = '
|
||||
\ . 'style_file(commandArgs(TRUE), transformers = '
|
||||
\ . ale#Var(a:buffer, 'r_styler_options') . ')"'
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
|
@ -2,6 +2,7 @@
|
||||
" Description: languagetool for markdown files
|
||||
"
|
||||
call ale#Set('languagetool_executable', 'languagetool')
|
||||
call ale#Set('languagetool_options', '--autoDetect')
|
||||
|
||||
function! ale#handlers#languagetool#GetExecutable(buffer) abort
|
||||
return ale#Var(a:buffer, 'languagetool_executable')
|
||||
@ -9,8 +10,10 @@ endfunction
|
||||
|
||||
function! ale#handlers#languagetool#GetCommand(buffer) abort
|
||||
let l:executable = ale#handlers#languagetool#GetExecutable(a:buffer)
|
||||
let l:options = ale#Var(a:buffer, 'languagetool_options')
|
||||
|
||||
return ale#Escape(l:executable) . ' --autoDetect %s'
|
||||
return ale#Escape(l:executable)
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options) . ' %s'
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#languagetool#HandleOutput(buffer, lines) abort
|
||||
|
@ -36,11 +36,3 @@ endfunction
|
||||
function! ale#handlers#ruby#HandleSyntaxErrors(buffer, lines) abort
|
||||
return s:HandleSyntaxError(a:buffer, a:lines)
|
||||
endfunction
|
||||
|
||||
function! ale#handlers#ruby#EscapeExecutable(executable, bundle_exec) abort
|
||||
let l:exec_args = a:executable =~? 'bundle'
|
||||
\ ? ' exec ' . a:bundle_exec
|
||||
\ : ''
|
||||
|
||||
return ale#Escape(a:executable) . l:exec_args
|
||||
endfunction
|
||||
|
@ -26,6 +26,25 @@ endif
|
||||
let s:MAX_POS_VALUES = 8
|
||||
let s:MAX_COL_SIZE = 1073741824 " pow(2, 30)
|
||||
|
||||
let s:has_nvim_highlight = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace')
|
||||
|
||||
if s:has_nvim_highlight
|
||||
let s:ns_id = nvim_create_namespace('ale_highlight')
|
||||
endif
|
||||
|
||||
" Wrappers are necessary to test this functionality by faking the calls in tests.
|
||||
function! ale#highlight#nvim_buf_add_highlight(buffer, ns_id, hl_group, line, col_start, col_end) abort
|
||||
" Ignore all errors for adding highlights.
|
||||
try
|
||||
call nvim_buf_add_highlight(a:buffer, a:ns_id, a:hl_group, a:line, a:col_start, a:col_end)
|
||||
catch
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! ale#highlight#nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end) abort
|
||||
call nvim_buf_clear_namespace(a:buffer, a:ns_id, a:line_start, a:line_end)
|
||||
endfunction
|
||||
|
||||
function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort
|
||||
if a:line >= a:end_line
|
||||
" For single lines, just return the one position.
|
||||
@ -51,15 +70,53 @@ endfunction
|
||||
" except these which have matching loclist item entries.
|
||||
|
||||
function! ale#highlight#RemoveHighlights() abort
|
||||
for l:match in getmatches()
|
||||
if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
|
||||
call matchdelete(l:match.id)
|
||||
endif
|
||||
endfor
|
||||
if s:has_nvim_highlight
|
||||
call ale#highlight#nvim_buf_clear_namespace(bufnr(''), s:ns_id, 0, -1)
|
||||
else
|
||||
for l:match in getmatches()
|
||||
if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
|
||||
call matchdelete(l:match.id)
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Same semantics of matchaddpos but will use nvim_buf_add_highlight if
|
||||
" available. This involves iterating over the position list, switching from
|
||||
" 1-based indexing to 0-based indexing, and translating the multiple ways
|
||||
" that position can be specified for matchaddpos into line + col_start +
|
||||
" col_end.
|
||||
function! s:matchaddpos(group, pos_list) abort
|
||||
if s:has_nvim_highlight
|
||||
for l:pos in a:pos_list
|
||||
let l:line = type(l:pos) == v:t_number
|
||||
\ ? l:pos - 1
|
||||
\ : l:pos[0] - 1
|
||||
|
||||
if type(l:pos) == v:t_number || len(l:pos) == 1
|
||||
let l:col_start = 0
|
||||
let l:col_end = s:MAX_COL_SIZE
|
||||
else
|
||||
let l:col_start = l:pos[1] - 1
|
||||
let l:col_end = l:col_start + get(l:pos, 2, 1)
|
||||
endif
|
||||
|
||||
call ale#highlight#nvim_buf_add_highlight(
|
||||
\ bufnr(''),
|
||||
\ s:ns_id,
|
||||
\ a:group,
|
||||
\ l:line,
|
||||
\ l:col_start,
|
||||
\ l:col_end,
|
||||
\)
|
||||
endfor
|
||||
else
|
||||
call matchaddpos(a:group, a:pos_list)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:highlight_line(bufnr, lnum, group) abort
|
||||
call matchaddpos(a:group, [a:lnum])
|
||||
call s:matchaddpos(a:group, [a:lnum])
|
||||
endfunction
|
||||
|
||||
function! s:highlight_range(bufnr, range, group) abort
|
||||
@ -72,7 +129,7 @@ function! s:highlight_range(bufnr, range, group) abort
|
||||
\ a:range.end_lnum,
|
||||
\ a:range.end_col
|
||||
\ ),
|
||||
\ 'matchaddpos(a:group, v:val)'
|
||||
\ 's:matchaddpos(a:group, v:val)'
|
||||
\)
|
||||
endfunction
|
||||
|
||||
|
@ -12,9 +12,12 @@ let s:linters = {}
|
||||
let s:default_ale_linter_aliases = {
|
||||
\ 'Dockerfile': 'dockerfile',
|
||||
\ 'csh': 'sh',
|
||||
\ 'javascriptreact': ['javascript', 'jsx'],
|
||||
\ 'plaintex': 'tex',
|
||||
\ 'rmarkdown': 'r',
|
||||
\ 'rmd': 'r',
|
||||
\ 'systemverilog': 'verilog',
|
||||
\ 'typescriptreact': ['typescript', 'tsx'],
|
||||
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
|
||||
\ 'vimwiki': 'markdown',
|
||||
\ 'vue': ['vue', 'javascript'],
|
||||
|
@ -37,6 +37,7 @@ function! ale#lsp#Register(executable_or_address, project, init_options) abort
|
||||
\ 'init_queue': [],
|
||||
\ 'capabilities': {
|
||||
\ 'hover': 0,
|
||||
\ 'rename': 0,
|
||||
\ 'references': 0,
|
||||
\ 'completion': 0,
|
||||
\ 'completion_trigger_characters': [],
|
||||
@ -199,6 +200,10 @@ function! s:UpdateCapabilities(conn, capabilities) abort
|
||||
let a:conn.capabilities.references = 1
|
||||
endif
|
||||
|
||||
if get(a:capabilities, 'renameProvider') is v:true
|
||||
let a:conn.capabilities.rename = 1
|
||||
endif
|
||||
|
||||
if !empty(get(a:capabilities, 'completionProvider'))
|
||||
let a:conn.capabilities.completion = 1
|
||||
endif
|
||||
@ -317,6 +322,7 @@ function! ale#lsp#MarkConnectionAsTsserver(conn_id) abort
|
||||
let l:conn.capabilities.completion_trigger_characters = ['.']
|
||||
let l:conn.capabilities.definition = 1
|
||||
let l:conn.capabilities.symbol_search = 1
|
||||
let l:conn.capabilities.rename = 1
|
||||
endfunction
|
||||
|
||||
function! s:SendInitMessage(conn) abort
|
||||
|
@ -162,3 +162,13 @@ function! ale#lsp#message#DidChangeConfiguration(buffer, config) abort
|
||||
\ 'settings': a:config,
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#message#Rename(buffer, line, column, new_name) abort
|
||||
return [0, 'textDocument/rename', {
|
||||
\ 'textDocument': {
|
||||
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
|
||||
\ },
|
||||
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
|
||||
\ 'newName': a:new_name,
|
||||
\}]
|
||||
endfunction
|
||||
|
@ -36,12 +36,14 @@ function! ale#lsp#tsserver_message#Geterr(buffer) abort
|
||||
return [1, 'ts@geterr', {'files': [expand('#' . a:buffer . ':p')]}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#tsserver_message#Completions(buffer, line, column, prefix) abort
|
||||
function! ale#lsp#tsserver_message#Completions(
|
||||
\ buffer, line, column, prefix, include_external) abort
|
||||
return [0, 'ts@completions', {
|
||||
\ 'line': a:line,
|
||||
\ 'offset': a:column,
|
||||
\ 'file': expand('#' . a:buffer . ':p'),
|
||||
\ 'prefix': a:prefix,
|
||||
\ 'includeExternalModuleExports': a:include_external,
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
@ -77,3 +79,27 @@ function! ale#lsp#tsserver_message#Quickinfo(buffer, line, column) abort
|
||||
\ 'file': expand('#' . a:buffer . ':p'),
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#tsserver_message#Rename(
|
||||
\ buffer, line, column, find_in_comments, find_in_strings) abort
|
||||
return [0, 'ts@rename', {
|
||||
\ 'line': a:line,
|
||||
\ 'offset': a:column,
|
||||
\ 'file': expand('#' . a:buffer . ':p'),
|
||||
\ 'arguments': {
|
||||
\ 'findInComments': a:find_in_comments,
|
||||
\ 'findInStrings': a:find_in_strings,
|
||||
\ }
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#tsserver_message#OrganizeImports(buffer) abort
|
||||
return [0, 'ts@organizeImports', {
|
||||
\ 'scope': {
|
||||
\ 'type': 'file',
|
||||
\ 'args': {
|
||||
\ 'file': expand('#' . a:buffer . ':p'),
|
||||
\ },
|
||||
\ },
|
||||
\}]
|
||||
endfunction
|
||||
|
@ -130,6 +130,12 @@ function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort
|
||||
call s:HandleLSPErrorMessage(l:linter_name, a:response)
|
||||
elseif l:method is# 'textDocument/publishDiagnostics'
|
||||
call s:HandleLSPDiagnostics(a:conn_id, a:response)
|
||||
elseif l:method is# 'window/showMessage'
|
||||
call ale#lsp_window#HandleShowMessage(
|
||||
\ s:lsp_linter_map[a:conn_id],
|
||||
\ g:ale_lsp_show_message_format,
|
||||
\ a:response.params
|
||||
\)
|
||||
elseif get(a:response, 'type', '') is# 'event'
|
||||
\&& get(a:response, 'event', '') is# 'semanticDiag'
|
||||
call s:HandleTSServerDiagnostics(a:response, 'semantic')
|
||||
|
58
sources_non_forked/ale/autoload/ale/lsp_window.vim
Normal file
58
sources_non_forked/ale/autoload/ale/lsp_window.vim
Normal file
@ -0,0 +1,58 @@
|
||||
" Author: suoto <andre820@gmail.com>
|
||||
" Description: Handling of window/* LSP methods, although right now only
|
||||
" handles window/showMessage
|
||||
|
||||
" Constants for message type codes
|
||||
let s:LSP_MESSAGE_TYPE_DISABLED = 0
|
||||
let s:LSP_MESSAGE_TYPE_ERROR = 1
|
||||
let s:LSP_MESSAGE_TYPE_WARNING = 2
|
||||
let s:LSP_MESSAGE_TYPE_INFORMATION = 3
|
||||
let s:LSP_MESSAGE_TYPE_LOG = 4
|
||||
|
||||
" Translate strings from the user config to a number so we can check
|
||||
" severities
|
||||
let s:CFG_TO_LSP_SEVERITY = {
|
||||
\ 'disabled': s:LSP_MESSAGE_TYPE_DISABLED,
|
||||
\ 'error': s:LSP_MESSAGE_TYPE_ERROR,
|
||||
\ 'warning': s:LSP_MESSAGE_TYPE_WARNING,
|
||||
\ 'information': s:LSP_MESSAGE_TYPE_INFORMATION,
|
||||
\ 'info': s:LSP_MESSAGE_TYPE_INFORMATION,
|
||||
\ 'log': s:LSP_MESSAGE_TYPE_LOG
|
||||
\}
|
||||
|
||||
" Handle window/showMessage response.
|
||||
" - details: dict containing linter name and format (g:ale_lsp_show_message_format)
|
||||
" - params: dict with the params for the call in the form of {type: number, message: string}
|
||||
function! ale#lsp_window#HandleShowMessage(linter_name, format, params) abort
|
||||
let l:message = a:params.message
|
||||
let l:type = a:params.type
|
||||
|
||||
" Get the configured severity level threshold and check if the message
|
||||
" should be displayed or not
|
||||
let l:configured_severity = tolower(get(g:, 'ale_lsp_show_message_severity', 'error'))
|
||||
" If the user has configured with a value we can't find on the conversion
|
||||
" dict, fall back to warning
|
||||
let l:cfg_severity_threshold = get(s:CFG_TO_LSP_SEVERITY, l:configured_severity, s:LSP_MESSAGE_TYPE_WARNING)
|
||||
|
||||
if l:type > l:cfg_severity_threshold
|
||||
return
|
||||
endif
|
||||
|
||||
" Severity will depend on the message type
|
||||
if l:type is# s:LSP_MESSAGE_TYPE_ERROR
|
||||
let l:severity = g:ale_echo_msg_error_str
|
||||
elseif l:type is# s:LSP_MESSAGE_TYPE_INFORMATION
|
||||
let l:severity = g:ale_echo_msg_info_str
|
||||
elseif l:type is# s:LSP_MESSAGE_TYPE_LOG
|
||||
let l:severity = g:ale_echo_msg_log_str
|
||||
else
|
||||
" Default to warning just in case
|
||||
let l:severity = g:ale_echo_msg_warning_str
|
||||
endif
|
||||
|
||||
let l:string = substitute(a:format, '\V%severity%', l:severity, 'g')
|
||||
let l:string = substitute(l:string, '\V%linter%', a:linter_name, 'g')
|
||||
let l:string = substitute(l:string, '\V%s\>', l:message, 'g')
|
||||
|
||||
call ale#util#ShowMessage(l:string)
|
||||
endfunction
|
59
sources_non_forked/ale/autoload/ale/organize_imports.vim
Normal file
59
sources_non_forked/ale/autoload/ale/organize_imports.vim
Normal file
@ -0,0 +1,59 @@
|
||||
" Author: Jerko Steiner <jerko.steiner@gmail.com>
|
||||
" Description: Organize imports support for tsserver
|
||||
"
|
||||
function! ale#organize_imports#HandleTSServerResponse(conn_id, response) abort
|
||||
if get(a:response, 'command', '') isnot# 'organizeImports'
|
||||
return
|
||||
endif
|
||||
|
||||
if get(a:response, 'success', v:false) isnot v:true
|
||||
return
|
||||
endif
|
||||
|
||||
let l:file_code_edits = a:response.body
|
||||
|
||||
call ale#code_action#HandleCodeAction({
|
||||
\ 'description': 'Organize Imports',
|
||||
\ 'changes': l:file_code_edits,
|
||||
\})
|
||||
endfunction
|
||||
|
||||
function! s:OnReady(linter, lsp_details) abort
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
if a:linter.lsp isnot# 'tsserver'
|
||||
call ale#util#Execute('echom ''OrganizeImports currently only works with tsserver''')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
|
||||
let l:Callback = function('ale#organize_imports#HandleTSServerResponse')
|
||||
|
||||
call ale#lsp#RegisterCallback(l:id, l:Callback)
|
||||
|
||||
let l:message = ale#lsp#tsserver_message#OrganizeImports(l:buffer)
|
||||
|
||||
let l:request_id = ale#lsp#Send(l:id, l:message)
|
||||
endfunction
|
||||
|
||||
function! s:OrganizeImports(linter) abort
|
||||
let l:buffer = bufnr('')
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
|
||||
if a:linter.lsp isnot# 'tsserver'
|
||||
let l:column = min([l:column, len(getline(l:line))])
|
||||
endif
|
||||
|
||||
let l:Callback = function('s:OnReady')
|
||||
call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||
endfunction
|
||||
|
||||
function! ale#organize_imports#Execute() abort
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
call s:OrganizeImports(l:linter)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
@ -54,14 +54,14 @@ function! ale#path#FindNearestDirectory(buffer, directory_name) abort
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" Given a buffer, a string to search for, an a global fallback for when
|
||||
" Given a buffer, a string to search for, and a global fallback for when
|
||||
" the search fails, look for a file in parent paths, and if that fails,
|
||||
" use the global fallback path instead.
|
||||
function! ale#path#ResolveLocalPath(buffer, search_string, global_fallback) abort
|
||||
" Search for a locally installed file first.
|
||||
let l:path = ale#path#FindNearestFile(a:buffer, a:search_string)
|
||||
|
||||
" If the serach fails, try the global executable instead.
|
||||
" If the search fails, try the global executable instead.
|
||||
if empty(l:path)
|
||||
let l:path = a:global_fallback
|
||||
endif
|
||||
|
225
sources_non_forked/ale/autoload/ale/rename.vim
Normal file
225
sources_non_forked/ale/autoload/ale/rename.vim
Normal file
@ -0,0 +1,225 @@
|
||||
" Author: Jerko Steiner <jerko.steiner@gmail.com>
|
||||
" Description: Rename symbol support for LSP / tsserver
|
||||
|
||||
let s:rename_map = {}
|
||||
|
||||
" Used to get the rename map in tests.
|
||||
function! ale#rename#GetMap() abort
|
||||
return deepcopy(s:rename_map)
|
||||
endfunction
|
||||
|
||||
" Used to set the rename map in tests.
|
||||
function! ale#rename#SetMap(map) abort
|
||||
let s:rename_map = a:map
|
||||
endfunction
|
||||
|
||||
function! ale#rename#ClearLSPData() abort
|
||||
let s:rename_map = {}
|
||||
endfunction
|
||||
|
||||
let g:ale_rename_tsserver_find_in_comments = get(g:, 'ale_rename_tsserver_find_in_comments')
|
||||
let g:ale_rename_tsserver_find_in_strings = get(g:, 'ale_rename_tsserver_find_in_strings')
|
||||
|
||||
function! s:message(message) abort
|
||||
call ale#util#Execute('echom ' . string(a:message))
|
||||
endfunction
|
||||
|
||||
function! ale#rename#HandleTSServerResponse(conn_id, response) abort
|
||||
if get(a:response, 'command', '') isnot# 'rename'
|
||||
return
|
||||
endif
|
||||
|
||||
if !has_key(s:rename_map, a:response.request_seq)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:old_name = s:rename_map[a:response.request_seq].old_name
|
||||
let l:new_name = s:rename_map[a:response.request_seq].new_name
|
||||
call remove(s:rename_map, a:response.request_seq)
|
||||
|
||||
if get(a:response, 'success', v:false) is v:false
|
||||
let l:message = get(a:response, 'message', 'unknown')
|
||||
call s:message('Error renaming "' . l:old_name . '" to: "' . l:new_name
|
||||
\ . '". Reason: ' . l:message)
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:changes = []
|
||||
|
||||
for l:response_item in a:response.body.locs
|
||||
let l:filename = l:response_item.file
|
||||
let l:text_changes = []
|
||||
|
||||
for l:loc in l:response_item.locs
|
||||
call add(l:text_changes, {
|
||||
\ 'start': {
|
||||
\ 'line': l:loc.start.line,
|
||||
\ 'offset': l:loc.start.offset,
|
||||
\ },
|
||||
\ 'end': {
|
||||
\ 'line': l:loc.end.line,
|
||||
\ 'offset': l:loc.end.offset,
|
||||
\ },
|
||||
\ 'newText': l:new_name,
|
||||
\})
|
||||
endfor
|
||||
|
||||
call add(l:changes, {
|
||||
\ 'fileName': l:filename,
|
||||
\ 'textChanges': l:text_changes,
|
||||
\})
|
||||
endfor
|
||||
|
||||
if empty(l:changes)
|
||||
call s:message('Error renaming "' . l:old_name . '" to: "' . l:new_name . '"')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
call ale#code_action#HandleCodeAction({
|
||||
\ 'description': 'rename',
|
||||
\ 'changes': l:changes,
|
||||
\})
|
||||
endfunction
|
||||
|
||||
function! ale#rename#HandleLSPResponse(conn_id, response) abort
|
||||
if has_key(a:response, 'id')
|
||||
\&& has_key(s:rename_map, a:response.id)
|
||||
call remove(s:rename_map, a:response.id)
|
||||
|
||||
if !has_key(a:response, 'result')
|
||||
call s:message('No rename result received from server')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:workspace_edit = a:response.result
|
||||
|
||||
if !has_key(l:workspace_edit, 'changes') || empty(l:workspace_edit.changes)
|
||||
call s:message('No changes received from server')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:changes = []
|
||||
|
||||
for l:file_name in keys(l:workspace_edit.changes)
|
||||
let l:text_edits = l:workspace_edit.changes[l:file_name]
|
||||
let l:text_changes = []
|
||||
|
||||
for l:edit in l:text_edits
|
||||
let l:range = l:edit.range
|
||||
let l:new_text = l:edit.newText
|
||||
|
||||
call add(l:text_changes, {
|
||||
\ 'start': {
|
||||
\ 'line': l:range.start.line + 1,
|
||||
\ 'offset': l:range.start.character + 1,
|
||||
\ },
|
||||
\ 'end': {
|
||||
\ 'line': l:range.end.line + 1,
|
||||
\ 'offset': l:range.end.character + 1,
|
||||
\ },
|
||||
\ 'newText': l:new_text,
|
||||
\})
|
||||
endfor
|
||||
|
||||
call add(l:changes, {
|
||||
\ 'fileName': ale#path#FromURI(l:file_name),
|
||||
\ 'textChanges': l:text_changes,
|
||||
\})
|
||||
endfor
|
||||
|
||||
call ale#code_action#HandleCodeAction({
|
||||
\ 'description': 'rename',
|
||||
\ 'changes': l:changes,
|
||||
\})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:OnReady(line, column, old_name, new_name, linter, lsp_details) abort
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
if !ale#lsp#HasCapability(l:id, 'rename')
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
|
||||
let l:Callback = a:linter.lsp is# 'tsserver'
|
||||
\ ? function('ale#rename#HandleTSServerResponse')
|
||||
\ : function('ale#rename#HandleLSPResponse')
|
||||
|
||||
call ale#lsp#RegisterCallback(l:id, l:Callback)
|
||||
|
||||
if a:linter.lsp is# 'tsserver'
|
||||
let l:message = ale#lsp#tsserver_message#Rename(
|
||||
\ l:buffer,
|
||||
\ a:line,
|
||||
\ a:column,
|
||||
\ g:ale_rename_tsserver_find_in_comments,
|
||||
\ g:ale_rename_tsserver_find_in_strings,
|
||||
\)
|
||||
else
|
||||
" Send a message saying the buffer has changed first, or the
|
||||
" rename position probably won't make sense.
|
||||
call ale#lsp#NotifyForChanges(l:id, l:buffer)
|
||||
|
||||
let l:message = ale#lsp#message#Rename(
|
||||
\ l:buffer,
|
||||
\ a:line,
|
||||
\ a:column,
|
||||
\ a:new_name
|
||||
\)
|
||||
endif
|
||||
|
||||
let l:request_id = ale#lsp#Send(l:id, l:message)
|
||||
|
||||
let s:rename_map[l:request_id] = {
|
||||
\ 'new_name': a:new_name,
|
||||
\ 'old_name': a:old_name,
|
||||
\}
|
||||
endfunction
|
||||
|
||||
function! s:ExecuteRename(linter, old_name, new_name) abort
|
||||
let l:buffer = bufnr('')
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
|
||||
if a:linter.lsp isnot# 'tsserver'
|
||||
let l:column = min([l:column, len(getline(l:line))])
|
||||
endif
|
||||
|
||||
let l:Callback = function(
|
||||
\ 's:OnReady', [l:line, l:column, a:old_name, a:new_name])
|
||||
call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||
endfunction
|
||||
|
||||
function! ale#rename#Execute() abort
|
||||
let l:lsp_linters = []
|
||||
|
||||
for l:linter in ale#linter#Get(&filetype)
|
||||
if !empty(l:linter.lsp)
|
||||
call add(l:lsp_linters, l:linter)
|
||||
endif
|
||||
endfor
|
||||
|
||||
if empty(l:lsp_linters)
|
||||
call s:message('No active LSPs')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:old_name = expand('<cword>')
|
||||
let l:new_name = ale#util#Input('New name: ', l:old_name)
|
||||
|
||||
if empty(l:new_name)
|
||||
call s:message('New name cannot be empty!')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
for l:lsp_linter in l:lsp_linters
|
||||
call s:ExecuteRename(l:lsp_linter, l:old_name, l:new_name)
|
||||
endfor
|
||||
endfunction
|
@ -74,3 +74,10 @@ function! ale#ruby#HandleRubocopOutput(buffer, lines) abort
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
function! ale#ruby#EscapeExecutable(executable, bundle_exec) abort
|
||||
let l:exec_args = a:executable =~? 'bundle'
|
||||
\ ? ' exec ' . a:bundle_exec
|
||||
\ : ''
|
||||
|
||||
return ale#Escape(a:executable) . l:exec_args
|
||||
endfunction
|
||||
|
@ -14,12 +14,16 @@ let g:ale_sign_style_error = get(g:, 'ale_sign_style_error', g:ale_sign_error)
|
||||
let g:ale_sign_warning = get(g:, 'ale_sign_warning', '--')
|
||||
let g:ale_sign_style_warning = get(g:, 'ale_sign_style_warning', g:ale_sign_warning)
|
||||
let g:ale_sign_info = get(g:, 'ale_sign_info', g:ale_sign_warning)
|
||||
let g:ale_sign_priority = get(g:, 'ale_sign_priority', 30)
|
||||
" This variable sets an offset which can be set for sign IDs.
|
||||
" This ID can be changed depending on what IDs are set for other plugins.
|
||||
" The dummy sign will use the ID exactly equal to the offset.
|
||||
let g:ale_sign_offset = get(g:, 'ale_sign_offset', 1000000)
|
||||
" This flag can be set to 1 to keep sign gutter always open
|
||||
let g:ale_sign_column_always = get(g:, 'ale_sign_column_always', 0)
|
||||
let g:ale_sign_highlight_linenrs = get(g:, 'ale_sign_highlight_linenrs', 0)
|
||||
|
||||
let s:supports_sign_groups = has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
|
||||
|
||||
if !hlexists('ALEErrorSign')
|
||||
highlight link ALEErrorSign error
|
||||
@ -82,7 +86,7 @@ execute 'sign define ALEInfoSign text=' . s:EscapeSignText(g:ale_sign_info)
|
||||
\ . ' texthl=ALEInfoSign linehl=ALEInfoLine'
|
||||
sign define ALEDummySign
|
||||
|
||||
if has('nvim-0.3.2')
|
||||
if g:ale_sign_highlight_linenrs && has('nvim-0.3.2')
|
||||
if !hlexists('ALEErrorSignLineNr')
|
||||
highlight link ALEErrorSignLineNr CursorLineNr
|
||||
endif
|
||||
@ -146,24 +150,59 @@ function! ale#sign#GetSignName(sublist) abort
|
||||
return 'ALEErrorSign'
|
||||
endfunction
|
||||
|
||||
function! s:PriorityCmd() abort
|
||||
if s:supports_sign_groups
|
||||
return ' priority=' . g:ale_sign_priority . ' '
|
||||
else
|
||||
return ''
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:GroupCmd() abort
|
||||
if s:supports_sign_groups
|
||||
return ' group=ale '
|
||||
else
|
||||
return ' '
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Read sign data for a buffer to a list of lines.
|
||||
function! ale#sign#ReadSigns(buffer) abort
|
||||
redir => l:output
|
||||
silent execute 'sign place buffer=' . a:buffer
|
||||
silent execute 'sign place ' . s:GroupCmd() . s:PriorityCmd()
|
||||
\ . ' buffer=' . a:buffer
|
||||
redir end
|
||||
|
||||
return split(l:output, "\n")
|
||||
endfunction
|
||||
|
||||
function! ale#sign#ParsePattern() abort
|
||||
if s:supports_sign_groups
|
||||
" Matches output like :
|
||||
" line=4 id=1 group=ale name=ALEErrorSign
|
||||
" строка=1 id=1000001 группа=ale имя=ALEErrorSign
|
||||
" 行=1 識別子=1000001 グループ=ale 名前=ALEWarningSign
|
||||
" línea=12 id=1000001 grupo=ale nombre=ALEWarningSign
|
||||
" riga=1 id=1000001 gruppo=ale nome=ALEWarningSign
|
||||
" Zeile=235 id=1000001 Gruppe=ale Name=ALEErrorSign
|
||||
let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=ale>.*\=(ALE[a-zA-Z]+Sign)'
|
||||
else
|
||||
" Matches output like :
|
||||
" line=4 id=1 name=ALEErrorSign
|
||||
" строка=1 id=1000001 имя=ALEErrorSign
|
||||
" 行=1 識別子=1000001 名前=ALEWarningSign
|
||||
" línea=12 id=1000001 nombre=ALEWarningSign
|
||||
" riga=1 id=1000001 nome=ALEWarningSign
|
||||
" Zeile=235 id=1000001 Name=ALEErrorSign
|
||||
let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=(ALE[a-zA-Z]+Sign)'
|
||||
endif
|
||||
|
||||
return l:pattern
|
||||
endfunction
|
||||
|
||||
" Given a list of lines for sign output, return a List of [line, id, group]
|
||||
function! ale#sign#ParseSigns(line_list) abort
|
||||
" Matches output like :
|
||||
" line=4 id=1 name=ALEErrorSign
|
||||
" строка=1 id=1000001 имя=ALEErrorSign
|
||||
" 行=1 識別子=1000001 名前=ALEWarningSign
|
||||
" línea=12 id=1000001 nombre=ALEWarningSign
|
||||
" riga=1 id=1000001, nome=ALEWarningSign
|
||||
let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=(ALE[a-zA-Z]+Sign)'
|
||||
let l:pattern =ale#sign#ParsePattern()
|
||||
let l:result = []
|
||||
let l:is_dummy_sign_set = 0
|
||||
|
||||
@ -318,8 +357,10 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
|
||||
if !l:is_dummy_sign_set && (!empty(a:sign_map) || g:ale_sign_column_always)
|
||||
call add(l:command_list, 'sign place '
|
||||
\ . g:ale_sign_offset
|
||||
\ . ' line=1 name=ALEDummySign buffer='
|
||||
\ . a:buffer
|
||||
\ . s:GroupCmd()
|
||||
\ . s:PriorityCmd()
|
||||
\ . ' line=1 name=ALEDummySign '
|
||||
\ . ' buffer=' . a:buffer
|
||||
\)
|
||||
let l:is_dummy_sign_set = 1
|
||||
endif
|
||||
@ -336,6 +377,8 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
|
||||
if index(l:info.current_id_list, l:info.new_id) < 0
|
||||
call add(l:command_list, 'sign place '
|
||||
\ . (l:info.new_id)
|
||||
\ . s:GroupCmd()
|
||||
\ . s:PriorityCmd()
|
||||
\ . ' line=' . l:line_str
|
||||
\ . ' name=' . (l:info.new_name)
|
||||
\ . ' buffer=' . a:buffer
|
||||
@ -350,6 +393,7 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
|
||||
if l:current_id isnot l:info.new_id
|
||||
call add(l:command_list, 'sign unplace '
|
||||
\ . l:current_id
|
||||
\ . s:GroupCmd()
|
||||
\ . ' buffer=' . a:buffer
|
||||
\)
|
||||
endif
|
||||
@ -360,6 +404,7 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
|
||||
if l:is_dummy_sign_set && !g:ale_sign_column_always
|
||||
call add(l:command_list, 'sign unplace '
|
||||
\ . g:ale_sign_offset
|
||||
\ . s:GroupCmd()
|
||||
\ . ' buffer=' . a:buffer
|
||||
\)
|
||||
endif
|
||||
@ -414,3 +459,12 @@ function! ale#sign#SetSigns(buffer, loclist) abort
|
||||
highlight link SignColumn ALESignColumnWithoutErrors
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Remove all signs.
|
||||
function! ale#sign#Clear() abort
|
||||
if s:supports_sign_groups
|
||||
sign unplace group=ale *
|
||||
else
|
||||
sign unplace *
|
||||
endif
|
||||
endfunction
|
||||
|
@ -477,3 +477,6 @@ function! ale#util#FindItemAtCursor(buffer) abort
|
||||
return [l:info, l:loc]
|
||||
endfunction
|
||||
|
||||
function! ale#util#Input(message, value) abort
|
||||
return input(a:message, a:value)
|
||||
endfunction
|
||||
|
Reference in New Issue
Block a user