experiment with ale
This commit is contained in:
parent
cb77c8dc0a
commit
d018ac3065
299
vim/.vim/autoload/ale.vim
Normal file
299
vim/.vim/autoload/ale.vim
Normal file
@ -0,0 +1,299 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>, David Alexander <opensource@thelonelyghost.com>
|
||||
" Description: Primary code path for the plugin
|
||||
" Manages execution of linters when requested by autocommands
|
||||
|
||||
" 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')
|
||||
|
||||
" 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')
|
||||
|
||||
" Return 1 if a file is too large for ALE to handle.
|
||||
function! ale#FileTooLarge(buffer) abort
|
||||
let l:max = getbufvar(a:buffer, 'ale_maximum_file_size', get(g:, 'ale_maximum_file_size', 0))
|
||||
|
||||
return l:max > 0 ? (line2byte(line('$') + 1) > l:max) : 0
|
||||
endfunction
|
||||
|
||||
" A function for checking various conditions whereby ALE just shouldn't
|
||||
" attempt to do anything, say if particular buffer types are open in Vim.
|
||||
function! ale#ShouldDoNothing(buffer) abort
|
||||
" The checks are split into separate if statements to make it possible to
|
||||
" profile each check individually with Vim's profiling tools.
|
||||
"
|
||||
" Do nothing if ALE is disabled.
|
||||
if !getbufvar(a:buffer, 'ale_enabled', get(g:, 'ale_enabled', 0))
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Don't perform any checks when newer NeoVim versions are exiting.
|
||||
if get(v:, 'exiting', v:null) isnot v:null
|
||||
return 1
|
||||
endif
|
||||
|
||||
let l:filetype = getbufvar(a:buffer, '&filetype')
|
||||
|
||||
" Do nothing when there's no filetype.
|
||||
if l:filetype is# ''
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Do nothing for diff buffers.
|
||||
if getbufvar(a:buffer, '&diff')
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Do nothing for blacklisted files.
|
||||
if index(get(g:, 'ale_filetype_blacklist', []), l:filetype) >= 0
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Do nothing if running from command mode.
|
||||
if s:getcmdwintype_exists && !empty(getcmdwintype())
|
||||
return 1
|
||||
endif
|
||||
|
||||
let l:filename = fnamemodify(bufname(a:buffer), ':t')
|
||||
|
||||
" Do nothing for directories.
|
||||
if l:filename is# '.'
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Don't start linting and so on when an operator is pending.
|
||||
if ale#util#Mode(1) is# 'no'
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Do nothing if running in the sandbox.
|
||||
if ale#util#InSandbox()
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Do nothing if the file is too large.
|
||||
if ale#FileTooLarge(a:buffer)
|
||||
return 1
|
||||
endif
|
||||
|
||||
" Do nothing from CtrlP buffers with CtrlP-funky.
|
||||
if exists(':CtrlPFunky') is 2
|
||||
\&& getbufvar(a:buffer, '&l:statusline') =~# 'CtrlPMode.*funky'
|
||||
return 1
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:Lint(buffer, should_lint_file, timer_id) abort
|
||||
" Use the filetype from the buffer
|
||||
let l:filetype = getbufvar(a:buffer, '&filetype')
|
||||
let l:linters = ale#linter#Get(l:filetype)
|
||||
|
||||
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
|
||||
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
|
||||
|
||||
" Load code to ignore linters only if we need to.
|
||||
if (
|
||||
\ !empty(l:ignore_config)
|
||||
\ || l:disable_lsp is 1
|
||||
\ || l:disable_lsp is v:true
|
||||
\ || (l:disable_lsp is# 'auto' && get(g:, 'lspconfig', 0))
|
||||
\)
|
||||
let l:linters = ale#engine#ignore#Exclude(
|
||||
\ l:filetype,
|
||||
\ l:linters,
|
||||
\ l:ignore_config,
|
||||
\ l:disable_lsp,
|
||||
\)
|
||||
endif
|
||||
|
||||
" Tell other sources that they can start checking the buffer now.
|
||||
let g:ale_want_results_buffer = a:buffer
|
||||
silent doautocmd <nomodeline> User ALEWantResults
|
||||
unlet! g:ale_want_results_buffer
|
||||
|
||||
" Don't set up buffer data and so on if there are no linters to run.
|
||||
if !has_key(g:ale_buffer_info, a:buffer) && empty(l:linters)
|
||||
return
|
||||
endif
|
||||
|
||||
" Clear lint_file linters, or only run them if the file exists.
|
||||
let l:lint_file = empty(l:linters)
|
||||
\ || (a:should_lint_file && filereadable(expand('#' . a:buffer . ':p')))
|
||||
|
||||
call ale#engine#RunLinters(a:buffer, l:linters, l:lint_file)
|
||||
endfunction
|
||||
|
||||
" (delay, [linting_flag, buffer_number])
|
||||
function! ale#Queue(delay, ...) abort
|
||||
if a:0 > 2
|
||||
throw 'too many arguments!'
|
||||
endif
|
||||
|
||||
let l:buffer = get(a:000, 1, v:null)
|
||||
|
||||
if l:buffer is v:null
|
||||
let l:buffer = bufnr('')
|
||||
endif
|
||||
|
||||
if type(l:buffer) isnot v:t_number
|
||||
throw 'buffer_number must be a Number'
|
||||
endif
|
||||
|
||||
if ale#ShouldDoNothing(l:buffer)
|
||||
return
|
||||
endif
|
||||
|
||||
" Default linting_flag to ''
|
||||
let l:should_lint_file = get(a:000, 0) is# 'lint_file'
|
||||
|
||||
if s:lint_timer != -1
|
||||
call timer_stop(s:lint_timer)
|
||||
let s:lint_timer = -1
|
||||
endif
|
||||
|
||||
if a:delay > 0
|
||||
let s:lint_timer = timer_start(
|
||||
\ a:delay,
|
||||
\ function('s:Lint', [l:buffer, l:should_lint_file])
|
||||
\)
|
||||
else
|
||||
call s:Lint(l:buffer, l:should_lint_file, 0)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let s:current_ale_version = [3, 3, 0]
|
||||
|
||||
" A function used to check for ALE features in files outside of the project.
|
||||
function! ale#Has(feature) abort
|
||||
let l:match = matchlist(a:feature, '\c\v^ale-(\d+)\.(\d+)(\.(\d+))?$')
|
||||
|
||||
if !empty(l:match)
|
||||
let l:version = [l:match[1] + 0, l:match[2] + 0, l:match[4] + 0]
|
||||
|
||||
return ale#semver#GTE(s:current_ale_version, l:version)
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" Given a buffer number and a variable name, look for that variable in the
|
||||
" buffer scope, then in global scope. If the name does not exist in the global
|
||||
" scope, an exception will be thrown.
|
||||
"
|
||||
" Every variable name will be prefixed with 'ale_'.
|
||||
function! ale#Var(buffer, variable_name) abort
|
||||
let l:full_name = 'ale_' . a:variable_name
|
||||
let l:vars = getbufvar(str2nr(a:buffer), '', {})
|
||||
|
||||
return get(l:vars, l:full_name, g:[l:full_name])
|
||||
endfunction
|
||||
|
||||
" Initialize a variable with a default value, if it isn't already set.
|
||||
"
|
||||
" Every variable name will be prefixed with 'ale_'.
|
||||
function! ale#Set(variable_name, default) abort
|
||||
let l:full_name = 'ale_' . a:variable_name
|
||||
|
||||
if !has_key(g:, l:full_name)
|
||||
let g:[l:full_name] = a:default
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Given a string for adding to a command, return the string padded with a
|
||||
" space on the left if it is not empty. Otherwise return an empty string.
|
||||
"
|
||||
" This can be used for making command strings cleaner and easier to test.
|
||||
function! ale#Pad(string) abort
|
||||
return !empty(a:string) ? ' ' . a:string : ''
|
||||
endfunction
|
||||
|
||||
" Given a environment variable name and a value, produce part of a command for
|
||||
" setting an environment variable before running a command. The syntax will be
|
||||
" valid for cmd on Windows, or most shells on Unix.
|
||||
function! ale#Env(variable_name, value) abort
|
||||
if has('win32')
|
||||
return 'set ' . ale#Escape(a:variable_name . '=' . a:value) . ' && '
|
||||
endif
|
||||
|
||||
return a:variable_name . '=' . ale#Escape(a:value) . ' '
|
||||
endfunction
|
||||
|
||||
" Escape a string suitably for each platform.
|
||||
" shellescape does not work on Windows.
|
||||
function! ale#Escape(str) abort
|
||||
if fnamemodify(&shell, ':t') is? 'cmd.exe'
|
||||
" If the string contains spaces, it will be surrounded by quotes.
|
||||
" Otherwise, special characters will be escaped with carets (^).
|
||||
return substitute(
|
||||
\ a:str =~# ' '
|
||||
\ ? '"' . substitute(a:str, '"', '""', 'g') . '"'
|
||||
\ : substitute(a:str, '\v([&|<>^])', '^\1', 'g'),
|
||||
\ '%',
|
||||
\ '%%',
|
||||
\ 'g',
|
||||
\)
|
||||
endif
|
||||
|
||||
return shellescape (a:str)
|
||||
endfunction
|
||||
|
||||
" Get the loclist item message according to a given format string.
|
||||
"
|
||||
" See `:help g:ale_loclist_msg_format` and `:help g:ale_echo_msg_format`
|
||||
function! ale#GetLocItemMessage(item, format_string) abort
|
||||
let l:msg = a:format_string
|
||||
let l:severity = g:ale_echo_msg_warning_str
|
||||
let l:code = get(a:item, 'code', '')
|
||||
let l:type = get(a:item, 'type', 'E')
|
||||
let l:linter_name = get(a:item, 'linter_name', '')
|
||||
let l:code_repl = !empty(l:code) ? '\=submatch(1) . l:code . submatch(2)' : ''
|
||||
|
||||
if l:type is# 'E'
|
||||
let l:severity = g:ale_echo_msg_error_str
|
||||
elseif l:type is# 'I'
|
||||
let l:severity = g:ale_echo_msg_info_str
|
||||
endif
|
||||
|
||||
" Replace special markers with certain information.
|
||||
" \=l:variable is used to avoid escaping issues.
|
||||
let l:msg = substitute(l:msg, '\v\%([^\%]*)code([^\%]*)\%', l:code_repl, 'g')
|
||||
let l:msg = substitute(l:msg, '\V%severity%', '\=l:severity', 'g')
|
||||
let l:msg = substitute(l:msg, '\V%type%', '\=l:type', 'g')
|
||||
let l:msg = substitute(l:msg, '\V%linter%', '\=l:linter_name', 'g')
|
||||
" Replace %s with the text.
|
||||
let l:msg = substitute(l:msg, '\V%s', '\=a:item.text', 'g')
|
||||
" Windows may insert carriage return line endings (^M), strip these characters.
|
||||
let l:msg = substitute(l:msg, '\r', '', 'g')
|
||||
|
||||
return l:msg
|
||||
endfunction
|
||||
|
||||
" Given a buffer and a linter or fixer name, return an Array of two-item
|
||||
" Arrays describing how to map filenames to and from the local to foreign file
|
||||
" systems.
|
||||
function! ale#GetFilenameMappings(buffer, name) abort
|
||||
let l:linter_mappings = ale#Var(a:buffer, 'filename_mappings')
|
||||
|
||||
if type(l:linter_mappings) is v:t_list
|
||||
return l:linter_mappings
|
||||
endif
|
||||
|
||||
let l:name = a:name
|
||||
|
||||
if !has_key(l:linter_mappings, l:name)
|
||||
" Use * as a default setting for all tools.
|
||||
let l:name = '*'
|
||||
endif
|
||||
|
||||
return get(l:linter_mappings, l:name, [])
|
||||
endfunction
|
45
vim/.vim/autoload/ale/ant.vim
Normal file
45
vim/.vim/autoload/ale/ant.vim
Normal file
@ -0,0 +1,45 @@
|
||||
" Author: Andrew Lee <andrew.lambda@tuta.io>.
|
||||
" Inspired by ale/gradle.vim by Michael Pardo <michael@michaelpardo.com>
|
||||
" Description: Functions for working with Ant projects.
|
||||
|
||||
" Given a buffer number, find an Ant project root
|
||||
function! ale#ant#FindProjectRoot(buffer) abort
|
||||
let l:build_xml_path = ale#path#FindNearestFile(a:buffer, 'build.xml')
|
||||
|
||||
if !empty(l:build_xml_path)
|
||||
return fnamemodify(l:build_xml_path, ':h')
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" Given a buffer number, find the path to the `ant` executable. Returns an empty
|
||||
" string if cannot find the executable.
|
||||
function! ale#ant#FindExecutable(buffer) abort
|
||||
if executable('ant')
|
||||
return 'ant'
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" Given a buffer number, get a working directory and command to print the
|
||||
" classpath of the root project.
|
||||
"
|
||||
" Returns an empty string for the command if Ant is not detected.
|
||||
function! ale#ant#BuildClasspathCommand(buffer) abort
|
||||
let l:executable = ale#ant#FindExecutable(a:buffer)
|
||||
|
||||
if !empty(l:executable)
|
||||
let l:project_root = ale#ant#FindProjectRoot(a:buffer)
|
||||
|
||||
if !empty(l:project_root)
|
||||
return [
|
||||
\ l:project_root,
|
||||
\ ale#Escape(l:executable) .' classpath -S -q'
|
||||
\]
|
||||
endif
|
||||
endif
|
||||
|
||||
return ['', '']
|
||||
endfunction
|
43
vim/.vim/autoload/ale/args.vim
Normal file
43
vim/.vim/autoload/ale/args.vim
Normal file
@ -0,0 +1,43 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: This module implements a function for parsing arguments for
|
||||
" commands.
|
||||
|
||||
" Given a list of valid arguments like ['foo', 'bar'] and a string to parse,
|
||||
" parse the arguments from the string and return [parsed_args, remainder].
|
||||
"
|
||||
" Arguments must be prefixed in the string with a single minus (-), and a
|
||||
" double minus (--) denotes the end of arguments.
|
||||
function! ale#args#Parse(arg_list, string) abort
|
||||
let l:parsed = {}
|
||||
let l:end_of_args = 0
|
||||
let l:word_list = split(a:string, ' ')
|
||||
let l:index = 0
|
||||
|
||||
while l:index < len(l:word_list)
|
||||
let l:word = l:word_list[l:index]
|
||||
|
||||
if l:word[:0] is# '-'
|
||||
let l:index += 1
|
||||
|
||||
if l:word is# '--'
|
||||
break
|
||||
endif
|
||||
|
||||
let l:arg = l:word[1:]
|
||||
|
||||
if index(a:arg_list, l:arg) >= 0
|
||||
let l:parsed[l:arg] = ''
|
||||
else
|
||||
throw 'Invalid argument: ' . l:word
|
||||
endif
|
||||
elseif l:word is# ''
|
||||
let l:index += 1
|
||||
else
|
||||
break
|
||||
endif
|
||||
endwhile
|
||||
|
||||
let l:new_string = join(l:word_list[l:index :], ' ')
|
||||
|
||||
return [l:parsed, l:new_string]
|
||||
endfunction
|
424
vim/.vim/autoload/ale/assert.vim
Normal file
424
vim/.vim/autoload/ale/assert.vim
Normal file
@ -0,0 +1,424 @@
|
||||
let s:command_output = []
|
||||
|
||||
function! ale#assert#GivenCommandOutput(...) abort
|
||||
let s:command_output = a:000
|
||||
endfunction
|
||||
|
||||
function! s:GetLinter() abort
|
||||
let l:linters = ale#linter#GetLintersLoaded()
|
||||
let l:filetype_linters = get(values(l:linters), 0, [])
|
||||
|
||||
if len(l:linters) is 0 || len(l:filetype_linters) is 0
|
||||
throw 'No linters were loaded'
|
||||
endif
|
||||
|
||||
if len(l:linters) > 1 || len(l:filetype_linters) > 1
|
||||
throw 'More than one linter was loaded'
|
||||
endif
|
||||
|
||||
return l:filetype_linters[0]
|
||||
endfunction
|
||||
|
||||
function! s:FormatExe(command, executable) abort
|
||||
return substitute(a:command, '%e', '\=ale#Escape(a:executable)', 'g')
|
||||
endfunction
|
||||
|
||||
function! s:ProcessDeferredCommands(initial_result) abort
|
||||
let l:result = a:initial_result
|
||||
let l:command_index = 0
|
||||
let l:command = []
|
||||
|
||||
while ale#command#IsDeferred(l:result)
|
||||
call add(l:command, s:FormatExe(l:result.command, l:result.executable))
|
||||
|
||||
if get(g:, 'ale_run_synchronously_emulate_commands')
|
||||
" Don't run commands, but simulate the results.
|
||||
let l:Callback = g:ale_run_synchronously_callbacks[0]
|
||||
let l:output = get(s:command_output, l:command_index, [])
|
||||
call l:Callback(0, l:output)
|
||||
unlet g:ale_run_synchronously_callbacks
|
||||
|
||||
let l:command_index += 1
|
||||
else
|
||||
" Run the commands in the shell, synchronously.
|
||||
call ale#test#FlushJobs()
|
||||
endif
|
||||
|
||||
let l:result = l:result.value
|
||||
endwhile
|
||||
|
||||
call add(l:command, l:result)
|
||||
|
||||
return l:command
|
||||
endfunction
|
||||
|
||||
function! s:ProcessDeferredCwds(initial_command, initial_cwd) abort
|
||||
let l:result = a:initial_command
|
||||
let l:last_cwd = v:null
|
||||
let l:command_index = 0
|
||||
let l:cwd_list = []
|
||||
|
||||
while ale#command#IsDeferred(l:result)
|
||||
call add(l:cwd_list, l:result.cwd)
|
||||
|
||||
if get(g:, 'ale_run_synchronously_emulate_commands')
|
||||
" Don't run commands, but simulate the results.
|
||||
let l:Callback = g:ale_run_synchronously_callbacks[0]
|
||||
let l:output = get(s:command_output, l:command_index, [])
|
||||
call l:Callback(0, l:output)
|
||||
unlet g:ale_run_synchronously_callbacks
|
||||
|
||||
let l:command_index += 1
|
||||
else
|
||||
" Run the commands in the shell, synchronously.
|
||||
call ale#test#FlushJobs()
|
||||
endif
|
||||
|
||||
let l:result = l:result.value
|
||||
endwhile
|
||||
|
||||
call add(l:cwd_list, a:initial_cwd is v:null ? l:last_cwd : a:initial_cwd)
|
||||
|
||||
return l:cwd_list
|
||||
endfunction
|
||||
|
||||
" Load the currently loaded linter for a test case, and check that the command
|
||||
" matches the given string.
|
||||
function! ale#assert#Linter(expected_executable, expected_command) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:linter = s:GetLinter()
|
||||
let l:executable = ale#linter#GetExecutable(l:buffer, l:linter)
|
||||
|
||||
while ale#command#IsDeferred(l:executable)
|
||||
call ale#test#FlushJobs()
|
||||
let l:executable = l:executable.value
|
||||
endwhile
|
||||
|
||||
let l:command = s:ProcessDeferredCommands(
|
||||
\ ale#linter#GetCommand(l:buffer, l:linter),
|
||||
\)
|
||||
|
||||
if type(a:expected_command) isnot v:t_list
|
||||
let l:command = l:command[-1]
|
||||
endif
|
||||
|
||||
if type(l:command) is v:t_string
|
||||
" Replace %e with the escaped executable, so tests keep passing after
|
||||
" linters are changed to use %e.
|
||||
let l:command = s:FormatExe(l:command, l:executable)
|
||||
elseif type(l:command) is v:t_list
|
||||
call map(l:command, 's:FormatExe(v:val, l:executable)')
|
||||
endif
|
||||
|
||||
AssertEqual
|
||||
\ [a:expected_executable, a:expected_command],
|
||||
\ [l:executable, l:command]
|
||||
endfunction
|
||||
|
||||
function! ale#assert#LinterCwd(expected_cwd) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:linter = s:GetLinter()
|
||||
|
||||
let l:initial_cwd = ale#linter#GetCwd(l:buffer, l:linter)
|
||||
call ale#command#SetCwd(l:buffer, l:initial_cwd)
|
||||
|
||||
let l:cwd = s:ProcessDeferredCwds(
|
||||
\ ale#linter#GetCommand(l:buffer, l:linter),
|
||||
\ l:initial_cwd,
|
||||
\)
|
||||
|
||||
call ale#command#ResetCwd(l:buffer)
|
||||
|
||||
if type(a:expected_cwd) isnot v:t_list
|
||||
let l:cwd = l:cwd[-1]
|
||||
endif
|
||||
|
||||
AssertEqual a:expected_cwd, l:cwd
|
||||
endfunction
|
||||
|
||||
function! ale#assert#FixerCwd(expected_cwd) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:cwd = s:ProcessDeferredCwds(s:FixerFunction(l:buffer), v:null)
|
||||
|
||||
if type(a:expected_cwd) isnot v:t_list
|
||||
let l:cwd = l:cwd[-1]
|
||||
endif
|
||||
|
||||
AssertEqual a:expected_cwd, l:cwd
|
||||
endfunction
|
||||
|
||||
function! ale#assert#Fixer(expected_result) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer))
|
||||
|
||||
if type(a:expected_result) isnot v:t_list
|
||||
let l:result = l:result[-1]
|
||||
endif
|
||||
|
||||
AssertEqual a:expected_result, l:result
|
||||
endfunction
|
||||
|
||||
function! ale#assert#FixerNotExecuted() abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:result = s:ProcessDeferredCommands(s:FixerFunction(l:buffer))[-1]
|
||||
|
||||
Assert empty(l:result), "The fixer will be executed when it shouldn't be"
|
||||
endfunction
|
||||
|
||||
function! ale#assert#LinterNotExecuted() abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:linter = s:GetLinter()
|
||||
let l:executable = ale#linter#GetExecutable(l:buffer, l:linter)
|
||||
let l:executed = 1
|
||||
|
||||
if !empty(l:executable)
|
||||
let l:command = ale#linter#GetCommand(l:buffer, l:linter)
|
||||
|
||||
if type(l:command) is v:t_list
|
||||
let l:command = l:command[-1]
|
||||
endif
|
||||
|
||||
let l:executed = !empty(l:command)
|
||||
else
|
||||
let l:executed = 0
|
||||
endif
|
||||
|
||||
Assert !l:executed, "The linter will be executed when it shouldn't be"
|
||||
endfunction
|
||||
|
||||
function! ale#assert#LSPOptions(expected_options) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:linter = s:GetLinter()
|
||||
let l:initialization_options = ale#lsp_linter#GetOptions(l:buffer, l:linter)
|
||||
|
||||
AssertEqual a:expected_options, l:initialization_options
|
||||
endfunction
|
||||
|
||||
function! ale#assert#LSPConfig(expected_config) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:linter = s:GetLinter()
|
||||
let l:config = ale#lsp_linter#GetConfig(l:buffer, l:linter)
|
||||
|
||||
AssertEqual a:expected_config, l:config
|
||||
endfunction
|
||||
|
||||
function! ale#assert#LSPLanguage(expected_language) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:linter = s:GetLinter()
|
||||
let l:language = ale#linter#GetLanguage(l:buffer, l:linter)
|
||||
|
||||
AssertEqual a:expected_language, l:language
|
||||
endfunction
|
||||
|
||||
function! ale#assert#LSPProject(expected_root) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:linter = s:GetLinter()
|
||||
let l:root = ale#lsp_linter#FindProjectRoot(l:buffer, l:linter)
|
||||
|
||||
AssertEqual a:expected_root, l:root
|
||||
endfunction
|
||||
|
||||
function! ale#assert#LSPAddress(expected_address) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:linter = s:GetLinter()
|
||||
let l:address = ale#linter#GetAddress(l:buffer, l:linter)
|
||||
|
||||
AssertEqual a:expected_address, l:address
|
||||
endfunction
|
||||
|
||||
function! ale#assert#SetUpLinterTestCommands() abort
|
||||
command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
|
||||
command! -nargs=+ AssertLinterCwd :call ale#assert#LinterCwd(<args>)
|
||||
command! -nargs=+ AssertLinter :call ale#assert#Linter(<args>)
|
||||
command! -nargs=0 AssertLinterNotExecuted :call ale#assert#LinterNotExecuted()
|
||||
command! -nargs=+ AssertLSPOptions :call ale#assert#LSPOptions(<args>)
|
||||
command! -nargs=+ AssertLSPConfig :call ale#assert#LSPConfig(<args>)
|
||||
command! -nargs=+ AssertLSPLanguage :call ale#assert#LSPLanguage(<args>)
|
||||
command! -nargs=+ AssertLSPProject :call ale#assert#LSPProject(<args>)
|
||||
command! -nargs=+ AssertLSPAddress :call ale#assert#LSPAddress(<args>)
|
||||
endfunction
|
||||
|
||||
function! ale#assert#SetUpFixerTestCommands() abort
|
||||
command! -nargs=+ GivenCommandOutput :call ale#assert#GivenCommandOutput(<args>)
|
||||
command! -nargs=+ AssertFixerCwd :call ale#assert#FixerCwd(<args>)
|
||||
command! -nargs=+ AssertFixer :call ale#assert#Fixer(<args>)
|
||||
command! -nargs=0 AssertFixerNotExecuted :call ale#assert#FixerNotExecuted()
|
||||
endfunction
|
||||
|
||||
function! ale#assert#ResetVariables(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
|
||||
|
||||
let l:option_suffix = get(a:000, 0, a:name)
|
||||
let l:prefix = 'ale_' . a:filetype . '_'
|
||||
\ . substitute(l:option_suffix, '-', '_', 'g')
|
||||
let l:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix'
|
||||
|
||||
" Save and clear linter variables.
|
||||
" We'll load the runtime file to reset them to defaults.
|
||||
for l:key in filter(keys(g:), l:filter_expr)
|
||||
execute 'Save g:' . l:key
|
||||
unlet g:[l:key]
|
||||
endfor
|
||||
|
||||
for l:key in filter(keys(b:), l:filter_expr)
|
||||
unlet b:[l:key]
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" A dummy function for making sure this module is loaded.
|
||||
function! ale#assert#SetUpLinterTest(filetype, name) abort
|
||||
" Set up a marker so ALE doesn't create real random temporary filenames.
|
||||
let g:ale_create_dummy_temporary_file = 1
|
||||
|
||||
" Remove current linters.
|
||||
call ale#linter#Reset()
|
||||
call ale#linter#PreventLoading(a:filetype)
|
||||
|
||||
Save g:ale_root
|
||||
let g:ale_root = {}
|
||||
|
||||
Save b:ale_root
|
||||
unlet! b:ale_root
|
||||
|
||||
call ale#assert#ResetVariables(a:filetype, a:name)
|
||||
|
||||
Save g:ale_c_build_dir
|
||||
unlet! g:ale_c_build_dir
|
||||
unlet! b:ale_c_build_dir
|
||||
|
||||
execute 'runtime ale_linters/' . a:filetype . '/' . a:name . '.vim'
|
||||
|
||||
if !exists('g:dir')
|
||||
call ale#test#SetDirectory('/testplugin/test/linter')
|
||||
endif
|
||||
|
||||
call ale#assert#SetUpLinterTestCommands()
|
||||
|
||||
let g:ale_run_synchronously = 1
|
||||
let g:ale_run_synchronously_emulate_commands = 1
|
||||
endfunction
|
||||
|
||||
function! ale#assert#TearDownLinterTest() abort
|
||||
unlet! g:ale_create_dummy_temporary_file
|
||||
unlet! g:ale_run_synchronously
|
||||
unlet! g:ale_run_synchronously_callbacks
|
||||
unlet! g:ale_run_synchronously_emulate_commands
|
||||
unlet! g:ale_run_synchronously_command_results
|
||||
let s:command_output = []
|
||||
|
||||
if exists(':GivenCommandOutput')
|
||||
delcommand GivenCommandOutput
|
||||
endif
|
||||
|
||||
if exists(':AssertLinterCwd')
|
||||
delcommand AssertLinterCwd
|
||||
endif
|
||||
|
||||
if exists(':AssertLinter')
|
||||
delcommand AssertLinter
|
||||
endif
|
||||
|
||||
if exists(':AssertLinterNotExecuted')
|
||||
delcommand AssertLinterNotExecuted
|
||||
endif
|
||||
|
||||
if exists(':AssertLSPOptions')
|
||||
delcommand AssertLSPOptions
|
||||
endif
|
||||
|
||||
if exists(':AssertLSPConfig')
|
||||
delcommand AssertLSPConfig
|
||||
endif
|
||||
|
||||
if exists(':AssertLSPLanguage')
|
||||
delcommand AssertLSPLanguage
|
||||
endif
|
||||
|
||||
if exists(':AssertLSPProject')
|
||||
delcommand AssertLSPProject
|
||||
endif
|
||||
|
||||
if exists(':AssertLSPAddress')
|
||||
delcommand AssertLSPAddress
|
||||
endif
|
||||
|
||||
if exists('g:dir')
|
||||
call ale#test#RestoreDirectory()
|
||||
endif
|
||||
|
||||
Restore
|
||||
|
||||
call ale#linter#Reset()
|
||||
|
||||
if exists('*ale#semver#ResetVersionCache')
|
||||
call ale#semver#ResetVersionCache()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
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:option_suffix = get(a:000, 0, a:name)
|
||||
call ale#assert#ResetVariables(a:filetype, a:name, l:option_suffix)
|
||||
|
||||
execute 'runtime autoload/ale/fixers/' . substitute(a:name, '-', '_', 'g') . '.vim'
|
||||
|
||||
if !exists('g:dir')
|
||||
call ale#test#SetDirectory('/testplugin/test/fixers')
|
||||
endif
|
||||
|
||||
call ale#assert#SetUpFixerTestCommands()
|
||||
|
||||
let g:ale_run_synchronously = 1
|
||||
let g:ale_run_synchronously_emulate_commands = 1
|
||||
endfunction
|
||||
|
||||
function! ale#assert#TearDownFixerTest() abort
|
||||
unlet! g:ale_create_dummy_temporary_file
|
||||
unlet! g:ale_run_synchronously
|
||||
unlet! g:ale_run_synchronously_callbacks
|
||||
unlet! g:ale_run_synchronously_emulate_commands
|
||||
unlet! g:ale_run_synchronously_command_results
|
||||
let s:command_output = []
|
||||
unlet! s:FixerFunction
|
||||
|
||||
if exists('g:dir')
|
||||
call ale#test#RestoreDirectory()
|
||||
endif
|
||||
|
||||
Restore
|
||||
|
||||
if exists('*ale#semver#ResetVersionCache')
|
||||
call ale#semver#ResetVersionCache()
|
||||
endif
|
||||
|
||||
if exists(':GivenCommandOutput')
|
||||
delcommand GivenCommandOutput
|
||||
endif
|
||||
|
||||
if exists(':AssertFixerCwd')
|
||||
delcommand AssertFixerCwd
|
||||
endif
|
||||
|
||||
if exists(':AssertFixer')
|
||||
delcommand AssertFixer
|
||||
endif
|
||||
|
||||
if exists(':AssertFixerNotExecuted')
|
||||
delcommand AssertFixerNotExecuted
|
||||
endif
|
||||
endfunction
|
74
vim/.vim/autoload/ale/balloon.vim
Normal file
74
vim/.vim/autoload/ale/balloon.vim
Normal file
@ -0,0 +1,74 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: balloonexpr support for ALE.
|
||||
|
||||
function! ale#balloon#MessageForPos(bufnr, lnum, col) abort
|
||||
let l:set_balloons = ale#Var(a:bufnr, 'set_balloons')
|
||||
let l:show_problems = 0
|
||||
let l:show_hover = 0
|
||||
|
||||
if l:set_balloons is 1
|
||||
let l:show_problems = 1
|
||||
let l:show_hover = 1
|
||||
elseif l:set_balloons is# 'hover'
|
||||
let l:show_hover = 1
|
||||
endif
|
||||
|
||||
" Don't show balloons if they are disabled, or linting is disabled.
|
||||
if !(l:show_problems || l:show_hover)
|
||||
\|| !g:ale_enabled
|
||||
\|| !getbufvar(a:bufnr, 'ale_enabled', 1)
|
||||
return ''
|
||||
endif
|
||||
|
||||
if l:show_problems
|
||||
let l:loclist = get(g:ale_buffer_info, a:bufnr, {'loclist': []}).loclist
|
||||
let l:index = ale#util#BinarySearch(l:loclist, a:bufnr, a:lnum, a:col)
|
||||
endif
|
||||
|
||||
" Show the diagnostics message if found, 'Hover' output otherwise
|
||||
if l:show_problems && l:index >= 0
|
||||
return l:loclist[l:index].text
|
||||
elseif l:show_hover && (
|
||||
\ exists('*balloon_show')
|
||||
\ || getbufvar(
|
||||
\ a:bufnr,
|
||||
\ 'ale_set_balloons_legacy_echo',
|
||||
\ get(g:, 'ale_set_balloons_legacy_echo', 0)
|
||||
\ )
|
||||
\)
|
||||
" Request LSP/tsserver hover information, but only if this version of
|
||||
" Vim supports the balloon_show function, or if we turned a legacy
|
||||
" setting on.
|
||||
call ale#hover#Show(a:bufnr, a:lnum, a:col, {'called_from_balloonexpr': 1})
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale#balloon#Expr() abort
|
||||
return ale#balloon#MessageForPos(v:beval_bufnr, v:beval_lnum, v:beval_col)
|
||||
endfunction
|
||||
|
||||
function! ale#balloon#Disable() abort
|
||||
if has('balloon_eval')
|
||||
set noballooneval
|
||||
set balloonexpr=
|
||||
endif
|
||||
|
||||
if has('balloon_eval_term')
|
||||
set noballoonevalterm
|
||||
set balloonexpr=
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#balloon#Enable() abort
|
||||
if has('balloon_eval')
|
||||
set ballooneval
|
||||
set balloonexpr=ale#balloon#Expr()
|
||||
endif
|
||||
|
||||
if has('balloon_eval_term')
|
||||
set balloonevalterm
|
||||
set balloonexpr=ale#balloon#Expr()
|
||||
endif
|
||||
endfunction
|
622
vim/.vim/autoload/ale/c.vim
Normal file
622
vim/.vim/autoload/ale/c.vim
Normal file
@ -0,0 +1,622 @@
|
||||
" Author: gagbo <gagbobada@gmail.com>, w0rp <devw0rp@gmail.com>, roel0 <postelmansroel@gmail.com>
|
||||
" Description: Functions for integrating with C-family linters.
|
||||
|
||||
call ale#Set('c_parse_makefile', 0)
|
||||
call ale#Set('c_always_make', has('unix') && !has('macunix'))
|
||||
call ale#Set('c_parse_compile_commands', 1)
|
||||
|
||||
let s:sep = has('win32') ? '\' : '/'
|
||||
|
||||
" Set just so tests can override it.
|
||||
let g:__ale_c_project_filenames = ['.git/HEAD', 'configure', 'Makefile', 'CMakeLists.txt']
|
||||
|
||||
let g:ale_c_build_dir_names = get(g:, 'ale_c_build_dir_names', [
|
||||
\ 'build',
|
||||
\ 'bin',
|
||||
\])
|
||||
|
||||
function! s:CanParseMakefile(buffer) abort
|
||||
" Something somewhere seems to delete this setting in tests, so ensure we
|
||||
" always have a default value.
|
||||
call ale#Set('c_parse_makefile', 0)
|
||||
|
||||
return ale#Var(a:buffer, 'c_parse_makefile')
|
||||
endfunction
|
||||
|
||||
function! ale#c#GetBuildDirectory(buffer) abort
|
||||
let l:build_dir = ale#Var(a:buffer, 'c_build_dir')
|
||||
|
||||
" c_build_dir has the priority if defined
|
||||
if !empty(l:build_dir)
|
||||
return l:build_dir
|
||||
endif
|
||||
|
||||
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||
|
||||
return ale#path#Dirname(l:json_file)
|
||||
endfunction
|
||||
|
||||
function! ale#c#ShellSplit(line) abort
|
||||
let l:stack = []
|
||||
let l:args = ['']
|
||||
let l:prev = ''
|
||||
|
||||
for l:char in split(a:line, '\zs')
|
||||
if l:char is# ''''
|
||||
if len(l:stack) > 0 && get(l:stack, -1) is# ''''
|
||||
call remove(l:stack, -1)
|
||||
elseif (len(l:stack) == 0 || get(l:stack, -1) isnot# '"') && l:prev isnot# '\'
|
||||
call add(l:stack, l:char)
|
||||
endif
|
||||
elseif (l:char is# '"' || l:char is# '`') && l:prev isnot# '\'
|
||||
if len(l:stack) > 0 && get(l:stack, -1) is# l:char
|
||||
call remove(l:stack, -1)
|
||||
elseif len(l:stack) == 0 || get(l:stack, -1) isnot# ''''
|
||||
call add(l:stack, l:char)
|
||||
endif
|
||||
elseif (l:char is# '(' || l:char is# '[' || l:char is# '{') && l:prev isnot# '\'
|
||||
if len(l:stack) == 0 || get(l:stack, -1) isnot# ''''
|
||||
call add(l:stack, l:char)
|
||||
endif
|
||||
elseif (l:char is# ')' || l:char is# ']' || l:char is# '}') && l:prev isnot# '\'
|
||||
if len(l:stack) > 0 && get(l:stack, -1) is# {')': '(', ']': '[', '}': '{'}[l:char]
|
||||
call remove(l:stack, -1)
|
||||
endif
|
||||
elseif l:char is# ' ' && len(l:stack) == 0
|
||||
if len(get(l:args, -1)) > 0
|
||||
call add(l:args, '')
|
||||
endif
|
||||
|
||||
continue
|
||||
endif
|
||||
|
||||
let l:args[-1] = get(l:args, -1) . l:char
|
||||
endfor
|
||||
|
||||
return l:args
|
||||
endfunction
|
||||
|
||||
" Takes the path prefix and a list of cflags and expands @file arguments to
|
||||
" the contents of the file.
|
||||
"
|
||||
" @file arguments are command line arguments recognised by gcc and clang. For
|
||||
" instance, if @./path/to/file was given to gcc, it would load .path/to/file
|
||||
" and use the contents of that file as arguments.
|
||||
function! ale#c#ExpandAtArgs(path_prefix, raw_split_lines) abort
|
||||
let l:out_lines = []
|
||||
|
||||
for l:option in a:raw_split_lines
|
||||
if stridx(l:option, '@') == 0
|
||||
" This is an argument specifying a location of a file containing other arguments
|
||||
let l:path = join(split(l:option, '\zs')[1:], '')
|
||||
|
||||
" Make path absolute
|
||||
if !ale#path#IsAbsolute(l:path)
|
||||
let l:rel_path = substitute(l:path, '"', '', 'g')
|
||||
let l:rel_path = substitute(l:rel_path, '''', '', 'g')
|
||||
let l:path = ale#path#GetAbsPath(a:path_prefix, l:rel_path)
|
||||
endif
|
||||
|
||||
" Read the file and add all the arguments
|
||||
try
|
||||
let l:additional_args = readfile(l:path)
|
||||
catch
|
||||
continue " All we can really do is skip this argument
|
||||
endtry
|
||||
|
||||
let l:file_lines = []
|
||||
|
||||
for l:line in l:additional_args
|
||||
let l:file_lines += ale#c#ShellSplit(l:line)
|
||||
endfor
|
||||
|
||||
" @file arguments can include other @file arguments, so we must
|
||||
" recurse.
|
||||
let l:out_lines += ale#c#ExpandAtArgs(a:path_prefix, l:file_lines)
|
||||
else
|
||||
" This is not an @file argument, so don't touch it.
|
||||
let l:out_lines += [l:option]
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:out_lines
|
||||
endfunction
|
||||
|
||||
" Quote C/C++ a compiler argument, if needed.
|
||||
"
|
||||
" Quoting arguments might cause issues with some systems/compilers, so we only
|
||||
" quote them if we need to.
|
||||
function! ale#c#QuoteArg(arg) abort
|
||||
if a:arg !~# '\v[#$&*()\\|[\]{};''"<>/?! ^%]'
|
||||
return a:arg
|
||||
endif
|
||||
|
||||
return ale#Escape(a:arg)
|
||||
endfunction
|
||||
|
||||
function! ale#c#ParseCFlags(path_prefix, should_quote, raw_arguments) abort
|
||||
" Expand @file arguments now before parsing
|
||||
let l:arguments = ale#c#ExpandAtArgs(a:path_prefix, a:raw_arguments)
|
||||
" A list of [already_quoted, argument]
|
||||
let l:items = []
|
||||
let l:option_index = 0
|
||||
|
||||
while l:option_index < len(l:arguments)
|
||||
let l:option = l:arguments[l:option_index]
|
||||
let l:option_index = l:option_index + 1
|
||||
|
||||
" Include options, that may need relative path fix
|
||||
if stridx(l:option, '-I') == 0
|
||||
\ || stridx(l:option, '-iquote') == 0
|
||||
\ || stridx(l:option, '-isystem') == 0
|
||||
\ || stridx(l:option, '-idirafter') == 0
|
||||
\ || stridx(l:option, '-iframework') == 0
|
||||
if stridx(l:option, '-I') == 0 && l:option isnot# '-I'
|
||||
let l:arg = join(split(l:option, '\zs')[2:], '')
|
||||
let l:option = '-I'
|
||||
else
|
||||
let l:arg = l:arguments[l:option_index]
|
||||
let l:option_index = l:option_index + 1
|
||||
endif
|
||||
|
||||
" Fix relative paths if needed
|
||||
if !ale#path#IsAbsolute(l:arg)
|
||||
let l:rel_path = substitute(l:arg, '"', '', 'g')
|
||||
let l:rel_path = substitute(l:rel_path, '''', '', 'g')
|
||||
let l:arg = ale#path#GetAbsPath(a:path_prefix, l:rel_path)
|
||||
endif
|
||||
|
||||
call add(l:items, [1, l:option])
|
||||
call add(l:items, [1, ale#Escape(l:arg)])
|
||||
" Options with arg that can be grouped with the option or separate
|
||||
elseif stridx(l:option, '-D') == 0 || stridx(l:option, '-B') == 0
|
||||
if l:option is# '-D' || l:option is# '-B'
|
||||
call add(l:items, [1, l:option])
|
||||
call add(l:items, [0, l:arguments[l:option_index]])
|
||||
let l:option_index = l:option_index + 1
|
||||
else
|
||||
call add(l:items, [0, l:option])
|
||||
endif
|
||||
" Options that have an argument (always separate)
|
||||
elseif l:option is# '-iprefix' || stridx(l:option, '-iwithprefix') == 0
|
||||
\ || l:option is# '-isysroot' || l:option is# '-imultilib'
|
||||
\ || l:option is# '-include' || l:option is# '-imacros'
|
||||
call add(l:items, [0, l:option])
|
||||
call add(l:items, [0, l:arguments[l:option_index]])
|
||||
let l:option_index = l:option_index + 1
|
||||
" Options without argument
|
||||
elseif (stridx(l:option, '-W') == 0 && stridx(l:option, '-Wa,') != 0 && stridx(l:option, '-Wl,') != 0 && stridx(l:option, '-Wp,') != 0)
|
||||
\ || l:option is# '-w' || stridx(l:option, '-pedantic') == 0
|
||||
\ || l:option is# '-ansi' || stridx(l:option, '-std=') == 0
|
||||
\ || stridx(l:option, '-f') == 0 && l:option !~# '\v^-f(dump|diagnostics|no-show-column|stack-usage)'
|
||||
\ || stridx(l:option, '-O') == 0
|
||||
\ || l:option is# '-C' || l:option is# '-CC' || l:option is# '-trigraphs'
|
||||
\ || stridx(l:option, '-nostdinc') == 0 || stridx(l:option, '-iplugindir=') == 0
|
||||
\ || stridx(l:option, '--sysroot=') == 0 || l:option is# '--no-sysroot-suffix'
|
||||
\ || stridx(l:option, '-m') == 0
|
||||
call add(l:items, [0, l:option])
|
||||
endif
|
||||
endwhile
|
||||
|
||||
if a:should_quote
|
||||
" Quote C arguments that haven't already been quoted above.
|
||||
" If and only if we've been asked to quote them.
|
||||
call map(l:items, 'v:val[0] ? v:val[1] : ale#c#QuoteArg(v:val[1])')
|
||||
else
|
||||
call map(l:items, 'v:val[1]')
|
||||
endif
|
||||
|
||||
return join(l:items, ' ')
|
||||
endfunction
|
||||
|
||||
function! ale#c#ParseCFlagsFromMakeOutput(buffer, make_output) abort
|
||||
if !s:CanParseMakefile(a:buffer)
|
||||
return v:null
|
||||
endif
|
||||
|
||||
let l:buffer_filename = expand('#' . a:buffer . ':t')
|
||||
let l:cflag_line = ''
|
||||
|
||||
" Find a line matching this buffer's filename in the make output.
|
||||
for l:line in a:make_output
|
||||
if stridx(l:line, l:buffer_filename) >= 0
|
||||
let l:cflag_line = l:line
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
let l:makefile_path = ale#path#FindNearestFile(a:buffer, 'Makefile')
|
||||
let l:makefile_dir = fnamemodify(l:makefile_path, ':p:h')
|
||||
|
||||
return ale#c#ParseCFlags(l:makefile_dir, 0, ale#c#ShellSplit(l:cflag_line))
|
||||
endfunction
|
||||
|
||||
" Given a buffer number, find the project directory containing
|
||||
" compile_commands.json, and the path to the compile_commands.json file.
|
||||
"
|
||||
" If compile_commands.json cannot be found, two empty strings will be
|
||||
" returned.
|
||||
function! ale#c#FindCompileCommands(buffer) abort
|
||||
" Look above the current source file to find compile_commands.json
|
||||
let l:json_file = ale#path#FindNearestFile(a:buffer, 'compile_commands.json')
|
||||
|
||||
if !empty(l:json_file)
|
||||
return [fnamemodify(l:json_file, ':h'), l:json_file]
|
||||
endif
|
||||
|
||||
" Search in build directories if we can't find it in the project.
|
||||
for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h'))
|
||||
for l:dirname in ale#Var(a:buffer, 'c_build_dir_names')
|
||||
let l:c_build_dir = l:path . s:sep . l:dirname
|
||||
let l:json_file = l:c_build_dir . s:sep . 'compile_commands.json'
|
||||
|
||||
if filereadable(l:json_file)
|
||||
return [l:path, l:json_file]
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
return ['', '']
|
||||
endfunction
|
||||
|
||||
" Find the project root for C/C++ projects.
|
||||
"
|
||||
" The location of compile_commands.json will be used to find project roots.
|
||||
"
|
||||
" If compile_commands.json cannot be found, other common configuration files
|
||||
" will be used to detect the project root.
|
||||
function! ale#c#FindProjectRoot(buffer) abort
|
||||
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||
|
||||
" Fall back on detecting the project root based on other filenames.
|
||||
if empty(l:root)
|
||||
for l:project_filename in g:__ale_c_project_filenames
|
||||
let l:full_path = ale#path#FindNearestFile(a:buffer, l:project_filename)
|
||||
|
||||
if !empty(l:full_path)
|
||||
let l:path = fnamemodify(l:full_path, ':h')
|
||||
|
||||
" Correct .git path detection.
|
||||
if fnamemodify(l:path, ':t') is# '.git'
|
||||
let l:path = fnamemodify(l:path, ':h')
|
||||
endif
|
||||
|
||||
return l:path
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
return l:root
|
||||
endfunction
|
||||
|
||||
" Cache compile_commands.json data in a Dictionary, so we don't need to read
|
||||
" the same files over and over again. The key in the dictionary will include
|
||||
" the last modified time of the file.
|
||||
if !exists('s:compile_commands_cache')
|
||||
let s:compile_commands_cache = {}
|
||||
endif
|
||||
|
||||
function! ale#c#ResetCompileCommandsCache() abort
|
||||
let s:compile_commands_cache = {}
|
||||
endfunction
|
||||
|
||||
function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
|
||||
let l:empty = [{}, {}]
|
||||
|
||||
if empty(a:compile_commands_file)
|
||||
return l:empty
|
||||
endif
|
||||
|
||||
let l:time = getftime(a:compile_commands_file)
|
||||
|
||||
if l:time < 0
|
||||
return l:empty
|
||||
endif
|
||||
|
||||
let l:key = a:compile_commands_file . ':' . l:time
|
||||
|
||||
if has_key(s:compile_commands_cache, l:key)
|
||||
return s:compile_commands_cache[l:key]
|
||||
endif
|
||||
|
||||
let l:raw_data = []
|
||||
silent! let l:raw_data = json_decode(join(readfile(a:compile_commands_file), ''))
|
||||
|
||||
if type(l:raw_data) isnot v:t_list
|
||||
let l:raw_data = []
|
||||
endif
|
||||
|
||||
let l:file_lookup = {}
|
||||
let l:dir_lookup = {}
|
||||
|
||||
for l:entry in (type(l:raw_data) is v:t_list ? l:raw_data : [])
|
||||
let l:filename = ale#path#GetAbsPath(l:entry.directory, l:entry.file)
|
||||
|
||||
" Store a key for lookups by the absolute path to the filename.
|
||||
let l:file_lookup[l:filename] = get(l:file_lookup, l:filename, []) + [l:entry]
|
||||
|
||||
" Store a key for fuzzy lookups by the absolute path to the directory.
|
||||
let l:dirname = fnamemodify(l:filename, ':h')
|
||||
let l:dir_lookup[l:dirname] = get(l:dir_lookup, l:dirname, []) + [l:entry]
|
||||
|
||||
" Store a key for fuzzy lookups by just the basename of the file.
|
||||
let l:basename = tolower(fnamemodify(l:entry.file, ':t'))
|
||||
let l:file_lookup[l:basename] = get(l:file_lookup, l:basename, []) + [l:entry]
|
||||
|
||||
" Store a key for fuzzy lookups by just the basename of the directory.
|
||||
let l:dirbasename = tolower(fnamemodify(l:entry.directory, ':p:h:t'))
|
||||
let l:dir_lookup[l:dirbasename] = get(l:dir_lookup, l:dirbasename, []) + [l:entry]
|
||||
endfor
|
||||
|
||||
if !empty(l:file_lookup) && !empty(l:dir_lookup)
|
||||
let l:result = [l:file_lookup, l:dir_lookup]
|
||||
let s:compile_commands_cache[l:key] = l:result
|
||||
|
||||
return l:result
|
||||
endif
|
||||
|
||||
return l:empty
|
||||
endfunction
|
||||
|
||||
" Get [should_quote, arguments] from either 'command' or 'arguments'
|
||||
" 'arguments' should be quoted later, the split 'command' strings should not.
|
||||
function! s:GetArguments(json_item) abort
|
||||
if has_key(a:json_item, 'arguments')
|
||||
return [1, a:json_item.arguments]
|
||||
elseif has_key(a:json_item, 'command')
|
||||
return [0, ale#c#ShellSplit(a:json_item.command)]
|
||||
endif
|
||||
|
||||
return [0, []]
|
||||
endfunction
|
||||
|
||||
function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
|
||||
let l:buffer_filename = ale#path#Simplify(expand('#' . a:buffer . ':p'))
|
||||
let l:basename = tolower(fnamemodify(l:buffer_filename, ':t'))
|
||||
" Look for any file in the same directory if we can't find an exact match.
|
||||
let l:dir = fnamemodify(l:buffer_filename, ':h')
|
||||
|
||||
" Search for an exact file match first.
|
||||
let l:file_list = get(a:file_lookup, l:buffer_filename, [])
|
||||
|
||||
" We may have to look for /foo/bar instead of C:\foo\bar
|
||||
if empty(l:file_list) && has('win32')
|
||||
let l:file_list = get(
|
||||
\ a:file_lookup,
|
||||
\ ale#path#RemoveDriveLetter(l:buffer_filename),
|
||||
\ []
|
||||
\)
|
||||
endif
|
||||
|
||||
" Try the absolute path to the directory second.
|
||||
let l:dir_list = get(a:dir_lookup, l:dir, [])
|
||||
|
||||
if empty(l:dir_list) && has('win32')
|
||||
let l:dir_list = get(
|
||||
\ a:dir_lookup,
|
||||
\ ale#path#RemoveDriveLetter(l:dir),
|
||||
\ []
|
||||
\)
|
||||
endif
|
||||
|
||||
if empty(l:file_list) && empty(l:dir_list)
|
||||
" If we can't find matches with the path to the file, try a
|
||||
" case-insensitive match for any similarly-named file.
|
||||
let l:file_list = get(a:file_lookup, l:basename, [])
|
||||
|
||||
" If we can't find matches with the path to the directory, try a
|
||||
" case-insensitive match for anything in similarly-named directory.
|
||||
let l:dir_list = get(a:dir_lookup, tolower(fnamemodify(l:dir, ':t')), [])
|
||||
endif
|
||||
|
||||
" A source file matching the header filename.
|
||||
let l:source_file = ''
|
||||
|
||||
if empty(l:file_list) && l:basename =~? '\.h$\|\.hpp$'
|
||||
for l:suffix in ['.c', '.cpp']
|
||||
" Try to find a source file by an absolute path first.
|
||||
let l:key = fnamemodify(l:buffer_filename, ':r') . l:suffix
|
||||
let l:file_list = get(a:file_lookup, l:key, [])
|
||||
|
||||
if empty(l:file_list) && has('win32')
|
||||
let l:file_list = get(
|
||||
\ a:file_lookup,
|
||||
\ ale#path#RemoveDriveLetter(l:key),
|
||||
\ []
|
||||
\)
|
||||
endif
|
||||
|
||||
if empty(l:file_list)
|
||||
" Look fuzzy matches on the basename second.
|
||||
let l:key = fnamemodify(l:basename, ':r') . l:suffix
|
||||
let l:file_list = get(a:file_lookup, l:key, [])
|
||||
endif
|
||||
|
||||
if !empty(l:file_list)
|
||||
let l:source_file = l:key
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
for l:item in l:file_list
|
||||
let l:filename = ale#path#GetAbsPath(l:item.directory, l:item.file)
|
||||
|
||||
" Load the flags for this file, or for a source file matching the
|
||||
" header file.
|
||||
if (
|
||||
\ bufnr(l:filename) is a:buffer
|
||||
\ || (
|
||||
\ !empty(l:source_file)
|
||||
\ && l:filename[-len(l:source_file):] is? l:source_file
|
||||
\ )
|
||||
\)
|
||||
let [l:should_quote, l:args] = s:GetArguments(l:item)
|
||||
|
||||
return ale#c#ParseCFlags(l:item.directory, l:should_quote, l:args)
|
||||
endif
|
||||
endfor
|
||||
|
||||
for l:item in l:dir_list
|
||||
let l:filename = ale#path#GetAbsPath(l:item.directory, l:item.file)
|
||||
|
||||
if ale#path#RemoveDriveLetter(fnamemodify(l:filename, ':h'))
|
||||
\ is? ale#path#RemoveDriveLetter(l:dir)
|
||||
let [l:should_quote, l:args] = s:GetArguments(l:item)
|
||||
|
||||
return ale#c#ParseCFlags(l:item.directory, l:should_quote, l:args)
|
||||
endif
|
||||
endfor
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale#c#FlagsFromCompileCommands(buffer, compile_commands_file) abort
|
||||
let l:lookups = s:GetLookupFromCompileCommandsFile(a:compile_commands_file)
|
||||
let l:file_lookup = l:lookups[0]
|
||||
let l:dir_lookup = l:lookups[1]
|
||||
|
||||
return ale#c#ParseCompileCommandsFlags(a:buffer, l:file_lookup, l:dir_lookup)
|
||||
endfunction
|
||||
|
||||
function! ale#c#GetCFlags(buffer, output) abort
|
||||
let l:cflags = v:null
|
||||
|
||||
if ale#Var(a:buffer, 'c_parse_compile_commands')
|
||||
let [l:root, l:json_file] = ale#c#FindCompileCommands(a:buffer)
|
||||
|
||||
if !empty(l:json_file)
|
||||
let l:cflags = ale#c#FlagsFromCompileCommands(a:buffer, l:json_file)
|
||||
endif
|
||||
endif
|
||||
|
||||
if empty(l:cflags) && s:CanParseMakefile(a:buffer) && !empty(a:output)
|
||||
let l:cflags = ale#c#ParseCFlagsFromMakeOutput(a:buffer, a:output)
|
||||
endif
|
||||
|
||||
if l:cflags is v:null
|
||||
let l:cflags = ale#c#IncludeOptions(ale#c#FindLocalHeaderPaths(a:buffer))
|
||||
endif
|
||||
|
||||
return l:cflags isnot v:null ? l:cflags : ''
|
||||
endfunction
|
||||
|
||||
function! ale#c#GetMakeCommand(buffer) abort
|
||||
if s:CanParseMakefile(a:buffer)
|
||||
let l:path = ale#path#FindNearestFile(a:buffer, 'Makefile')
|
||||
|
||||
if empty(l:path)
|
||||
let l:path = ale#path#FindNearestFile(a:buffer, 'GNUmakefile')
|
||||
endif
|
||||
|
||||
if !empty(l:path)
|
||||
let l:always_make = ale#Var(a:buffer, 'c_always_make')
|
||||
|
||||
return [
|
||||
\ fnamemodify(l:path, ':h'),
|
||||
\ 'make -n' . (l:always_make ? ' --always-make' : ''),
|
||||
\]
|
||||
endif
|
||||
endif
|
||||
|
||||
return ['', '']
|
||||
endfunction
|
||||
|
||||
function! ale#c#RunMakeCommand(buffer, Callback) abort
|
||||
let [l:cwd, l:command] = ale#c#GetMakeCommand(a:buffer)
|
||||
|
||||
if empty(l:command)
|
||||
return a:Callback(a:buffer, [])
|
||||
endif
|
||||
|
||||
return ale#command#Run(
|
||||
\ a:buffer,
|
||||
\ l:command,
|
||||
\ {b, output -> a:Callback(a:buffer, output)},
|
||||
\ {'cwd': l:cwd},
|
||||
\)
|
||||
endfunction
|
||||
|
||||
" Given a buffer number, search for a project root, and output a List
|
||||
" of directories to include based on some heuristics.
|
||||
"
|
||||
" For projects with headers in the project root, the project root will
|
||||
" be returned.
|
||||
"
|
||||
" For projects with an 'include' directory, that directory will be returned.
|
||||
function! ale#c#FindLocalHeaderPaths(buffer) abort
|
||||
let l:project_root = ale#c#FindProjectRoot(a:buffer)
|
||||
|
||||
if empty(l:project_root)
|
||||
return []
|
||||
endif
|
||||
|
||||
" See if we can find .h files directory in the project root.
|
||||
" If we can, that's our include directory.
|
||||
if !empty(globpath(l:project_root, '*.h', 0))
|
||||
return [l:project_root]
|
||||
endif
|
||||
|
||||
" Look for .hpp files too.
|
||||
if !empty(globpath(l:project_root, '*.hpp', 0))
|
||||
return [l:project_root]
|
||||
endif
|
||||
|
||||
" If we find an 'include' directory in the project root, then use that.
|
||||
if isdirectory(l:project_root . '/include')
|
||||
return [ale#path#Simplify(l:project_root . s:sep . 'include')]
|
||||
endif
|
||||
|
||||
return []
|
||||
endfunction
|
||||
|
||||
" Given a List of include paths, create a string containing the -I include
|
||||
" options for those paths, with the paths escaped for use in the shell.
|
||||
function! ale#c#IncludeOptions(include_paths) abort
|
||||
let l:option_list = []
|
||||
|
||||
for l:path in a:include_paths
|
||||
call add(l:option_list, '-I' . ale#Escape(l:path))
|
||||
endfor
|
||||
|
||||
if empty(l:option_list)
|
||||
return ''
|
||||
endif
|
||||
|
||||
return join(l:option_list)
|
||||
endfunction
|
||||
|
||||
" Get the language flag depending on on the executable, options and
|
||||
" file extension
|
||||
function! ale#c#GetLanguageFlag(
|
||||
\ buffer,
|
||||
\ executable,
|
||||
\ use_header_lang_flag,
|
||||
\ header_exts,
|
||||
\ linter_lang_flag
|
||||
\) abort
|
||||
" Use only '-header' if the executable is 'clang' by default
|
||||
if a:use_header_lang_flag == -1
|
||||
let l:use_header_lang_flag = a:executable =~# 'clang'
|
||||
else
|
||||
let l:use_header_lang_flag = a:use_header_lang_flag
|
||||
endif
|
||||
|
||||
" If we don't use the header language flag, return the default linter
|
||||
" language flag
|
||||
if !l:use_header_lang_flag
|
||||
return a:linter_lang_flag
|
||||
endif
|
||||
|
||||
" Get the buffer file extension
|
||||
let l:buf_ext = expand('#' . a:buffer . ':e')
|
||||
|
||||
" If the buffer file is an header according to its extension, use
|
||||
" the linter language flag + '-header', ex: 'c-header'
|
||||
if index(a:header_exts, l:buf_ext) >= 0
|
||||
return a:linter_lang_flag . '-header'
|
||||
endif
|
||||
|
||||
" Else, use the default linter language flag
|
||||
return a:linter_lang_flag
|
||||
endfunction
|
379
vim/.vim/autoload/ale/code_action.vim
Normal file
379
vim/.vim/autoload/ale/code_action.vim
Normal file
@ -0,0 +1,379 @@
|
||||
" Author: Jerko Steiner <jerko.steiner@gmail.com>
|
||||
" Description: Code action support for LSP / tsserver
|
||||
|
||||
function! ale#code_action#ReloadBuffer() abort
|
||||
let l:buffer = bufnr('')
|
||||
|
||||
execute 'augroup ALECodeActionReloadGroup' . l:buffer
|
||||
autocmd!
|
||||
augroup END
|
||||
|
||||
silent! execute 'augroup! ALECodeActionReloadGroup' . l:buffer
|
||||
|
||||
call ale#util#Execute(':e!')
|
||||
endfunction
|
||||
|
||||
function! ale#code_action#HandleCodeAction(code_action, options) abort
|
||||
let l:current_buffer = bufnr('')
|
||||
let l:changes = a:code_action.changes
|
||||
|
||||
for l:file_code_edit in l:changes
|
||||
call ale#code_action#ApplyChanges(
|
||||
\ l:file_code_edit.fileName,
|
||||
\ l:file_code_edit.textChanges,
|
||||
\ a:options,
|
||||
\)
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:ChangeCmp(left, right) abort
|
||||
if a:left.start.line < a:right.start.line
|
||||
return -1
|
||||
endif
|
||||
|
||||
if a:left.start.line > a:right.start.line
|
||||
return 1
|
||||
endif
|
||||
|
||||
if a:left.start.offset < a:right.start.offset
|
||||
return -1
|
||||
endif
|
||||
|
||||
if a:left.start.offset > a:right.start.offset
|
||||
return 1
|
||||
endif
|
||||
|
||||
if a:left.end.line < a:right.end.line
|
||||
return -1
|
||||
endif
|
||||
|
||||
if a:left.end.line > a:right.end.line
|
||||
return 1
|
||||
endif
|
||||
|
||||
if a:left.end.offset < a:right.end.offset
|
||||
return -1
|
||||
endif
|
||||
|
||||
if a:left.end.offset > a:right.end.offset
|
||||
return 1
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! ale#code_action#ApplyChanges(filename, changes, options) abort
|
||||
let l:should_save = get(a:options, 'should_save')
|
||||
let l:conn_id = get(a:options, 'conn_id')
|
||||
|
||||
let l:orig_buffer = bufnr('')
|
||||
|
||||
" The buffer is used to determine the fileformat, if available.
|
||||
let l:buffer = bufnr(a:filename)
|
||||
|
||||
if l:buffer != l:orig_buffer
|
||||
call ale#util#Execute('silent edit ' . a:filename)
|
||||
let l:buffer = bufnr('')
|
||||
endif
|
||||
|
||||
let l:lines = getbufline(l:buffer, 1, '$')
|
||||
|
||||
" Add empty line if there's trailing newline, like readfile() does.
|
||||
if getbufvar(l:buffer, '&eol')
|
||||
let l:lines += ['']
|
||||
endif
|
||||
|
||||
let l:pos = getpos('.')[1:2]
|
||||
|
||||
" Changes have to be sorted so we apply them from bottom-to-top
|
||||
for l:code_edit in reverse(sort(copy(a:changes), function('s:ChangeCmp')))
|
||||
let l:line = l:code_edit.start.line
|
||||
let l:column = l:code_edit.start.offset
|
||||
let l:end_line = l:code_edit.end.line
|
||||
let l:end_column = l:code_edit.end.offset
|
||||
let l:text = l:code_edit.newText
|
||||
|
||||
let l:insertions = split(l:text, '\n', 1)
|
||||
|
||||
" Fix invalid columns
|
||||
let l:column = l:column > 0 ? l:column : 1
|
||||
let l:end_column = l:end_column > 0 ? l:end_column : 1
|
||||
|
||||
" Clamp start to BOF
|
||||
if l:line < 1
|
||||
let [l:line, l:column] = [1, 1]
|
||||
endif
|
||||
|
||||
" Clamp start to EOF
|
||||
if l:line > len(l:lines) || l:line == len(l:lines) && l:column > len(l:lines[-1]) + 1
|
||||
let [l:line, l:column] = [len(l:lines), len(l:lines[-1]) + 1]
|
||||
" Special case when start is after EOL
|
||||
elseif l:line < len(l:lines) && l:column > len(l:lines[l:line - 1]) + 1
|
||||
let [l:line, l:column] = [l:line + 1, 1]
|
||||
endif
|
||||
|
||||
" Adjust end: clamp if invalid and/or adjust if we moved start
|
||||
if l:end_line < l:line || l:end_line == l:line && l:end_column < l:column
|
||||
let [l:end_line, l:end_column] = [l:line, l:column]
|
||||
endif
|
||||
|
||||
" Clamp end to EOF
|
||||
if l:end_line > len(l:lines) || l:end_line == len(l:lines) && l:end_column > len(l:lines[-1]) + 1
|
||||
let [l:end_line, l:end_column] = [len(l:lines), len(l:lines[-1]) + 1]
|
||||
" Special case when end is after EOL
|
||||
elseif l:end_line < len(l:lines) && l:end_column > len(l:lines[l:end_line - 1]) + 1
|
||||
let [l:end_line, l:end_column] = [l:end_line + 1, 1]
|
||||
endif
|
||||
|
||||
" Careful, [:-1] is not an empty list
|
||||
let l:start = l:line is 1 ? [] : l:lines[: l:line - 2]
|
||||
let l:middle = l:column is 1 ? [''] : [l:lines[l:line - 1][: l:column - 2]]
|
||||
|
||||
let l:middle[-1] .= l:insertions[0]
|
||||
let l:middle += l:insertions[1:]
|
||||
let l:middle[-1] .= l:lines[l:end_line - 1][l:end_column - 1 :]
|
||||
|
||||
let l:end_line_len = len(l:lines[l:end_line - 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:column_offset = len(l:middle[-1]) - l:end_line_len
|
||||
|
||||
" Keep cursor where it was (if outside of changes) or move it after
|
||||
" the changed text (if inside), but don't touch it when the change
|
||||
" spans the entire buffer, in which case we have no clue and it's
|
||||
" better to not do anything.
|
||||
if l:line isnot 1 || l:column isnot 1
|
||||
\|| l:end_line < l:lines_before_change
|
||||
\|| l:end_line == l:lines_before_change && l:end_column <= 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])
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Make sure to add a trailing newline if and only if it should be added.
|
||||
if l:lines[-1] is# '' && getbufvar(l:buffer, '&eol')
|
||||
call remove(l:lines, -1)
|
||||
else
|
||||
call setbufvar(l:buffer, '&eol', 0)
|
||||
endif
|
||||
|
||||
call ale#util#SetBufferContents(l:buffer, l:lines)
|
||||
|
||||
call ale#lsp#NotifyForChanges(l:conn_id, l:buffer)
|
||||
|
||||
if l:should_save
|
||||
call ale#util#Execute('silent w!')
|
||||
endif
|
||||
|
||||
call setpos('.', [0, l:pos[0], l:pos[1], 0])
|
||||
|
||||
if l:orig_buffer != l:buffer && bufexists(l:orig_buffer)
|
||||
call ale#util#Execute('silent buf ' . string(l:orig_buffer))
|
||||
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 necessary, 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
|
||||
|
||||
function! ale#code_action#GetChanges(workspace_edit) abort
|
||||
if a:workspace_edit is v:null
|
||||
return {}
|
||||
endif
|
||||
|
||||
let l:changes = {}
|
||||
|
||||
if has_key(a:workspace_edit, 'changes') && !empty(a:workspace_edit.changes)
|
||||
return a:workspace_edit.changes
|
||||
elseif has_key(a:workspace_edit, 'documentChanges')
|
||||
let l:document_changes = []
|
||||
|
||||
if type(a:workspace_edit.documentChanges) is v:t_dict
|
||||
\ && has_key(a:workspace_edit.documentChanges, 'edits')
|
||||
call add(l:document_changes, a:workspace_edit.documentChanges)
|
||||
elseif type(a:workspace_edit.documentChanges) is v:t_list
|
||||
let l:document_changes = a:workspace_edit.documentChanges
|
||||
endif
|
||||
|
||||
for l:text_document_edit in l:document_changes
|
||||
let l:filename = l:text_document_edit.textDocument.uri
|
||||
let l:edits = l:text_document_edit.edits
|
||||
let l:changes[l:filename] = l:edits
|
||||
endfor
|
||||
endif
|
||||
|
||||
return l:changes
|
||||
endfunction
|
||||
|
||||
function! ale#code_action#BuildChangesList(changes_map) abort
|
||||
let l:changes = []
|
||||
|
||||
for l:file_name in keys(a:changes_map)
|
||||
let l:text_edits = a:changes_map[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#util#ToResource(l:file_name),
|
||||
\ 'textChanges': l:text_changes,
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:changes
|
||||
endfunction
|
||||
|
||||
function! s:EscapeMenuName(text) abort
|
||||
return substitute(a:text, '\\\| \|\.\|&', '\\\0', 'g')
|
||||
endfunction
|
||||
|
||||
function! s:UpdateMenu(data, menu_items) abort
|
||||
silent! aunmenu PopUp.Refactor\.\.\.
|
||||
|
||||
if empty(a:data)
|
||||
return
|
||||
endif
|
||||
|
||||
for [l:type, l:item] in a:menu_items
|
||||
let l:name = l:type is# 'tsserver' ? l:item.name : l:item.title
|
||||
let l:func_name = l:type is# 'tsserver'
|
||||
\ ? 'ale#codefix#ApplyTSServerCodeAction'
|
||||
\ : 'ale#codefix#ApplyLSPCodeAction'
|
||||
|
||||
execute printf(
|
||||
\ 'anoremenu <silent> PopUp.&Refactor\.\.\..%s'
|
||||
\ . ' :call %s(%s, %s)<CR>',
|
||||
\ s:EscapeMenuName(l:name),
|
||||
\ l:func_name,
|
||||
\ string(a:data),
|
||||
\ string(l:item),
|
||||
\)
|
||||
endfor
|
||||
|
||||
if empty(a:menu_items)
|
||||
silent! anoremenu PopUp.Refactor\.\.\..(None) :silent
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:GetCodeActions(linter, options) abort
|
||||
let l:buffer = bufnr('')
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
let l:column = min([l:column, len(getline(l:line))])
|
||||
|
||||
let l:location = {
|
||||
\ 'buffer': l:buffer,
|
||||
\ 'line': l:line,
|
||||
\ 'column': l:column,
|
||||
\ 'end_line': l:line,
|
||||
\ 'end_column': l:column,
|
||||
\}
|
||||
let l:Callback = function('s:OnReady', [l:location, a:options])
|
||||
call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||
endfunction
|
||||
|
||||
function! ale#code_action#GetCodeActions(options) abort
|
||||
silent! aunmenu PopUp.Rename
|
||||
silent! aunmenu PopUp.Refactor\.\.\.
|
||||
|
||||
" Only display the menu items if there's an LSP server.
|
||||
if len(ale#lsp_linter#GetEnabled(bufnr(''))) > 0
|
||||
if !empty(expand('<cword>'))
|
||||
silent! anoremenu <silent> PopUp.Rename :ALERename<CR>
|
||||
endif
|
||||
|
||||
silent! anoremenu <silent> PopUp.Refactor\.\.\..(None) :silent<CR>
|
||||
|
||||
call ale#codefix#Execute(
|
||||
\ mode() is# 'v' || mode() is# "\<C-V>",
|
||||
\ function('s:UpdateMenu')
|
||||
\)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:Setup(enabled) abort
|
||||
augroup ALECodeActionsGroup
|
||||
autocmd!
|
||||
|
||||
if a:enabled
|
||||
autocmd MenuPopup * :call ale#code_action#GetCodeActions({})
|
||||
endif
|
||||
augroup END
|
||||
|
||||
if !a:enabled
|
||||
silent! augroup! ALECodeActionsGroup
|
||||
|
||||
silent! aunmenu PopUp.Rename
|
||||
silent! aunmenu PopUp.Refactor\.\.\.
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#code_action#EnablePopUpMenu() abort
|
||||
call s:Setup(1)
|
||||
endfunction
|
||||
|
||||
function! ale#code_action#DisablePopUpMenu() abort
|
||||
call s:Setup(0)
|
||||
endfunction
|
491
vim/.vim/autoload/ale/codefix.vim
Normal file
491
vim/.vim/autoload/ale/codefix.vim
Normal file
@ -0,0 +1,491 @@
|
||||
" Author: Dalius Dobravolskas <dalius.dobravolskas@gmail.com>
|
||||
" Description: Code Fix support for tsserver and LSP servers
|
||||
|
||||
let s:codefix_map = {}
|
||||
|
||||
" Used to get the codefix map in tests.
|
||||
function! ale#codefix#GetMap() abort
|
||||
return deepcopy(s:codefix_map)
|
||||
endfunction
|
||||
|
||||
" Used to set the codefix map in tests.
|
||||
function! ale#codefix#SetMap(map) abort
|
||||
let s:codefix_map = a:map
|
||||
endfunction
|
||||
|
||||
function! ale#codefix#ClearLSPData() abort
|
||||
let s:codefix_map = {}
|
||||
endfunction
|
||||
|
||||
function! s:message(message) abort
|
||||
call ale#util#Execute('echom ' . string(a:message))
|
||||
endfunction
|
||||
|
||||
function! ale#codefix#ApplyTSServerCodeAction(data, item) abort
|
||||
if has_key(a:item, 'changes')
|
||||
let l:changes = a:item.changes
|
||||
|
||||
call ale#code_action#HandleCodeAction(
|
||||
\ {
|
||||
\ 'description': 'codefix',
|
||||
\ 'changes': l:changes,
|
||||
\ },
|
||||
\ {},
|
||||
\)
|
||||
else
|
||||
let l:message = ale#lsp#tsserver_message#GetEditsForRefactor(
|
||||
\ a:data.buffer,
|
||||
\ a:data.line,
|
||||
\ a:data.column,
|
||||
\ a:data.end_line,
|
||||
\ a:data.end_column,
|
||||
\ a:item.id[0],
|
||||
\ a:item.id[1],
|
||||
\)
|
||||
|
||||
let l:request_id = ale#lsp#Send(a:data.connection_id, l:message)
|
||||
|
||||
let s:codefix_map[l:request_id] = a:data
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#codefix#HandleTSServerResponse(conn_id, response) abort
|
||||
if !has_key(a:response, 'request_seq')
|
||||
\ || !has_key(s:codefix_map, a:response.request_seq)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:data = remove(s:codefix_map, a:response.request_seq)
|
||||
let l:MenuCallback = get(l:data, 'menu_callback', v:null)
|
||||
|
||||
if get(a:response, 'command', '') is# 'getCodeFixes'
|
||||
if get(a:response, 'success', v:false) is v:false
|
||||
\&& l:MenuCallback is v:null
|
||||
let l:message = get(a:response, 'message', 'unknown')
|
||||
call s:message('Error while getting code fixes. Reason: ' . l:message)
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:result = get(a:response, 'body', [])
|
||||
call filter(l:result, 'has_key(v:val, ''changes'')')
|
||||
|
||||
if l:MenuCallback isnot v:null
|
||||
call l:MenuCallback(
|
||||
\ l:data,
|
||||
\ map(copy(l:result), '[''tsserver'', v:val]')
|
||||
\)
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
if len(l:result) == 0
|
||||
call s:message('No code fixes available.')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:code_fix_to_apply = 0
|
||||
|
||||
if len(l:result) == 1
|
||||
let l:code_fix_to_apply = 1
|
||||
else
|
||||
let l:codefix_no = 1
|
||||
let l:codefixstring = "Code Fixes:\n"
|
||||
|
||||
for l:codefix in l:result
|
||||
let l:codefixstring .= l:codefix_no . ') '
|
||||
\ . l:codefix.description . "\n"
|
||||
let l:codefix_no += 1
|
||||
endfor
|
||||
|
||||
let l:codefixstring .= 'Type number and <Enter> (empty cancels): '
|
||||
|
||||
let l:code_fix_to_apply = ale#util#Input(l:codefixstring, '')
|
||||
let l:code_fix_to_apply = str2nr(l:code_fix_to_apply)
|
||||
|
||||
if l:code_fix_to_apply == 0
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
call ale#codefix#ApplyTSServerCodeAction(
|
||||
\ l:data,
|
||||
\ l:result[l:code_fix_to_apply - 1],
|
||||
\)
|
||||
elseif get(a:response, 'command', '') is# 'getApplicableRefactors'
|
||||
if get(a:response, 'success', v:false) is v:false
|
||||
\&& l:MenuCallback is v:null
|
||||
let l:message = get(a:response, 'message', 'unknown')
|
||||
call s:message('Error while getting applicable refactors. Reason: ' . l:message)
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:result = get(a:response, 'body', [])
|
||||
|
||||
if len(l:result) == 0
|
||||
call s:message('No applicable refactors available.')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:refactors = []
|
||||
|
||||
for l:item in l:result
|
||||
for l:action in l:item.actions
|
||||
call add(l:refactors, {
|
||||
\ 'name': l:action.description,
|
||||
\ 'id': [l:item.name, l:action.name],
|
||||
\})
|
||||
endfor
|
||||
endfor
|
||||
|
||||
if l:MenuCallback isnot v:null
|
||||
call l:MenuCallback(
|
||||
\ l:data,
|
||||
\ map(copy(l:refactors), '[''tsserver'', v:val]')
|
||||
\)
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:refactor_no = 1
|
||||
let l:refactorstring = "Applicable refactors:\n"
|
||||
|
||||
for l:refactor in l:refactors
|
||||
let l:refactorstring .= l:refactor_no . ') '
|
||||
\ . l:refactor.name . "\n"
|
||||
let l:refactor_no += 1
|
||||
endfor
|
||||
|
||||
let l:refactorstring .= 'Type number and <Enter> (empty cancels): '
|
||||
|
||||
let l:refactor_to_apply = ale#util#Input(l:refactorstring, '')
|
||||
let l:refactor_to_apply = str2nr(l:refactor_to_apply)
|
||||
|
||||
if l:refactor_to_apply == 0
|
||||
return
|
||||
endif
|
||||
|
||||
let l:id = l:refactors[l:refactor_to_apply - 1].id
|
||||
|
||||
call ale#codefix#ApplyTSServerCodeAction(
|
||||
\ l:data,
|
||||
\ l:refactors[l:refactor_to_apply - 1],
|
||||
\)
|
||||
elseif get(a:response, 'command', '') is# 'getEditsForRefactor'
|
||||
if get(a:response, 'success', v:false) is v:false
|
||||
let l:message = get(a:response, 'message', 'unknown')
|
||||
call s:message('Error while getting edits for refactor. Reason: ' . l:message)
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
call ale#code_action#HandleCodeAction(
|
||||
\ {
|
||||
\ 'description': 'editsForRefactor',
|
||||
\ 'changes': a:response.body.edits,
|
||||
\ },
|
||||
\ {},
|
||||
\)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#codefix#ApplyLSPCodeAction(data, item) abort
|
||||
if has_key(a:item, 'command')
|
||||
\&& type(a:item.command) == v:t_dict
|
||||
let l:command = a:item.command
|
||||
let l:message = ale#lsp#message#ExecuteCommand(
|
||||
\ l:command.command,
|
||||
\ l:command.arguments,
|
||||
\)
|
||||
|
||||
let l:request_id = ale#lsp#Send(a:data.connection_id, l:message)
|
||||
elseif has_key(a:item, 'command') && has_key(a:item, 'arguments')
|
||||
\&& type(a:item.command) == v:t_string
|
||||
let l:message = ale#lsp#message#ExecuteCommand(
|
||||
\ a:item.command,
|
||||
\ a:item.arguments,
|
||||
\)
|
||||
|
||||
let l:request_id = ale#lsp#Send(a:data.connection_id, l:message)
|
||||
elseif has_key(a:item, 'edit') || has_key(a:item, 'arguments')
|
||||
if has_key(a:item, 'edit')
|
||||
let l:topass = a:item.edit
|
||||
else
|
||||
let l:topass = a:item.arguments[0]
|
||||
endif
|
||||
|
||||
let l:changes_map = ale#code_action#GetChanges(l:topass)
|
||||
|
||||
if empty(l:changes_map)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:changes = ale#code_action#BuildChangesList(l:changes_map)
|
||||
|
||||
call ale#code_action#HandleCodeAction(
|
||||
\ {
|
||||
\ 'description': 'codeaction',
|
||||
\ 'changes': l:changes,
|
||||
\ },
|
||||
\ {},
|
||||
\)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#codefix#HandleLSPResponse(conn_id, response) abort
|
||||
if has_key(a:response, 'method')
|
||||
\ && a:response.method is# 'workspace/applyEdit'
|
||||
\ && has_key(a:response, 'params')
|
||||
let l:params = a:response.params
|
||||
|
||||
let l:changes_map = ale#code_action#GetChanges(l:params.edit)
|
||||
|
||||
if empty(l:changes_map)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:changes = ale#code_action#BuildChangesList(l:changes_map)
|
||||
|
||||
call ale#code_action#HandleCodeAction(
|
||||
\ {
|
||||
\ 'description': 'applyEdit',
|
||||
\ 'changes': l:changes,
|
||||
\ },
|
||||
\ {}
|
||||
\)
|
||||
elseif has_key(a:response, 'id')
|
||||
\&& has_key(s:codefix_map, a:response.id)
|
||||
let l:data = remove(s:codefix_map, a:response.id)
|
||||
let l:MenuCallback = get(l:data, 'menu_callback', v:null)
|
||||
|
||||
let l:result = get(a:response, 'result')
|
||||
|
||||
if type(l:result) != v:t_list
|
||||
let l:result = []
|
||||
endif
|
||||
|
||||
" Send the results to the menu callback, if set.
|
||||
if l:MenuCallback isnot v:null
|
||||
call l:MenuCallback(
|
||||
\ l:data,
|
||||
\ map(copy(l:result), '[''lsp'', v:val]')
|
||||
\)
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
if len(l:result) == 0
|
||||
call s:message('No code actions received from server')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:codeaction_no = 1
|
||||
let l:codeactionstring = "Code Fixes:\n"
|
||||
|
||||
for l:codeaction in l:result
|
||||
let l:codeactionstring .= l:codeaction_no . ') '
|
||||
\ . l:codeaction.title . "\n"
|
||||
let l:codeaction_no += 1
|
||||
endfor
|
||||
|
||||
let l:codeactionstring .= 'Type number and <Enter> (empty cancels): '
|
||||
|
||||
let l:codeaction_to_apply = ale#util#Input(l:codeactionstring, '')
|
||||
let l:codeaction_to_apply = str2nr(l:codeaction_to_apply)
|
||||
|
||||
if l:codeaction_to_apply == 0
|
||||
return
|
||||
endif
|
||||
|
||||
let l:item = l:result[l:codeaction_to_apply - 1]
|
||||
|
||||
call ale#codefix#ApplyLSPCodeAction(l:data, l:item)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:FindError(buffer, line, column, end_line, end_column, linter_name) abort
|
||||
let l:nearest_error = v:null
|
||||
|
||||
if a:line == a:end_line
|
||||
\&& a:column == a:end_column
|
||||
\&& has_key(g:ale_buffer_info, a:buffer)
|
||||
let l:nearest_error_diff = -1
|
||||
|
||||
for l:error in get(g:ale_buffer_info[a:buffer], 'loclist', [])
|
||||
if has_key(l:error, 'code')
|
||||
\ && (a:linter_name is v:null || l:error.linter_name is# a:linter_name)
|
||||
\ && l:error.lnum == a:line
|
||||
let l:diff = abs(l:error.col - a:column)
|
||||
|
||||
if l:nearest_error_diff == -1 || l:diff < l:nearest_error_diff
|
||||
let l:nearest_error_diff = l:diff
|
||||
let l:nearest_error = l:error
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
return l:nearest_error
|
||||
endfunction
|
||||
|
||||
function! s:OnReady(
|
||||
\ line,
|
||||
\ column,
|
||||
\ end_line,
|
||||
\ end_column,
|
||||
\ MenuCallback,
|
||||
\ linter,
|
||||
\ lsp_details,
|
||||
\) abort
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
if !ale#lsp#HasCapability(l:id, 'code_actions')
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
|
||||
if a:linter.lsp is# 'tsserver'
|
||||
let l:nearest_error =
|
||||
\ s:FindError(l:buffer, a:line, a:column, a:end_line, a:end_column, a:linter.lsp)
|
||||
|
||||
if l:nearest_error isnot v:null
|
||||
let l:message = ale#lsp#tsserver_message#GetCodeFixes(
|
||||
\ l:buffer,
|
||||
\ a:line,
|
||||
\ a:column,
|
||||
\ a:line,
|
||||
\ a:column,
|
||||
\ [l:nearest_error.code],
|
||||
\)
|
||||
else
|
||||
let l:message = ale#lsp#tsserver_message#GetApplicableRefactors(
|
||||
\ l:buffer,
|
||||
\ a:line,
|
||||
\ a:column,
|
||||
\ a:end_line,
|
||||
\ a:end_column,
|
||||
\)
|
||||
endif
|
||||
else
|
||||
" Send a message saying the buffer has changed first, otherwise
|
||||
" completions won't know what text is nearby.
|
||||
call ale#lsp#NotifyForChanges(l:id, l:buffer)
|
||||
|
||||
let l:diagnostics = []
|
||||
let l:nearest_error =
|
||||
\ s:FindError(l:buffer, a:line, a:column, a:end_line, a:end_column, v:null)
|
||||
|
||||
if l:nearest_error isnot v:null
|
||||
let l:diagnostics = [
|
||||
\ {
|
||||
\ 'code': l:nearest_error.code,
|
||||
\ 'message': l:nearest_error.text,
|
||||
\ 'range': {
|
||||
\ 'start': {
|
||||
\ 'line': l:nearest_error.lnum - 1,
|
||||
\ 'character': l:nearest_error.col - 1,
|
||||
\ },
|
||||
\ 'end': {
|
||||
\ 'line': get(l:nearest_error, 'end_lnum', 1) - 1,
|
||||
\ 'character': get(l:nearest_error, 'end_col', 0)
|
||||
\ },
|
||||
\ },
|
||||
\ },
|
||||
\]
|
||||
endif
|
||||
|
||||
let l:message = ale#lsp#message#CodeAction(
|
||||
\ l:buffer,
|
||||
\ a:line,
|
||||
\ a:column,
|
||||
\ a:end_line,
|
||||
\ a:end_column,
|
||||
\ l:diagnostics,
|
||||
\)
|
||||
endif
|
||||
|
||||
let l:Callback = a:linter.lsp is# 'tsserver'
|
||||
\ ? function('ale#codefix#HandleTSServerResponse')
|
||||
\ : function('ale#codefix#HandleLSPResponse')
|
||||
|
||||
call ale#lsp#RegisterCallback(l:id, l:Callback)
|
||||
|
||||
let l:request_id = ale#lsp#Send(l:id, l:message)
|
||||
|
||||
let s:codefix_map[l:request_id] = {
|
||||
\ 'connection_id': l:id,
|
||||
\ 'buffer': l:buffer,
|
||||
\ 'line': a:line,
|
||||
\ 'column': a:column,
|
||||
\ 'end_line': a:end_line,
|
||||
\ 'end_column': a:end_column,
|
||||
\ 'menu_callback': a:MenuCallback,
|
||||
\}
|
||||
endfunction
|
||||
|
||||
function! s:ExecuteGetCodeFix(linter, range, MenuCallback) abort
|
||||
let l:buffer = bufnr('')
|
||||
|
||||
if a:range == 0
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
let l:end_line = l:line
|
||||
let l:end_column = l:column
|
||||
|
||||
" Expand the range to cover the current word, if there is one.
|
||||
let l:cword = expand('<cword>')
|
||||
|
||||
if !empty(l:cword)
|
||||
let l:search_pos = searchpos('\V' . l:cword, 'bn', l:line)
|
||||
|
||||
if l:search_pos != [0, 0]
|
||||
let l:column = l:search_pos[1]
|
||||
let l:end_column = l:column + len(l:cword) - 1
|
||||
endif
|
||||
endif
|
||||
elseif mode() is# 'v' || mode() is# "\<C-V>"
|
||||
" You need to get the start and end in a different way when you're in
|
||||
" visual mode.
|
||||
let [l:line, l:column] = getpos('v')[1:2]
|
||||
let [l:end_line, l:end_column] = getpos('.')[1:2]
|
||||
else
|
||||
let [l:line, l:column] = getpos("'<")[1:2]
|
||||
let [l:end_line, l:end_column] = getpos("'>")[1:2]
|
||||
endif
|
||||
|
||||
let l:column = max([min([l:column, len(getline(l:line))]), 1])
|
||||
let l:end_column = min([l:end_column, len(getline(l:end_line))])
|
||||
|
||||
let l:Callback = function(
|
||||
\ 's:OnReady', [l:line, l:column, l:end_line, l:end_column, a:MenuCallback]
|
||||
\)
|
||||
|
||||
call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||
endfunction
|
||||
|
||||
function! ale#codefix#Execute(range, ...) abort
|
||||
if a:0 > 1
|
||||
throw 'Too many arguments'
|
||||
endif
|
||||
|
||||
let l:MenuCallback = get(a:000, 0, v:null)
|
||||
let l:linters = ale#lsp_linter#GetEnabled(bufnr(''))
|
||||
|
||||
if empty(l:linters)
|
||||
if l:MenuCallback is v:null
|
||||
call s:message('No active LSPs')
|
||||
else
|
||||
call l:MenuCallback({}, [])
|
||||
endif
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
for l:linter in l:linters
|
||||
call s:ExecuteGetCodeFix(l:linter, a:range, l:MenuCallback)
|
||||
endfor
|
||||
endfunction
|
473
vim/.vim/autoload/ale/command.vim
Normal file
473
vim/.vim/autoload/ale/command.vim
Normal file
@ -0,0 +1,473 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Functions for formatting command strings, running commands, and
|
||||
" managing files during linting and fixing cycles.
|
||||
|
||||
" This dictionary holds lists of files and directories to remove later.
|
||||
if !exists('s:buffer_data')
|
||||
let s:buffer_data = {}
|
||||
endif
|
||||
|
||||
" The regular expression used for formatting filenames with modifiers.
|
||||
let s:path_format_regex = '\v\%s(%(:h|:t|:r|:e)*)'
|
||||
|
||||
" Used to get the data in tests.
|
||||
function! ale#command#GetData() abort
|
||||
return deepcopy(s:buffer_data)
|
||||
endfunction
|
||||
|
||||
function! ale#command#ClearData() abort
|
||||
let s:buffer_data = {}
|
||||
endfunction
|
||||
|
||||
function! ale#command#InitData(buffer) abort
|
||||
if !has_key(s:buffer_data, a:buffer)
|
||||
let s:buffer_data[a:buffer] = {
|
||||
\ 'jobs': {},
|
||||
\ 'file_list': [],
|
||||
\ 'directory_list': [],
|
||||
\}
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Set the cwd for commands that are about to run.
|
||||
" Used internally.
|
||||
function! ale#command#SetCwd(buffer, cwd) abort
|
||||
call ale#command#InitData(a:buffer)
|
||||
let s:buffer_data[a:buffer].cwd = a:cwd
|
||||
endfunction
|
||||
|
||||
function! ale#command#ResetCwd(buffer) abort
|
||||
if has_key(s:buffer_data, a:buffer)
|
||||
let s:buffer_data[a:buffer].cwd = v:null
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#command#ManageFile(buffer, file) abort
|
||||
call ale#command#InitData(a:buffer)
|
||||
call add(s:buffer_data[a:buffer].file_list, a:file)
|
||||
endfunction
|
||||
|
||||
function! ale#command#ManageDirectory(buffer, directory) abort
|
||||
call ale#command#InitData(a:buffer)
|
||||
call add(s:buffer_data[a:buffer].directory_list, a:directory)
|
||||
endfunction
|
||||
|
||||
function! ale#command#CreateFile(buffer) abort
|
||||
" This variable can be set to 1 in tests to stub this out.
|
||||
if get(g:, 'ale_create_dummy_temporary_file')
|
||||
return 'TEMP'
|
||||
endif
|
||||
|
||||
let l:temporary_file = ale#util#Tempname()
|
||||
call ale#command#ManageFile(a:buffer, l:temporary_file)
|
||||
|
||||
return l:temporary_file
|
||||
endfunction
|
||||
|
||||
" Create a new temporary directory and manage it in one go.
|
||||
function! ale#command#CreateDirectory(buffer) abort
|
||||
" This variable can be set to 1 in tests to stub this out.
|
||||
if get(g:, 'ale_create_dummy_temporary_file')
|
||||
return 'TEMP_DIR'
|
||||
endif
|
||||
|
||||
let l:temporary_directory = ale#util#Tempname()
|
||||
" Create the temporary directory for the file, unreadable by 'other'
|
||||
" users.
|
||||
call mkdir(l:temporary_directory, '', 0750)
|
||||
call ale#command#ManageDirectory(a:buffer, l:temporary_directory)
|
||||
|
||||
return l:temporary_directory
|
||||
endfunction
|
||||
|
||||
function! ale#command#RemoveManagedFiles(buffer) abort
|
||||
let l:info = get(s:buffer_data, a:buffer, {})
|
||||
|
||||
if !empty(l:info) && empty(l:info.jobs)
|
||||
" We can't delete anything in a sandbox, so wait until we escape from
|
||||
" it to delete temporary files and directories.
|
||||
if ale#util#InSandbox()
|
||||
return
|
||||
endif
|
||||
|
||||
" Delete files with a call akin to a plan `rm` command.
|
||||
for l:filename in l:info.file_list
|
||||
call delete(l:filename)
|
||||
endfor
|
||||
|
||||
" Delete directories like `rm -rf`.
|
||||
" Directories are handled differently from files, so paths that are
|
||||
" intended to be single files can be set up for automatic deletion
|
||||
" without accidentally deleting entire directories.
|
||||
for l:directory in l:info.directory_list
|
||||
call delete(l:directory, 'rf')
|
||||
endfor
|
||||
|
||||
call remove(s:buffer_data, a:buffer)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#command#CreateTempFile(buffer, temporary_file, input) abort
|
||||
if empty(a:temporary_file)
|
||||
" There is no file, so we didn't create anything.
|
||||
return 0
|
||||
endif
|
||||
|
||||
" Use an existing list of lines of input if we have it, or get the lines
|
||||
" from the file.
|
||||
let l:lines = a:input isnot v:null ? a:input : getbufline(a:buffer, 1, '$')
|
||||
|
||||
let l:temporary_directory = fnamemodify(a:temporary_file, ':h')
|
||||
" Create the temporary directory for the file, unreadable by 'other'
|
||||
" users.
|
||||
call mkdir(l:temporary_directory, '', 0750)
|
||||
" Automatically delete the directory later.
|
||||
call ale#command#ManageDirectory(a:buffer, l:temporary_directory)
|
||||
" Write the buffer out to a file.
|
||||
call ale#util#Writefile(a:buffer, l:lines, a:temporary_file)
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! s:TemporaryFilename(buffer) abort
|
||||
let l:filename = fnamemodify(bufname(a:buffer), ':t')
|
||||
|
||||
if empty(l:filename)
|
||||
" If the buffer's filename is empty, create a dummy filename.
|
||||
let l:ft = getbufvar(a:buffer, '&filetype')
|
||||
let l:filename = 'file' . ale#filetypes#GuessExtension(l:ft)
|
||||
endif
|
||||
|
||||
" Create a temporary filename, <temp_dir>/<original_basename>
|
||||
" The file itself will not be created by this function.
|
||||
return ale#util#Tempname() . (has('win32') ? '\' : '/') . l:filename
|
||||
endfunction
|
||||
|
||||
" Given part of a command, replace any % with %%, so that no characters in
|
||||
" the string will be replaced with filenames, etc.
|
||||
function! ale#command#EscapeCommandPart(command_part) abort
|
||||
return substitute(a:command_part, '%', '%%', 'g')
|
||||
endfunction
|
||||
|
||||
" Format a filename, converting it with filename mappings, if non-empty,
|
||||
" and escaping it for putting into a command string.
|
||||
"
|
||||
" The filename can be modified.
|
||||
function! s:FormatFilename(filename, mappings, modifiers) abort
|
||||
let l:filename = a:filename
|
||||
|
||||
if !empty(a:mappings)
|
||||
let l:filename = ale#filename_mapping#Map(l:filename, a:mappings)
|
||||
endif
|
||||
|
||||
if !empty(a:modifiers)
|
||||
let l:filename = fnamemodify(l:filename, a:modifiers)
|
||||
endif
|
||||
|
||||
return ale#Escape(l:filename)
|
||||
endfunction
|
||||
|
||||
" Produce a command prefix to check to a particular directory for a command.
|
||||
" %s format markers with filename-modifiers can be used as the directory, and
|
||||
" will be returned verbatim for formatting in paths relative to files.
|
||||
function! ale#command#CdString(directory) abort
|
||||
let l:match = matchstrpos(a:directory, s:path_format_regex)
|
||||
" Do not escape the directory here if it's a valid format string.
|
||||
" This allows us to use sequences like %s:h, %s:h:h, etc.
|
||||
let l:directory = l:match[1:] == [0, len(a:directory)]
|
||||
\ ? a:directory
|
||||
\ : ale#Escape(a:directory)
|
||||
|
||||
if has('win32')
|
||||
return 'cd /d ' . l:directory . ' && '
|
||||
endif
|
||||
|
||||
return 'cd ' . l:directory . ' && '
|
||||
endfunction
|
||||
|
||||
" Given a command string, replace every...
|
||||
" %s -> with the current filename
|
||||
" %t -> with the name of an unused file in a temporary directory
|
||||
" %% -> with a literal %
|
||||
function! ale#command#FormatCommand(
|
||||
\ buffer,
|
||||
\ executable,
|
||||
\ command,
|
||||
\ pipe_file_if_needed,
|
||||
\ input,
|
||||
\ cwd,
|
||||
\ mappings,
|
||||
\) abort
|
||||
let l:temporary_file = ''
|
||||
let l:command = a:command
|
||||
|
||||
if !empty(a:cwd)
|
||||
let l:command = ale#command#CdString(a:cwd) . l:command
|
||||
endif
|
||||
|
||||
" First replace all uses of %%, used for literal percent characters,
|
||||
" with an ugly string.
|
||||
let l:command = substitute(l:command, '%%', '<<PERCENTS>>', 'g')
|
||||
|
||||
" Replace %e with the escaped executable, if available.
|
||||
if !empty(a:executable) && l:command =~# '%e'
|
||||
let l:command = substitute(l:command, '%e', '\=ale#Escape(a:executable)', 'g')
|
||||
endif
|
||||
|
||||
" Replace all %s occurrences in the string with the name of the current
|
||||
" file.
|
||||
if l:command =~# '%s'
|
||||
let l:filename = fnamemodify(bufname(a:buffer), ':p')
|
||||
let l:command = substitute(
|
||||
\ l:command,
|
||||
\ s:path_format_regex,
|
||||
\ '\=s:FormatFilename(l:filename, a:mappings, submatch(1))',
|
||||
\ 'g'
|
||||
\)
|
||||
endif
|
||||
|
||||
if a:input isnot v:false && l:command =~# '%t'
|
||||
" Create a temporary filename, <temp_dir>/<original_basename>
|
||||
" The file itself will not be created by this function.
|
||||
let l:temporary_file = s:TemporaryFilename(a:buffer)
|
||||
let l:command = substitute(
|
||||
\ l:command,
|
||||
\ '\v\%t(%(:h|:t|:r|:e)*)',
|
||||
\ '\=s:FormatFilename(l:temporary_file, a:mappings, submatch(1))',
|
||||
\ 'g'
|
||||
\)
|
||||
endif
|
||||
|
||||
" Finish formatting so %% becomes %.
|
||||
let l:command = substitute(l:command, '<<PERCENTS>>', '%', 'g')
|
||||
|
||||
if a:pipe_file_if_needed && empty(l:temporary_file)
|
||||
" If we are to send the Vim buffer to a command, we'll do it
|
||||
" in the shell. We'll write out the file to a temporary file,
|
||||
" and then read it back in, in the shell.
|
||||
let l:temporary_file = s:TemporaryFilename(a:buffer)
|
||||
let l:command = l:command . ' < ' . ale#Escape(l:temporary_file)
|
||||
endif
|
||||
|
||||
let l:file_created = ale#command#CreateTempFile(
|
||||
\ a:buffer,
|
||||
\ l:temporary_file,
|
||||
\ a:input,
|
||||
\)
|
||||
|
||||
return [l:temporary_file, l:command, l:file_created]
|
||||
endfunction
|
||||
|
||||
function! ale#command#StopJobs(buffer, job_type) abort
|
||||
let l:info = get(s:buffer_data, a:buffer, {})
|
||||
|
||||
if !empty(l:info)
|
||||
let l:new_map = {}
|
||||
|
||||
for [l:job_id, l:job_type] in items(l:info.jobs)
|
||||
let l:job_id = str2nr(l:job_id)
|
||||
|
||||
if a:job_type is# 'all' || a:job_type is# l:job_type
|
||||
call ale#job#Stop(l:job_id)
|
||||
else
|
||||
let l:new_map[l:job_id] = l:job_type
|
||||
endif
|
||||
endfor
|
||||
|
||||
let l:info.jobs = l:new_map
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:GatherOutput(line_list, job_id, line) abort
|
||||
call add(a:line_list, a:line)
|
||||
endfunction
|
||||
|
||||
function! s:ExitCallback(buffer, line_list, Callback, data) abort
|
||||
if !has_key(s:buffer_data, a:buffer)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:jobs = s:buffer_data[a:buffer].jobs
|
||||
|
||||
if !has_key(l:jobs, a:data.job_id)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:job_type = remove(l:jobs, a:data.job_id)
|
||||
|
||||
if g:ale_history_enabled
|
||||
call ale#history#SetExitCode(a:buffer, a:data.job_id, a:data.exit_code)
|
||||
|
||||
" Log the output of the command for ALEInfo if we should.
|
||||
if g:ale_history_log_output && a:data.log_output is 1
|
||||
call ale#history#RememberOutput(
|
||||
\ a:buffer,
|
||||
\ a:data.job_id,
|
||||
\ a:line_list[:]
|
||||
\)
|
||||
endif
|
||||
endif
|
||||
|
||||
" If the callback starts any new jobs, use the same job type for them.
|
||||
call setbufvar(a:buffer, 'ale_job_type', l:job_type)
|
||||
let l:value = a:Callback(a:buffer, a:line_list, {
|
||||
\ 'exit_code': a:data.exit_code,
|
||||
\ 'temporary_file': a:data.temporary_file,
|
||||
\})
|
||||
|
||||
let l:result = a:data.result
|
||||
let l:result.value = l:value
|
||||
|
||||
" Set the default cwd for this buffer in this call stack.
|
||||
call ale#command#SetCwd(a:buffer, l:result.cwd)
|
||||
|
||||
try
|
||||
if get(l:result, 'result_callback', v:null) isnot v:null
|
||||
call call(l:result.result_callback, [l:value])
|
||||
endif
|
||||
finally
|
||||
call ale#command#ResetCwd(a:buffer)
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! ale#command#Run(buffer, command, Callback, ...) abort
|
||||
let l:options = get(a:000, 0, {})
|
||||
|
||||
if len(a:000) > 1
|
||||
throw 'Too many arguments!'
|
||||
endif
|
||||
|
||||
let l:output_stream = get(l:options, 'output_stream', 'stdout')
|
||||
let l:line_list = []
|
||||
let l:cwd = get(l:options, 'cwd', v:null)
|
||||
|
||||
if l:cwd is v:null
|
||||
" Default the working directory to whatever it was for the last
|
||||
" command run in the chain.
|
||||
let l:cwd = get(get(s:buffer_data, a:buffer, {}), 'cwd', v:null)
|
||||
endif
|
||||
|
||||
let [l:temporary_file, l:command, l:file_created] = ale#command#FormatCommand(
|
||||
\ a:buffer,
|
||||
\ get(l:options, 'executable', ''),
|
||||
\ a:command,
|
||||
\ get(l:options, 'read_buffer', 0),
|
||||
\ get(l:options, 'input', v:null),
|
||||
\ l:cwd,
|
||||
\ get(l:options, 'filename_mappings', []),
|
||||
\)
|
||||
let l:command = ale#job#PrepareCommand(a:buffer, l:command)
|
||||
let l:job_options = {
|
||||
\ 'exit_cb': {job_id, exit_code -> s:ExitCallback(
|
||||
\ a:buffer,
|
||||
\ l:line_list,
|
||||
\ a:Callback,
|
||||
\ {
|
||||
\ 'job_id': job_id,
|
||||
\ 'exit_code': exit_code,
|
||||
\ 'temporary_file': l:temporary_file,
|
||||
\ 'log_output': get(l:options, 'log_output', 1),
|
||||
\ 'result': l:result,
|
||||
\ }
|
||||
\ )},
|
||||
\ 'mode': 'nl',
|
||||
\}
|
||||
|
||||
if l:output_stream is# 'stdout'
|
||||
let l:job_options.out_cb = function('s:GatherOutput', [l:line_list])
|
||||
elseif l:output_stream is# 'stderr'
|
||||
let l:job_options.err_cb = function('s:GatherOutput', [l:line_list])
|
||||
elseif l:output_stream is# 'both'
|
||||
let l:job_options.out_cb = function('s:GatherOutput', [l:line_list])
|
||||
let l:job_options.err_cb = function('s:GatherOutput', [l:line_list])
|
||||
endif
|
||||
|
||||
let l:status = 'failed'
|
||||
|
||||
if get(g:, 'ale_run_synchronously') == 1
|
||||
if get(g:, 'ale_emulate_job_failure') == 1
|
||||
let l:job_id = 0
|
||||
else
|
||||
" Generate a fake job ID for tests.
|
||||
let s:fake_job_id = get(s:, 'fake_job_id', 0) + 1
|
||||
let l:job_id = s:fake_job_id
|
||||
endif
|
||||
elseif has('win32')
|
||||
let l:job_id = ale#job#StartWithCmd(l:command, l:job_options)
|
||||
else
|
||||
let l:job_id = ale#job#Start(l:command, l:job_options)
|
||||
endif
|
||||
|
||||
if l:job_id
|
||||
let l:status = 'started'
|
||||
let l:job_type = getbufvar(a:buffer, 'ale_job_type', 'all')
|
||||
|
||||
call ale#command#InitData(a:buffer)
|
||||
let s:buffer_data[a:buffer].jobs[l:job_id] = l:job_type
|
||||
endif
|
||||
|
||||
if g:ale_history_enabled
|
||||
call ale#history#Add(a:buffer, l:status, l:job_id, l:command)
|
||||
endif
|
||||
|
||||
if !l:job_id
|
||||
return 0
|
||||
endif
|
||||
|
||||
" We'll return this Dictionary. A `result_callback` can be assigned to it
|
||||
" later for capturing the result of a:Callback.
|
||||
"
|
||||
" The `_deferred_job_id` is used for both checking the type of object, and
|
||||
" for checking the job ID and status.
|
||||
"
|
||||
" The cwd is kept and used as the default value for the next command in
|
||||
" the chain.
|
||||
"
|
||||
" The original command here is used in tests.
|
||||
let l:result = {
|
||||
\ '_deferred_job_id': l:job_id,
|
||||
\ 'executable': get(l:options, 'executable', ''),
|
||||
\ 'cwd': l:cwd,
|
||||
\ 'command': a:command,
|
||||
\}
|
||||
|
||||
if get(g:, 'ale_run_synchronously') == 1 && l:job_id
|
||||
if !exists('g:ale_run_synchronously_callbacks')
|
||||
let g:ale_run_synchronously_callbacks = []
|
||||
endif
|
||||
|
||||
if get(g:, 'ale_run_synchronously_emulate_commands', 0)
|
||||
call add(
|
||||
\ g:ale_run_synchronously_callbacks,
|
||||
\ {exit_code, output -> [
|
||||
\ extend(l:line_list, output),
|
||||
\ l:job_options.exit_cb(l:job_id, exit_code),
|
||||
\ ]}
|
||||
\)
|
||||
else
|
||||
" Run a command synchronously if this test option is set.
|
||||
call extend(l:line_list, systemlist(
|
||||
\ type(l:command) is v:t_list
|
||||
\ ? join(l:command[0:1]) . ' ' . ale#Escape(l:command[2])
|
||||
\ : l:command
|
||||
\))
|
||||
|
||||
" Don't capture output when the callbacks aren't set.
|
||||
if !has_key(l:job_options, 'out_cb')
|
||||
\&& !has_key(l:job_options, 'err_cb')
|
||||
let l:line_list = []
|
||||
endif
|
||||
|
||||
call add(
|
||||
\ g:ale_run_synchronously_callbacks,
|
||||
\ {-> l:job_options.exit_cb(l:job_id, v:shell_error)}
|
||||
\)
|
||||
endif
|
||||
endif
|
||||
|
||||
return l:result
|
||||
endfunction
|
||||
|
||||
function! ale#command#IsDeferred(value) abort
|
||||
return type(a:value) is v:t_dict && has_key(a:value, '_deferred_job_id')
|
||||
endfunction
|
1070
vim/.vim/autoload/ale/completion.vim
Normal file
1070
vim/.vim/autoload/ale/completion.vim
Normal file
File diff suppressed because it is too large
Load Diff
3
vim/.vim/autoload/ale/completion/python.vim
Normal file
3
vim/.vim/autoload/ale/completion/python.vim
Normal file
@ -0,0 +1,3 @@
|
||||
function! ale#completion#python#CompletionItemFilter(buffer, item) abort
|
||||
return a:item.label !~# '\v^__[a-z_]+__'
|
||||
endfunction
|
191
vim/.vim/autoload/ale/cursor.vim
Normal file
191
vim/.vim/autoload/ale/cursor.vim
Normal file
@ -0,0 +1,191 @@
|
||||
scriptencoding utf-8
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Author: João Paulo S. de Souza <joao.paulo.silvasouza@hotmail.com>
|
||||
" Description: Echoes lint message for the current line, if any
|
||||
|
||||
" Controls the milliseconds delay before echoing a message.
|
||||
let g:ale_echo_delay = get(g:, 'ale_echo_delay', 10)
|
||||
" A string format for the echoed message.
|
||||
let g:ale_echo_msg_format = get(g:, 'ale_echo_msg_format', '%code: %%s')
|
||||
|
||||
let s:cursor_timer = -1
|
||||
|
||||
" A wrapper for echon so we can test messages we echo in Vader tests.
|
||||
function! ale#cursor#Echom(message) abort
|
||||
if mode() is# 'n'
|
||||
" no-custom-checks
|
||||
exec "norm! :echom a:message\n"
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#cursor#TruncatedEcho(original_message) abort
|
||||
let l:message = a:original_message
|
||||
" Change tabs to spaces.
|
||||
let l:message = substitute(l:message, "\t", ' ', 'g')
|
||||
" Remove any newlines in the message.
|
||||
let l:message = substitute(l:message, "\n", '', 'g')
|
||||
" Convert indentation groups into single spaces for better legibility when
|
||||
" put on a single line
|
||||
let l:message = substitute(l:message, ' \+', ' ', 'g')
|
||||
|
||||
" We need to remember the setting for shortmess and reset it again.
|
||||
let l:shortmess_options = &l:shortmess
|
||||
|
||||
try
|
||||
let l:cursor_position = getpos('.')
|
||||
|
||||
" The message is truncated and saved to the history.
|
||||
silent! setlocal shortmess+=T
|
||||
|
||||
try
|
||||
call ale#cursor#Echom(l:message)
|
||||
catch /^Vim\%((\a\+)\)\=:E523/
|
||||
" Fallback into manual truncate (#1987)
|
||||
let l:winwidth = winwidth(0)
|
||||
|
||||
if l:winwidth < strdisplaywidth(l:message)
|
||||
" Truncate message longer than window width with trailing '...'
|
||||
let l:message = l:message[:l:winwidth - 4] . '...'
|
||||
endif
|
||||
|
||||
exec 'echomsg l:message'
|
||||
catch /E481/
|
||||
" Do nothing if running from a visual selection.
|
||||
endtry
|
||||
|
||||
" Reset the cursor position if we moved off the end of the line.
|
||||
" Using :norm and :echomsg can move the cursor off the end of the
|
||||
" line.
|
||||
if l:cursor_position != getpos('.')
|
||||
call setpos('.', l:cursor_position)
|
||||
endif
|
||||
finally
|
||||
let &l:shortmess = l:shortmess_options
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
function! s:StopCursorTimer() abort
|
||||
if s:cursor_timer != -1
|
||||
call timer_stop(s:cursor_timer)
|
||||
let s:cursor_timer = -1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#cursor#EchoCursorWarning(...) abort
|
||||
let l:buffer = bufnr('')
|
||||
|
||||
if !g:ale_echo_cursor && !g:ale_cursor_detail
|
||||
return
|
||||
endif
|
||||
|
||||
" Only echo the warnings in normal mode, otherwise we will get problems.
|
||||
if mode(1) isnot# 'n'
|
||||
return
|
||||
endif
|
||||
|
||||
if ale#ShouldDoNothing(l:buffer)
|
||||
return
|
||||
endif
|
||||
|
||||
let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer)
|
||||
|
||||
if g:ale_echo_cursor
|
||||
if !empty(l:loc)
|
||||
let l:format = ale#Var(l:buffer, 'echo_msg_format')
|
||||
let l:msg = ale#GetLocItemMessage(l:loc, l:format)
|
||||
call ale#cursor#TruncatedEcho(l:msg)
|
||||
let l:info.echoed = 1
|
||||
elseif get(l:info, 'echoed')
|
||||
" We'll only clear the echoed message when moving off errors once,
|
||||
" so we don't continually clear the echo line.
|
||||
"
|
||||
" no-custom-checks
|
||||
echo
|
||||
let l:info.echoed = 0
|
||||
endif
|
||||
endif
|
||||
|
||||
if g:ale_cursor_detail
|
||||
if !empty(l:loc)
|
||||
call s:ShowCursorDetailForItem(l:loc, {'stay_here': 1})
|
||||
else
|
||||
call ale#preview#CloseIfTypeMatches('ale-preview')
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#cursor#EchoCursorWarningWithDelay() abort
|
||||
let l:buffer = bufnr('')
|
||||
|
||||
if !g:ale_echo_cursor && !g:ale_cursor_detail
|
||||
return
|
||||
endif
|
||||
|
||||
" Only echo the warnings in normal mode, otherwise we will get problems.
|
||||
if mode(1) isnot# 'n'
|
||||
return
|
||||
endif
|
||||
|
||||
call s:StopCursorTimer()
|
||||
|
||||
let l:pos = getpos('.')[0:2]
|
||||
|
||||
if !exists('w:last_pos')
|
||||
let w:last_pos = [0, 0, 0]
|
||||
endif
|
||||
|
||||
" Check the current buffer, line, and column number against the last
|
||||
" recorded position. If the position has actually changed, *then*
|
||||
" we should echo something. Otherwise we can end up doing processing
|
||||
" the echo message far too frequently.
|
||||
if l:pos != w:last_pos
|
||||
let l:delay = ale#Var(l:buffer, 'echo_delay')
|
||||
|
||||
let w:last_pos = l:pos
|
||||
let s:cursor_timer = timer_start(
|
||||
\ l:delay,
|
||||
\ function('ale#cursor#EchoCursorWarning')
|
||||
\)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:ShowCursorDetailForItem(loc, options) abort
|
||||
let l:stay_here = get(a:options, 'stay_here', 0)
|
||||
|
||||
let s:last_detailed_line = line('.')
|
||||
let l:message = get(a:loc, 'detail', a:loc.text)
|
||||
let l:lines = split(l:message, "\n")
|
||||
|
||||
if g:ale_floating_preview || g:ale_detail_to_floating_preview
|
||||
call ale#floating_preview#Show(l:lines)
|
||||
else
|
||||
call ale#preview#Show(l:lines, {'stay_here': l:stay_here})
|
||||
|
||||
" Clear the echo message if we manually displayed details.
|
||||
if !l:stay_here
|
||||
" no-custom-checks
|
||||
echo
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#cursor#ShowCursorDetail() abort
|
||||
let l:buffer = bufnr('')
|
||||
|
||||
" Only echo the warnings in normal mode, otherwise we will get problems.
|
||||
if mode() isnot# 'n'
|
||||
return
|
||||
endif
|
||||
|
||||
if ale#ShouldDoNothing(l:buffer)
|
||||
return
|
||||
endif
|
||||
|
||||
call s:StopCursorTimer()
|
||||
|
||||
let [l:info, l:loc] = ale#util#FindItemAtCursor(l:buffer)
|
||||
|
||||
if !empty(l:loc)
|
||||
call s:ShowCursorDetailForItem(l:loc, {'stay_here': 0})
|
||||
endif
|
||||
endfunction
|
16
vim/.vim/autoload/ale/d.vim
Normal file
16
vim/.vim/autoload/ale/d.vim
Normal file
@ -0,0 +1,16 @@
|
||||
" Author: Auri <me@aurieh.me>
|
||||
" Description: Functions for integrating with D linters.
|
||||
|
||||
function! ale#d#FindDUBConfig(buffer) abort
|
||||
" Find a DUB configuration file in ancestor paths.
|
||||
" The most DUB-specific names will be tried first.
|
||||
for l:possible_filename in ['dub.sdl', 'dub.json', 'package.json']
|
||||
let l:dub_file = ale#path#FindNearestFile(a:buffer, l:possible_filename)
|
||||
|
||||
if !empty(l:dub_file)
|
||||
return l:dub_file
|
||||
endif
|
||||
endfor
|
||||
|
||||
return ''
|
||||
endfunction
|
363
vim/.vim/autoload/ale/debugging.vim
Normal file
363
vim/.vim/autoload/ale/debugging.vim
Normal file
@ -0,0 +1,363 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: This file implements debugging information for ALE
|
||||
|
||||
let g:ale_info_default_mode = get(g:, 'ale_info_default_mode', 'preview')
|
||||
|
||||
let s:global_variable_list = [
|
||||
\ 'ale_cache_executable_check_failures',
|
||||
\ 'ale_change_sign_column_color',
|
||||
\ 'ale_command_wrapper',
|
||||
\ 'ale_completion_delay',
|
||||
\ 'ale_completion_enabled',
|
||||
\ 'ale_completion_max_suggestions',
|
||||
\ 'ale_disable_lsp',
|
||||
\ 'ale_echo_cursor',
|
||||
\ 'ale_echo_msg_error_str',
|
||||
\ 'ale_echo_msg_format',
|
||||
\ 'ale_echo_msg_info_str',
|
||||
\ 'ale_echo_msg_warning_str',
|
||||
\ 'ale_enabled',
|
||||
\ 'ale_fix_on_save',
|
||||
\ 'ale_fixers',
|
||||
\ 'ale_history_enabled',
|
||||
\ 'ale_info_default_mode',
|
||||
\ 'ale_history_log_output',
|
||||
\ 'ale_keep_list_window_open',
|
||||
\ 'ale_lint_delay',
|
||||
\ 'ale_lint_on_enter',
|
||||
\ 'ale_lint_on_filetype_changed',
|
||||
\ 'ale_lint_on_insert_leave',
|
||||
\ 'ale_lint_on_save',
|
||||
\ 'ale_lint_on_text_changed',
|
||||
\ 'ale_linter_aliases',
|
||||
\ 'ale_linters',
|
||||
\ 'ale_linters_explicit',
|
||||
\ 'ale_linters_ignore',
|
||||
\ 'ale_list_vertical',
|
||||
\ 'ale_list_window_size',
|
||||
\ 'ale_loclist_msg_format',
|
||||
\ 'ale_max_buffer_history_size',
|
||||
\ 'ale_max_signs',
|
||||
\ 'ale_maximum_file_size',
|
||||
\ 'ale_open_list',
|
||||
\ 'ale_pattern_options',
|
||||
\ 'ale_pattern_options_enabled',
|
||||
\ 'ale_root',
|
||||
\ 'ale_set_balloons',
|
||||
\ 'ale_set_highlights',
|
||||
\ 'ale_set_loclist',
|
||||
\ 'ale_set_quickfix',
|
||||
\ 'ale_set_signs',
|
||||
\ 'ale_sign_column_always',
|
||||
\ 'ale_sign_error',
|
||||
\ 'ale_sign_info',
|
||||
\ 'ale_sign_offset',
|
||||
\ 'ale_sign_style_error',
|
||||
\ 'ale_sign_style_warning',
|
||||
\ 'ale_sign_warning',
|
||||
\ 'ale_sign_highlight_linenrs',
|
||||
\ 'ale_type_map',
|
||||
\ 'ale_use_neovim_diagnostics_api',
|
||||
\ 'ale_use_global_executables',
|
||||
\ 'ale_virtualtext_cursor',
|
||||
\ 'ale_warn_about_trailing_blank_lines',
|
||||
\ 'ale_warn_about_trailing_whitespace',
|
||||
\]
|
||||
|
||||
function! s:Echo(message) abort
|
||||
" no-custom-checks
|
||||
echo a:message
|
||||
endfunction
|
||||
|
||||
function! s:GetLinterVariables(filetype, exclude_linter_names) abort
|
||||
let l:variable_list = []
|
||||
let l:filetype_parts = split(a:filetype, '\.')
|
||||
|
||||
for l:key in keys(g:)
|
||||
" Extract variable names like: 'ale_python_flake8_executable'
|
||||
let l:match = matchlist(l:key, '\v^ale_([^_]+)_([^_]+)_.+$')
|
||||
|
||||
" Include matching variables.
|
||||
if !empty(l:match)
|
||||
\&& index(l:filetype_parts, l:match[1]) >= 0
|
||||
\&& index(a:exclude_linter_names, l:match[2]) == -1
|
||||
call add(l:variable_list, l:key)
|
||||
endif
|
||||
endfor
|
||||
|
||||
call sort(l:variable_list)
|
||||
|
||||
return l:variable_list
|
||||
endfunction
|
||||
|
||||
function! s:EchoLinterVariables(variable_list) abort
|
||||
for l:key in a:variable_list
|
||||
call s:Echo('let g:' . l:key . ' = ' . string(g:[l:key]))
|
||||
|
||||
if has_key(b:, l:key)
|
||||
call s:Echo('let b:' . l:key . ' = ' . string(b:[l:key]))
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:EchoGlobalVariables() abort
|
||||
for l:key in s:global_variable_list
|
||||
call s:Echo('let g:' . l:key . ' = ' . string(get(g:, l:key, v:null)))
|
||||
|
||||
if has_key(b:, l:key)
|
||||
call s:Echo('let b:' . l:key . ' = ' . string(b:[l:key]))
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Echo a command that was run.
|
||||
function! s:EchoCommand(item) abort
|
||||
let l:status_message = a:item.status
|
||||
|
||||
" Include the exit code in output if we have it.
|
||||
if a:item.status is# 'finished'
|
||||
let l:status_message .= ' - exit code ' . a:item.exit_code
|
||||
endif
|
||||
|
||||
call s:Echo('(' . l:status_message . ') ' . string(a:item.command))
|
||||
|
||||
if g:ale_history_log_output && has_key(a:item, 'output')
|
||||
if empty(a:item.output)
|
||||
call s:Echo('')
|
||||
call s:Echo('<<<NO OUTPUT RETURNED>>>')
|
||||
call s:Echo('')
|
||||
else
|
||||
call s:Echo('')
|
||||
call s:Echo('<<<OUTPUT STARTS>>>')
|
||||
|
||||
for l:line in a:item.output
|
||||
call s:Echo(l:line)
|
||||
endfor
|
||||
|
||||
call s:Echo('<<<OUTPUT ENDS>>>')
|
||||
call s:Echo('')
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Echo the results of an executable check.
|
||||
function! s:EchoExecutable(item) abort
|
||||
call s:Echo(printf(
|
||||
\ '(executable check - %s) %s',
|
||||
\ a:item.status ? 'success' : 'failure',
|
||||
\ a:item.command,
|
||||
\))
|
||||
endfunction
|
||||
|
||||
function! s:EchoCommandHistory() abort
|
||||
let l:buffer = bufnr('%')
|
||||
|
||||
for l:item in ale#history#Get(l:buffer)
|
||||
if l:item.job_id is# 'executable'
|
||||
call s:EchoExecutable(l:item)
|
||||
else
|
||||
call s:EchoCommand(l:item)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:EchoLinterAliases(all_linters) abort
|
||||
let l:first = 1
|
||||
|
||||
for l:linter in a:all_linters
|
||||
if !empty(l:linter.aliases)
|
||||
if l:first
|
||||
call s:Echo(' Linter Aliases:')
|
||||
endif
|
||||
|
||||
let l:first = 0
|
||||
|
||||
call s:Echo(string(l:linter.name) . ' -> ' . string(l:linter.aliases))
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:EchoLSPErrorMessages(all_linter_names) abort
|
||||
let l:lsp_error_messages = get(g:, 'ale_lsp_error_messages', {})
|
||||
let l:header_echoed = 0
|
||||
|
||||
for l:linter_name in a:all_linter_names
|
||||
let l:error_list = get(l:lsp_error_messages, l:linter_name, [])
|
||||
|
||||
if !empty(l:error_list)
|
||||
if !l:header_echoed
|
||||
call s:Echo(' LSP Error Messages:')
|
||||
call s:Echo('')
|
||||
endif
|
||||
|
||||
call s:Echo('(Errors for ' . l:linter_name . ')')
|
||||
|
||||
for l:message in l:error_list
|
||||
for l:line in split(l:message, "\n")
|
||||
call s:Echo(l:line)
|
||||
endfor
|
||||
endfor
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:GetIgnoredLinters(buffer, enabled_linters) abort
|
||||
let l:filetype = &filetype
|
||||
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
|
||||
let l:disable_lsp = ale#Var(a:buffer, 'disable_lsp')
|
||||
|
||||
if (
|
||||
\ !empty(l:ignore_config)
|
||||
\ || l:disable_lsp is 1
|
||||
\ || l:disable_lsp is v:true
|
||||
\ || (l:disable_lsp is# 'auto' && get(g:, 'lspconfig', 0))
|
||||
\)
|
||||
let l:non_ignored = ale#engine#ignore#Exclude(
|
||||
\ l:filetype,
|
||||
\ a:enabled_linters,
|
||||
\ l:ignore_config,
|
||||
\ l:disable_lsp,
|
||||
\)
|
||||
else
|
||||
let l:non_ignored = copy(a:enabled_linters)
|
||||
endif
|
||||
|
||||
call map(l:non_ignored, 'v:val.name')
|
||||
|
||||
return filter(
|
||||
\ copy(a:enabled_linters),
|
||||
\ 'index(l:non_ignored, v:val.name) < 0'
|
||||
\)
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#Info(...) abort
|
||||
let l:options = (a:0 > 0) ? a:1 : {}
|
||||
let l:show_preview_info = get(l:options, 'preview')
|
||||
|
||||
let l:buffer = bufnr('')
|
||||
let l:filetype = &filetype
|
||||
|
||||
let l:enabled_linters = deepcopy(ale#linter#Get(l:filetype))
|
||||
|
||||
" But have to build the list of available linters ourselves.
|
||||
let l:all_linters = []
|
||||
let l:linter_variable_list = []
|
||||
|
||||
for l:part in split(l:filetype, '\.')
|
||||
let l:aliased_filetype = ale#linter#ResolveFiletype(l:part)
|
||||
call extend(l:all_linters, ale#linter#GetAll(l:aliased_filetype))
|
||||
endfor
|
||||
|
||||
let l:all_names = map(copy(l:all_linters), 'v:val[''name'']')
|
||||
let l:enabled_names = map(copy(l:enabled_linters), 'v:val[''name'']')
|
||||
let l:exclude_names = filter(copy(l:all_names), 'index(l:enabled_names, v:val) == -1')
|
||||
|
||||
" Load linter variables to display
|
||||
" This must be done after linters are loaded.
|
||||
let l:variable_list = s:GetLinterVariables(l:filetype, l:exclude_names)
|
||||
|
||||
let l:fixers = ale#fix#registry#SuggestedFixers(l:filetype)
|
||||
let l:fixers = uniq(sort(l:fixers[0] + l:fixers[1]))
|
||||
let l:fixers_string = join(map(copy(l:fixers), '"\n " . v:val'), '')
|
||||
|
||||
" Get the names of ignored linters.
|
||||
let l:ignored_names = map(
|
||||
\ s:GetIgnoredLinters(l:buffer, l:enabled_linters),
|
||||
\ 'v:val.name'
|
||||
\)
|
||||
|
||||
call s:Echo(' Current Filetype: ' . l:filetype)
|
||||
call s:Echo('Available Linters: ' . string(l:all_names))
|
||||
call s:EchoLinterAliases(l:all_linters)
|
||||
call s:Echo(' Enabled Linters: ' . string(l:enabled_names))
|
||||
call s:Echo(' Ignored Linters: ' . string(l:ignored_names))
|
||||
call s:Echo(' Suggested Fixers:' . l:fixers_string)
|
||||
" We use this line with only a space to know where to end highlights.
|
||||
call s:Echo(' ')
|
||||
|
||||
" Only show Linter Variables directive if there are any.
|
||||
if !empty(l:variable_list)
|
||||
call s:Echo(' Linter Variables:')
|
||||
|
||||
if l:show_preview_info
|
||||
call s:Echo('" Press Space to read :help for a setting')
|
||||
endif
|
||||
|
||||
call s:EchoLinterVariables(l:variable_list)
|
||||
" We use this line with only a space to know where to end highlights.
|
||||
call s:Echo(' ')
|
||||
endif
|
||||
|
||||
call s:Echo(' Global Variables:')
|
||||
|
||||
if l:show_preview_info
|
||||
call s:Echo('" Press Space to read :help for a setting')
|
||||
endif
|
||||
|
||||
call s:EchoGlobalVariables()
|
||||
call s:Echo(' ')
|
||||
call s:EchoLSPErrorMessages(l:all_names)
|
||||
call s:Echo(' Command History:')
|
||||
call s:Echo('')
|
||||
call s:EchoCommandHistory()
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#InfoToClipboard() abort
|
||||
if !has('clipboard')
|
||||
call s:Echo('clipboard not available. Try :ALEInfoToFile instead.')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:output = execute('call ale#debugging#Info()')
|
||||
|
||||
let @+ = l:output
|
||||
call s:Echo('ALEInfo copied to your clipboard')
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#InfoToFile(filename) abort
|
||||
let l:expanded_filename = expand(a:filename)
|
||||
|
||||
let l:output = execute('call ale#debugging#Info()')
|
||||
|
||||
call writefile(split(l:output, "\n"), l:expanded_filename)
|
||||
call s:Echo('ALEInfo written to ' . l:expanded_filename)
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#InfoToPreview() abort
|
||||
let l:output = execute('call ale#debugging#Info({''preview'': 1})')
|
||||
|
||||
call ale#preview#Show(split(l:output, "\n"), {
|
||||
\ 'filetype': 'ale-info',
|
||||
\})
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#InfoCommand(...) abort
|
||||
if len(a:000) > 1
|
||||
" no-custom-checks
|
||||
echom 'Invalid ALEInfo arguments!'
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
" Get 'echo' from '-echo', if there's an argument.
|
||||
let l:mode = get(a:000, '')[1:]
|
||||
|
||||
if empty(l:mode)
|
||||
let l:mode = ale#Var(bufnr(''), 'info_default_mode')
|
||||
endif
|
||||
|
||||
if l:mode is# 'echo'
|
||||
call ale#debugging#Info()
|
||||
elseif l:mode is# 'clip' || l:mode is# 'clipboard'
|
||||
call ale#debugging#InfoToClipboard()
|
||||
else
|
||||
call ale#debugging#InfoToPreview()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#debugging#InfoToClipboardDeprecatedCommand() abort
|
||||
" no-custom-checks
|
||||
echom 'ALEInfoToClipboard is deprecated. Use ALEInfo -clipboard instead.'
|
||||
call ale#debugging#InfoToClipboard()
|
||||
endfunction
|
305
vim/.vim/autoload/ale/definition.vim
Normal file
305
vim/.vim/autoload/ale/definition.vim
Normal file
@ -0,0 +1,305 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Go to definition support for LSP linters.
|
||||
|
||||
let s:go_to_definition_map = {}
|
||||
|
||||
" Enable automatic updates of the tagstack
|
||||
let g:ale_update_tagstack = get(g:, 'ale_update_tagstack', 1)
|
||||
let g:ale_default_navigation = get(g:, 'ale_default_navigation', 'buffer')
|
||||
|
||||
" Used to get the definition map in tests.
|
||||
function! ale#definition#GetMap() abort
|
||||
return deepcopy(s:go_to_definition_map)
|
||||
endfunction
|
||||
|
||||
" Used to set the definition map in tests.
|
||||
function! ale#definition#SetMap(map) abort
|
||||
let s:go_to_definition_map = a:map
|
||||
endfunction
|
||||
|
||||
function! ale#definition#ClearLSPData() abort
|
||||
let s:go_to_definition_map = {}
|
||||
endfunction
|
||||
|
||||
function! ale#definition#UpdateTagStack() abort
|
||||
let l:should_update_tagstack = exists('*gettagstack') && exists('*settagstack') && g:ale_update_tagstack
|
||||
|
||||
if l:should_update_tagstack
|
||||
" Grab the old location (to jump back to) and the word under the
|
||||
" cursor (as a label for the tagstack)
|
||||
let l:old_location = [bufnr('%'), line('.'), col('.'), 0]
|
||||
let l:tagname = expand('<cword>')
|
||||
let l:winid = win_getid()
|
||||
call settagstack(l:winid, {'items': [{'from': l:old_location, 'tagname': l:tagname}]}, 'a')
|
||||
call settagstack(l:winid, {'curidx': len(gettagstack(l:winid)['items']) + 1})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#definition#FormatTSServerResponse(response_item, options) abort
|
||||
if get(a:options, 'open_in') is# 'quickfix'
|
||||
return {
|
||||
\ 'filename': a:response_item.file,
|
||||
\ 'lnum': a:response_item.start.line,
|
||||
\ 'col': a:response_item.start.offset,
|
||||
\}
|
||||
else
|
||||
return {
|
||||
\ 'filename': a:response_item.file,
|
||||
\ 'line': a:response_item.start.line,
|
||||
\ 'column': a:response_item.start.offset,
|
||||
\}
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#definition#HandleTSServerResponse(conn_id, response) abort
|
||||
if has_key(a:response, 'request_seq')
|
||||
\&& has_key(s:go_to_definition_map, a:response.request_seq)
|
||||
let l:options = remove(s:go_to_definition_map, a:response.request_seq)
|
||||
|
||||
if get(a:response, 'success', v:false) is v:true && !empty(a:response.body)
|
||||
let l:item_list = []
|
||||
|
||||
for l:response_item in a:response.body
|
||||
call add(
|
||||
\ l:item_list,
|
||||
\ ale#definition#FormatTSServerResponse(l:response_item, l:options)
|
||||
\)
|
||||
endfor
|
||||
|
||||
if empty(l:item_list)
|
||||
call ale#util#Execute('echom ''No definitions found''')
|
||||
elseif len(l:item_list) == 1
|
||||
let l:filename = l:item_list[0].filename
|
||||
|
||||
if get(l:options, 'open_in') is# 'quickfix'
|
||||
let l:line = l:item_list[0].lnum
|
||||
let l:column = l:item_list[0].col
|
||||
else
|
||||
let l:line = l:item_list[0].line
|
||||
let l:column = l:item_list[0].column
|
||||
endif
|
||||
|
||||
call ale#definition#UpdateTagStack()
|
||||
call ale#util#Open(l:filename, l:line, l:column, l:options)
|
||||
else
|
||||
if get(l:options, 'open_in') is# 'quickfix'
|
||||
call setqflist([], 'r')
|
||||
call setqflist(l:item_list, 'a')
|
||||
call ale#util#Execute('cc 1')
|
||||
else
|
||||
call ale#definition#UpdateTagStack()
|
||||
call ale#preview#ShowSelection(l:item_list, l:options)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#definition#FormatLSPResponse(response_item, options) abort
|
||||
if has_key(a:response_item, 'targetUri')
|
||||
" LocationLink items use targetUri
|
||||
let l:uri = a:response_item.targetUri
|
||||
let l:line = a:response_item.targetRange.start.line + 1
|
||||
let l:column = a:response_item.targetRange.start.character + 1
|
||||
else
|
||||
" LocationLink items use uri
|
||||
let l:uri = a:response_item.uri
|
||||
let l:line = a:response_item.range.start.line + 1
|
||||
let l:column = a:response_item.range.start.character + 1
|
||||
endif
|
||||
|
||||
if get(a:options, 'open_in') is# 'quickfix'
|
||||
return {
|
||||
\ 'filename': ale#util#ToResource(l:uri),
|
||||
\ 'lnum': l:line,
|
||||
\ 'col': l:column,
|
||||
\}
|
||||
else
|
||||
return {
|
||||
\ 'filename': ale#util#ToResource(l:uri),
|
||||
\ 'line': l:line,
|
||||
\ 'column': l:column,
|
||||
\}
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#definition#HandleLSPResponse(conn_id, response) abort
|
||||
if has_key(a:response, 'id')
|
||||
\&& has_key(s:go_to_definition_map, a:response.id)
|
||||
let l:options = remove(s:go_to_definition_map, a:response.id)
|
||||
|
||||
" The result can be a Dictionary item, a List of the same, or null.
|
||||
let l:result = get(a:response, 'result', v:null)
|
||||
|
||||
if type(l:result) is v:t_dict
|
||||
let l:result = [l:result]
|
||||
elseif type(l:result) isnot v:t_list
|
||||
let l:result = []
|
||||
endif
|
||||
|
||||
let l:item_list = []
|
||||
|
||||
for l:response_item in l:result
|
||||
call add(l:item_list,
|
||||
\ ale#definition#FormatLSPResponse(l:response_item, l:options)
|
||||
\)
|
||||
endfor
|
||||
|
||||
if empty(l:item_list)
|
||||
call ale#util#Execute('echom ''No definitions found''')
|
||||
elseif len(l:item_list) == 1
|
||||
call ale#definition#UpdateTagStack()
|
||||
|
||||
let l:uri = ale#util#ToURI(l:item_list[0].filename)
|
||||
|
||||
if get(l:options, 'open_in') is# 'quickfix'
|
||||
let l:line = l:item_list[0].lnum
|
||||
let l:column = l:item_list[0].col
|
||||
else
|
||||
let l:line = l:item_list[0].line
|
||||
let l:column = l:item_list[0].column
|
||||
endif
|
||||
|
||||
let l:uri_handler = ale#uri#GetURIHandler(l:uri)
|
||||
|
||||
if l:uri_handler is# v:null
|
||||
let l:filename = ale#path#FromFileURI(l:uri)
|
||||
call ale#util#Open(l:filename, l:line, l:column, l:options)
|
||||
else
|
||||
call l:uri_handler.OpenURILink(l:uri, l:line, l:column, l:options, a:conn_id)
|
||||
endif
|
||||
else
|
||||
if get(l:options, 'open_in') is# 'quickfix'
|
||||
call setqflist([], 'r')
|
||||
call setqflist(l:item_list, 'a')
|
||||
call ale#util#Execute('cc 1')
|
||||
else
|
||||
call ale#definition#UpdateTagStack()
|
||||
call ale#preview#ShowSelection(l:item_list, l:options)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:OnReady(line, column, options, capability, linter, lsp_details) abort
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
if !ale#lsp#HasCapability(l:id, a:capability)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
|
||||
let l:Callback = a:linter.lsp is# 'tsserver'
|
||||
\ ? function('ale#definition#HandleTSServerResponse')
|
||||
\ : function('ale#definition#HandleLSPResponse')
|
||||
call ale#lsp#RegisterCallback(l:id, l:Callback)
|
||||
|
||||
if a:linter.lsp is# 'tsserver'
|
||||
if a:capability is# 'definition'
|
||||
let l:message = ale#lsp#tsserver_message#Definition(
|
||||
\ l:buffer,
|
||||
\ a:line,
|
||||
\ a:column
|
||||
\)
|
||||
elseif a:capability is# 'typeDefinition'
|
||||
let l:message = ale#lsp#tsserver_message#TypeDefinition(
|
||||
\ l:buffer,
|
||||
\ a:line,
|
||||
\ a:column
|
||||
\)
|
||||
elseif a:capability is# 'implementation'
|
||||
let l:message = ale#lsp#tsserver_message#Implementation(
|
||||
\ l:buffer,
|
||||
\ a:line,
|
||||
\ a:column
|
||||
\)
|
||||
endif
|
||||
else
|
||||
" Send a message saying the buffer has changed first, or the
|
||||
" definition position probably won't make sense.
|
||||
call ale#lsp#NotifyForChanges(l:id, l:buffer)
|
||||
|
||||
" For LSP completions, we need to clamp the column to the length of
|
||||
" the line. python-language-server and perhaps others do not implement
|
||||
" this correctly.
|
||||
if a:capability is# 'definition'
|
||||
let l:message = ale#lsp#message#Definition(l:buffer, a:line, a:column)
|
||||
elseif a:capability is# 'typeDefinition'
|
||||
let l:message = ale#lsp#message#TypeDefinition(l:buffer, a:line, a:column)
|
||||
elseif a:capability is# 'implementation'
|
||||
let l:message = ale#lsp#message#Implementation(l:buffer, a:line, a:column)
|
||||
else
|
||||
" XXX: log here?
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:request_id = ale#lsp#Send(l:id, l:message)
|
||||
|
||||
let s:go_to_definition_map[l:request_id] = {
|
||||
\ 'open_in': get(a:options, 'open_in', 'current-buffer'),
|
||||
\}
|
||||
endfunction
|
||||
|
||||
function! s:GoToLSPDefinition(linter, options, capability) abort
|
||||
let l:buffer = bufnr('')
|
||||
let [l:line, l:column] = getpos('.')[1:2]
|
||||
let l:column = min([l:column, len(getline(l:line))])
|
||||
|
||||
let l:Callback = function(
|
||||
\ 's:OnReady',
|
||||
\ [l:line, l:column, a:options, a:capability]
|
||||
\)
|
||||
call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||
endfunction
|
||||
|
||||
function! ale#definition#GoTo(options) abort
|
||||
for l:linter in ale#lsp_linter#GetEnabled(bufnr(''))
|
||||
call s:GoToLSPDefinition(l:linter, a:options, 'definition')
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#definition#GoToType(options) abort
|
||||
for l:linter in ale#lsp_linter#GetEnabled(bufnr(''))
|
||||
call s:GoToLSPDefinition(l:linter, a:options, 'typeDefinition')
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#definition#GoToImpl(options) abort
|
||||
for l:linter in ale#lsp_linter#GetEnabled(bufnr(''))
|
||||
call s:GoToLSPDefinition(l:linter, a:options, 'implementation')
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#definition#GoToCommandHandler(command, ...) abort
|
||||
let l:options = {}
|
||||
|
||||
if len(a:000) > 0
|
||||
for l:option in a:000
|
||||
if l:option is? '-tab'
|
||||
let l:options.open_in = 'tab'
|
||||
elseif l:option is? '-split'
|
||||
let l:options.open_in = 'split'
|
||||
elseif l:option is? '-vsplit'
|
||||
let l:options.open_in = 'vsplit'
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
if !has_key(l:options, 'open_in')
|
||||
let l:default_navigation = ale#Var(bufnr(''), 'default_navigation')
|
||||
|
||||
if index(['tab', 'split', 'vsplit'], l:default_navigation) >= 0
|
||||
let l:options.open_in = l:default_navigation
|
||||
endif
|
||||
endif
|
||||
|
||||
if a:command is# 'type'
|
||||
call ale#definition#GoToType(l:options)
|
||||
elseif a:command is# 'implementation'
|
||||
call ale#definition#GoToImpl(l:options)
|
||||
else
|
||||
call ale#definition#GoTo(l:options)
|
||||
endif
|
||||
endfunction
|
24
vim/.vim/autoload/ale/dhall.vim
Normal file
24
vim/.vim/autoload/ale/dhall.vim
Normal file
@ -0,0 +1,24 @@
|
||||
" Author: Pat Brisbin <pbrisbin@gmail.com>, toastal <toastal@protonmail.com>
|
||||
" Description: Functions for working with Dhall’s executable
|
||||
|
||||
call ale#Set('dhall_executable', 'dhall')
|
||||
call ale#Set('dhall_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('dhall_options', '')
|
||||
|
||||
function! ale#dhall#GetExecutable(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'dhall_executable')
|
||||
|
||||
" Dhall is written in Haskell and commonly installed with Stack
|
||||
return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'dhall')
|
||||
endfunction
|
||||
|
||||
function! ale#dhall#GetExecutableWithOptions(buffer) abort
|
||||
let l:executable = ale#dhall#GetExecutable(a:buffer)
|
||||
|
||||
return l:executable
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'dhall_options'))
|
||||
endfunction
|
||||
|
||||
function! ale#dhall#GetCommand(buffer) abort
|
||||
return '%e ' . ale#Pad(ale#Var(a:buffer, 'dhall_options'))
|
||||
endfunction
|
757
vim/.vim/autoload/ale/engine.vim
Normal file
757
vim/.vim/autoload/ale/engine.vim
Normal file
@ -0,0 +1,757 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Backend execution and job management
|
||||
" Executes linters in the background, using NeoVim or Vim 8 jobs
|
||||
|
||||
" Remapping of linter problems.
|
||||
let g:ale_type_map = get(g:, 'ale_type_map', {})
|
||||
let g:ale_filename_mappings = get(g:, 'ale_filename_mappings', {})
|
||||
|
||||
if !has_key(s:, 'executable_cache_map')
|
||||
let s:executable_cache_map = {}
|
||||
endif
|
||||
|
||||
function! ale#engine#CleanupEveryBuffer() abort
|
||||
for l:key in keys(g:ale_buffer_info)
|
||||
" The key could be a filename or a buffer number, so try and
|
||||
" convert it to a number. We need a number for the other
|
||||
" functions.
|
||||
let l:buffer = str2nr(l:key)
|
||||
|
||||
if l:buffer > 0
|
||||
" Stop all jobs and clear the results for everything, and delete
|
||||
" all of the data we stored for the buffer.
|
||||
call ale#engine#Cleanup(l:buffer)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#engine#MarkLinterActive(info, linter) abort
|
||||
let l:found = 0
|
||||
|
||||
for l:other_linter in a:info.active_linter_list
|
||||
if l:other_linter.name is# a:linter.name
|
||||
let l:found = 1
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
if !l:found
|
||||
call add(a:info.active_linter_list, a:linter)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#engine#MarkLinterInactive(info, linter_name) abort
|
||||
call filter(a:info.active_linter_list, 'v:val.name isnot# a:linter_name')
|
||||
endfunction
|
||||
|
||||
function! ale#engine#ResetExecutableCache() abort
|
||||
let s:executable_cache_map = {}
|
||||
endfunction
|
||||
|
||||
" Check if files are executable, and if they are, remember that they are
|
||||
" for subsequent calls. We'll keep checking until programs can be executed.
|
||||
function! ale#engine#IsExecutable(buffer, executable) abort
|
||||
if empty(a:executable)
|
||||
" Don't log the executable check if the executable string is empty.
|
||||
return 0
|
||||
endif
|
||||
|
||||
" Check for a cached executable() check.
|
||||
let l:result = get(s:executable_cache_map, a:executable, v:null)
|
||||
|
||||
if l:result isnot v:null
|
||||
return l:result
|
||||
endif
|
||||
|
||||
" Check if the file is executable, and convert -1 to 1.
|
||||
let l:result = executable(a:executable) isnot 0
|
||||
|
||||
" Cache the executable check if we found it, or if the option to cache
|
||||
" failing checks is on.
|
||||
if l:result || get(g:, 'ale_cache_executable_check_failures', 0)
|
||||
let s:executable_cache_map[a:executable] = l:result
|
||||
endif
|
||||
|
||||
if g:ale_history_enabled
|
||||
call ale#history#Add(a:buffer, l:result, 'executable', a:executable)
|
||||
endif
|
||||
|
||||
return l:result
|
||||
endfunction
|
||||
|
||||
function! ale#engine#InitBufferInfo(buffer) abort
|
||||
if !has_key(g:ale_buffer_info, a:buffer)
|
||||
" active_linter_list will hold the list of active linter names
|
||||
" loclist holds the loclist items after all jobs have completed.
|
||||
let g:ale_buffer_info[a:buffer] = {
|
||||
\ 'active_linter_list': [],
|
||||
\ 'active_other_sources_list': [],
|
||||
\ 'loclist': [],
|
||||
\}
|
||||
|
||||
return 1
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" This function is documented and part of the public API.
|
||||
"
|
||||
" Return 1 if ALE is busy checking a given buffer
|
||||
function! ale#engine#IsCheckingBuffer(buffer) abort
|
||||
let l:info = get(g:ale_buffer_info, a:buffer, {})
|
||||
|
||||
return !empty(get(l:info, 'active_linter_list', []))
|
||||
\ || !empty(get(l:info, 'active_other_sources_list', []))
|
||||
endfunction
|
||||
|
||||
function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_source) abort
|
||||
let l:info = get(g:ale_buffer_info, a:buffer, {})
|
||||
|
||||
if empty(l:info)
|
||||
return
|
||||
endif
|
||||
|
||||
if !a:from_other_source
|
||||
" Remove this linter from the list of active linters.
|
||||
" This may have already been done when the job exits.
|
||||
call filter(l:info.active_linter_list, 'v:val.name isnot# a:linter_name')
|
||||
endif
|
||||
|
||||
" Make some adjustments to the loclists to fix common problems, and also
|
||||
" to set default values for loclist items.
|
||||
let l:linter_loclist = ale#engine#FixLocList(
|
||||
\ a:buffer,
|
||||
\ a:linter_name,
|
||||
\ a:from_other_source,
|
||||
\ a:loclist,
|
||||
\)
|
||||
|
||||
" Remove previous items for this linter.
|
||||
call filter(l:info.loclist, 'v:val.linter_name isnot# a:linter_name')
|
||||
|
||||
" We don't need to add items or sort the list when this list is empty.
|
||||
if !empty(l:linter_loclist)
|
||||
" Add the new items.
|
||||
call extend(l:info.loclist, l:linter_loclist)
|
||||
|
||||
" Sort the loclist again.
|
||||
" We need a sorted list so we can run a binary search against it
|
||||
" for efficient lookup of the messages in the cursor handler.
|
||||
call sort(l:info.loclist, 'ale#util#LocItemCompare')
|
||||
endif
|
||||
|
||||
if ale#ShouldDoNothing(a:buffer)
|
||||
return
|
||||
endif
|
||||
|
||||
call ale#engine#SetResults(a:buffer, l:info.loclist)
|
||||
endfunction
|
||||
|
||||
function! s:HandleExit(job_info, buffer, output, data) abort
|
||||
let l:buffer_info = get(g:ale_buffer_info, a:buffer)
|
||||
|
||||
if empty(l:buffer_info)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:linter = a:job_info.linter
|
||||
let l:executable = a:job_info.executable
|
||||
|
||||
" Remove this job from the list.
|
||||
call ale#engine#MarkLinterInactive(l:buffer_info, l:linter.name)
|
||||
|
||||
" Stop here if we land in the handle for a job completing if we're in
|
||||
" a sandbox.
|
||||
if ale#util#InSandbox()
|
||||
return
|
||||
endif
|
||||
|
||||
if has('nvim') && !empty(a:output) && empty(a:output[-1])
|
||||
call remove(a:output, -1)
|
||||
endif
|
||||
|
||||
try
|
||||
let l:loclist = ale#util#GetFunction(l:linter.callback)(a:buffer, a:output)
|
||||
" Handle the function being unknown, or being deleted.
|
||||
catch /E700/
|
||||
let l:loclist = []
|
||||
endtry
|
||||
|
||||
call ale#engine#HandleLoclist(l:linter.name, a:buffer, l:loclist, 0)
|
||||
endfunction
|
||||
|
||||
function! ale#engine#SetResults(buffer, loclist) abort
|
||||
let l:linting_is_done = !ale#engine#IsCheckingBuffer(a:buffer)
|
||||
|
||||
if g:ale_use_neovim_diagnostics_api
|
||||
call ale#engine#SendResultsToNeovimDiagnostics(a:buffer, a:loclist)
|
||||
endif
|
||||
|
||||
" Set signs first. This could potentially fix some line numbers.
|
||||
" The List could be sorted again here by SetSigns.
|
||||
if !g:ale_use_neovim_diagnostics_api && g:ale_set_signs
|
||||
call ale#sign#SetSigns(a:buffer, a:loclist)
|
||||
endif
|
||||
|
||||
if g:ale_set_quickfix || g:ale_set_loclist
|
||||
call ale#list#SetLists(a:buffer, a:loclist)
|
||||
endif
|
||||
|
||||
if exists('*ale#statusline#Update')
|
||||
" Don't load/run if not already loaded.
|
||||
call ale#statusline#Update(a:buffer, a:loclist)
|
||||
endif
|
||||
|
||||
if !g:ale_use_neovim_diagnostics_api && g:ale_set_highlights
|
||||
call ale#highlight#SetHighlights(a:buffer, a:loclist)
|
||||
endif
|
||||
|
||||
if !g:ale_use_neovim_diagnostics_api
|
||||
\&& (g:ale_virtualtext_cursor is# 'all' || g:ale_virtualtext_cursor == 2)
|
||||
call ale#virtualtext#SetTexts(a:buffer, a:loclist)
|
||||
endif
|
||||
|
||||
if l:linting_is_done
|
||||
if g:ale_echo_cursor
|
||||
" Try and echo the warning now.
|
||||
" This will only do something meaningful if we're in normal mode.
|
||||
call ale#cursor#EchoCursorWarning()
|
||||
endif
|
||||
|
||||
if !g:ale_use_neovim_diagnostics_api
|
||||
\&& (g:ale_virtualtext_cursor is# 'current' || g:ale_virtualtext_cursor == 1)
|
||||
" Try and show the warning now.
|
||||
" This will only do something meaningful if we're in normal mode.
|
||||
call ale#virtualtext#ShowCursorWarning()
|
||||
endif
|
||||
|
||||
" Reset the save event marker, used for opening windows, etc.
|
||||
call setbufvar(a:buffer, 'ale_save_event_fired', 0)
|
||||
" Set a marker showing how many times a buffer has been checked.
|
||||
call setbufvar(
|
||||
\ a:buffer,
|
||||
\ 'ale_linted',
|
||||
\ getbufvar(a:buffer, 'ale_linted', 0) + 1
|
||||
\)
|
||||
|
||||
" Automatically remove all managed temporary files and directories
|
||||
" now that all jobs have completed.
|
||||
call ale#command#RemoveManagedFiles(a:buffer)
|
||||
|
||||
" Call user autocommands. This allows users to hook into ALE's lint cycle.
|
||||
silent doautocmd <nomodeline> User ALELintPost
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#engine#SendResultsToNeovimDiagnostics(buffer, loclist) abort
|
||||
if !has('nvim-0.6')
|
||||
" We will warn the user on startup as well if they try to set
|
||||
" g:ale_use_neovim_diagnostics_api outside of a Neovim context.
|
||||
return
|
||||
endif
|
||||
|
||||
" Keep the Lua surface area really small in the VimL part of ALE,
|
||||
" and just require the diagnostics.lua module on demand.
|
||||
let l:SendDiagnostics = luaeval('require("ale.diagnostics").sendAleResultsToDiagnostics')
|
||||
call l:SendDiagnostics(a:buffer, a:loclist)
|
||||
endfunction
|
||||
|
||||
function! s:RemapItemTypes(type_map, loclist) abort
|
||||
for l:item in a:loclist
|
||||
let l:key = l:item.type
|
||||
\ . (get(l:item, 'sub_type', '') is# 'style' ? 'S' : '')
|
||||
let l:new_key = get(a:type_map, l:key, '')
|
||||
|
||||
if l:new_key is# 'E'
|
||||
\|| l:new_key is# 'ES'
|
||||
\|| l:new_key is# 'W'
|
||||
\|| l:new_key is# 'WS'
|
||||
\|| l:new_key is# 'I'
|
||||
let l:item.type = l:new_key[0]
|
||||
|
||||
if l:new_key is# 'ES' || l:new_key is# 'WS'
|
||||
let l:item.sub_type = 'style'
|
||||
elseif has_key(l:item, 'sub_type')
|
||||
call remove(l:item, 'sub_type')
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#engine#FixLocList(buffer, linter_name, from_other_source, loclist) abort
|
||||
let l:mappings = ale#GetFilenameMappings(a:buffer, a:linter_name)
|
||||
|
||||
if !empty(l:mappings)
|
||||
" We need to apply reverse filename mapping here.
|
||||
let l:mappings = ale#filename_mapping#Invert(l:mappings)
|
||||
endif
|
||||
|
||||
let l:bufnr_map = {}
|
||||
let l:new_loclist = []
|
||||
|
||||
" Some errors have line numbers beyond the end of the file,
|
||||
" so we need to adjust them so they set the error at the last line
|
||||
" of the file instead.
|
||||
let l:last_line_number = ale#util#GetLineCount(a:buffer)
|
||||
|
||||
for l:old_item in a:loclist
|
||||
" Copy the loclist item with some default values and corrections.
|
||||
"
|
||||
" line and column numbers will be converted to numbers.
|
||||
" The buffer will default to the buffer being checked.
|
||||
" The vcol setting will default to 0, a byte index.
|
||||
" The error type will default to 'E' for errors.
|
||||
" The error number will default to -1.
|
||||
"
|
||||
" The line number and text are the only required keys.
|
||||
"
|
||||
" The linter_name will be set on the errors so it can be used in
|
||||
" output, filtering, etc..
|
||||
let l:item = {
|
||||
\ 'bufnr': a:buffer,
|
||||
\ 'text': l:old_item.text,
|
||||
\ 'lnum': str2nr(l:old_item.lnum),
|
||||
\ 'col': str2nr(get(l:old_item, 'col', 0)),
|
||||
\ 'vcol': 0,
|
||||
\ 'type': get(l:old_item, 'type', 'E'),
|
||||
\ 'nr': get(l:old_item, 'nr', -1),
|
||||
\ 'linter_name': a:linter_name,
|
||||
\}
|
||||
|
||||
if a:from_other_source
|
||||
let l:item.from_other_source = 1
|
||||
endif
|
||||
|
||||
if has_key(l:old_item, 'code')
|
||||
let l:item.code = l:old_item.code
|
||||
endif
|
||||
|
||||
let l:old_name = get(l:old_item, 'filename', '')
|
||||
|
||||
" Map parsed from output to local filesystem files.
|
||||
if !empty(l:old_name) && !empty(l:mappings)
|
||||
let l:old_name = ale#filename_mapping#Map(l:old_name, l:mappings)
|
||||
endif
|
||||
|
||||
if !empty(l:old_name) && !ale#path#IsTempName(l:old_name)
|
||||
" Use the filename given.
|
||||
" Temporary files are assumed to be for this buffer,
|
||||
" and the filename is not included then, because it looks bad
|
||||
" in the loclist window.
|
||||
let l:filename = l:old_name
|
||||
let l:item.filename = l:filename
|
||||
|
||||
if has_key(l:old_item, 'bufnr')
|
||||
" If a buffer number is also given, include that too.
|
||||
" If Vim detects that he buffer number is valid, it will
|
||||
" be used instead of the filename.
|
||||
let l:item.bufnr = l:old_item.bufnr
|
||||
elseif has_key(l:bufnr_map, l:filename)
|
||||
" Get the buffer number from the map, which can be faster.
|
||||
let l:item.bufnr = l:bufnr_map[l:filename]
|
||||
else
|
||||
" Look up the buffer number.
|
||||
let l:item.bufnr = bufnr(l:filename)
|
||||
let l:bufnr_map[l:filename] = l:item.bufnr
|
||||
endif
|
||||
elseif has_key(l:old_item, 'bufnr')
|
||||
let l:item.bufnr = l:old_item.bufnr
|
||||
endif
|
||||
|
||||
if has_key(l:old_item, 'detail')
|
||||
let l:item.detail = l:old_item.detail
|
||||
endif
|
||||
|
||||
" Pass on a end_col 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 has_key(l:old_item, 'end_lnum')
|
||||
let l:item.end_lnum = str2nr(l:old_item.end_lnum)
|
||||
|
||||
" When the error ends after the end of the file, put it at the
|
||||
" end. This is only done for the current buffer.
|
||||
if l:item.bufnr == a:buffer && l:item.end_lnum > l:last_line_number
|
||||
let l:item.end_lnum = l:last_line_number
|
||||
endif
|
||||
endif
|
||||
|
||||
if has_key(l:old_item, 'sub_type')
|
||||
let l:item.sub_type = l:old_item.sub_type
|
||||
endif
|
||||
|
||||
if l:item.lnum < 1
|
||||
" When errors appear before line 1, put them at line 1.
|
||||
let l:item.lnum = 1
|
||||
elseif l:item.bufnr == a:buffer && l:item.lnum > l:last_line_number
|
||||
" When errors go beyond the end of the file, put them at the end.
|
||||
" This is only done for the current buffer.
|
||||
let l:item.lnum = l:last_line_number
|
||||
elseif get(l:old_item, 'vcol', 0)
|
||||
" Convert virtual column positions to byte positions.
|
||||
" The positions will be off if the buffer has changed recently.
|
||||
let l:line = getbufline(a:buffer, l:item.lnum)[0]
|
||||
|
||||
let l:item.col = ale#util#Col(l:line, l:item.col)
|
||||
|
||||
if has_key(l:item, 'end_col')
|
||||
let l:end_line = get(l:item, 'end_lnum', l:line) != l:line
|
||||
\ ? getbufline(a:buffer, l:item.end_lnum)[0]
|
||||
\ : l:line
|
||||
|
||||
let l:item.end_col = ale#util#Col(l:end_line, l:item.end_col)
|
||||
endif
|
||||
endif
|
||||
|
||||
call add(l:new_loclist, l:item)
|
||||
endfor
|
||||
|
||||
let l:type_map = get(ale#Var(a:buffer, 'type_map'), a:linter_name, {})
|
||||
|
||||
if !empty(l:type_map)
|
||||
call s:RemapItemTypes(l:type_map, l:new_loclist)
|
||||
endif
|
||||
|
||||
return l:new_loclist
|
||||
endfunction
|
||||
|
||||
" Given part of a command, replace any % with %%, so that no characters in
|
||||
" the string will be replaced with filenames, etc.
|
||||
function! ale#engine#EscapeCommandPart(command_part) abort
|
||||
" TODO: Emit deprecation warning here later.
|
||||
return ale#command#EscapeCommandPart(a:command_part)
|
||||
endfunction
|
||||
|
||||
" Run a job.
|
||||
"
|
||||
" Returns 1 when a job was started successfully.
|
||||
function! s:RunJob(command, options) abort
|
||||
if ale#command#IsDeferred(a:command)
|
||||
let a:command.result_callback = {
|
||||
\ command -> s:RunJob(command, a:options)
|
||||
\}
|
||||
|
||||
return 1
|
||||
endif
|
||||
|
||||
let l:command = a:command
|
||||
|
||||
if empty(l:command)
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:cwd = a:options.cwd
|
||||
let l:executable = a:options.executable
|
||||
let l:buffer = a:options.buffer
|
||||
let l:linter = a:options.linter
|
||||
let l:output_stream = a:options.output_stream
|
||||
let l:read_buffer = a:options.read_buffer && !a:options.lint_file
|
||||
let l:info = g:ale_buffer_info[l:buffer]
|
||||
|
||||
let l:Callback = function('s:HandleExit', [{
|
||||
\ 'linter': l:linter,
|
||||
\ 'executable': l:executable,
|
||||
\}])
|
||||
let l:result = ale#command#Run(l:buffer, l:command, l:Callback, {
|
||||
\ 'cwd': l:cwd,
|
||||
\ 'output_stream': l:output_stream,
|
||||
\ 'executable': l:executable,
|
||||
\ 'read_buffer': l:read_buffer,
|
||||
\ 'log_output': 1,
|
||||
\ 'filename_mappings': ale#GetFilenameMappings(l:buffer, l:linter.name),
|
||||
\})
|
||||
|
||||
" Only proceed if the job is being run.
|
||||
if empty(l:result)
|
||||
return 0
|
||||
endif
|
||||
|
||||
call ale#engine#MarkLinterActive(l:info, l:linter)
|
||||
|
||||
silent doautocmd <nomodeline> User ALEJobStarted
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! s:StopCurrentJobs(buffer, clear_lint_file_jobs, linter_slots) abort
|
||||
let l:info = get(g:ale_buffer_info, a:buffer, {})
|
||||
call ale#command#StopJobs(a:buffer, 'linter')
|
||||
|
||||
" Update the active linter list, clearing out anything not running.
|
||||
if a:clear_lint_file_jobs
|
||||
call ale#command#StopJobs(a:buffer, 'file_linter')
|
||||
let l:info.active_linter_list = []
|
||||
else
|
||||
let l:lint_file_map = {}
|
||||
|
||||
" Use a previously computed map of `lint_file` values to find
|
||||
" linters that are used for linting files.
|
||||
for [l:lint_file, l:linter] in a:linter_slots
|
||||
if l:lint_file is 1
|
||||
let l:lint_file_map[l:linter.name] = 1
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Keep jobs for linting files when we're only linting buffers.
|
||||
call filter(l:info.active_linter_list, 'get(l:lint_file_map, v:val.name)')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#engine#Stop(buffer) abort
|
||||
call s:StopCurrentJobs(a:buffer, 1, [])
|
||||
endfunction
|
||||
|
||||
function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort
|
||||
" Figure out which linters are still enabled, and remove
|
||||
" problems for linters which are no longer enabled.
|
||||
" Problems from other sources will be kept.
|
||||
let l:name_map = {}
|
||||
|
||||
for l:linter in a:linters
|
||||
let l:name_map[l:linter.name] = 1
|
||||
endfor
|
||||
|
||||
call filter(
|
||||
\ get(g:ale_buffer_info[a:buffer], 'loclist', []),
|
||||
\ 'get(v:val, ''from_other_source'') || get(l:name_map, get(v:val, ''linter_name''))',
|
||||
\)
|
||||
endfunction
|
||||
|
||||
function! s:AddProblemsFromOtherBuffers(buffer, linters) abort
|
||||
let l:filename = expand('#' . a:buffer . ':p')
|
||||
let l:loclist = []
|
||||
let l:name_map = {}
|
||||
|
||||
" Build a map of the active linters.
|
||||
for l:linter in a:linters
|
||||
let l:name_map[l:linter.name] = 1
|
||||
endfor
|
||||
|
||||
" Find the items from other buffers, for the linters that are enabled.
|
||||
for l:info in values(g:ale_buffer_info)
|
||||
for l:item in l:info.loclist
|
||||
if has_key(l:item, 'filename')
|
||||
\&& l:item.filename is# l:filename
|
||||
\&& has_key(l:name_map, l:item.linter_name)
|
||||
" Copy the items and set the buffer numbers to this one.
|
||||
let l:new_item = copy(l:item)
|
||||
let l:new_item.bufnr = a:buffer
|
||||
call add(l:loclist, l:new_item)
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
if !empty(l:loclist)
|
||||
call sort(l:loclist, function('ale#util#LocItemCompareWithText'))
|
||||
call uniq(l:loclist, function('ale#util#LocItemCompareWithText'))
|
||||
|
||||
" Set the loclist variable, used by some parts of ALE.
|
||||
let g:ale_buffer_info[a:buffer].loclist = l:loclist
|
||||
call ale#engine#SetResults(a:buffer, l:loclist)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:RunIfExecutable(buffer, linter, lint_file, executable) abort
|
||||
if ale#command#IsDeferred(a:executable)
|
||||
let a:executable.result_callback = {
|
||||
\ executable -> s:RunIfExecutable(
|
||||
\ a:buffer,
|
||||
\ a:linter,
|
||||
\ a:lint_file,
|
||||
\ executable
|
||||
\ )
|
||||
\}
|
||||
|
||||
return 1
|
||||
endif
|
||||
|
||||
if ale#engine#IsExecutable(a:buffer, a:executable)
|
||||
" Use different job types for file or linter jobs.
|
||||
let l:job_type = a:lint_file ? 'file_linter' : 'linter'
|
||||
call setbufvar(a:buffer, 'ale_job_type', l:job_type)
|
||||
|
||||
" Get the cwd for the linter and set it before we call GetCommand.
|
||||
" This will ensure that ale#command#Run uses it by default.
|
||||
let l:cwd = ale#linter#GetCwd(a:buffer, a:linter)
|
||||
|
||||
if l:cwd isnot v:null
|
||||
call ale#command#SetCwd(a:buffer, l:cwd)
|
||||
endif
|
||||
|
||||
let l:command = ale#linter#GetCommand(a:buffer, a:linter)
|
||||
|
||||
if l:cwd isnot v:null
|
||||
call ale#command#ResetCwd(a:buffer)
|
||||
endif
|
||||
|
||||
let l:options = {
|
||||
\ 'cwd': l:cwd,
|
||||
\ 'executable': a:executable,
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'linter': a:linter,
|
||||
\ 'output_stream': get(a:linter, 'output_stream', 'stdout'),
|
||||
\ 'read_buffer': a:linter.read_buffer,
|
||||
\ 'lint_file': a:lint_file,
|
||||
\}
|
||||
|
||||
return s:RunJob(l:command, l:options)
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" Run a linter for a buffer.
|
||||
"
|
||||
" Returns 1 if the linter was successfully run.
|
||||
function! s:RunLinter(buffer, linter, lint_file) abort
|
||||
if !empty(a:linter.lsp)
|
||||
return ale#lsp_linter#CheckWithLSP(a:buffer, a:linter)
|
||||
else
|
||||
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
|
||||
|
||||
return s:RunIfExecutable(a:buffer, a:linter, a:lint_file, l:executable)
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:GetLintFileSlots(buffer, linters) abort
|
||||
let l:linter_slots = []
|
||||
|
||||
for l:linter in a:linters
|
||||
let l:LintFile = l:linter.lint_file
|
||||
|
||||
if type(l:LintFile) is v:t_func
|
||||
let l:LintFile = l:LintFile(a:buffer)
|
||||
endif
|
||||
|
||||
call add(l:linter_slots, [l:LintFile, l:linter])
|
||||
endfor
|
||||
|
||||
return l:linter_slots
|
||||
endfunction
|
||||
|
||||
function! s:GetLintFileValues(slots, Callback) abort
|
||||
let l:deferred_list = []
|
||||
let l:new_slots = []
|
||||
|
||||
for [l:lint_file, l:linter] in a:slots
|
||||
while ale#command#IsDeferred(l:lint_file) && has_key(l:lint_file, 'value')
|
||||
" If we've already computed the return value, use it.
|
||||
let l:lint_file = l:lint_file.value
|
||||
endwhile
|
||||
|
||||
if ale#command#IsDeferred(l:lint_file)
|
||||
" If we are going to return the result later, wait for it.
|
||||
call add(l:deferred_list, l:lint_file)
|
||||
else
|
||||
" If we have the value now, coerce it to 0 or 1.
|
||||
let l:lint_file = l:lint_file is 1
|
||||
endif
|
||||
|
||||
call add(l:new_slots, [l:lint_file, l:linter])
|
||||
endfor
|
||||
|
||||
if !empty(l:deferred_list)
|
||||
for l:deferred in l:deferred_list
|
||||
let l:deferred.result_callback =
|
||||
\ {-> s:GetLintFileValues(l:new_slots, a:Callback)}
|
||||
endfor
|
||||
else
|
||||
call a:Callback(l:new_slots)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:RunLinters(
|
||||
\ buffer,
|
||||
\ linters,
|
||||
\ slots,
|
||||
\ should_lint_file,
|
||||
\ new_buffer,
|
||||
\) abort
|
||||
call s:StopCurrentJobs(a:buffer, a:should_lint_file, a:slots)
|
||||
call s:RemoveProblemsForDisabledLinters(a:buffer, a:linters)
|
||||
|
||||
" We can only clear the results if we aren't checking the buffer.
|
||||
let l:can_clear_results = !ale#engine#IsCheckingBuffer(a:buffer)
|
||||
|
||||
silent doautocmd <nomodeline> User ALELintPre
|
||||
|
||||
for [l:lint_file, l:linter] in a:slots
|
||||
" Only run lint_file linters if we should.
|
||||
if !l:lint_file || a:should_lint_file
|
||||
if s:RunLinter(a:buffer, l:linter, l:lint_file)
|
||||
" If a single linter ran, we shouldn't clear everything.
|
||||
let l:can_clear_results = 0
|
||||
endif
|
||||
else
|
||||
" If we skipped running a lint_file linter still in the list,
|
||||
" we shouldn't clear everything.
|
||||
let l:can_clear_results = 0
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Clear the results if we can. This needs to be done when linters are
|
||||
" disabled, or ALE itself is disabled.
|
||||
if l:can_clear_results
|
||||
call ale#engine#SetResults(a:buffer, [])
|
||||
elseif a:new_buffer
|
||||
call s:AddProblemsFromOtherBuffers(
|
||||
\ a:buffer,
|
||||
\ map(copy(a:slots), 'v:val[1]')
|
||||
\)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#engine#RunLinters(buffer, linters, should_lint_file) abort
|
||||
" Initialise the buffer information if needed.
|
||||
let l:new_buffer = ale#engine#InitBufferInfo(a:buffer)
|
||||
|
||||
call s:GetLintFileValues(
|
||||
\ s:GetLintFileSlots(a:buffer, a:linters),
|
||||
\ {
|
||||
\ slots -> s:RunLinters(
|
||||
\ a:buffer,
|
||||
\ a:linters,
|
||||
\ slots,
|
||||
\ a:should_lint_file,
|
||||
\ l:new_buffer,
|
||||
\ )
|
||||
\ }
|
||||
\)
|
||||
endfunction
|
||||
|
||||
" Clean up a buffer.
|
||||
"
|
||||
" This function will stop all current jobs for the buffer,
|
||||
" clear the state of everything, and remove the Dictionary for managing
|
||||
" the buffer.
|
||||
function! ale#engine#Cleanup(buffer) abort
|
||||
" Don't bother with cleanup code when newer NeoVim versions are exiting.
|
||||
if get(v:, 'exiting', v:null) isnot v:null
|
||||
return
|
||||
endif
|
||||
|
||||
if exists('*ale#lsp#CloseDocument')
|
||||
call ale#lsp#CloseDocument(a:buffer)
|
||||
endif
|
||||
|
||||
if !has_key(g:ale_buffer_info, a:buffer)
|
||||
return
|
||||
endif
|
||||
|
||||
call ale#engine#RunLinters(a:buffer, [], 1)
|
||||
|
||||
call remove(g:ale_buffer_info, a:buffer)
|
||||
endfunction
|
||||
|
||||
" Given a buffer number, return the warnings and errors for a given buffer.
|
||||
function! ale#engine#GetLoclist(buffer) abort
|
||||
if !has_key(g:ale_buffer_info, a:buffer)
|
||||
return []
|
||||
endif
|
||||
|
||||
return g:ale_buffer_info[a:buffer].loclist
|
||||
endfunction
|
97
vim/.vim/autoload/ale/engine/ignore.vim
Normal file
97
vim/.vim/autoload/ale/engine/ignore.vim
Normal file
@ -0,0 +1,97 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Code for ignoring linters. Only loaded and if configured.
|
||||
|
||||
" A map for remapping lspconfig server names to linter names or aliases in
|
||||
" ALE. We should change the names where they will conflict with names in ALE.
|
||||
"
|
||||
" Notes on names from nvim-lspconfig not included here.
|
||||
"
|
||||
" * 'rubocop' is run in a language server mode
|
||||
" * 'eslint' is run via 'vscode-eslint-language-server'
|
||||
let s:lspconfig_map = {
|
||||
\ 'als': 'adals',
|
||||
\ 'ansiblels': 'ansible-language-server',
|
||||
\ 'bicep': 'bicep_language_server',
|
||||
\ 'cmake': 'cmake_language_server',
|
||||
\ 'denols': 'deno',
|
||||
\ 'erlangls': 'erlang_ls',
|
||||
\ 'html': 'vscodehtml',
|
||||
\ 'ocamlls': 'ocaml-language-server',
|
||||
\ 'ols': 'odin-lsp',
|
||||
\ 'puppet': 'puppet_languageserver',
|
||||
\}
|
||||
|
||||
" Given a filetype and a configuration for ignoring linters, return a List of
|
||||
" Strings for linter names to ignore.
|
||||
function! ale#engine#ignore#GetList(filetype, config) abort
|
||||
if type(a:config) is v:t_list
|
||||
return a:config
|
||||
endif
|
||||
|
||||
if type(a:config) is v:t_dict
|
||||
let l:names_to_remove = []
|
||||
|
||||
for l:part in split(a:filetype , '\.')
|
||||
call extend(l:names_to_remove, get(a:config, l:part, []))
|
||||
endfor
|
||||
|
||||
return l:names_to_remove
|
||||
endif
|
||||
|
||||
return []
|
||||
endfunction
|
||||
|
||||
" This function can be mocked in tests.
|
||||
function! ale#engine#ignore#GetLSPConfigNames() abort
|
||||
return luaeval('require ''ale.util''.configured_lspconfig_servers()')
|
||||
endfunction
|
||||
|
||||
function! s:GetMappedLSPConfigNames() abort
|
||||
" Check the lspconfig flag before calling luaeval.
|
||||
if !get(g:, 'lspconfig', 0)
|
||||
return []
|
||||
endif
|
||||
|
||||
let l:lspconfig_servers = ale#engine#ignore#GetLSPConfigNames()
|
||||
|
||||
return map(
|
||||
\ !empty(l:lspconfig_servers) ? l:lspconfig_servers : [],
|
||||
\ {_, val -> get(s:lspconfig_map, val, val) }
|
||||
\)
|
||||
endfunction
|
||||
|
||||
" Given a List of linter descriptions, exclude the linters to be ignored.
|
||||
function! ale#engine#ignore#Exclude(filetype, all_linters, config, disable_lsp) abort
|
||||
let l:names_to_remove = ale#engine#ignore#GetList(a:filetype, a:config)
|
||||
|
||||
" If configured to automatically ignore otherwise configured LSP linter
|
||||
" names, add them to the names to remove. This could ignore linters
|
||||
" with matching names that are not marked as LSP linters.
|
||||
if a:disable_lsp is# 'auto'
|
||||
call extend(l:names_to_remove, s:GetMappedLSPConfigNames())
|
||||
endif
|
||||
|
||||
let l:ignore_all_lsps = a:disable_lsp is 1 || a:disable_lsp is v:true
|
||||
let l:filtered_linters = []
|
||||
|
||||
for l:linter in a:all_linters
|
||||
let l:should_include = index(l:names_to_remove, l:linter.name) == -1
|
||||
let l:i = 0
|
||||
|
||||
while l:should_include && l:i < len(l:linter.aliases)
|
||||
let l:name = l:linter.aliases[l:i]
|
||||
let l:should_include = index(l:names_to_remove, l:name) == -1
|
||||
let l:i += 1
|
||||
endwhile
|
||||
|
||||
if l:should_include && l:ignore_all_lsps
|
||||
let l:should_include = empty(get(l:linter, 'lsp'))
|
||||
endif
|
||||
|
||||
if l:should_include
|
||||
call add(l:filtered_linters, l:linter)
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:filtered_linters
|
||||
endfunction
|
228
vim/.vim/autoload/ale/events.vim
Normal file
228
vim/.vim/autoload/ale/events.vim
Normal file
@ -0,0 +1,228 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: ALE functions for autocmd events.
|
||||
|
||||
" Get the number of milliseconds since some vague, but consistent, point in
|
||||
" the past.
|
||||
"
|
||||
" This function can be used for timing execution, etc.
|
||||
"
|
||||
" The time will be returned as a Number.
|
||||
function! ale#events#ClockMilliseconds() abort
|
||||
return float2nr(reltimefloat(reltime()) * 1000)
|
||||
endfunction
|
||||
|
||||
function! ale#events#QuitEvent(buffer) abort
|
||||
" Remember when ALE is quitting for BufWrite, etc.
|
||||
call setbufvar(a:buffer, 'ale_quitting', ale#events#ClockMilliseconds())
|
||||
endfunction
|
||||
|
||||
function! ale#events#QuitRecently(buffer) abort
|
||||
let l:time = getbufvar(a:buffer, 'ale_quitting', 0)
|
||||
|
||||
return l:time && ale#events#ClockMilliseconds() - l:time < 1000
|
||||
endfunction
|
||||
|
||||
function! ale#events#SaveEvent(buffer) abort
|
||||
let l:should_lint = ale#Var(a:buffer, 'enabled') && g:ale_lint_on_save
|
||||
|
||||
if l:should_lint
|
||||
call setbufvar(a:buffer, 'ale_save_event_fired', 1)
|
||||
endif
|
||||
|
||||
if ale#Var(a:buffer, 'fix_on_save') && !ale#events#QuitRecently(a:buffer)
|
||||
let l:will_fix = ale#fix#Fix(a:buffer, 'save_file')
|
||||
let l:should_lint = l:should_lint && !l:will_fix
|
||||
endif
|
||||
|
||||
if l:should_lint && !ale#events#QuitRecently(a:buffer)
|
||||
call ale#Queue(0, 'lint_file', a:buffer)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#events#LintOnEnter(buffer) abort
|
||||
" Unmark a file as being changed outside of Vim after we try to check it.
|
||||
call setbufvar(a:buffer, 'ale_file_changed', 0)
|
||||
|
||||
if ale#Var(a:buffer, 'enabled') && g:ale_lint_on_enter
|
||||
call ale#Queue(0, 'lint_file', a:buffer)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#events#ReadOrEnterEvent(buffer) abort
|
||||
" Apply pattern options if the variable is set.
|
||||
if get(g:, 'ale_pattern_options_enabled', 1)
|
||||
\&& !empty(get(g:, 'ale_pattern_options'))
|
||||
call ale#pattern_options#SetOptions(a:buffer)
|
||||
endif
|
||||
|
||||
" When entering a buffer, we are no longer quitting it.
|
||||
call setbufvar(a:buffer, 'ale_quitting', 0)
|
||||
let l:filetype = getbufvar(a:buffer, '&filetype')
|
||||
call setbufvar(a:buffer, 'ale_original_filetype', l:filetype)
|
||||
|
||||
" If the file changed outside of Vim, check it on BufEnter,BufRead
|
||||
if getbufvar(a:buffer, 'ale_file_changed')
|
||||
call ale#events#LintOnEnter(a:buffer)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#events#FileTypeEvent(buffer, new_filetype) abort
|
||||
" The old filetype will be set to an empty string by the BuFEnter event,
|
||||
" and not linting when the old filetype hasn't been set yet prevents
|
||||
" buffers being checked when you enter them when linting on enter is off.
|
||||
let l:old_filetype = getbufvar(a:buffer, 'ale_original_filetype', v:null)
|
||||
|
||||
if l:old_filetype isnot v:null
|
||||
\&& !empty(a:new_filetype)
|
||||
\&& a:new_filetype isnot# l:old_filetype
|
||||
" Remember what the new filetype is.
|
||||
call setbufvar(a:buffer, 'ale_original_filetype', a:new_filetype)
|
||||
|
||||
if g:ale_lint_on_filetype_changed
|
||||
call ale#Queue(300, 'lint_file', a:buffer)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#events#FileChangedEvent(buffer) abort
|
||||
call setbufvar(a:buffer, 'ale_file_changed', 1)
|
||||
|
||||
if bufnr('') == a:buffer
|
||||
call ale#events#LintOnEnter(a:buffer)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" A timer for emulating InsertLeave.
|
||||
"
|
||||
" We only need a single timer, and we'll lint the last buffer we entered
|
||||
" insert mode on.
|
||||
if !exists('s:insert_leave_timer')
|
||||
let s:insert_leave_timer = -1
|
||||
endif
|
||||
|
||||
function! ale#events#EmulateInsertLeave(buffer) abort
|
||||
if mode() is# 'n'
|
||||
call timer_stop(s:insert_leave_timer)
|
||||
call ale#Queue(0, '', a:buffer)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#events#InsertEnterEvent(buffer) abort
|
||||
if g:ale_close_preview_on_insert && exists('*ale#preview#CloseIfTypeMatches')
|
||||
call ale#preview#CloseIfTypeMatches('ale-preview')
|
||||
endif
|
||||
|
||||
" Start a repeating timer if the use might not trigger InsertLeave, so we
|
||||
" can emulate its behavior.
|
||||
if ale#Var(a:buffer, 'lint_on_insert_leave')
|
||||
\&& maparg("\<C-c>", 'i') isnot# '<Esc>'
|
||||
call timer_stop(s:insert_leave_timer)
|
||||
let s:insert_leave_timer = timer_start(
|
||||
\ 100,
|
||||
\ {-> ale#events#EmulateInsertLeave(a:buffer) },
|
||||
\ {'repeat': -1}
|
||||
\)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#events#InsertLeaveEvent(buffer) abort
|
||||
if ale#Var(a:buffer, 'lint_on_insert_leave')
|
||||
" Kill the InsertLeave emulation if the event fired.
|
||||
call timer_stop(s:insert_leave_timer)
|
||||
call ale#Queue(0)
|
||||
endif
|
||||
|
||||
" Look for a warning to echo as soon as we leave Insert mode.
|
||||
" The script's position variable used when moving the cursor will
|
||||
" not be changed here.
|
||||
"
|
||||
" We don't echo this message in emulated insert leave mode, as the user
|
||||
" may want less work to happen on pressing <C-c> versus <Esc>
|
||||
if exists('*ale#engine#Cleanup')
|
||||
call ale#cursor#EchoCursorWarning()
|
||||
|
||||
if g:ale_virtualtext_cursor is# 'current' || g:ale_virtualtext_cursor is# 1 || g:ale_virtualtext_cursor is# '1'
|
||||
" Show a virtualtext message if enabled.
|
||||
call ale#virtualtext#ShowCursorWarning()
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#events#Init() abort
|
||||
" This value used to be a Boolean as a Number, and is now a String.
|
||||
let l:text_changed = '' . g:ale_lint_on_text_changed
|
||||
|
||||
augroup ALEEvents
|
||||
autocmd!
|
||||
|
||||
" These events always need to be set up.
|
||||
autocmd BufEnter,BufRead * call ale#events#ReadOrEnterEvent(str2nr(expand('<abuf>')))
|
||||
autocmd BufWritePost * call ale#events#SaveEvent(str2nr(expand('<abuf>')))
|
||||
|
||||
if g:ale_enabled
|
||||
if l:text_changed is? 'always' || l:text_changed is# '1'
|
||||
autocmd TextChanged,TextChangedI * call ale#Queue(ale#Var(str2nr(expand('<abuf>')), 'lint_delay'))
|
||||
elseif l:text_changed is? 'normal'
|
||||
autocmd TextChanged * call ale#Queue(ale#Var(str2nr(expand('<abuf>')), 'lint_delay'))
|
||||
elseif l:text_changed is? 'insert'
|
||||
autocmd TextChangedI * call ale#Queue(ale#Var(str2nr(expand('<abuf>')), 'lint_delay'))
|
||||
endif
|
||||
|
||||
if g:ale_lint_on_enter
|
||||
autocmd BufWinEnter * call ale#events#LintOnEnter(str2nr(expand('<abuf>')))
|
||||
" Track when the file is changed outside of Vim.
|
||||
autocmd FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand('<abuf>')))
|
||||
endif
|
||||
|
||||
if g:ale_lint_on_filetype_changed
|
||||
" Only start linting if the FileType actually changes after
|
||||
" opening a buffer. The FileType will fire when buffers are opened.
|
||||
autocmd FileType * call ale#events#FileTypeEvent(
|
||||
\ str2nr(expand('<abuf>')),
|
||||
\ expand('<amatch>')
|
||||
\)
|
||||
endif
|
||||
|
||||
" Add an InsertEnter event if we need to close the preview window
|
||||
" on entering insert mode, or if we want to run ALE on leaving
|
||||
" insert mode and <C-c> is not the same as <Esc>.
|
||||
"
|
||||
" We will emulate leaving insert mode for users that might not
|
||||
" trigger InsertLeave.
|
||||
if g:ale_close_preview_on_insert
|
||||
\|| (g:ale_lint_on_insert_leave && maparg("\<C-c>", 'i') isnot# '<Esc>')
|
||||
autocmd InsertEnter * call ale#events#InsertEnterEvent(str2nr(expand('<abuf>')))
|
||||
endif
|
||||
|
||||
let l:add_insert_leave_event = g:ale_lint_on_insert_leave
|
||||
|
||||
if g:ale_echo_cursor || g:ale_cursor_detail
|
||||
" We need to make the message display on InsertLeave
|
||||
let l:add_insert_leave_event = 1
|
||||
|
||||
autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarningWithDelay() | endif
|
||||
endif
|
||||
|
||||
if g:ale_virtualtext_cursor is# 'current' || g:ale_virtualtext_cursor is# 1 || g:ale_virtualtext_cursor is# '1'
|
||||
" We need to make the message display on InsertLeave
|
||||
let l:add_insert_leave_event = 1
|
||||
|
||||
autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#virtualtext#ShowCursorWarningWithDelay() | endif
|
||||
endif
|
||||
|
||||
if l:add_insert_leave_event
|
||||
autocmd InsertLeave * call ale#events#InsertLeaveEvent(str2nr(expand('<abuf>')))
|
||||
endif
|
||||
|
||||
if g:ale_hover_cursor
|
||||
autocmd CursorHold * if exists('*ale#lsp#Send') | call ale#hover#ShowTruncatedMessageAtCursor() | endif
|
||||
endif
|
||||
endif
|
||||
augroup END
|
||||
|
||||
augroup AleURISchemes
|
||||
autocmd!
|
||||
|
||||
autocmd BufNewFile,BufReadPre jdt://** call ale#uri#jdt#ReadJDTLink(expand('<amatch>'))
|
||||
augroup END
|
||||
endfunction
|
22
vim/.vim/autoload/ale/filename_mapping.vim
Normal file
22
vim/.vim/autoload/ale/filename_mapping.vim
Normal file
@ -0,0 +1,22 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Logic for handling mappings between files
|
||||
|
||||
" Invert filesystem mappings so they can be mapped in reverse.
|
||||
function! ale#filename_mapping#Invert(filename_mappings) abort
|
||||
return map(copy(a:filename_mappings), '[v:val[1], v:val[0]]')
|
||||
endfunction
|
||||
|
||||
" Given a filename and some filename_mappings, map a filename.
|
||||
function! ale#filename_mapping#Map(filename, filename_mappings) abort
|
||||
let l:simplified_filename = ale#path#Simplify(a:filename)
|
||||
|
||||
for [l:mapping_from, l:mapping_to] in a:filename_mappings
|
||||
let l:mapping_from = ale#path#Simplify(l:mapping_from)
|
||||
|
||||
if l:simplified_filename[:len(l:mapping_from) - 1] is# l:mapping_from
|
||||
return l:mapping_to . l:simplified_filename[len(l:mapping_from):]
|
||||
endif
|
||||
endfor
|
||||
|
||||
return a:filename
|
||||
endfunction
|
133
vim/.vim/autoload/ale/filerename.vim
Normal file
133
vim/.vim/autoload/ale/filerename.vim
Normal file
@ -0,0 +1,133 @@
|
||||
" Author: Dalius Dobravolskas <dalius.dobravolskas@gmail.com>
|
||||
" Description: Rename file support for tsserver
|
||||
|
||||
let s:filerename_map = {}
|
||||
|
||||
" Used to get the rename map in tests.
|
||||
function! ale#filerename#GetMap() abort
|
||||
return deepcopy(s:filerename_map)
|
||||
endfunction
|
||||
|
||||
" Used to set the rename map in tests.
|
||||
function! ale#filerename#SetMap(map) abort
|
||||
let s:filerename_map = a:map
|
||||
endfunction
|
||||
|
||||
function! ale#filerename#ClearLSPData() abort
|
||||
let s:filerename_map = {}
|
||||
endfunction
|
||||
|
||||
function! s:message(message) abort
|
||||
call ale#util#Execute('echom ' . string(a:message))
|
||||
endfunction
|
||||
|
||||
function! ale#filerename#HandleTSServerResponse(conn_id, response) abort
|
||||
if get(a:response, 'command', '') isnot# 'getEditsForFileRename'
|
||||
return
|
||||
endif
|
||||
|
||||
if !has_key(s:filerename_map, a:response.request_seq)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:options = remove(s:filerename_map, a:response.request_seq)
|
||||
|
||||
let l:old_name = l:options.old_name
|
||||
let l:new_name = l:options.new_name
|
||||
|
||||
if get(a:response, 'success', v:false) is v:false
|
||||
let l:message = get(a:response, 'message', 'unknown')
|
||||
call s:message('Error renaming file "' . l:old_name . '" to "' . l:new_name
|
||||
\ . '". Reason: ' . l:message)
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:changes = a:response.body
|
||||
|
||||
if empty(l:changes)
|
||||
call s:message('No changes while renaming "' . l:old_name . '" to "' . l:new_name . '"')
|
||||
else
|
||||
call ale#code_action#HandleCodeAction(
|
||||
\ {
|
||||
\ 'description': 'filerename',
|
||||
\ 'changes': l:changes,
|
||||
\ },
|
||||
\ {
|
||||
\ 'should_save': 1,
|
||||
\ },
|
||||
\)
|
||||
endif
|
||||
|
||||
silent! noautocmd execute 'saveas ' . l:new_name
|
||||
call delete(l:old_name)
|
||||
endfunction
|
||||
|
||||
function! s:OnReady(options, linter, lsp_details) abort
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
if !ale#lsp#HasCapability(l:id, 'filerename')
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
|
||||
let l:Callback = function('ale#filerename#HandleTSServerResponse')
|
||||
|
||||
call ale#lsp#RegisterCallback(l:id, l:Callback)
|
||||
|
||||
let l:message = ale#lsp#tsserver_message#GetEditsForFileRename(
|
||||
\ a:options.old_name,
|
||||
\ a:options.new_name,
|
||||
\)
|
||||
|
||||
let l:request_id = ale#lsp#Send(l:id, l:message)
|
||||
|
||||
let s:filerename_map[l:request_id] = a:options
|
||||
endfunction
|
||||
|
||||
function! s:ExecuteFileRename(linter, options) abort
|
||||
let l:buffer = bufnr('')
|
||||
|
||||
let l:Callback = function('s:OnReady', [a:options])
|
||||
call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||
endfunction
|
||||
|
||||
function! ale#filerename#Execute() abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:lsp_linters = []
|
||||
|
||||
for l:linter in ale#lsp_linter#GetEnabled(l:buffer)
|
||||
if l:linter.lsp is# 'tsserver'
|
||||
call add(l:lsp_linters, l:linter)
|
||||
endif
|
||||
endfor
|
||||
|
||||
if empty(l:lsp_linters)
|
||||
call s:message('No active tsserver LSPs')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:old_name = expand('#' . l:buffer . ':p')
|
||||
let l:new_name = ale#util#Input('New file name: ', l:old_name, 'file')
|
||||
|
||||
if l:old_name is# l:new_name
|
||||
call s:message('New file name matches old file name')
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
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:ExecuteFileRename(l:lsp_linter, {
|
||||
\ 'old_name': l:old_name,
|
||||
\ 'new_name': l:new_name,
|
||||
\})
|
||||
endfor
|
||||
endfunction
|
58
vim/.vim/autoload/ale/filetypes.vim
Normal file
58
vim/.vim/autoload/ale/filetypes.vim
Normal file
@ -0,0 +1,58 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: This file handles guessing file extensions for filetypes, etc.
|
||||
|
||||
function! ale#filetypes#LoadExtensionMap() abort
|
||||
" Output includes:
|
||||
" '*.erl setf erlang'
|
||||
let l:output = execute('exec "autocmd"')
|
||||
|
||||
let l:map = {}
|
||||
|
||||
for l:line in split(l:output, "\n")
|
||||
" Parse filetypes, like so:
|
||||
"
|
||||
" *.erl setf erlang
|
||||
" *.md set filetype=markdown
|
||||
" *.snippet setlocal filetype=snippets
|
||||
let l:match = matchlist(l:line, '\v^ *\*(\.[^ ]+).*set(f *| *filetype=|local *filetype=)([^ ]+)')
|
||||
|
||||
if !empty(l:match)
|
||||
let l:map[substitute(l:match[3], '^=', '', '')] = l:match[1]
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:map
|
||||
endfunction
|
||||
|
||||
let s:cached_map = {}
|
||||
|
||||
function! s:GetCachedExtensionMap() abort
|
||||
if empty(s:cached_map)
|
||||
let s:cached_map = ale#filetypes#LoadExtensionMap()
|
||||
endif
|
||||
|
||||
return s:cached_map
|
||||
endfunction
|
||||
|
||||
function! ale#filetypes#GuessExtension(filetype) abort
|
||||
let l:map = s:GetCachedExtensionMap()
|
||||
let l:ext = get(l:map, a:filetype, '')
|
||||
|
||||
" If we have an exact match, like something for javascript.jsx, use that.
|
||||
if !empty(l:ext)
|
||||
return l:ext
|
||||
endif
|
||||
|
||||
" If we don't have an exact match, use the first filetype in the compound
|
||||
" filetype.
|
||||
for l:part in split(a:filetype, '\.')
|
||||
let l:ext = get(l:map, l:part, '')
|
||||
|
||||
if !empty(l:ext)
|
||||
return l:ext
|
||||
endif
|
||||
endfor
|
||||
|
||||
" Return an empty string if we don't find anything.
|
||||
return ''
|
||||
endfunction
|
399
vim/.vim/autoload/ale/fix.vim
Normal file
399
vim/.vim/autoload/ale/fix.vim
Normal file
@ -0,0 +1,399 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Functions for fixing code with programs, or other means.
|
||||
|
||||
let g:ale_fix_on_save_ignore = get(g:, 'ale_fix_on_save_ignore', {})
|
||||
let g:ale_filename_mappings = get(g:, 'ale_filename_mappings', {})
|
||||
|
||||
" Apply fixes queued up for buffers which may be hidden.
|
||||
" Vim doesn't let you modify hidden buffers.
|
||||
function! ale#fix#ApplyQueuedFixes(buffer) abort
|
||||
let l:data = get(g:ale_fix_buffer_data, a:buffer, {'done': 0})
|
||||
|
||||
if !l:data.done || (!ale#util#HasBuflineApi() && a:buffer isnot bufnr(''))
|
||||
return
|
||||
endif
|
||||
|
||||
call remove(g:ale_fix_buffer_data, a:buffer)
|
||||
|
||||
try
|
||||
if l:data.changes_made
|
||||
let l:new_lines = ale#util#SetBufferContents(a:buffer, l:data.output)
|
||||
|
||||
if l:data.should_save
|
||||
if a:buffer is bufnr('')
|
||||
if empty(&buftype)
|
||||
noautocmd :w!
|
||||
else
|
||||
set nomodified
|
||||
endif
|
||||
else
|
||||
call writefile(l:new_lines, expand('#' . a:buffer . ':p')) " no-custom-checks
|
||||
call setbufvar(a:buffer, '&modified', 0)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
catch /E21\|E5555/
|
||||
" If we cannot modify the buffer now, try again later.
|
||||
let g:ale_fix_buffer_data[a:buffer] = l:data
|
||||
|
||||
return
|
||||
endtry
|
||||
|
||||
if l:data.should_save
|
||||
let l:should_lint = ale#Var(a:buffer, 'fix_on_save')
|
||||
\ && ale#Var(a:buffer, 'lint_on_save')
|
||||
else
|
||||
let l:should_lint = l:data.changes_made
|
||||
endif
|
||||
|
||||
silent doautocmd <nomodeline> User ALEFixPost
|
||||
|
||||
" If ALE linting is enabled, check for problems with the file again after
|
||||
" fixing problems.
|
||||
if g:ale_enabled
|
||||
\&& l:should_lint
|
||||
\&& !ale#events#QuitRecently(a:buffer)
|
||||
call ale#Queue(0, l:data.should_save ? 'lint_file' : '')
|
||||
endif
|
||||
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 " no-custom-checks
|
||||
let l:data.done = 1
|
||||
|
||||
call ale#command#RemoveManagedFiles(a:buffer)
|
||||
|
||||
if !bufexists(a:buffer)
|
||||
" Remove the buffer data when it doesn't exist.
|
||||
call remove(g:ale_fix_buffer_data, a:buffer)
|
||||
endif
|
||||
|
||||
if l:data.changes_made && bufexists(a:buffer)
|
||||
let l:lines = getbufline(a:buffer, 1, '$')
|
||||
|
||||
if l:data.lines_before != l:lines
|
||||
call remove(g:ale_fix_buffer_data, a:buffer)
|
||||
|
||||
if !l:data.ignore_file_changed_errors
|
||||
" no-custom-checks
|
||||
echoerr 'The file was changed before fixing finished'
|
||||
endif
|
||||
|
||||
return
|
||||
endif
|
||||
endif
|
||||
|
||||
" We can only change the lines of a buffer which is currently open,
|
||||
" so try and apply the fixes to the current buffer.
|
||||
call ale#fix#ApplyQueuedFixes(a:buffer)
|
||||
endfunction
|
||||
|
||||
function! s:HandleExit(job_info, buffer, job_output, data) abort
|
||||
let l:buffer_info = get(g:ale_fix_buffer_data, a:buffer, {})
|
||||
|
||||
if empty(l:buffer_info)
|
||||
return
|
||||
endif
|
||||
|
||||
if a:job_info.read_temporary_file
|
||||
let l:output = !empty(a:data.temporary_file)
|
||||
\ ? readfile(a:data.temporary_file)
|
||||
\ : []
|
||||
else
|
||||
let l:output = a:job_output
|
||||
endif
|
||||
|
||||
let l:ProcessWith = get(a:job_info, 'process_with', v:null)
|
||||
|
||||
" Post-process the output with a function if we have one.
|
||||
if l:ProcessWith isnot v:null
|
||||
let l:output = call(l:ProcessWith, [a:buffer, l:output])
|
||||
endif
|
||||
|
||||
" Use the output of the job for changing the file if it isn't empty,
|
||||
" otherwise skip this job and use the input from before.
|
||||
"
|
||||
" We'll use the input from before for chained commands.
|
||||
if !empty(split(join(l:output)))
|
||||
let l:input = l:output
|
||||
else
|
||||
let l:input = a:job_info.input
|
||||
endif
|
||||
|
||||
call s:RunFixer({
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'input': l:input,
|
||||
\ 'callback_list': a:job_info.callback_list,
|
||||
\ 'callback_index': a:job_info.callback_index + 1,
|
||||
\})
|
||||
endfunction
|
||||
|
||||
function! s:RunJob(result, options) abort
|
||||
if ale#command#IsDeferred(a:result)
|
||||
let a:result.result_callback = {x -> s:RunJob(x, a:options)}
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:buffer = a:options.buffer
|
||||
let l:input = a:options.input
|
||||
let l:fixer_name = a:options.fixer_name
|
||||
|
||||
if a:result is 0 || type(a:result) is v:t_list
|
||||
if type(a:result) is v:t_list
|
||||
let l:input = a:result
|
||||
endif
|
||||
|
||||
call s:RunFixer({
|
||||
\ 'buffer': l:buffer,
|
||||
\ 'input': l:input,
|
||||
\ 'callback_index': a:options.callback_index + 1,
|
||||
\ 'callback_list': a:options.callback_list,
|
||||
\})
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:command = get(a:result, 'command', '')
|
||||
|
||||
if empty(l:command)
|
||||
" If the command is empty, skip to the next item.
|
||||
call s:RunFixer({
|
||||
\ 'buffer': l:buffer,
|
||||
\ 'input': l:input,
|
||||
\ 'callback_index': a:options.callback_index,
|
||||
\ 'callback_list': a:options.callback_list,
|
||||
\})
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let l:read_temporary_file = get(a:result, 'read_temporary_file', 0)
|
||||
let l:read_buffer = get(a:result, 'read_buffer', 1)
|
||||
let l:output_stream = get(a:result, 'output_stream', 'stdout')
|
||||
let l:cwd = get(a:result, 'cwd', v:null)
|
||||
|
||||
if l:read_temporary_file
|
||||
let l:output_stream = 'none'
|
||||
endif
|
||||
|
||||
let l:Callback = function('s:HandleExit', [{
|
||||
\ 'input': l:input,
|
||||
\ 'callback_index': a:options.callback_index,
|
||||
\ 'callback_list': a:options.callback_list,
|
||||
\ 'process_with': get(a:result, 'process_with', v:null),
|
||||
\ 'read_temporary_file': l:read_temporary_file,
|
||||
\}])
|
||||
let l:run_result = ale#command#Run(l:buffer, l:command, l:Callback, {
|
||||
\ 'output_stream': l:output_stream,
|
||||
\ 'executable': '',
|
||||
\ 'read_buffer': l:read_buffer,
|
||||
\ 'input': l:input,
|
||||
\ 'log_output': 0,
|
||||
\ 'cwd': l:cwd,
|
||||
\ 'filename_mappings': ale#GetFilenameMappings(l:buffer, l:fixer_name),
|
||||
\})
|
||||
|
||||
if empty(l:run_result)
|
||||
call s:RunFixer({
|
||||
\ 'buffer': l:buffer,
|
||||
\ 'input': l:input,
|
||||
\ 'callback_index': a:options.callback_index + 1,
|
||||
\ 'callback_list': a:options.callback_list,
|
||||
\})
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:RunFixer(options) abort
|
||||
let l:buffer = a:options.buffer
|
||||
let l:input = a:options.input
|
||||
let l:index = a:options.callback_index
|
||||
|
||||
if len(a:options.callback_list) <= l:index
|
||||
call ale#fix#ApplyFixes(l:buffer, l:input)
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
let [l:fixer_name, l:Function] = a:options.callback_list[l:index]
|
||||
|
||||
" Record new jobs started as fixer jobs.
|
||||
call setbufvar(l:buffer, 'ale_job_type', 'fixer')
|
||||
|
||||
" Regular fixer commands accept (buffer, [input])
|
||||
let l:result = ale#util#FunctionArgCount(l:Function) == 1
|
||||
\ ? call(l:Function, [l:buffer])
|
||||
\ : call(l:Function, [l:buffer, copy(l:input)])
|
||||
|
||||
call s:RunJob(l:result, {
|
||||
\ 'buffer': l:buffer,
|
||||
\ 'input': l:input,
|
||||
\ 'callback_list': a:options.callback_list,
|
||||
\ 'callback_index': l:index,
|
||||
\ 'fixer_name': l:fixer_name,
|
||||
\})
|
||||
endfunction
|
||||
|
||||
function! s:AddSubCallbacks(full_list, callbacks) abort
|
||||
if type(a:callbacks) is v:t_string
|
||||
call add(a:full_list, a:callbacks)
|
||||
elseif type(a:callbacks) is v:t_list
|
||||
call extend(a:full_list, a:callbacks)
|
||||
else
|
||||
return 0
|
||||
endif
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! s:IgnoreFixers(callback_list, filetype, config) abort
|
||||
if type(a:config) is v:t_list
|
||||
let l:ignore_list = a:config
|
||||
else
|
||||
let l:ignore_list = []
|
||||
|
||||
for l:part in split(a:filetype , '\.')
|
||||
call extend(l:ignore_list, get(a:config, l:part, []))
|
||||
endfor
|
||||
endif
|
||||
|
||||
call filter(a:callback_list, 'index(l:ignore_list, v:val) < 0')
|
||||
endfunction
|
||||
|
||||
function! s:GetCallbacks(buffer, fixing_flag, fixers) abort
|
||||
if len(a:fixers)
|
||||
let l:callback_list = a:fixers
|
||||
elseif type(get(b:, 'ale_fixers')) is v:t_list
|
||||
" Lists can be used for buffer-local variables only
|
||||
let l:callback_list = b:ale_fixers
|
||||
else
|
||||
" buffer and global options can use dictionaries mapping filetypes to
|
||||
" callbacks to run.
|
||||
let l:fixers = ale#Var(a:buffer, 'fixers')
|
||||
let l:callback_list = []
|
||||
let l:matched = 0
|
||||
|
||||
for l:sub_type in split(&filetype, '\.')
|
||||
if s:AddSubCallbacks(l:callback_list, get(l:fixers, l:sub_type))
|
||||
let l:matched = 1
|
||||
endif
|
||||
endfor
|
||||
|
||||
" If we couldn't find fixers for a filetype, default to '*' fixers.
|
||||
if !l:matched
|
||||
call s:AddSubCallbacks(l:callback_list, get(l:fixers, '*'))
|
||||
endif
|
||||
endif
|
||||
|
||||
if a:fixing_flag is# 'save_file'
|
||||
let l:config = ale#Var(a:buffer, 'fix_on_save_ignore')
|
||||
|
||||
if !empty(l:config)
|
||||
call s:IgnoreFixers(l:callback_list, &filetype, l:config)
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:corrected_list = []
|
||||
|
||||
" Variables with capital characters are needed, or Vim will complain about
|
||||
" funcref variables.
|
||||
for l:Item in l:callback_list
|
||||
" Try to capture the names of registered fixer names, so we can use
|
||||
" them for filename mapping or other purposes later.
|
||||
let l:fixer_name = v:null
|
||||
|
||||
if type(l:Item) is v:t_string
|
||||
let l:Func = ale#fix#registry#GetFunc(l:Item)
|
||||
|
||||
if !empty(l:Func)
|
||||
let l:fixer_name = l:Item
|
||||
let l:Item = l:Func
|
||||
endif
|
||||
endif
|
||||
|
||||
try
|
||||
call add(l:corrected_list, [
|
||||
\ l:fixer_name,
|
||||
\ ale#util#GetFunction(l:Item)
|
||||
\])
|
||||
catch /E475/
|
||||
" Rethrow exceptions for failing to get a function so we can print
|
||||
" a friendly message about it.
|
||||
throw 'BADNAME ' . v:exception
|
||||
endtry
|
||||
endfor
|
||||
|
||||
return l:corrected_list
|
||||
endfunction
|
||||
|
||||
function! ale#fix#InitBufferData(buffer, fixing_flag) abort
|
||||
" The 'done' flag tells the function for applying changes when fixing
|
||||
" is complete.
|
||||
let g:ale_fix_buffer_data[a:buffer] = {
|
||||
\ 'lines_before': getbufline(a:buffer, 1, '$'),
|
||||
\ 'done': 0,
|
||||
\ 'should_save': a:fixing_flag is# 'save_file',
|
||||
\ 'ignore_file_changed_errors': a:fixing_flag is# '!',
|
||||
\ 'temporary_directory_list': [],
|
||||
\}
|
||||
endfunction
|
||||
|
||||
" Accepts an optional argument for what to do when fixing.
|
||||
"
|
||||
" Returns 0 if no fixes can be applied, and 1 if fixing can be done.
|
||||
function! ale#fix#Fix(buffer, fixing_flag, ...) abort
|
||||
if a:fixing_flag isnot# ''
|
||||
\&& a:fixing_flag isnot# '!'
|
||||
\&& a:fixing_flag isnot# 'save_file'
|
||||
throw "fixing_flag must be '', '!', or 'save_file'"
|
||||
endif
|
||||
|
||||
try
|
||||
let l:callback_list = s:GetCallbacks(a:buffer, a:fixing_flag, a:000)
|
||||
catch /E700\|BADNAME/
|
||||
if a:fixing_flag isnot# '!'
|
||||
let l:function_name = join(split(split(v:exception, ':')[3]))
|
||||
let l:echo_message = printf(
|
||||
\ 'There is no fixer named `%s`. Check :ALEFixSuggest',
|
||||
\ l:function_name,
|
||||
\)
|
||||
" no-custom-checks
|
||||
echom l:echo_message
|
||||
endif
|
||||
|
||||
return 0
|
||||
endtry
|
||||
|
||||
if empty(l:callback_list)
|
||||
if a:fixing_flag is# ''
|
||||
" no-custom-checks
|
||||
echom 'No fixers have been defined. Try :ALEFixSuggest'
|
||||
endif
|
||||
|
||||
return 0
|
||||
endif
|
||||
|
||||
call ale#command#StopJobs(a:buffer, 'fixer')
|
||||
" Clean up any files we might have left behind from a previous run.
|
||||
call ale#command#RemoveManagedFiles(a:buffer)
|
||||
call ale#fix#InitBufferData(a:buffer, a:fixing_flag)
|
||||
|
||||
silent doautocmd <nomodeline> User ALEFixPre
|
||||
|
||||
call s:RunFixer({
|
||||
\ 'buffer': a:buffer,
|
||||
\ 'input': g:ale_fix_buffer_data[a:buffer].lines_before,
|
||||
\ 'callback_index': 0,
|
||||
\ 'callback_list': l:callback_list,
|
||||
\})
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
" Set up an autocmd command to try and apply buffer fixes when available.
|
||||
augroup ALEBufferFixGroup
|
||||
autocmd!
|
||||
autocmd BufEnter * call ale#fix#ApplyQueuedFixes(str2nr(expand('<abuf>')))
|
||||
augroup END
|
875
vim/.vim/autoload/ale/fix/registry.vim
Normal file
875
vim/.vim/autoload/ale/fix/registry.vim
Normal file
@ -0,0 +1,875 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: A registry of functions for fixing things.
|
||||
|
||||
let s:default_registry = {
|
||||
\ 'add_blank_lines_for_python_control_statements': {
|
||||
\ 'function': 'ale#fixers#generic_python#AddLinesBeforeControlStatements',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Add blank lines before control statements.',
|
||||
\ },
|
||||
\ 'alejandra': {
|
||||
\ 'function': 'ale#fixers#alejandra#Fix',
|
||||
\ 'suggested_filetypes': ['nix'],
|
||||
\ 'description': 'The Uncompromising Nix Code Formatter',
|
||||
\ },
|
||||
\ 'align_help_tags': {
|
||||
\ 'function': 'ale#fixers#help#AlignTags',
|
||||
\ 'suggested_filetypes': ['help'],
|
||||
\ 'description': 'Align help tags to the right margin',
|
||||
\ },
|
||||
\ 'autoimport': {
|
||||
\ 'function': 'ale#fixers#autoimport#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Fix import issues with autoimport.',
|
||||
\ },
|
||||
\ 'autoflake': {
|
||||
\ 'function': 'ale#fixers#autoflake#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Fix flake issues with autoflake.',
|
||||
\ },
|
||||
\ 'autopep8': {
|
||||
\ 'function': 'ale#fixers#autopep8#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Fix PEP8 issues with autopep8.',
|
||||
\ },
|
||||
\ 'bibclean': {
|
||||
\ 'function': 'ale#fixers#bibclean#Fix',
|
||||
\ 'suggested_filetypes': ['bib'],
|
||||
\ 'description': 'Format bib files using bibclean.',
|
||||
\ },
|
||||
\ 'biome': {
|
||||
\ 'function': 'ale#fixers#biome#Fix',
|
||||
\ 'suggested_filetypes': ['javascript', 'typescript', 'json', 'jsonc'],
|
||||
\ 'description': 'Fix JavaScript and TypeScript using biome.',
|
||||
\ },
|
||||
\ 'black': {
|
||||
\ 'function': 'ale#fixers#black#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Fix PEP8 issues with black.',
|
||||
\ },
|
||||
\ 'buf-format': {
|
||||
\ 'function': 'ale#fixers#buf_format#Fix',
|
||||
\ 'suggested_filetypes': ['proto'],
|
||||
\ 'description': 'Fix .proto files with buf format.',
|
||||
\ },
|
||||
\ 'buildifier': {
|
||||
\ 'function': 'ale#fixers#buildifier#Fix',
|
||||
\ 'suggested_filetypes': ['bzl'],
|
||||
\ 'description': 'Format BUILD and .bzl files with buildifier.',
|
||||
\ },
|
||||
\ 'css-beautify': {
|
||||
\ 'function': 'ale#fixers#css_beautify#Fix',
|
||||
\ 'suggested_filetypes': ['css'],
|
||||
\ 'description': 'Format CSS using css-beautify from js-beautify.',
|
||||
\ },
|
||||
\ 'deno': {
|
||||
\ 'function': 'ale#fixers#deno#Fix',
|
||||
\ 'suggested_filetypes': ['typescript'],
|
||||
\ 'description': 'Fix TypeScript using deno fmt.',
|
||||
\ },
|
||||
\ 'dfmt': {
|
||||
\ 'function': 'ale#fixers#dfmt#Fix',
|
||||
\ 'suggested_filetypes': ['d'],
|
||||
\ 'description': 'Fix D files with dfmt.',
|
||||
\ },
|
||||
\ 'dhall': {
|
||||
\ 'function': 'ale#fixers#dhall#Fix',
|
||||
\ 'suggested_filetypes': ['dhall'],
|
||||
\ 'description': 'Fix Dhall files with dhall-format.',
|
||||
\ },
|
||||
\ 'dhall-format': {
|
||||
\ 'function': 'ale#fixers#dhall_format#Fix',
|
||||
\ 'suggested_filetypes': ['dhall'],
|
||||
\ 'description': 'Standard code formatter for the Dhall language',
|
||||
\ 'aliases': ['dhall'],
|
||||
\ },
|
||||
\ 'dhall-freeze': {
|
||||
\ 'function': 'ale#fixers#dhall_freeze#Freeze',
|
||||
\ 'suggested_filetypes': ['dhall'],
|
||||
\ 'description': 'Add integrity checks to remote import statements of an expression for the Dhall language',
|
||||
\ },
|
||||
\ 'dhall-lint': {
|
||||
\ 'function': 'ale#fixers#dhall_lint#Fix',
|
||||
\ 'suggested_filetypes': ['dhall'],
|
||||
\ 'description': 'Standard code formatter for the Dhall language and removing dead code',
|
||||
\ },
|
||||
\ 'dune': {
|
||||
\ 'function': 'ale#fixers#dune#Fix',
|
||||
\ 'suggested_filetypes': ['dune'],
|
||||
\ 'description': 'Fix dune files with dune format',
|
||||
\ },
|
||||
\ 'fecs': {
|
||||
\ 'function': 'ale#fixers#fecs#Fix',
|
||||
\ 'suggested_filetypes': ['javascript', 'css', 'html'],
|
||||
\ 'description': 'Apply fecs format to a file.',
|
||||
\ },
|
||||
\ 'hurlfmt': {
|
||||
\ 'function': 'ale#fixers#hurlfmt#Fix',
|
||||
\ 'suggested_filetypes': ['hurl'],
|
||||
\ 'description': 'Fix hurl files with hurlfmt.',
|
||||
\ },
|
||||
\ 'tidy': {
|
||||
\ 'function': 'ale#fixers#tidy#Fix',
|
||||
\ 'suggested_filetypes': ['html'],
|
||||
\ 'description': 'Fix HTML files with tidy.',
|
||||
\ },
|
||||
\ 'prettier_standard': {
|
||||
\ 'function': 'ale#fixers#prettier_standard#Fix',
|
||||
\ 'suggested_filetypes': ['javascript'],
|
||||
\ 'description': 'Apply prettier-standard to a file.',
|
||||
\ 'aliases': ['prettier-standard'],
|
||||
\ },
|
||||
\ 'elm-format': {
|
||||
\ 'function': 'ale#fixers#elm_format#Fix',
|
||||
\ 'suggested_filetypes': ['elm'],
|
||||
\ 'description': 'Apply elm-format to a file.',
|
||||
\ 'aliases': ['format'],
|
||||
\ },
|
||||
\ 'nimpretty': {
|
||||
\ 'function': 'ale#fixers#nimpretty#Fix',
|
||||
\ 'suggested_filetypes': ['nim'],
|
||||
\ 'description': 'Apply nimpretty to a file.',
|
||||
\ },
|
||||
\ 'erblint': {
|
||||
\ 'function': 'ale#fixers#erblint#Fix',
|
||||
\ 'suggested_filetypes': ['eruby'],
|
||||
\ 'description': 'Apply erblint --autocorrect to a file.',
|
||||
\ },
|
||||
\ 'eslint': {
|
||||
\ 'function': 'ale#fixers#eslint#Fix',
|
||||
\ 'suggested_filetypes': ['javascript', 'typescript', 'astro'],
|
||||
\ 'description': 'Apply eslint --fix to a file.',
|
||||
\ },
|
||||
\ 'mix_format': {
|
||||
\ 'function': 'ale#fixers#mix_format#Fix',
|
||||
\ 'suggested_filetypes': ['elixir'],
|
||||
\ 'description': 'Apply mix format to a file.',
|
||||
\ },
|
||||
\ 'isort': {
|
||||
\ 'function': 'ale#fixers#isort#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Sort Python imports with isort.',
|
||||
\ },
|
||||
\ 'prettier': {
|
||||
\ 'function': 'ale#fixers#prettier#Fix',
|
||||
\ 'suggested_filetypes': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue', 'svelte', 'html', 'yaml', 'openapi', 'ruby', 'astro'],
|
||||
\ 'description': 'Apply prettier to a file.',
|
||||
\ },
|
||||
\ 'prettier_eslint': {
|
||||
\ 'function': 'ale#fixers#prettier_eslint#Fix',
|
||||
\ 'suggested_filetypes': ['javascript'],
|
||||
\ 'description': 'Apply prettier-eslint to a file.',
|
||||
\ 'aliases': ['prettier-eslint'],
|
||||
\ },
|
||||
\ 'pyflyby': {
|
||||
\ 'function': 'ale#fixers#pyflyby#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Tidy Python imports with pyflyby.',
|
||||
\ },
|
||||
\ 'importjs': {
|
||||
\ 'function': 'ale#fixers#importjs#Fix',
|
||||
\ 'suggested_filetypes': ['javascript'],
|
||||
\ 'description': 'automatic imports for javascript',
|
||||
\ },
|
||||
\ 'puppetlint': {
|
||||
\ 'function': 'ale#fixers#puppetlint#Fix',
|
||||
\ 'suggested_filetypes': ['puppet'],
|
||||
\ 'description': 'Run puppet-lint -f on a file.',
|
||||
\ },
|
||||
\ 'remove_trailing_lines': {
|
||||
\ 'function': 'ale#fixers#generic#RemoveTrailingBlankLines',
|
||||
\ 'suggested_filetypes': [],
|
||||
\ 'description': 'Remove all blank lines at the end of a file.',
|
||||
\ },
|
||||
\ 'trim_whitespace': {
|
||||
\ 'function': 'ale#fixers#generic#TrimWhitespace',
|
||||
\ 'suggested_filetypes': [],
|
||||
\ 'description': 'Remove all trailing whitespace characters at the end of every line.',
|
||||
\ },
|
||||
\ 'yamlfix': {
|
||||
\ 'function': 'ale#fixers#yamlfix#Fix',
|
||||
\ 'suggested_filetypes': ['yaml'],
|
||||
\ 'description': 'Fix YAML files with yamlfix.',
|
||||
\ },
|
||||
\ 'yamlfmt': {
|
||||
\ 'function': 'ale#fixers#yamlfmt#Fix',
|
||||
\ 'suggested_filetypes': ['yaml'],
|
||||
\ 'description': 'Format YAML files with yamlfmt.',
|
||||
\ },
|
||||
\ 'yapf': {
|
||||
\ 'function': 'ale#fixers#yapf#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Fix Python files with yapf.',
|
||||
\ },
|
||||
\ 'rubocop': {
|
||||
\ 'function': 'ale#fixers#rubocop#Fix',
|
||||
\ 'suggested_filetypes': ['ruby'],
|
||||
\ 'description': 'Fix ruby files with rubocop --auto-correct.',
|
||||
\ },
|
||||
\ 'rufo': {
|
||||
\ 'function': 'ale#fixers#rufo#Fix',
|
||||
\ 'suggested_filetypes': ['ruby'],
|
||||
\ 'description': 'Fix ruby files with rufo',
|
||||
\ },
|
||||
\ 'scalafmt': {
|
||||
\ 'function': 'ale#fixers#scalafmt#Fix',
|
||||
\ 'suggested_filetypes': ['sbt', 'scala'],
|
||||
\ 'description': 'Fix Scala files using scalafmt',
|
||||
\ },
|
||||
\ 'sorbet': {
|
||||
\ 'function': 'ale#fixers#sorbet#Fix',
|
||||
\ 'suggested_filetypes': ['ruby'],
|
||||
\ 'description': 'Fix ruby files with srb tc --autocorrect.',
|
||||
\ },
|
||||
\ 'standard': {
|
||||
\ 'function': 'ale#fixers#standard#Fix',
|
||||
\ 'suggested_filetypes': ['javascript'],
|
||||
\ 'description': 'Fix JavaScript files using standard --fix',
|
||||
\ },
|
||||
\ 'standardrb': {
|
||||
\ 'function': 'ale#fixers#standardrb#Fix',
|
||||
\ 'suggested_filetypes': ['ruby'],
|
||||
\ 'description': 'Fix ruby files with standardrb --fix',
|
||||
\ },
|
||||
\ 'statix': {
|
||||
\ 'function': 'ale#fixers#statix#Fix',
|
||||
\ 'suggested_filetypes': ['nix'],
|
||||
\ 'description': 'Fix common Nix antipatterns with statix fix',
|
||||
\ },
|
||||
\ 'stylelint': {
|
||||
\ 'function': 'ale#fixers#stylelint#Fix',
|
||||
\ 'suggested_filetypes': ['css', 'sass', 'scss', 'sugarss', 'stylus'],
|
||||
\ 'description': 'Fix stylesheet files using stylelint --fix.',
|
||||
\ },
|
||||
\ 'swiftformat': {
|
||||
\ 'function': 'ale#fixers#swiftformat#Fix',
|
||||
\ 'suggested_filetypes': ['swift'],
|
||||
\ 'description': 'Apply SwiftFormat to a file.',
|
||||
\ },
|
||||
\ 'syntax_tree': {
|
||||
\ 'function': 'ale#fixers#syntax_tree#Fix',
|
||||
\ 'suggested_filetypes': ['ruby'],
|
||||
\ 'description': 'Fix ruby files with stree write',
|
||||
\ },
|
||||
\ 'apple-swift-format': {
|
||||
\ 'function': 'ale#fixers#appleswiftformat#Fix',
|
||||
\ 'suggested_filetypes': ['swift'],
|
||||
\ 'description': 'Apply apple/swift-format to a file.',
|
||||
\ },
|
||||
\ 'phpcbf': {
|
||||
\ 'function': 'ale#fixers#phpcbf#Fix',
|
||||
\ 'suggested_filetypes': ['php'],
|
||||
\ 'description': 'Fix PHP files with phpcbf.',
|
||||
\ },
|
||||
\ 'php_cs_fixer': {
|
||||
\ 'function': 'ale#fixers#php_cs_fixer#Fix',
|
||||
\ 'suggested_filetypes': ['php'],
|
||||
\ 'description': 'Fix PHP files with php-cs-fixer.',
|
||||
\ },
|
||||
\ 'pint': {
|
||||
\ 'function': 'ale#fixers#pint#Fix',
|
||||
\ 'suggested_filetypes': ['php'],
|
||||
\ 'description': 'Fix PHP files with Laravel Pint.',
|
||||
\ },
|
||||
\ 'astyle': {
|
||||
\ 'function': 'ale#fixers#astyle#Fix',
|
||||
\ 'suggested_filetypes': ['c', 'cpp'],
|
||||
\ 'description': 'Fix C/C++ with astyle.',
|
||||
\ },
|
||||
\ 'clangtidy': {
|
||||
\ 'function': 'ale#fixers#clangtidy#Fix',
|
||||
\ 'suggested_filetypes': ['c', 'cpp', 'objc'],
|
||||
\ 'description': 'Fix C/C++ and ObjectiveC files with clang-tidy.',
|
||||
\ },
|
||||
\ 'clang-format': {
|
||||
\ 'function': 'ale#fixers#clangformat#Fix',
|
||||
\ 'suggested_filetypes': ['c', 'cpp', 'cs', 'cuda', 'java', 'javascript', 'json', 'objc', 'proto'],
|
||||
\ 'description': 'Fix C, C++, C#, CUDA, Java, JavaScript, JSON, ObjectiveC and Protobuf files with clang-format.',
|
||||
\ },
|
||||
\ 'cmakeformat': {
|
||||
\ 'function': 'ale#fixers#cmakeformat#Fix',
|
||||
\ 'suggested_filetypes': ['cmake'],
|
||||
\ 'description': 'Fix CMake files with cmake-format.',
|
||||
\ },
|
||||
\ 'fish_indent': {
|
||||
\ 'function': 'ale#fixers#fish_indent#Fix',
|
||||
\ 'suggested_filetypes': ['fish'],
|
||||
\ 'description': 'Format fish scripts using fish_indent.',
|
||||
\ },
|
||||
\ 'forge': {
|
||||
\ 'function': 'ale#fixers#forge#Fix',
|
||||
\ 'suggested_filetypes': ['solidity'],
|
||||
\ 'description': 'Fix Solidity files with forge fmt.',
|
||||
\ },
|
||||
\ 'gleam_format': {
|
||||
\ 'function': 'ale#fixers#gleam_format#Fix',
|
||||
\ 'suggested_filetypes': ['gleam'],
|
||||
\ 'description': 'Fix Gleam files with gleam format.',
|
||||
\ },
|
||||
\ 'gofmt': {
|
||||
\ 'function': 'ale#fixers#gofmt#Fix',
|
||||
\ 'suggested_filetypes': ['go'],
|
||||
\ 'description': 'Fix Go files with go fmt.',
|
||||
\ },
|
||||
\ 'gofumpt': {
|
||||
\ 'function': 'ale#fixers#gofumpt#Fix',
|
||||
\ 'suggested_filetypes': ['go'],
|
||||
\ 'description': 'Fix Go files with gofumpt, a stricter go fmt.',
|
||||
\ },
|
||||
\ 'goimports': {
|
||||
\ 'function': 'ale#fixers#goimports#Fix',
|
||||
\ 'suggested_filetypes': ['go'],
|
||||
\ 'description': 'Fix Go files imports with goimports.',
|
||||
\ },
|
||||
\ 'golines': {
|
||||
\ 'function': 'ale#fixers#golines#Fix',
|
||||
\ 'suggested_filetypes': ['go'],
|
||||
\ 'description': 'Fix Go file long lines with golines',
|
||||
\ },
|
||||
\ 'gomod': {
|
||||
\ 'function': 'ale#fixers#gomod#Fix',
|
||||
\ 'suggested_filetypes': ['gomod'],
|
||||
\ 'description': 'Fix Go module files with go mod edit -fmt.',
|
||||
\ },
|
||||
\ 'gopls': {
|
||||
\ 'function': 'ale#fixers#gopls#Fix',
|
||||
\ 'suggested_filetypes': ['go'],
|
||||
\ 'description': 'Fix Go files with gopls.',
|
||||
\ },
|
||||
\ 'tslint': {
|
||||
\ 'function': 'ale#fixers#tslint#Fix',
|
||||
\ 'suggested_filetypes': ['typescript'],
|
||||
\ 'description': 'Fix typescript files with tslint --fix.',
|
||||
\ },
|
||||
\ 'rustfmt': {
|
||||
\ 'function': 'ale#fixers#rustfmt#Fix',
|
||||
\ 'suggested_filetypes': ['rust'],
|
||||
\ 'description': 'Fix Rust files with Rustfmt.',
|
||||
\ },
|
||||
\ 'textlint': {
|
||||
\ 'function': 'ale#fixers#textlint#Fix',
|
||||
\ 'suggested_filetypes': ['text','markdown','asciidoc','tex'],
|
||||
\ 'description': 'Fix text files with textlint --fix',
|
||||
\ },
|
||||
\ 'hackfmt': {
|
||||
\ 'function': 'ale#fixers#hackfmt#Fix',
|
||||
\ 'suggested_filetypes': ['hack'],
|
||||
\ 'description': 'Fix Hack files with hackfmt.',
|
||||
\ },
|
||||
\ 'floskell': {
|
||||
\ 'function': 'ale#fixers#floskell#Fix',
|
||||
\ 'suggested_filetypes': ['haskell'],
|
||||
\ 'description': 'Fix Haskell files with floskell.',
|
||||
\ },
|
||||
\ 'hfmt': {
|
||||
\ 'function': 'ale#fixers#hfmt#Fix',
|
||||
\ 'suggested_filetypes': ['haskell'],
|
||||
\ 'description': 'Fix Haskell files with hfmt.',
|
||||
\ },
|
||||
\ 'brittany': {
|
||||
\ 'function': 'ale#fixers#brittany#Fix',
|
||||
\ 'suggested_filetypes': ['haskell'],
|
||||
\ 'description': 'Fix Haskell files with brittany.',
|
||||
\ },
|
||||
\ 'hindent': {
|
||||
\ 'function': 'ale#fixers#hindent#Fix',
|
||||
\ 'suggested_filetypes': ['haskell'],
|
||||
\ 'description': 'Fix Haskell files with hindent.',
|
||||
\ },
|
||||
\ 'hlint': {
|
||||
\ 'function': 'ale#fixers#hlint#Fix',
|
||||
\ 'suggested_filetypes': ['haskell'],
|
||||
\ 'description': 'Refactor Haskell files with hlint.',
|
||||
\ },
|
||||
\ 'stylish-haskell': {
|
||||
\ 'function': 'ale#fixers#stylish_haskell#Fix',
|
||||
\ 'suggested_filetypes': ['haskell'],
|
||||
\ 'description': 'Refactor Haskell files with stylish-haskell.',
|
||||
\ },
|
||||
\ 'purs-tidy': {
|
||||
\ 'function': 'ale#fixers#purs_tidy#Fix',
|
||||
\ 'suggested_filetypes': ['purescript'],
|
||||
\ 'description': 'Format PureScript files with purs-tidy.',
|
||||
\ },
|
||||
\ 'purty': {
|
||||
\ 'function': 'ale#fixers#purty#Fix',
|
||||
\ 'suggested_filetypes': ['purescript'],
|
||||
\ 'description': 'Format PureScript files with purty.',
|
||||
\ },
|
||||
\ 'ocamlformat': {
|
||||
\ 'function': 'ale#fixers#ocamlformat#Fix',
|
||||
\ 'suggested_filetypes': ['ocaml', 'ocamlinterface'],
|
||||
\ 'description': 'Fix OCaml files with ocamlformat.',
|
||||
\ },
|
||||
\ 'ocp-indent': {
|
||||
\ 'function': 'ale#fixers#ocp_indent#Fix',
|
||||
\ 'suggested_filetypes': ['ocaml', 'ocamlinterface'],
|
||||
\ 'description': 'Fix OCaml files with ocp-indent.',
|
||||
\ },
|
||||
\ 'refmt': {
|
||||
\ 'function': 'ale#fixers#refmt#Fix',
|
||||
\ 'suggested_filetypes': ['reason'],
|
||||
\ 'description': 'Fix ReasonML files with refmt.',
|
||||
\ },
|
||||
\ 'pandoc': {
|
||||
\ 'function': 'ale#fixers#pandoc#Fix',
|
||||
\ 'suggested_filetypes': ['markdown'],
|
||||
\ 'description': 'Fix markdown files with pandoc.',
|
||||
\ },
|
||||
\ 'shfmt': {
|
||||
\ 'function': 'ale#fixers#shfmt#Fix',
|
||||
\ 'suggested_filetypes': ['sh'],
|
||||
\ 'description': 'Fix sh files with shfmt.',
|
||||
\ },
|
||||
\ 'sqlfluff': {
|
||||
\ 'function': 'ale#fixers#sqlfluff#Fix',
|
||||
\ 'suggested_filetypes': ['sql'],
|
||||
\ 'description': 'Fix SQL files with sqlfluff.',
|
||||
\ },
|
||||
\ 'sqlfmt': {
|
||||
\ 'function': 'ale#fixers#sqlfmt#Fix',
|
||||
\ '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'],
|
||||
\ 'description': 'Fix Java files with google-java-format.',
|
||||
\ },
|
||||
\ 'fixjson': {
|
||||
\ 'function': 'ale#fixers#fixjson#Fix',
|
||||
\ 'suggested_filetypes': ['json'],
|
||||
\ 'description': 'Fix JSON files with fixjson.',
|
||||
\ },
|
||||
\ 'jq': {
|
||||
\ 'function': 'ale#fixers#jq#Fix',
|
||||
\ 'suggested_filetypes': ['json'],
|
||||
\ 'description': 'Fix JSON files with jq.',
|
||||
\ },
|
||||
\ 'protolint': {
|
||||
\ 'function': 'ale#fixers#protolint#Fix',
|
||||
\ 'suggested_filetypes': ['proto'],
|
||||
\ 'description': 'Fix Protocol Buffer files with protolint.',
|
||||
\ },
|
||||
\ 'perltidy': {
|
||||
\ 'function': 'ale#fixers#perltidy#Fix',
|
||||
\ 'suggested_filetypes': ['perl'],
|
||||
\ 'description': 'Fix Perl files with perltidy.',
|
||||
\ },
|
||||
\ 'xo': {
|
||||
\ 'function': 'ale#fixers#xo#Fix',
|
||||
\ 'suggested_filetypes': ['javascript', 'typescript'],
|
||||
\ 'description': 'Fix JavaScript/TypeScript files using xo --fix.',
|
||||
\ },
|
||||
\ 'qmlfmt': {
|
||||
\ 'function': 'ale#fixers#qmlfmt#Fix',
|
||||
\ 'suggested_filetypes': ['qml'],
|
||||
\ 'description': 'Fix QML files with qmlfmt.',
|
||||
\ },
|
||||
\ 'dartfmt': {
|
||||
\ 'function': 'ale#fixers#dartfmt#Fix',
|
||||
\ 'suggested_filetypes': ['dart'],
|
||||
\ 'description': 'Fix Dart files with dartfmt.',
|
||||
\ },
|
||||
\ 'dart-format': {
|
||||
\ 'function': 'ale#fixers#dart_format#Fix',
|
||||
\ 'suggested_filetypes': ['dart'],
|
||||
\ 'description': 'Fix Dart files with dart format.',
|
||||
\ },
|
||||
\ 'dotnet-format': {
|
||||
\ 'function': 'ale#fixers#dotnet_format#Fix',
|
||||
\ 'suggested_filetypes': ['cs'],
|
||||
\ 'description': 'Fix C# files with dotnet format.',
|
||||
\ },
|
||||
\ 'xmllint': {
|
||||
\ 'function': 'ale#fixers#xmllint#Fix',
|
||||
\ 'suggested_filetypes': ['xml'],
|
||||
\ 'description': 'Fix XML files with xmllint.',
|
||||
\ },
|
||||
\ 'uncrustify': {
|
||||
\ 'function': 'ale#fixers#uncrustify#Fix',
|
||||
\ 'suggested_filetypes': ['c', 'cpp', 'cs', 'objc', 'objcpp', 'd', 'java', 'p', 'vala' ],
|
||||
\ 'description': 'Fix C, C++, C#, ObjectiveC, ObjectiveC++, D, Java, Pawn, and VALA files with uncrustify.',
|
||||
\ },
|
||||
\ 'terraform': {
|
||||
\ 'function': 'ale#fixers#terraform#Fix',
|
||||
\ 'suggested_filetypes': ['hcl', 'terraform'],
|
||||
\ 'description': 'Fix tf and hcl files with terraform fmt.',
|
||||
\ },
|
||||
\ 'packer': {
|
||||
\ 'function': 'ale#fixers#packer#Fix',
|
||||
\ 'suggested_filetypes': ['hcl', 'packer'],
|
||||
\ 'description': 'Fix Packer HCL files with packer fmt.',
|
||||
\ },
|
||||
\ 'crystal': {
|
||||
\ 'function': 'ale#fixers#crystal#Fix',
|
||||
\ 'suggested_filetypes': ['cr'],
|
||||
\ 'description': 'Fix cr (crystal).',
|
||||
\ },
|
||||
\ 'ktlint': {
|
||||
\ 'function': 'ale#fixers#ktlint#Fix',
|
||||
\ 'suggested_filetypes': ['kt', 'kotlin'],
|
||||
\ 'description': 'Fix Kotlin files with ktlint.',
|
||||
\ },
|
||||
\ 'styler': {
|
||||
\ 'function': 'ale#fixers#styler#Fix',
|
||||
\ 'suggested_filetypes': ['r', 'rmarkdown', 'rmd'],
|
||||
\ 'description': 'Fix R files with styler.',
|
||||
\ },
|
||||
\ 'latexindent': {
|
||||
\ 'function': 'ale#fixers#latexindent#Fix',
|
||||
\ 'suggested_filetypes': ['tex'],
|
||||
\ 'description' : 'Indent code within environments, commands, after headings and within special code blocks.',
|
||||
\ },
|
||||
\ 'pgformatter': {
|
||||
\ 'function': 'ale#fixers#pgformatter#Fix',
|
||||
\ 'suggested_filetypes': ['sql'],
|
||||
\ 'description': 'A PostgreSQL SQL syntax beautifier',
|
||||
\ },
|
||||
\ 'reorder-python-imports': {
|
||||
\ 'function': 'ale#fixers#reorder_python_imports#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Sort Python imports with reorder-python-imports.',
|
||||
\ },
|
||||
\ 'gnatpp': {
|
||||
\ 'function': 'ale#fixers#gnatpp#Fix',
|
||||
\ 'suggested_filetypes': ['ada'],
|
||||
\ 'description': 'Format Ada files with gnatpp.',
|
||||
\ },
|
||||
\ 'nixfmt': {
|
||||
\ 'function': 'ale#fixers#nixfmt#Fix',
|
||||
\ 'suggested_filetypes': ['nix'],
|
||||
\ 'description': 'A nix formatter written in Haskell.',
|
||||
\ },
|
||||
\ 'nixpkgs-fmt': {
|
||||
\ 'function': 'ale#fixers#nixpkgsfmt#Fix',
|
||||
\ 'suggested_filetypes': ['nix'],
|
||||
\ 'description': 'A formatter for Nix code',
|
||||
\ },
|
||||
\ 'remark-lint': {
|
||||
\ 'function': 'ale#fixers#remark_lint#Fix',
|
||||
\ 'suggested_filetypes': ['markdown'],
|
||||
\ 'description': 'Fix markdown files with remark-lint',
|
||||
\ },
|
||||
\ 'html-beautify': {
|
||||
\ 'function': 'ale#fixers#html_beautify#Fix',
|
||||
\ 'suggested_filetypes': ['html', 'htmldjango'],
|
||||
\ 'description': 'Fix HTML files with html-beautify from js-beautify.',
|
||||
\ },
|
||||
\ 'htmlbeautifier': {
|
||||
\ 'function': 'ale#fixers#htmlbeautifier#Fix',
|
||||
\ 'suggested_filetypes': ['eruby'],
|
||||
\ 'description': 'Fix ERB files with htmlbeautifier gem.',
|
||||
\ },
|
||||
\ 'lua-format': {
|
||||
\ 'function': 'ale#fixers#lua_format#Fix',
|
||||
\ 'suggested_filetypes': ['lua'],
|
||||
\ 'description': 'Fix Lua files with lua-format.',
|
||||
\ },
|
||||
\ 'luafmt': {
|
||||
\ 'function': 'ale#fixers#luafmt#Fix',
|
||||
\ 'suggested_filetypes': ['lua'],
|
||||
\ 'description': 'Fix Lua files with luafmt.',
|
||||
\ },
|
||||
\ 'dprint': {
|
||||
\ 'function': 'ale#fixers#dprint#Fix',
|
||||
\ 'suggested_filetypes': ['dockerfile', 'javascript', 'json', 'markdown', 'toml', 'typescript'],
|
||||
\ 'description': 'Pluggable and configurable code formatting platform',
|
||||
\ },
|
||||
\ 'stylua': {
|
||||
\ 'function': 'ale#fixers#stylua#Fix',
|
||||
\ 'suggested_filetypes': ['lua'],
|
||||
\ 'description': 'Fix Lua files with stylua.',
|
||||
\ },
|
||||
\ 'ormolu': {
|
||||
\ 'function': 'ale#fixers#ormolu#Fix',
|
||||
\ 'suggested_filetypes': ['haskell'],
|
||||
\ 'description': 'A formatter for Haskell source code.',
|
||||
\ },
|
||||
\ 'fourmolu': {
|
||||
\ 'function': 'ale#fixers#fourmolu#Fix',
|
||||
\ 'suggested_filetypes': ['haskell'],
|
||||
\ 'description': 'A formatter for Haskell source code.',
|
||||
\ },
|
||||
\ 'jsonnetfmt': {
|
||||
\ 'function': 'ale#fixers#jsonnetfmt#Fix',
|
||||
\ 'suggested_filetypes': ['jsonnet'],
|
||||
\ 'description': 'Fix jsonnet files with jsonnetfmt',
|
||||
\ },
|
||||
\ 'ptop': {
|
||||
\ 'function': 'ale#fixers#ptop#Fix',
|
||||
\ 'suggested_filetypes': ['pascal'],
|
||||
\ 'description': 'Fix Pascal files with ptop.',
|
||||
\ },
|
||||
\ 'opafmt': {
|
||||
\ 'function': 'ale#fixers#opafmt#Fix',
|
||||
\ 'suggested_filetypes': ['rego'],
|
||||
\ 'description': 'Fix rego files with opa fmt.',
|
||||
\ },
|
||||
\ 'vfmt': {
|
||||
\ 'function': 'ale#fixers#vfmt#Fix',
|
||||
\ 'suggested_filetypes': ['v'],
|
||||
\ 'description': 'A formatter for V source code.',
|
||||
\ },
|
||||
\ 'zigfmt': {
|
||||
\ 'function': 'ale#fixers#zigfmt#Fix',
|
||||
\ 'suggested_filetypes': ['zig'],
|
||||
\ 'description': 'Official formatter for Zig',
|
||||
\ },
|
||||
\ 'raco_fmt': {
|
||||
\ 'function': 'ale#fixers#raco_fmt#Fix',
|
||||
\ 'suggested_filetypes': ['racket'],
|
||||
\ 'description': 'Fix Racket files with raco fmt.',
|
||||
\ },
|
||||
\ 'ruff': {
|
||||
\ 'function': 'ale#fixers#ruff#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Fix python files with ruff.',
|
||||
\ },
|
||||
\ 'ruff_format': {
|
||||
\ 'function': 'ale#fixers#ruff_format#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'Fix python files with the ruff formatter.',
|
||||
\ },
|
||||
\ 'pycln': {
|
||||
\ 'function': 'ale#fixers#pycln#Fix',
|
||||
\ 'suggested_filetypes': ['python'],
|
||||
\ 'description': 'remove unused python import statements',
|
||||
\ },
|
||||
\ 'rustywind': {
|
||||
\ 'function': 'ale#fixers#rustywind#Fix',
|
||||
\ 'suggested_filetypes': ['html'],
|
||||
\ 'description': 'Sort Tailwind CSS classes',
|
||||
\ },
|
||||
\ 'npm-groovy-lint': {
|
||||
\ 'function': 'ale#fixers#npmgroovylint#Fix',
|
||||
\ 'suggested_filetypes': ['groovy'],
|
||||
\ 'description': 'Fix Groovy files with npm-groovy-fix.',
|
||||
\ },
|
||||
\ 'erb-formatter': {
|
||||
\ 'function': 'ale#fixers#erbformatter#Fix',
|
||||
\ 'suggested_filetypes': ['eruby'],
|
||||
\ 'description': 'Apply erb-formatter -w to eruby/erb files.',
|
||||
\ },
|
||||
\ 'nickel_format': {
|
||||
\ 'function': 'ale#fixers#nickel_format#Fix',
|
||||
\ 'suggested_filetypes': ['nickel'],
|
||||
\ 'description': 'Fix nickel files with nickel format',
|
||||
\ },
|
||||
\ 'rubyfmt': {
|
||||
\ 'function': 'ale#fixers#rubyfmt#Fix',
|
||||
\ 'suggested_filetypes': ['ruby'],
|
||||
\ 'description': 'A formatter for Ruby source code',
|
||||
\ },
|
||||
\}
|
||||
|
||||
" Reset the function registry to the default entries.
|
||||
function! ale#fix#registry#ResetToDefaults() abort
|
||||
let s:entries = deepcopy(s:default_registry)
|
||||
let s:aliases = {}
|
||||
|
||||
" Set up aliases for fixers too.
|
||||
for [l:key, l:entry] in items(s:entries)
|
||||
for l:alias in get(l:entry, 'aliases', [])
|
||||
let s:aliases[l:alias] = l:key
|
||||
endfor
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
" Set up entries now.
|
||||
call ale#fix#registry#ResetToDefaults()
|
||||
|
||||
" Remove everything from the registry, useful for tests.
|
||||
function! ale#fix#registry#Clear() abort
|
||||
let s:entries = {}
|
||||
let s:aliases = {}
|
||||
endfunction
|
||||
|
||||
" Add a function for fixing problems to the registry.
|
||||
" (name, func, filetypes, desc, aliases)
|
||||
function! ale#fix#registry#Add(name, func, filetypes, desc, ...) abort
|
||||
" This command will throw from the sandbox.
|
||||
let &l:equalprg=&l:equalprg
|
||||
|
||||
if type(a:name) isnot v:t_string
|
||||
throw '''name'' must be a String'
|
||||
endif
|
||||
|
||||
if type(a:func) isnot v:t_string
|
||||
throw '''func'' must be a String'
|
||||
endif
|
||||
|
||||
if type(a:filetypes) isnot v:t_list
|
||||
throw '''filetypes'' must be a List'
|
||||
endif
|
||||
|
||||
for l:type in a:filetypes
|
||||
if type(l:type) isnot v:t_string
|
||||
throw 'Each entry of ''filetypes'' must be a String'
|
||||
endif
|
||||
endfor
|
||||
|
||||
if type(a:desc) isnot v:t_string
|
||||
throw '''desc'' must be a String'
|
||||
endif
|
||||
|
||||
let l:aliases = get(a:000, 0, [])
|
||||
|
||||
if type(l:aliases) isnot v:t_list
|
||||
\|| !empty(filter(copy(l:aliases), 'type(v:val) isnot v:t_string'))
|
||||
throw '''aliases'' must be a List of String values'
|
||||
endif
|
||||
|
||||
let s:entries[a:name] = {
|
||||
\ 'function': a:func,
|
||||
\ 'suggested_filetypes': a:filetypes,
|
||||
\ 'description': a:desc,
|
||||
\}
|
||||
|
||||
" Set up aliases for the fixer.
|
||||
if !empty(l:aliases)
|
||||
let s:entries[a:name].aliases = l:aliases
|
||||
|
||||
for l:alias in l:aliases
|
||||
let s:aliases[l:alias] = a:name
|
||||
endfor
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Get a function from the registry by its short name.
|
||||
function! ale#fix#registry#GetFunc(name) abort
|
||||
" Use the exact name, or an alias.
|
||||
let l:resolved_name = !has_key(s:entries, a:name)
|
||||
\ ? get(s:aliases, a:name, a:name)
|
||||
\ : a:name
|
||||
|
||||
return get(s:entries, l:resolved_name, {'function': ''}).function
|
||||
endfunction
|
||||
|
||||
function! s:ShouldSuggestForType(suggested_filetypes, type_list) abort
|
||||
for l:type in a:type_list
|
||||
if index(a:suggested_filetypes, l:type) >= 0
|
||||
return 1
|
||||
endif
|
||||
endfor
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:IsGenericFixer(suggested_filetypes) abort
|
||||
if empty(a:suggested_filetypes)
|
||||
return 1
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:FormatEntry(key, entry) abort
|
||||
let l:aliases_str = ''
|
||||
|
||||
" Show aliases in :ALEFixSuggest if they are there.
|
||||
if !empty(get(a:entry, 'aliases', []))
|
||||
let l:aliases_str = ', ' . join(
|
||||
\ map(copy(a:entry.aliases), 'string(v:val)'),
|
||||
\ ','
|
||||
\)
|
||||
endif
|
||||
|
||||
return printf(
|
||||
\ '%s%s - %s',
|
||||
\ string(a:key),
|
||||
\ l:aliases_str,
|
||||
\ a:entry.description,
|
||||
\)
|
||||
endfunction
|
||||
|
||||
" Get list of applicable fixers for filetype, including generic fixers
|
||||
function! ale#fix#registry#GetApplicableFixers(filetype) abort
|
||||
let l:type_list = split(a:filetype, '\.')
|
||||
let l:fixer_name_list = []
|
||||
|
||||
for l:key in sort(keys(s:entries))
|
||||
let l:suggested_filetypes = s:entries[l:key].suggested_filetypes
|
||||
|
||||
if s:IsGenericFixer(l:suggested_filetypes) || s:ShouldSuggestForType(l:suggested_filetypes, l:type_list)
|
||||
call add(l:fixer_name_list, l:key)
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:fixer_name_list
|
||||
endfunction
|
||||
|
||||
" Function that returns autocomplete candidates for ALEFix command
|
||||
function! ale#fix#registry#CompleteFixers(ArgLead, CmdLine, CursorPos) abort
|
||||
return filter(ale#fix#registry#GetApplicableFixers(&filetype), 'v:val =~? a:ArgLead')
|
||||
endfunction
|
||||
|
||||
function! ale#fix#registry#SuggestedFixers(filetype) abort
|
||||
let l:type_list = split(a:filetype, '\.')
|
||||
let l:filetype_fixer_list = []
|
||||
|
||||
for l:key in sort(keys(s:entries))
|
||||
let l:suggested_filetypes = s:entries[l:key].suggested_filetypes
|
||||
|
||||
if s:ShouldSuggestForType(l:suggested_filetypes, l:type_list)
|
||||
call add(
|
||||
\ l:filetype_fixer_list,
|
||||
\ s:FormatEntry(l:key, s:entries[l:key]),
|
||||
\)
|
||||
endif
|
||||
endfor
|
||||
|
||||
let l:generic_fixer_list = []
|
||||
|
||||
for l:key in sort(keys(s:entries))
|
||||
if s:IsGenericFixer(s:entries[l:key].suggested_filetypes)
|
||||
call add(
|
||||
\ l:generic_fixer_list,
|
||||
\ s:FormatEntry(l:key, s:entries[l:key]),
|
||||
\)
|
||||
endif
|
||||
endfor
|
||||
|
||||
return [l:filetype_fixer_list, l:generic_fixer_list]
|
||||
endfunction
|
||||
|
||||
" Suggest functions to use from the registry.
|
||||
function! ale#fix#registry#Suggest(filetype) abort
|
||||
let l:suggested = ale#fix#registry#SuggestedFixers(a:filetype)
|
||||
let l:filetype_fixer_list = l:suggested[0]
|
||||
let l:generic_fixer_list = l:suggested[1]
|
||||
|
||||
let l:filetype_fixer_header = !empty(l:filetype_fixer_list)
|
||||
\ ? ['Try the following fixers appropriate for the filetype:', '']
|
||||
\ : []
|
||||
let l:generic_fixer_header = !empty(l:generic_fixer_list)
|
||||
\ ? ['Try the following generic fixers:', '']
|
||||
\ : []
|
||||
|
||||
let l:has_both_lists = !empty(l:filetype_fixer_list) && !empty(l:generic_fixer_list)
|
||||
|
||||
let l:lines =
|
||||
\ l:filetype_fixer_header
|
||||
\ + l:filetype_fixer_list
|
||||
\ + (l:has_both_lists ? [''] : [])
|
||||
\ + l:generic_fixer_header
|
||||
\ + l:generic_fixer_list
|
||||
|
||||
if empty(l:lines)
|
||||
let l:lines = ['There is nothing in the registry to suggest.']
|
||||
else
|
||||
let l:lines += ['', 'See :help ale-fix-configuration']
|
||||
endif
|
||||
|
||||
let l:lines += ['', 'Press q to close this window']
|
||||
|
||||
new +set\ filetype=ale-fix-suggest
|
||||
call setline(1, l:lines)
|
||||
setlocal nomodified
|
||||
setlocal nomodifiable
|
||||
endfunction
|
13
vim/.vim/autoload/ale/fixers/alejandra.vim
Normal file
13
vim/.vim/autoload/ale/fixers/alejandra.vim
Normal file
@ -0,0 +1,13 @@
|
||||
call ale#Set('nix_alejandra_executable', 'alejandra')
|
||||
call ale#Set('nix_alejandra_options', '')
|
||||
|
||||
function! ale#fixers#alejandra#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'nix_alejandra_executable')
|
||||
let l:options = ale#Var(a:buffer, 'nix_alejandra_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' -- -'
|
||||
\}
|
||||
endfunction
|
16
vim/.vim/autoload/ale/fixers/appleswiftformat.vim
Normal file
16
vim/.vim/autoload/ale/fixers/appleswiftformat.vim
Normal file
@ -0,0 +1,16 @@
|
||||
" Author: (bosr) <bosr@bosr.cc>
|
||||
" Description: Integration of apple/swift-format formatter with ALE.
|
||||
|
||||
function! ale#fixers#appleswiftformat#Fix(buffer) abort
|
||||
let l:command_args = ale#swift#GetAppleSwiftFormatCommand(a:buffer) . ' format --in-place %t'
|
||||
let l:config_args = ale#swift#GetAppleSwiftFormatConfigArgs(a:buffer)
|
||||
|
||||
if l:config_args isnot# ''
|
||||
let l:command_args = l:command_args . ' ' . l:config_args
|
||||
endif
|
||||
|
||||
return {
|
||||
\ 'read_temporary_file': 1,
|
||||
\ 'command': l:command_args,
|
||||
\}
|
||||
endfunction
|
59
vim/.vim/autoload/ale/fixers/astyle.vim
Normal file
59
vim/.vim/autoload/ale/fixers/astyle.vim
Normal file
@ -0,0 +1,59 @@
|
||||
" Author: James Kim <jhlink@users.noreply.github.com>
|
||||
" Description: Fix C/C++ files with astyle.
|
||||
|
||||
function! s:set_variables() abort
|
||||
for l:ft in ['c', 'cpp']
|
||||
call ale#Set(l:ft . '_astyle_executable', 'astyle')
|
||||
call ale#Set(l:ft . '_astyle_project_options', '')
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
call s:set_variables()
|
||||
|
||||
|
||||
function! ale#fixers#astyle#Var(buffer, name) abort
|
||||
let l:ft = getbufvar(str2nr(a:buffer), '&filetype')
|
||||
let l:ft = l:ft =~# 'cpp' ? 'cpp' : 'c'
|
||||
|
||||
return ale#Var(a:buffer, l:ft . '_astyle_' . a:name)
|
||||
endfunction
|
||||
|
||||
" Try to find a project options file.
|
||||
function! ale#fixers#astyle#FindProjectOptions(buffer) abort
|
||||
let l:proj_options = ale#fixers#astyle#Var(a:buffer, 'project_options')
|
||||
|
||||
" If user has set project options variable then use it and skip any searching.
|
||||
" This would allow users to use project files named differently than .astylerc.
|
||||
if !empty(l:proj_options)
|
||||
return l:proj_options
|
||||
endif
|
||||
|
||||
" Try to find nearest .astylerc file.
|
||||
let l:proj_options = fnamemodify(ale#path#FindNearestFile(a:buffer, '.astylerc'), ':t')
|
||||
|
||||
if !empty(l:proj_options)
|
||||
return l:proj_options
|
||||
endif
|
||||
|
||||
" Try to find nearest _astylerc file.
|
||||
let l:proj_options = fnamemodify(ale#path#FindNearestFile(a:buffer, '_astylerc'), ':t')
|
||||
|
||||
if !empty(l:proj_options)
|
||||
return l:proj_options
|
||||
endif
|
||||
|
||||
" If no project options file is found return an empty string.
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#astyle#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#astyle#Var(a:buffer, 'executable')
|
||||
let l:proj_options = ale#fixers#astyle#FindProjectOptions(a:buffer)
|
||||
let l:command = ' --stdin=' . ale#Escape(expand('#' . a:buffer))
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (empty(l:proj_options) ? '' : ' --project=' . l:proj_options)
|
||||
\ . l:command
|
||||
\}
|
||||
endfunction
|
46
vim/.vim/autoload/ale/fixers/autoflake.vim
Normal file
46
vim/.vim/autoload/ale/fixers/autoflake.vim
Normal file
@ -0,0 +1,46 @@
|
||||
" Author: circld <circld1@gmail.com>
|
||||
" Description: Fixing files with autoflake.
|
||||
|
||||
call ale#Set('python_autoflake_executable', 'autoflake')
|
||||
call ale#Set('python_autoflake_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('python_autoflake_options', '')
|
||||
call ale#Set('python_autoflake_auto_pipenv', 0)
|
||||
call ale#Set('python_autoflake_auto_poetry', 0)
|
||||
call ale#Set('python_autoflake_auto_uv', 0)
|
||||
|
||||
function! ale#fixers#autoflake#GetExecutable(buffer) abort
|
||||
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_autoflake_auto_pipenv'))
|
||||
\ && ale#python#PipenvPresent(a:buffer)
|
||||
return 'pipenv'
|
||||
endif
|
||||
|
||||
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_autoflake_auto_poetry'))
|
||||
\ && ale#python#PoetryPresent(a:buffer)
|
||||
return 'poetry'
|
||||
endif
|
||||
|
||||
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_autoflake_auto_uv'))
|
||||
\ && ale#python#UvPresent(a:buffer)
|
||||
return 'uv'
|
||||
endif
|
||||
|
||||
return ale#python#FindExecutable(a:buffer, 'python_autoflake', ['autoflake'])
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#autoflake#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#autoflake#GetExecutable(a:buffer)
|
||||
|
||||
let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$'
|
||||
\ ? ' run autoflake'
|
||||
\ : ''
|
||||
|
||||
let l:options = ale#Var(a:buffer, 'python_autoflake_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . l:exec_args
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --in-place '
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
45
vim/.vim/autoload/ale/fixers/autoimport.vim
Normal file
45
vim/.vim/autoload/ale/fixers/autoimport.vim
Normal file
@ -0,0 +1,45 @@
|
||||
" Author: lyz-code
|
||||
" Description: Fixing Python imports with autoimport.
|
||||
|
||||
call ale#Set('python_autoimport_executable', 'autoimport')
|
||||
call ale#Set('python_autoimport_options', '')
|
||||
call ale#Set('python_autoimport_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('python_autoimport_auto_pipenv', 0)
|
||||
call ale#Set('python_autoimport_auto_poetry', 0)
|
||||
call ale#Set('python_autoimport_auto_uv', 0)
|
||||
|
||||
function! ale#fixers#autoimport#GetExecutable(buffer) abort
|
||||
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_autoimport_auto_pipenv'))
|
||||
\ && ale#python#PipenvPresent(a:buffer)
|
||||
return 'pipenv'
|
||||
endif
|
||||
|
||||
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_autoimport_auto_poetry'))
|
||||
\ && ale#python#PoetryPresent(a:buffer)
|
||||
return 'poetry'
|
||||
endif
|
||||
|
||||
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_autoimport_auto_uv'))
|
||||
\ && ale#python#UvPresent(a:buffer)
|
||||
return 'uv'
|
||||
endif
|
||||
|
||||
return ale#python#FindExecutable(a:buffer, 'python_autoimport', ['autoimport'])
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#autoimport#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#autoimport#GetExecutable(a:buffer)
|
||||
|
||||
let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$'
|
||||
\ ? ' run autoimport'
|
||||
\ : ''
|
||||
|
||||
let l:options = ale#Var(a:buffer, 'python_autoimport_options')
|
||||
|
||||
return {
|
||||
\ 'cwd': '%s:h',
|
||||
\ 'command': ale#Escape(l:executable) . l:exec_args
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' -',
|
||||
\}
|
||||
endfunction
|
44
vim/.vim/autoload/ale/fixers/autopep8.vim
Normal file
44
vim/.vim/autoload/ale/fixers/autopep8.vim
Normal file
@ -0,0 +1,44 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Fixing files with autopep8.
|
||||
|
||||
call ale#Set('python_autopep8_executable', 'autopep8')
|
||||
call ale#Set('python_autopep8_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('python_autopep8_options', '')
|
||||
call ale#Set('python_autopep8_auto_pipenv', 0)
|
||||
call ale#Set('python_autopep8_auto_poetry', 0)
|
||||
call ale#Set('python_autopep8_auto_uv', 0)
|
||||
|
||||
function! ale#fixers#autopep8#GetExecutable(buffer) abort
|
||||
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_autopep8_auto_pipenv'))
|
||||
\ && ale#python#PipenvPresent(a:buffer)
|
||||
return 'pipenv'
|
||||
endif
|
||||
|
||||
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_autopep8_auto_poetry'))
|
||||
\ && ale#python#PoetryPresent(a:buffer)
|
||||
return 'poetry'
|
||||
endif
|
||||
|
||||
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_autopep8_auto_uv'))
|
||||
\ && ale#python#UvPresent(a:buffer)
|
||||
return 'uv'
|
||||
endif
|
||||
|
||||
return ale#python#FindExecutable(a:buffer, 'python_autopep8', ['autopep8'])
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#autopep8#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#autopep8#GetExecutable(a:buffer)
|
||||
|
||||
let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$'
|
||||
\ ? ' run autopep8'
|
||||
\ : ''
|
||||
|
||||
let l:options = ale#Var(a:buffer, 'python_autopep8_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . l:exec_args
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' -',
|
||||
\}
|
||||
endfunction
|
15
vim/.vim/autoload/ale/fixers/bibclean.vim
Normal file
15
vim/.vim/autoload/ale/fixers/bibclean.vim
Normal file
@ -0,0 +1,15 @@
|
||||
" Author: Horacio Sanson - https://github.com/hsanson
|
||||
" Description: Support for bibclean fixer for BibTeX files.
|
||||
|
||||
call ale#Set('bib_bibclean_executable', 'bibclean')
|
||||
call ale#Set('bib_bibclean_options', '-align-equals')
|
||||
|
||||
function! ale#fixers#bibclean#Fix(buffer) abort
|
||||
let l:options = ale#Var(a:buffer, 'bib_bibclean_options')
|
||||
let l:executable = ale#Var(a:buffer, 'bib_bibclean_executable')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' ' . (empty(l:options) ? '' : l:options),
|
||||
\}
|
||||
endfunction
|
12
vim/.vim/autoload/ale/fixers/biome.vim
Normal file
12
vim/.vim/autoload/ale/fixers/biome.vim
Normal file
@ -0,0 +1,12 @@
|
||||
function! ale#fixers#biome#Fix(buffer) abort
|
||||
let l:executable = ale#handlers#biome#GetExecutable(a:buffer)
|
||||
let l:options = ale#Var(a:buffer, 'biome_options')
|
||||
let l:apply = ale#Var(a:buffer, 'biome_fixer_apply_unsafe') ? '--apply-unsafe' : '--apply'
|
||||
|
||||
return {
|
||||
\ 'read_temporary_file': 1,
|
||||
\ 'command': ale#Escape(l:executable) . ' check ' . l:apply
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' %t'
|
||||
\}
|
||||
endfunction
|
58
vim/.vim/autoload/ale/fixers/black.vim
Normal file
58
vim/.vim/autoload/ale/fixers/black.vim
Normal file
@ -0,0 +1,58 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Fixing Python files with black.
|
||||
"
|
||||
call ale#Set('python_black_executable', 'black')
|
||||
call ale#Set('python_black_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('python_black_options', '')
|
||||
call ale#Set('python_black_auto_pipenv', 0)
|
||||
call ale#Set('python_black_auto_poetry', 0)
|
||||
call ale#Set('python_black_auto_uv', 0)
|
||||
call ale#Set('python_black_change_directory', 1)
|
||||
|
||||
function! ale#fixers#black#GetExecutable(buffer) abort
|
||||
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_black_auto_pipenv'))
|
||||
\ && ale#python#PipenvPresent(a:buffer)
|
||||
return 'pipenv'
|
||||
endif
|
||||
|
||||
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_black_auto_poetry'))
|
||||
\ && ale#python#PoetryPresent(a:buffer)
|
||||
return 'poetry'
|
||||
endif
|
||||
|
||||
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_black_auto_uv'))
|
||||
\ && ale#python#UvPresent(a:buffer)
|
||||
return 'uv'
|
||||
endif
|
||||
|
||||
return ale#python#FindExecutable(a:buffer, 'python_black', ['black'])
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#black#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#black#GetExecutable(a:buffer)
|
||||
let l:cmd = [ale#Escape(l:executable)]
|
||||
|
||||
if l:executable =~? 'pipenv\|poetry\|uv$'
|
||||
call extend(l:cmd, ['run', 'black'])
|
||||
endif
|
||||
|
||||
let l:options = ale#Var(a:buffer, 'python_black_options')
|
||||
|
||||
if !empty(l:options)
|
||||
call add(l:cmd, l:options)
|
||||
endif
|
||||
|
||||
if expand('#' . a:buffer . ':e') is? 'pyi'
|
||||
call add(l:cmd, '--pyi')
|
||||
endif
|
||||
|
||||
call add(l:cmd, '-')
|
||||
|
||||
let l:result = {'command': join(l:cmd, ' ')}
|
||||
|
||||
if ale#Var(a:buffer, 'python_black_change_directory')
|
||||
let l:result.cwd = '%s:h'
|
||||
endif
|
||||
|
||||
return l:result
|
||||
endfunction
|
22
vim/.vim/autoload/ale/fixers/brittany.vim
Normal file
22
vim/.vim/autoload/ale/fixers/brittany.vim
Normal file
@ -0,0 +1,22 @@
|
||||
" Author: eborden <evan@evan-borden.com>, ifyouseewendy <ifyouseewendy@gmail.com>, aspidiets <emarshall85@gmail.com>
|
||||
" Description: Integration of brittany with ALE.
|
||||
|
||||
call ale#Set('haskell_brittany_executable', 'brittany')
|
||||
|
||||
function! ale#fixers#brittany#GetExecutable(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'haskell_brittany_executable')
|
||||
|
||||
return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'brittany')
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#brittany#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#brittany#GetExecutable(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': l:executable
|
||||
\ . ' --write-mode inplace'
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
|
12
vim/.vim/autoload/ale/fixers/buf_format.vim
Normal file
12
vim/.vim/autoload/ale/fixers/buf_format.vim
Normal file
@ -0,0 +1,12 @@
|
||||
" Author: Alex McKinney <alexmckinney01@gmail.com>
|
||||
" Description: Run buf format.
|
||||
|
||||
call ale#Set('proto_buf_format_executable', 'buf')
|
||||
|
||||
function! ale#fixers#buf_format#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'proto_buf_format_executable')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . ' format %t',
|
||||
\}
|
||||
endfunction
|
26
vim/.vim/autoload/ale/fixers/buildifier.vim
Normal file
26
vim/.vim/autoload/ale/fixers/buildifier.vim
Normal file
@ -0,0 +1,26 @@
|
||||
" Author: Jon Parise <jon@indelible.org>
|
||||
" Description: Format Bazel BUILD and .bzl files with buildifier.
|
||||
"
|
||||
call ale#Set('bazel_buildifier_executable', 'buildifier')
|
||||
call ale#Set('bazel_buildifier_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('bazel_buildifier_options', '')
|
||||
|
||||
function! ale#fixers#buildifier#GetExecutable(buffer) abort
|
||||
return ale#path#FindExecutable(a:buffer, 'bazel_buildifier', [
|
||||
\ 'buildifier',
|
||||
\])
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#buildifier#Fix(buffer) abort
|
||||
let l:executable = ale#Escape(ale#fixers#buildifier#GetExecutable(a:buffer))
|
||||
let l:options = ale#Var(a:buffer, 'bazel_buildifier_options')
|
||||
let l:filename = ale#Escape(bufname(a:buffer))
|
||||
|
||||
let l:command = l:executable . ' -mode fix -lint fix -path ' . l:filename
|
||||
|
||||
if l:options isnot# ''
|
||||
let l:command .= ' ' . l:options
|
||||
endif
|
||||
|
||||
return {'command': l:command . ' -'}
|
||||
endfunction
|
47
vim/.vim/autoload/ale/fixers/clangformat.vim
Normal file
47
vim/.vim/autoload/ale/fixers/clangformat.vim
Normal file
@ -0,0 +1,47 @@
|
||||
scriptencoding utf-8
|
||||
" Author: Peter Renström <renstrom.peter@gmail.com>
|
||||
" Description: Fixing C/C++ files with clang-format.
|
||||
|
||||
call ale#Set('c_clangformat_executable', 'clang-format')
|
||||
call ale#Set('c_clangformat_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('c_clangformat_options', '')
|
||||
call ale#Set('c_clangformat_style_option', '')
|
||||
call ale#Set('c_clangformat_use_local_file', 0)
|
||||
|
||||
function! ale#fixers#clangformat#GetExecutable(buffer) abort
|
||||
return ale#path#FindExecutable(a:buffer, 'c_clangformat', [
|
||||
\ 'clang-format',
|
||||
\])
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#clangformat#Fix(buffer) abort
|
||||
let l:executable = ale#Escape(ale#fixers#clangformat#GetExecutable(a:buffer))
|
||||
let l:filename = ale#Escape(bufname(a:buffer))
|
||||
let l:options = ale#Var(a:buffer, 'c_clangformat_options')
|
||||
let l:style_option = ale#Var(a:buffer, 'c_clangformat_style_option')
|
||||
let l:use_local_file = ale#Var(a:buffer, 'c_clangformat_use_local_file')
|
||||
|
||||
if l:style_option isnot# ''
|
||||
let l:style_option = '-style=' . "'" . l:style_option . "'"
|
||||
endif
|
||||
|
||||
if l:use_local_file
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, '.clang-format')
|
||||
|
||||
if !empty(l:config)
|
||||
let l:style_option = '-style=file'
|
||||
endif
|
||||
endif
|
||||
|
||||
if l:style_option isnot# ''
|
||||
let l:options .= ' ' . l:style_option
|
||||
endif
|
||||
|
||||
let l:command = l:executable . ' --assume-filename=' . l:filename
|
||||
|
||||
if l:options isnot# ''
|
||||
let l:command .= ' ' . l:options
|
||||
endif
|
||||
|
||||
return {'command': l:command}
|
||||
endfunction
|
52
vim/.vim/autoload/ale/fixers/clangtidy.vim
Normal file
52
vim/.vim/autoload/ale/fixers/clangtidy.vim
Normal file
@ -0,0 +1,52 @@
|
||||
scriptencoding utf-8
|
||||
" Author: ObserverOfTime <chronobserver@disroot.org>
|
||||
" Description: Fixing C/C++ files with clang-tidy.
|
||||
|
||||
function! s:set_variables() abort
|
||||
let l:use_global = get(g:, 'ale_use_global_executables', 0)
|
||||
|
||||
for l:ft in ['c', 'cpp']
|
||||
call ale#Set(l:ft . '_clangtidy_executable', 'clang-tidy')
|
||||
call ale#Set(l:ft . '_clangtidy_use_global', l:use_global)
|
||||
call ale#Set(l:ft . '_clangtidy_checks', [])
|
||||
call ale#Set(l:ft . '_clangtidy_options', '')
|
||||
call ale#Set(l:ft . '_clangtidy_extra_options', '')
|
||||
call ale#Set(l:ft . '_clangtidy_fix_errors', 1)
|
||||
endfor
|
||||
|
||||
call ale#Set('c_build_dir', '')
|
||||
endfunction
|
||||
|
||||
call s:set_variables()
|
||||
|
||||
function! ale#fixers#clangtidy#Var(buffer, name) abort
|
||||
let l:ft = getbufvar(str2nr(a:buffer), '&filetype')
|
||||
let l:ft = l:ft =~# 'cpp' ? 'cpp' : 'c'
|
||||
|
||||
return ale#Var(a:buffer, l:ft . '_clangtidy_' . a:name)
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#clangtidy#GetCommand(buffer) abort
|
||||
let l:checks = join(ale#fixers#clangtidy#Var(a:buffer, 'checks'), ',')
|
||||
let l:extra_options = ale#fixers#clangtidy#Var(a:buffer, 'extra_options')
|
||||
let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
|
||||
let l:options = empty(l:build_dir)
|
||||
\ ? ale#fixers#clangtidy#Var(a:buffer, 'options') : ''
|
||||
let l:fix_errors = ale#fixers#clangtidy#Var(a:buffer, 'fix_errors')
|
||||
|
||||
return ' -fix' . (l:fix_errors ? ' -fix-errors' : '')
|
||||
\ . (empty(l:checks) ? '' : ' -checks=' . ale#Escape(l:checks))
|
||||
\ . (empty(l:extra_options) ? '' : ' ' . l:extra_options)
|
||||
\ . (empty(l:build_dir) ? '' : ' -p ' . ale#Escape(l:build_dir))
|
||||
\ . ' %t' . (empty(l:options) ? '' : ' -- ' . l:options)
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#clangtidy#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#clangtidy#Var(a:buffer, 'executable')
|
||||
let l:command = ale#fixers#clangtidy#GetCommand(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . l:command,
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
16
vim/.vim/autoload/ale/fixers/cmakeformat.vim
Normal file
16
vim/.vim/autoload/ale/fixers/cmakeformat.vim
Normal file
@ -0,0 +1,16 @@
|
||||
" Author: Attila Maczak <attila@maczak.hu>
|
||||
" Description: Integration of cmakeformat with ALE.
|
||||
|
||||
call ale#Set('cmake_cmakeformat_executable', 'cmake-format')
|
||||
call ale#Set('cmake_cmakeformat_options', '')
|
||||
|
||||
function! ale#fixers#cmakeformat#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'cmake_cmakeformat_executable')
|
||||
let l:options = ale#Var(a:buffer, 'cmake_cmakeformat_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' -'
|
||||
\}
|
||||
endfunction
|
14
vim/.vim/autoload/ale/fixers/crystal.vim
Normal file
14
vim/.vim/autoload/ale/fixers/crystal.vim
Normal file
@ -0,0 +1,14 @@
|
||||
call ale#Set('crystal_format_executable', 'crystal')
|
||||
call ale#Set('crystal_format_options', '')
|
||||
|
||||
function! ale#fixers#crystal#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'crystal_format_executable')
|
||||
let l:options = ale#Var(a:buffer, 'crystal_format_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' tool format'
|
||||
\ . ale#Pad(l:options)
|
||||
\ . ' -'
|
||||
\}
|
||||
endfunction
|
20
vim/.vim/autoload/ale/fixers/css_beautify.vim
Normal file
20
vim/.vim/autoload/ale/fixers/css_beautify.vim
Normal file
@ -0,0 +1,20 @@
|
||||
" Author: https://github.com/Spixmaster
|
||||
" Description: Format CSS using css-beautify from js-beautify.
|
||||
|
||||
call ale#Set('css_css_beautify_executable', 'css-beautify')
|
||||
call ale#Set('css_css_beautify_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('css_css_beautify_options', '')
|
||||
|
||||
function! ale#fixers#css_beautify#Fix(buffer) abort
|
||||
let l:executable = ale#python#FindExecutable(
|
||||
\ a:buffer,
|
||||
\ 'css_css_beautify',
|
||||
\ ['css-beautify']
|
||||
\)
|
||||
|
||||
let l:options = ale#Var(a:buffer, 'css_css_beautify_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . ' ' . l:options . ' -',
|
||||
\}
|
||||
endfunction
|
18
vim/.vim/autoload/ale/fixers/dart_format.vim
Normal file
18
vim/.vim/autoload/ale/fixers/dart_format.vim
Normal file
@ -0,0 +1,18 @@
|
||||
" Author: ghsang <gwonhyuksang@gmail.com>
|
||||
" Description: Integration of dart format with ALE.
|
||||
|
||||
call ale#Set('dart_format_executable', 'dart')
|
||||
call ale#Set('dart_format_options', '')
|
||||
|
||||
function! ale#fixers#dart_format#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'dart_format_executable')
|
||||
let l:options = ale#Var(a:buffer, 'dart_format_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' format'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
18
vim/.vim/autoload/ale/fixers/dartfmt.vim
Normal file
18
vim/.vim/autoload/ale/fixers/dartfmt.vim
Normal file
@ -0,0 +1,18 @@
|
||||
" Author: reisub0 <reisub0@gmail.com>
|
||||
" Description: Integration of dartfmt with ALE.
|
||||
|
||||
call ale#Set('dart_dartfmt_executable', 'dartfmt')
|
||||
call ale#Set('dart_dartfmt_options', '')
|
||||
|
||||
function! ale#fixers#dartfmt#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'dart_dartfmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'dart_dartfmt_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' -w'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
17
vim/.vim/autoload/ale/fixers/deno.vim
Normal file
17
vim/.vim/autoload/ale/fixers/deno.vim
Normal file
@ -0,0 +1,17 @@
|
||||
function! ale#fixers#deno#Fix(buffer) abort
|
||||
let l:executable = ale#handlers#deno#GetExecutable(a:buffer)
|
||||
|
||||
if !executable(l:executable)
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:options = ' fmt -'
|
||||
|
||||
if ale#Var(a:buffer, 'deno_unstable')
|
||||
let l:options = l:options . ' --unstable'
|
||||
endif
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . l:options
|
||||
\}
|
||||
endfunction
|
18
vim/.vim/autoload/ale/fixers/dfmt.vim
Normal file
18
vim/.vim/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
|
11
vim/.vim/autoload/ale/fixers/dhall_format.vim
Normal file
11
vim/.vim/autoload/ale/fixers/dhall_format.vim
Normal file
@ -0,0 +1,11 @@
|
||||
" Author: toastal <toastal@posteo.net>
|
||||
" Description: Dhall’s built-in formatter
|
||||
"
|
||||
function! ale#fixers#dhall_format#Fix(buffer) abort
|
||||
let l:executable = ale#dhall#GetExecutableWithOptions(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': l:executable
|
||||
\ . ' format'
|
||||
\}
|
||||
endfunction
|
14
vim/.vim/autoload/ale/fixers/dhall_freeze.vim
Normal file
14
vim/.vim/autoload/ale/fixers/dhall_freeze.vim
Normal file
@ -0,0 +1,14 @@
|
||||
" Author: toastal <toastal@posteo.net>
|
||||
" Description: Dhall’s package freezing
|
||||
|
||||
call ale#Set('dhall_freeze_options', '')
|
||||
|
||||
function! ale#fixers#dhall_freeze#Freeze(buffer) abort
|
||||
let l:executable = ale#dhall#GetExecutableWithOptions(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': l:executable
|
||||
\ . ' freeze'
|
||||
\ . ale#Pad(ale#Var(a:buffer, 'dhall_freeze_options'))
|
||||
\}
|
||||
endfunction
|
11
vim/.vim/autoload/ale/fixers/dhall_lint.vim
Normal file
11
vim/.vim/autoload/ale/fixers/dhall_lint.vim
Normal file
@ -0,0 +1,11 @@
|
||||
" Author: toastal <toastal@posteo.net>
|
||||
" Description: Dhall’s built-in linter/formatter
|
||||
|
||||
function! ale#fixers#dhall_lint#Fix(buffer) abort
|
||||
let l:executable = ale#dhall#GetExecutableWithOptions(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': l:executable
|
||||
\ . ' lint'
|
||||
\}
|
||||
endfunction
|
18
vim/.vim/autoload/ale/fixers/dotnet_format.vim
Normal file
18
vim/.vim/autoload/ale/fixers/dotnet_format.vim
Normal file
@ -0,0 +1,18 @@
|
||||
" Author: ghsang <gwonhyuksang@gmail.com>
|
||||
" Description: Integration of dotnet format with ALE.
|
||||
|
||||
call ale#Set('cs_dotnet_format_executable', 'dotnet')
|
||||
call ale#Set('cs_dotnet_format_options', '')
|
||||
|
||||
function! ale#fixers#dotnet_format#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'cs_dotnet_format_executable')
|
||||
let l:options = ale#Var(a:buffer, 'cs_dotnet_format_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' format'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' --folder --include %t "$(dirname %t)"',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
29
vim/.vim/autoload/ale/fixers/dprint.vim
Normal file
29
vim/.vim/autoload/ale/fixers/dprint.vim
Normal file
@ -0,0 +1,29 @@
|
||||
call ale#Set('dprint_executable', 'dprint')
|
||||
call ale#Set('dprint_executable_override', 0)
|
||||
call ale#Set('dprint_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('dprint_options', '')
|
||||
call ale#Set('dprint_config', 'dprint.json')
|
||||
|
||||
function! ale#fixers#dprint#Fix(buffer) abort
|
||||
let l:executable = ale#path#FindExecutable(a:buffer, 'dprint', ['dprint'])
|
||||
let l:executable_override = ale#Var(a:buffer, 'dprint_executable_override')
|
||||
|
||||
if !executable(l:executable) && !l:executable_override
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:options = ale#Var(a:buffer, 'dprint_options')
|
||||
let l:config = ale#path#FindNearestFile(a:buffer, ale#Var(a:buffer, 'dprint_config'))
|
||||
|
||||
if !empty(l:config)
|
||||
let l:options = l:options . ' -c ' . ale#Escape(l:config)
|
||||
endif
|
||||
|
||||
let l:options = l:options . ' --stdin %s'
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' fmt '
|
||||
\ . l:options
|
||||
\}
|
||||
endfunction
|
16
vim/.vim/autoload/ale/fixers/dune.vim
Normal file
16
vim/.vim/autoload/ale/fixers/dune.vim
Normal file
@ -0,0 +1,16 @@
|
||||
" Author: Albert Peschar <albert@peschar.net>
|
||||
" Description: Fix files with dune format.
|
||||
|
||||
call ale#Set('ocaml_dune_executable', 'dune')
|
||||
call ale#Set('ocaml_dune_options', '')
|
||||
|
||||
function! ale#fixers#dune#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ocaml_dune_executable')
|
||||
let l:options = ale#Var(a:buffer, 'ocaml_dune_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' format'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options),
|
||||
\}
|
||||
endfunction
|
23
vim/.vim/autoload/ale/fixers/elm_format.vim
Normal file
23
vim/.vim/autoload/ale/fixers/elm_format.vim
Normal file
@ -0,0 +1,23 @@
|
||||
" Author: soywod <clement.douin@gmail.com>
|
||||
" Description: Integration of elm-format with ALE.
|
||||
|
||||
call ale#Set('elm_format_executable', 'elm-format')
|
||||
call ale#Set('elm_format_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('elm_format_options', '--yes')
|
||||
|
||||
function! ale#fixers#elm_format#GetExecutable(buffer) abort
|
||||
return ale#path#FindExecutable(a:buffer, 'elm_format', [
|
||||
\ 'node_modules/.bin/elm-format',
|
||||
\])
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#elm_format#Fix(buffer) abort
|
||||
let l:options = ale#Var(a:buffer, 'elm_format_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(ale#fixers#elm_format#GetExecutable(a:buffer))
|
||||
\ . ' %t'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options),
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
13
vim/.vim/autoload/ale/fixers/erbformatter.vim
Normal file
13
vim/.vim/autoload/ale/fixers/erbformatter.vim
Normal file
@ -0,0 +1,13 @@
|
||||
" Author: Arash Mousavi <arash-m>
|
||||
" Description: Support for ERB::Formetter https://github.com/nebulab/erb-formatter
|
||||
|
||||
call ale#Set('eruby_erbformatter_executable', 'erb-formatter')
|
||||
|
||||
function! ale#fixers#erbformatter#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'eruby_erbformatter_executable')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . ' -w %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
40
vim/.vim/autoload/ale/fixers/erblint.vim
Normal file
40
vim/.vim/autoload/ale/fixers/erblint.vim
Normal file
@ -0,0 +1,40 @@
|
||||
" Author: Roeland Moors - https://github.com/roelandmoors
|
||||
" Description: ERB Lint, support for https://github.com/Shopify/erb-lint
|
||||
|
||||
call ale#Set('eruby_erblint_executable', 'erblint')
|
||||
call ale#Set('eruby_erblint_options', '')
|
||||
|
||||
|
||||
" Erblint fixer outputs diagnostics first and then the fixed
|
||||
" output. These are delimited by something like this:
|
||||
" ================ /path/to/demo.html.erb ==================
|
||||
" We only need the output after this
|
||||
function! ale#fixers#erblint#PostProcess(buffer, output) abort
|
||||
let l:line = 0
|
||||
|
||||
for l:output in a:output
|
||||
let l:line = l:line + 1
|
||||
|
||||
if l:output =~# "^=\\+.*=\\+$"
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
|
||||
return a:output[l:line :]
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#erblint#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'eruby_erblint_executable')
|
||||
let l:options = ale#Var(a:buffer, 'eruby_erblint_options')
|
||||
|
||||
return ale#ruby#EscapeExecutable(l:executable, 'erblint')
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --autocorrect --stdin %s'
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#erblint#Fix(buffer) abort
|
||||
return {
|
||||
\ 'command': ale#fixers#erblint#GetCommand(a:buffer),
|
||||
\ 'process_with': 'ale#fixers#erblint#PostProcess'
|
||||
\}
|
||||
endfunction
|
21
vim/.vim/autoload/ale/fixers/erlfmt.vim
Normal file
21
vim/.vim/autoload/ale/fixers/erlfmt.vim
Normal file
@ -0,0 +1,21 @@
|
||||
" Author: AntoineGagne - https://github.com/AntoineGagne
|
||||
" Description: Integration of erlfmt with ALE.
|
||||
|
||||
call ale#Set('erlang_erlfmt_executable', 'erlfmt')
|
||||
call ale#Set('erlang_erlfmt_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('erlang_erlfmt_options', '')
|
||||
|
||||
function! ale#fixers#erlfmt#GetExecutable(buffer) abort
|
||||
return ale#path#FindExecutable(a:buffer, 'erlang_erlfmt', ['erlfmt'])
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#erlfmt#Fix(buffer) abort
|
||||
let l:options = ale#Var(a:buffer, 'erlang_erlfmt_options')
|
||||
let l:executable = ale#fixers#erlfmt#GetExecutable(a:buffer)
|
||||
|
||||
let l:command = ale#Escape(l:executable) . (empty(l:options) ? '' : ' ' . l:options) . ' %s'
|
||||
|
||||
return {
|
||||
\ 'command': l:command
|
||||
\}
|
||||
endfunction
|
83
vim/.vim/autoload/ale/fixers/eslint.vim
Normal file
83
vim/.vim/autoload/ale/fixers/eslint.vim
Normal file
@ -0,0 +1,83 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Fixing files with eslint.
|
||||
|
||||
function! ale#fixers#eslint#Fix(buffer) abort
|
||||
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
|
||||
let l:command = ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ' --version'
|
||||
|
||||
return ale#semver#RunWithVersionCheck(
|
||||
\ a:buffer,
|
||||
\ l:executable,
|
||||
\ l:command,
|
||||
\ function('ale#fixers#eslint#ApplyFixForVersion'),
|
||||
\)
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#eslint#ProcessFixDryRunOutput(buffer, output) abort
|
||||
for l:item in ale#util#FuzzyJSONDecode(a:output, [])
|
||||
return split(get(l:item, 'output', ''), "\n")
|
||||
endfor
|
||||
|
||||
return []
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#eslint#ProcessEslintDOutput(buffer, output) abort
|
||||
" If the output is an error message, don't use it.
|
||||
for l:line in a:output[:10]
|
||||
if l:line =~# '\v^Error:|^Could not connect'
|
||||
return []
|
||||
endif
|
||||
endfor
|
||||
|
||||
return a:output
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#eslint#ApplyFixForVersion(buffer, version) abort
|
||||
let l:executable = ale#handlers#eslint#GetExecutable(a:buffer)
|
||||
let l:options = ale#Var(a:buffer, 'javascript_eslint_options')
|
||||
|
||||
" Use the configuration file from the options, if configured.
|
||||
if l:options =~# '\v(^| )-c|(^| )--config'
|
||||
let l:config = ''
|
||||
let l:has_config = 1
|
||||
else
|
||||
let l:config = ale#handlers#eslint#FindConfig(a:buffer)
|
||||
let l:has_config = !empty(l:config)
|
||||
endif
|
||||
|
||||
if !l:has_config
|
||||
return 0
|
||||
endif
|
||||
|
||||
" Use --fix-to-stdout with eslint_d
|
||||
if l:executable =~# 'eslint_d$' && ale#semver#GTE(a:version, [3, 19, 0])
|
||||
return {
|
||||
\ 'cwd': ale#handlers#eslint#GetCwd(a:buffer),
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ale#Pad(l:options)
|
||||
\ . ' --stdin-filename %s --stdin --fix-to-stdout',
|
||||
\ 'process_with': 'ale#fixers#eslint#ProcessEslintDOutput',
|
||||
\}
|
||||
endif
|
||||
|
||||
" 4.9.0 is the first version with --fix-dry-run
|
||||
if ale#semver#GTE(a:version, [4, 9, 0])
|
||||
return {
|
||||
\ 'cwd': ale#handlers#eslint#GetCwd(a:buffer),
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ale#Pad(l:options)
|
||||
\ . ' --stdin-filename %s --stdin --fix-dry-run --format=json',
|
||||
\ 'process_with': 'ale#fixers#eslint#ProcessFixDryRunOutput',
|
||||
\}
|
||||
endif
|
||||
|
||||
return {
|
||||
\ 'cwd': ale#handlers#eslint#GetCwd(a:buffer),
|
||||
\ 'command': ale#node#Executable(a:buffer, l:executable)
|
||||
\ . ale#Pad(l:options)
|
||||
\ . (!empty(l:config) ? ' -c ' . ale#Escape(l:config) : '')
|
||||
\ . ' --fix %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
17
vim/.vim/autoload/ale/fixers/fecs.vim
Normal file
17
vim/.vim/autoload/ale/fixers/fecs.vim
Normal file
@ -0,0 +1,17 @@
|
||||
" Author: harttle <yangjvn@126.com>
|
||||
" Description: Apply fecs format to a file.
|
||||
|
||||
function! ale#fixers#fecs#Fix(buffer) abort
|
||||
let l:executable = ale#handlers#fecs#GetExecutable(a:buffer)
|
||||
|
||||
if !executable(l:executable)
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:config_options = ' format --replace=true %t'
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . l:config_options,
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
19
vim/.vim/autoload/ale/fixers/fish_indent.vim
Normal file
19
vim/.vim/autoload/ale/fixers/fish_indent.vim
Normal file
@ -0,0 +1,19 @@
|
||||
" Author: Chen YuanYuan <cyyever@outlook.com>
|
||||
" Description: Integration of fish_indent with ALE.
|
||||
|
||||
call ale#Set('fish_fish_indent_executable', 'fish_indent')
|
||||
call ale#Set('fish_fish_indent_options', '')
|
||||
|
||||
function! ale#fixers#fish_indent#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'fish_fish_indent_executable')
|
||||
let l:options = ale#Var(a:buffer, 'fish_fish_indent_options')
|
||||
let l:filename = ale#Escape(bufname(a:buffer))
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' -w '
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
28
vim/.vim/autoload/ale/fixers/fixjson.vim
Normal file
28
vim/.vim/autoload/ale/fixers/fixjson.vim
Normal file
@ -0,0 +1,28 @@
|
||||
" Author: rhysd <https://rhysd.github.io>
|
||||
" Description: Integration of fixjson with ALE.
|
||||
|
||||
call ale#Set('json_fixjson_executable', 'fixjson')
|
||||
call ale#Set('json_fixjson_options', '')
|
||||
call ale#Set('json_fixjson_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
|
||||
function! ale#fixers#fixjson#GetExecutable(buffer) abort
|
||||
return ale#path#FindExecutable(a:buffer, 'json_fixjson', [
|
||||
\ 'node_modules/.bin/fixjson',
|
||||
\])
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#fixjson#Fix(buffer) abort
|
||||
let l:executable = ale#Escape(ale#fixers#fixjson#GetExecutable(a:buffer))
|
||||
let l:filename = ale#Escape(bufname(a:buffer))
|
||||
let l:command = l:executable . ' --stdin-filename ' . l:filename
|
||||
|
||||
let l:options = ale#Var(a:buffer, 'json_fixjson_options')
|
||||
|
||||
if l:options isnot# ''
|
||||
let l:command .= ' ' . l:options
|
||||
endif
|
||||
|
||||
return {
|
||||
\ 'command': l:command
|
||||
\}
|
||||
endfunction
|
20
vim/.vim/autoload/ale/fixers/floskell.vim
Normal file
20
vim/.vim/autoload/ale/fixers/floskell.vim
Normal file
@ -0,0 +1,20 @@
|
||||
" Author: robertjlooby <robertjlooby@gmail.com>
|
||||
" Description: Integration of floskell with ALE.
|
||||
|
||||
call ale#Set('haskell_floskell_executable', 'floskell')
|
||||
|
||||
function! ale#fixers#floskell#GetExecutable(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'haskell_floskell_executable')
|
||||
|
||||
return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'floskell')
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#floskell#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#floskell#GetExecutable(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': l:executable
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
11
vim/.vim/autoload/ale/fixers/forge.vim
Normal file
11
vim/.vim/autoload/ale/fixers/forge.vim
Normal file
@ -0,0 +1,11 @@
|
||||
call ale#Set('solidity_forge_executable', 'forge')
|
||||
|
||||
function! ale#fixers#forge#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'solidity_forge_executable')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' fmt %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
20
vim/.vim/autoload/ale/fixers/fourmolu.vim
Normal file
20
vim/.vim/autoload/ale/fixers/fourmolu.vim
Normal file
@ -0,0 +1,20 @@
|
||||
call ale#Set('haskell_fourmolu_executable', 'fourmolu')
|
||||
call ale#Set('haskell_fourmolu_options', '')
|
||||
|
||||
function! ale#fixers#fourmolu#GetExecutable(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'haskell_fourmolu_executable')
|
||||
|
||||
return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'fourmolu')
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#fourmolu#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#fourmolu#GetExecutable(a:buffer)
|
||||
let l:options = ale#Var(a:buffer, 'haskell_fourmolu_options')
|
||||
|
||||
return {
|
||||
\ 'command': l:executable
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' --stdin-input-file '
|
||||
\ . ale#Escape(@%),
|
||||
\}
|
||||
endfunction
|
25
vim/.vim/autoload/ale/fixers/generic.vim
Normal file
25
vim/.vim/autoload/ale/fixers/generic.vim
Normal file
@ -0,0 +1,25 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Generic functions for fixing files with.
|
||||
|
||||
function! ale#fixers#generic#RemoveTrailingBlankLines(buffer, lines) abort
|
||||
let l:end_index = len(a:lines) - 1
|
||||
|
||||
while l:end_index > 0 && empty(a:lines[l:end_index])
|
||||
let l:end_index -= 1
|
||||
endwhile
|
||||
|
||||
return a:lines[:l:end_index]
|
||||
endfunction
|
||||
|
||||
" Remove all whitespaces at the end of lines
|
||||
function! ale#fixers#generic#TrimWhitespace(buffer, lines) abort
|
||||
let l:index = 0
|
||||
let l:lines_new = range(len(a:lines))
|
||||
|
||||
for l:line in a:lines
|
||||
let l:lines_new[l:index] = substitute(l:line, '\s\+$', '', 'g')
|
||||
let l:index = l:index + 1
|
||||
endfor
|
||||
|
||||
return l:lines_new
|
||||
endfunction
|
75
vim/.vim/autoload/ale/fixers/generic_python.vim
Normal file
75
vim/.vim/autoload/ale/fixers/generic_python.vim
Normal file
@ -0,0 +1,75 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Generic fixer functions for Python.
|
||||
|
||||
" Add blank lines before control statements.
|
||||
function! ale#fixers#generic_python#AddLinesBeforeControlStatements(buffer, lines) abort
|
||||
let l:new_lines = []
|
||||
let l:last_indent_size = 0
|
||||
let l:last_line_is_blank = 0
|
||||
let l:in_docstring = 0
|
||||
|
||||
for l:line in a:lines
|
||||
let l:indent_size = len(matchstr(l:line, '^ *'))
|
||||
|
||||
if !l:in_docstring
|
||||
" Make sure it is not just a single line docstring and then verify
|
||||
" it's starting a new docstring
|
||||
if match(l:line, '\v^ *("""|'''''').*("""|'''''')') == -1
|
||||
\&& match(l:line, '\v^ *("""|'''''')') >= 0
|
||||
let l:in_docstring = 1
|
||||
endif
|
||||
else
|
||||
if match(l:line, '\v^ *.*("""|'''''')') >= 0
|
||||
let l:in_docstring = 0
|
||||
endif
|
||||
endif
|
||||
|
||||
if !l:last_line_is_blank
|
||||
\&& !l:in_docstring
|
||||
\&& l:indent_size <= l:last_indent_size
|
||||
\&& match(l:line, '\v^ *(return|if|for|while|break|continue)(\(| |$)') >= 0
|
||||
call add(l:new_lines, '')
|
||||
endif
|
||||
|
||||
call add(l:new_lines, l:line)
|
||||
let l:last_indent_size = l:indent_size
|
||||
let l:last_line_is_blank = empty(split(l:line))
|
||||
endfor
|
||||
|
||||
return l:new_lines
|
||||
endfunction
|
||||
|
||||
" This function breaks up long lines so that autopep8 or other tools can
|
||||
" fix the badly-indented code which is produced as a result.
|
||||
function! ale#fixers#generic_python#BreakUpLongLines(buffer, lines) abort
|
||||
" Default to a maximum line length of 79
|
||||
let l:max_line_length = 79
|
||||
let l:conf = ale#path#FindNearestFile(a:buffer, 'setup.cfg')
|
||||
|
||||
" Read the maximum line length from setup.cfg
|
||||
if !empty(l:conf)
|
||||
for l:match in ale#util#GetMatches(
|
||||
\ readfile(l:conf),
|
||||
\ '\v^ *max-line-length *\= *(\d+)',
|
||||
\)
|
||||
let l:max_line_length = str2nr(l:match[1])
|
||||
endfor
|
||||
endif
|
||||
|
||||
let l:new_list = []
|
||||
|
||||
for l:line in a:lines
|
||||
if len(l:line) > l:max_line_length && l:line !~# '# *noqa'
|
||||
let l:line = substitute(l:line, '\v([(,])([^)])', '\1\n\2', 'g')
|
||||
let l:line = substitute(l:line, '\v([^(])([)])', '\1,\n\2', 'g')
|
||||
|
||||
for l:split_line in split(l:line, "\n")
|
||||
call add(l:new_list, l:split_line)
|
||||
endfor
|
||||
else
|
||||
call add(l:new_list, l:line)
|
||||
endif
|
||||
endfor
|
||||
|
||||
return l:new_list
|
||||
endfunction
|
19
vim/.vim/autoload/ale/fixers/gleam_format.vim
Normal file
19
vim/.vim/autoload/ale/fixers/gleam_format.vim
Normal file
@ -0,0 +1,19 @@
|
||||
" Author: Jonathan Palardt https://github.com/jpalardy
|
||||
" Description: Integration of 'gleam format' with ALE.
|
||||
|
||||
call ale#Set('gleam_format_executable', 'gleam')
|
||||
|
||||
function! ale#fixers#gleam_format#GetExecutable(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'gleam_format_executable')
|
||||
|
||||
return ale#Escape(l:executable)
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#gleam_format#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#gleam_format#GetExecutable(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': l:executable . ' format %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
17
vim/.vim/autoload/ale/fixers/gnatpp.vim
Normal file
17
vim/.vim/autoload/ale/fixers/gnatpp.vim
Normal file
@ -0,0 +1,17 @@
|
||||
" Author: tim <tim@inept.tech>
|
||||
" Description: Fix files with gnatpp.
|
||||
|
||||
call ale#Set('ada_gnatpp_executable', 'gnatpp')
|
||||
call ale#Set('ada_gnatpp_options', '')
|
||||
|
||||
function! ale#fixers#gnatpp#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ada_gnatpp_executable')
|
||||
let l:options = ale#Var(a:buffer, 'ada_gnatpp_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
16
vim/.vim/autoload/ale/fixers/gofmt.vim
Normal file
16
vim/.vim/autoload/ale/fixers/gofmt.vim
Normal file
@ -0,0 +1,16 @@
|
||||
" Author: aliou <code@aliou.me>
|
||||
" Description: Integration of gofmt with ALE.
|
||||
|
||||
call ale#Set('go_gofmt_executable', 'gofmt')
|
||||
call ale#Set('go_gofmt_options', '')
|
||||
|
||||
function! ale#fixers#gofmt#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'go_gofmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'go_gofmt_options')
|
||||
let l:env = ale#go#EnvString(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': l:env . ale#Escape(l:executable)
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\}
|
||||
endfunction
|
17
vim/.vim/autoload/ale/fixers/gofumpt.vim
Normal file
17
vim/.vim/autoload/ale/fixers/gofumpt.vim
Normal file
@ -0,0 +1,17 @@
|
||||
" Author: David Houston <houstdav000>
|
||||
" Description: A stricter gofmt implementation.
|
||||
|
||||
call ale#Set('go_gofumpt_executable', 'gofumpt')
|
||||
call ale#Set('go_gofumpt_options', '')
|
||||
|
||||
function! ale#fixers#gofumpt#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'go_gofumpt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'go_gofumpt_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ale#Pad(l:options)
|
||||
\ . ' -w -- %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
23
vim/.vim/autoload/ale/fixers/goimports.vim
Normal file
23
vim/.vim/autoload/ale/fixers/goimports.vim
Normal file
@ -0,0 +1,23 @@
|
||||
" Author: Jeff Willette <jrwillette88@gmail.com>
|
||||
" Description: Integration of goimports with ALE.
|
||||
|
||||
call ale#Set('go_goimports_executable', 'goimports')
|
||||
call ale#Set('go_goimports_options', '')
|
||||
|
||||
function! ale#fixers#goimports#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'go_goimports_executable')
|
||||
let l:options = ale#Var(a:buffer, 'go_goimports_options')
|
||||
let l:env = ale#go#EnvString(a:buffer)
|
||||
|
||||
if !executable(l:executable)
|
||||
return 0
|
||||
endif
|
||||
|
||||
return {
|
||||
\ 'command': l:env . ale#Escape(l:executable)
|
||||
\ . ' -l -w -srcdir %s'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
21
vim/.vim/autoload/ale/fixers/golines.vim
Normal file
21
vim/.vim/autoload/ale/fixers/golines.vim
Normal file
@ -0,0 +1,21 @@
|
||||
" Author Pig Frown <pigfrown@protonmail.com>
|
||||
" Description: Fix Go files long lines with golines"
|
||||
|
||||
call ale#Set('go_golines_executable', 'golines')
|
||||
|
||||
call ale#Set('go_golines_options', '')
|
||||
|
||||
function! ale#fixers#golines#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'go_golines_executable')
|
||||
let l:options = ale#Var(a:buffer, 'go_golines_options')
|
||||
let l:env = ale#go#EnvString(a:buffer)
|
||||
|
||||
if !executable(l:executable)
|
||||
return 0
|
||||
endif
|
||||
|
||||
return {
|
||||
\ 'command': l:env . ale#Escape(l:executable)
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\}
|
||||
endfunction
|
11
vim/.vim/autoload/ale/fixers/gomod.vim
Normal file
11
vim/.vim/autoload/ale/fixers/gomod.vim
Normal file
@ -0,0 +1,11 @@
|
||||
call ale#Set('go_go_executable', 'go')
|
||||
|
||||
function! ale#fixers#gomod#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'go_go_executable')
|
||||
let l:env = ale#go#EnvString(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': l:env . ale#Escape(l:executable) . ' mod edit -fmt %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
23
vim/.vim/autoload/ale/fixers/google_java_format.vim
Normal file
23
vim/.vim/autoload/ale/fixers/google_java_format.vim
Normal file
@ -0,0 +1,23 @@
|
||||
" Author: butlerx <butlerx@notthe,cloud>
|
||||
" Description: Integration of Google-java-format with ALE.
|
||||
|
||||
call ale#Set('java_google_java_format_executable', 'google-java-format')
|
||||
call ale#Set('java_google_java_format_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('java_google_java_format_options', '')
|
||||
|
||||
function! ale#fixers#google_java_format#Fix(buffer) abort
|
||||
let l:options = ale#Var(a:buffer, 'java_google_java_format_options')
|
||||
let l:executable = ale#Var(a:buffer, 'java_google_java_format_executable')
|
||||
|
||||
if !executable(l:executable)
|
||||
return 0
|
||||
endif
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' ' . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' --replace'
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
23
vim/.vim/autoload/ale/fixers/gopls.vim
Normal file
23
vim/.vim/autoload/ale/fixers/gopls.vim
Normal file
@ -0,0 +1,23 @@
|
||||
" Author: Sean Enck <enckse@voidedtech.com>
|
||||
" Description: Integration of gopls format with ALE.
|
||||
|
||||
call ale#Set('go_gopls_fix_executable', 'gopls')
|
||||
call ale#Set('go_gopls_fix_options', '')
|
||||
|
||||
function! ale#fixers#gopls#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'go_gopls_fix_executable')
|
||||
let l:options = ale#Var(a:buffer, 'go_gopls_fix_options')
|
||||
let l:env = ale#go#EnvString(a:buffer)
|
||||
|
||||
if !executable(l:executable)
|
||||
return 0
|
||||
endif
|
||||
|
||||
return {
|
||||
\ 'command': l:env . ale#Escape(l:executable)
|
||||
\ . ' format'
|
||||
\ . ale#Pad(l:options)
|
||||
\ . ' -l -w %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
18
vim/.vim/autoload/ale/fixers/hackfmt.vim
Normal file
18
vim/.vim/autoload/ale/fixers/hackfmt.vim
Normal file
@ -0,0 +1,18 @@
|
||||
" Author: Sam Howie <samhowie@gmail.com>
|
||||
" Description: Integration of hackfmt with ALE.
|
||||
|
||||
call ale#Set('hack_hackfmt_executable', 'hackfmt')
|
||||
call ale#Set('hack_hackfmt_options', '')
|
||||
|
||||
function! ale#fixers#hackfmt#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'hack_hackfmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'hack_hackfmt_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' -i'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
24
vim/.vim/autoload/ale/fixers/help.vim
Normal file
24
vim/.vim/autoload/ale/fixers/help.vim
Normal file
@ -0,0 +1,24 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Generic fixer functions for Vim help documents.
|
||||
|
||||
function! ale#fixers#help#AlignTags(buffer, lines) abort
|
||||
let l:new_lines = []
|
||||
|
||||
for l:line in a:lines
|
||||
if len(l:line) != 79
|
||||
let l:match = matchlist(l:line, '\v +(\*[^*]+\*)$')
|
||||
|
||||
if !empty(l:match)
|
||||
let l:start = l:line[:-len(l:match[0]) - 1]
|
||||
let l:tag = l:match[1]
|
||||
let l:spaces = repeat(' ', 79 - len(l:start) - len(l:tag))
|
||||
|
||||
let l:line = l:start . l:spaces . l:tag
|
||||
endif
|
||||
endif
|
||||
|
||||
call add(l:new_lines, l:line)
|
||||
endfor
|
||||
|
||||
return l:new_lines
|
||||
endfunction
|
16
vim/.vim/autoload/ale/fixers/hfmt.vim
Normal file
16
vim/.vim/autoload/ale/fixers/hfmt.vim
Normal file
@ -0,0 +1,16 @@
|
||||
" Author: zack <zack@kourouma.me>
|
||||
" Description: Integration of hfmt with ALE.
|
||||
|
||||
call ale#Set('haskell_hfmt_executable', 'hfmt')
|
||||
|
||||
function! ale#fixers#hfmt#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'haskell_hfmt_executable')
|
||||
|
||||
return {
|
||||
\ 'command': ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'hfmt')
|
||||
\ . ' -w'
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
||||
|
20
vim/.vim/autoload/ale/fixers/hindent.vim
Normal file
20
vim/.vim/autoload/ale/fixers/hindent.vim
Normal file
@ -0,0 +1,20 @@
|
||||
" Author: AlexeiDrake <drake.alexei@gmail.com>
|
||||
" Description: Integration of hindent formatting with ALE.
|
||||
"
|
||||
call ale#Set('haskell_hindent_executable', 'hindent')
|
||||
|
||||
function! ale#fixers#hindent#GetExecutable(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'haskell_hindent_executable')
|
||||
|
||||
return ale#handlers#haskell_stack#EscapeExecutable(l:executable, 'hindent')
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#hindent#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#hindent#GetExecutable(a:buffer)
|
||||
|
||||
return {
|
||||
\ 'command': l:executable
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
13
vim/.vim/autoload/ale/fixers/hlint.vim
Normal file
13
vim/.vim/autoload/ale/fixers/hlint.vim
Normal file
@ -0,0 +1,13 @@
|
||||
" Author: eborden <evan@evan-borden.com>
|
||||
" Description: Integration of hlint refactor with ALE.
|
||||
"
|
||||
|
||||
function! ale#fixers#hlint#Fix(buffer) abort
|
||||
return {
|
||||
\ 'command': ale#handlers#hlint#GetExecutable(a:buffer)
|
||||
\ . ' --refactor'
|
||||
\ . ' --refactor-options="--inplace"'
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
20
vim/.vim/autoload/ale/fixers/html_beautify.vim
Normal file
20
vim/.vim/autoload/ale/fixers/html_beautify.vim
Normal file
@ -0,0 +1,20 @@
|
||||
" Author: WhyNotHugo <hugo@barrera.io>
|
||||
" Description: Format 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', '')
|
||||
|
||||
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
|
13
vim/.vim/autoload/ale/fixers/htmlbeautifier.vim
Normal file
13
vim/.vim/autoload/ale/fixers/htmlbeautifier.vim
Normal file
@ -0,0 +1,13 @@
|
||||
" Author: Arash Mousavi <arash-m>
|
||||
" Description: Support for HTML Beautifier https://github.com/threedaymonk/htmlbeautifier
|
||||
|
||||
call ale#Set('eruby_htmlbeautifier_executable', 'htmlbeautifier')
|
||||
|
||||
function! ale#fixers#htmlbeautifier#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'eruby_htmlbeautifier_executable')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
15
vim/.vim/autoload/ale/fixers/hurlfmt.vim
Normal file
15
vim/.vim/autoload/ale/fixers/hurlfmt.vim
Normal file
@ -0,0 +1,15 @@
|
||||
call ale#Set('hurl_hurlfmt_executable', 'hurlfmt')
|
||||
|
||||
function! ale#fixers#hurlfmt#GetCommand(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'hurl_hurlfmt_executable')
|
||||
|
||||
return ale#Escape(l:executable)
|
||||
\ . ' --out hurl'
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#hurlfmt#Fix(buffer) abort
|
||||
return {
|
||||
\ 'command': ale#fixers#hurlfmt#GetCommand(a:buffer)
|
||||
\}
|
||||
endfunction
|
||||
|
25
vim/.vim/autoload/ale/fixers/importjs.vim
Normal file
25
vim/.vim/autoload/ale/fixers/importjs.vim
Normal file
@ -0,0 +1,25 @@
|
||||
" Author: Jeff Willette <jrwillette88@gmail.com>
|
||||
" Description: Integration of importjs with ALE.
|
||||
|
||||
call ale#Set('javascript_importjs_executable', 'importjs')
|
||||
|
||||
function! ale#fixers#importjs#ProcessOutput(buffer, output) abort
|
||||
let l:result = ale#util#FuzzyJSONDecode(a:output, [])
|
||||
|
||||
return split(get(l:result, 'fileContent', ''), "\n")
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#importjs#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'javascript_importjs_executable')
|
||||
|
||||
if !executable(l:executable)
|
||||
return 0
|
||||
endif
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' fix'
|
||||
\ . ' %s',
|
||||
\ 'process_with': 'ale#fixers#importjs#ProcessOutput',
|
||||
\}
|
||||
endfunction
|
77
vim/.vim/autoload/ale/fixers/isort.vim
Normal file
77
vim/.vim/autoload/ale/fixers/isort.vim
Normal file
@ -0,0 +1,77 @@
|
||||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Fixing Python imports with isort.
|
||||
|
||||
call ale#Set('python_isort_executable', 'isort')
|
||||
call ale#Set('python_isort_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('python_isort_options', '')
|
||||
call ale#Set('python_isort_auto_pipenv', 0)
|
||||
call ale#Set('python_isort_auto_poetry', 0)
|
||||
call ale#Set('python_isort_auto_uv', 0)
|
||||
|
||||
function! ale#fixers#isort#GetExecutable(buffer) abort
|
||||
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_isort_auto_pipenv'))
|
||||
\ && ale#python#PipenvPresent(a:buffer)
|
||||
return 'pipenv'
|
||||
endif
|
||||
|
||||
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_isort_auto_poetry'))
|
||||
\ && ale#python#PoetryPresent(a:buffer)
|
||||
return 'poetry'
|
||||
endif
|
||||
|
||||
if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_isort_auto_uv'))
|
||||
\ && ale#python#UvPresent(a:buffer)
|
||||
return 'uv'
|
||||
endif
|
||||
|
||||
return ale#python#FindExecutable(a:buffer, 'python_isort', ['isort'])
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#isort#GetCmd(buffer) abort
|
||||
let l:executable = ale#fixers#isort#GetExecutable(a:buffer)
|
||||
let l:cmd = [ale#Escape(l:executable)]
|
||||
|
||||
if l:executable =~? 'pipenv\|poetry\|uv$'
|
||||
call extend(l:cmd, ['run', 'isort'])
|
||||
endif
|
||||
|
||||
return join(l:cmd, ' ')
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#isort#FixForVersion(buffer, version) abort
|
||||
let l:executable = ale#fixers#isort#GetExecutable(a:buffer)
|
||||
let l:cmd = [ale#Escape(l:executable)]
|
||||
|
||||
if l:executable =~? 'pipenv\|poetry\|uv$'
|
||||
call extend(l:cmd, ['run', 'isort'])
|
||||
endif
|
||||
|
||||
if ale#semver#GTE(a:version, [5, 7, 0])
|
||||
call add(l:cmd, '--filename %s')
|
||||
endif
|
||||
|
||||
let l:options = ale#Var(a:buffer, 'python_isort_options')
|
||||
|
||||
if !empty(l:options)
|
||||
call add(l:cmd, l:options)
|
||||
endif
|
||||
|
||||
call add(l:cmd, '-')
|
||||
|
||||
return {
|
||||
\ 'cwd': '%s:h',
|
||||
\ 'command': join(l:cmd, ' '),
|
||||
\}
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#isort#Fix(buffer) abort
|
||||
let l:executable = ale#fixers#isort#GetExecutable(a:buffer)
|
||||
let l:command = ale#fixers#isort#GetCmd(a:buffer) . ale#Pad('--version')
|
||||
|
||||
return ale#semver#RunWithVersionCheck(
|
||||
\ a:buffer,
|
||||
\ l:executable,
|
||||
\ l:command,
|
||||
\ function('ale#fixers#isort#FixForVersion'),
|
||||
\)
|
||||
endfunction
|
22
vim/.vim/autoload/ale/fixers/jq.vim
Normal file
22
vim/.vim/autoload/ale/fixers/jq.vim
Normal file
@ -0,0 +1,22 @@
|
||||
call ale#Set('json_jq_executable', 'jq')
|
||||
call ale#Set('json_jq_options', '')
|
||||
call ale#Set('json_jq_filters', '.')
|
||||
|
||||
function! ale#fixers#jq#GetExecutable(buffer) abort
|
||||
return ale#Var(a:buffer, 'json_jq_executable')
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#jq#Fix(buffer) abort
|
||||
let l:options = ale#Var(a:buffer, 'json_jq_options')
|
||||
let l:filters = ale#Var(a:buffer, 'json_jq_filters')
|
||||
|
||||
if empty(l:filters)
|
||||
return 0
|
||||
endif
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(ale#fixers#jq#GetExecutable(a:buffer))
|
||||
\ . ' ' . l:filters . ' '
|
||||
\ . l:options,
|
||||
\}
|
||||
endfunction
|
18
vim/.vim/autoload/ale/fixers/jsonnetfmt.vim
Normal file
18
vim/.vim/autoload/ale/fixers/jsonnetfmt.vim
Normal file
@ -0,0 +1,18 @@
|
||||
" Authors: Trevor Whitney <trevorjwhitney@gmail.com> and Takuya Kosugiyama <re@itkq.jp>
|
||||
" Description: Integration of jsonnetfmt with ALE.
|
||||
|
||||
call ale#Set('jsonnet_jsonnetfmt_executable', 'jsonnetfmt')
|
||||
call ale#Set('jsonnet_jsonnetfmt_options', '')
|
||||
|
||||
function! ale#fixers#jsonnetfmt#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'jsonnet_jsonnetfmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'jsonnet_jsonnetfmt_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' -i'
|
||||
\ . ale#Pad(l:options)
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
8
vim/.vim/autoload/ale/fixers/ktlint.vim
Normal file
8
vim/.vim/autoload/ale/fixers/ktlint.vim
Normal file
@ -0,0 +1,8 @@
|
||||
" Author: Michael Phillips <michaeljoelphillips@gmail.com>
|
||||
" Description: Fix Kotlin files with ktlint.
|
||||
|
||||
function! ale#fixers#ktlint#Fix(buffer) abort
|
||||
return {
|
||||
\ 'command': ale#handlers#ktlint#GetCommand(a:buffer) . ' --format'
|
||||
\}
|
||||
endfunction
|
16
vim/.vim/autoload/ale/fixers/latexindent.vim
Normal file
16
vim/.vim/autoload/ale/fixers/latexindent.vim
Normal file
@ -0,0 +1,16 @@
|
||||
" Author: riley-martine <riley.martine@protonmail.com>
|
||||
" Description: Integration of latexindent with ALE.
|
||||
|
||||
call ale#Set('tex_latexindent_executable', 'latexindent')
|
||||
call ale#Set('tex_latexindent_options', '')
|
||||
|
||||
function! ale#fixers#latexindent#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'tex_latexindent_executable')
|
||||
let l:options = ale#Var(a:buffer, 'tex_latexindent_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' -l'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\}
|
||||
endfunction
|
16
vim/.vim/autoload/ale/fixers/lua_format.vim
Normal file
16
vim/.vim/autoload/ale/fixers/lua_format.vim
Normal file
@ -0,0 +1,16 @@
|
||||
" Author: Mathias Jean Johansen <mathias@mjj.io>
|
||||
" Description: Integration of LuaFormatter with ALE.
|
||||
|
||||
call ale#Set('lua_lua_format_executable', 'lua-format')
|
||||
call ale#Set('lua_lua_format_options', '')
|
||||
|
||||
function! ale#fixers#lua_format#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'lua_lua_format_executable')
|
||||
let l:options = ale#Var(a:buffer, 'lua_lua_format_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ale#Pad(l:options)
|
||||
\ . ' -i',
|
||||
\}
|
||||
endfunction
|
13
vim/.vim/autoload/ale/fixers/luafmt.vim
Normal file
13
vim/.vim/autoload/ale/fixers/luafmt.vim
Normal file
@ -0,0 +1,13 @@
|
||||
call ale#Set('lua_luafmt_executable', 'luafmt')
|
||||
call ale#Set('lua_luafmt_options', '')
|
||||
|
||||
function! ale#fixers#luafmt#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'lua_luafmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'lua_luafmt_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' --stdin',
|
||||
\}
|
||||
endfunction
|
25
vim/.vim/autoload/ale/fixers/mix_format.vim
Normal file
25
vim/.vim/autoload/ale/fixers/mix_format.vim
Normal file
@ -0,0 +1,25 @@
|
||||
" Author: carakan <carakan@gmail.com>, Fernando Mendes <fernando@mendes.codes>
|
||||
" Description: Fixing files with elixir formatter 'mix format'.
|
||||
|
||||
call ale#Set('elixir_mix_executable', 'mix')
|
||||
call ale#Set('elixir_mix_format_options', '')
|
||||
|
||||
function! ale#fixers#mix_format#GetExecutable(buffer) abort
|
||||
return ale#Var(a:buffer, 'elixir_mix_executable')
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#mix_format#GetCommand(buffer) abort
|
||||
let l:executable = ale#Escape(ale#fixers#mix_format#GetExecutable(a:buffer))
|
||||
let l:options = ale#Var(a:buffer, 'elixir_mix_format_options')
|
||||
|
||||
return l:executable . ' format'
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' %t'
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#mix_format#Fix(buffer) abort
|
||||
return {
|
||||
\ 'command': ale#fixers#mix_format#GetCommand(a:buffer),
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
16
vim/.vim/autoload/ale/fixers/nickel_format.vim
Normal file
16
vim/.vim/autoload/ale/fixers/nickel_format.vim
Normal file
@ -0,0 +1,16 @@
|
||||
" Author: Yining <zhang.yining@gmail.com>
|
||||
" Description: nickel format as ALE fixer for Nickel files
|
||||
|
||||
call ale#Set('nickel_nickel_format_executable', 'nickel')
|
||||
call ale#Set('nickel_nickel_format_options', '')
|
||||
|
||||
function! ale#fixers#nickel_format#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'nickel_nickel_format_executable')
|
||||
let l:options = ale#Var(a:buffer, 'nickel_nickel_format_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . ' format'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\}
|
||||
endfunction
|
||||
|
15
vim/.vim/autoload/ale/fixers/nimpretty.vim
Normal file
15
vim/.vim/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
|
15
vim/.vim/autoload/ale/fixers/nixfmt.vim
Normal file
15
vim/.vim/autoload/ale/fixers/nixfmt.vim
Normal file
@ -0,0 +1,15 @@
|
||||
scriptencoding utf-8
|
||||
" Author: houstdav000 <houstdav000@gh0st.sh>
|
||||
" Description: Fix files with nixfmt
|
||||
|
||||
call ale#Set('nix_nixfmt_executable', 'nixfmt')
|
||||
call ale#Set('nix_nixfmt_options', '')
|
||||
|
||||
function! ale#fixers#nixfmt#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'nix_nixfmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'nix_nixfmt_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable) . ale#Pad(l:options),
|
||||
\}
|
||||
endfunction
|
12
vim/.vim/autoload/ale/fixers/nixpkgsfmt.vim
Normal file
12
vim/.vim/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
|
16
vim/.vim/autoload/ale/fixers/npmgroovylint.vim
Normal file
16
vim/.vim/autoload/ale/fixers/npmgroovylint.vim
Normal file
@ -0,0 +1,16 @@
|
||||
" Author: lucas-str <lucas.sturelle@ik.me>
|
||||
" Description: Integration of npm-groovy-lint for Groovy files.
|
||||
|
||||
call ale#Set('groovy_npmgroovylint_fix_options', '--fix')
|
||||
|
||||
function! ale#fixers#npmgroovylint#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'groovy_npmgroovylint_executable')
|
||||
let l:options = ale#Var(a:buffer, 'groovy_npmgroovylint_fix_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' %t',
|
||||
\ 'read_temporary_file': 1,
|
||||
\}
|
||||
endfunction
|
17
vim/.vim/autoload/ale/fixers/ocamlformat.vim
Normal file
17
vim/.vim/autoload/ale/fixers/ocamlformat.vim
Normal file
@ -0,0 +1,17 @@
|
||||
" Author: Stephen Lumenta <@sbl>
|
||||
" Description: Integration of ocamlformat with ALE.
|
||||
|
||||
call ale#Set('ocaml_ocamlformat_executable', 'ocamlformat')
|
||||
call ale#Set('ocaml_ocamlformat_options', '')
|
||||
|
||||
function! ale#fixers#ocamlformat#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ocaml_ocamlformat_executable')
|
||||
let l:options = ale#Var(a:buffer, 'ocaml_ocamlformat_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' --name=%s'
|
||||
\ . ' -'
|
||||
\}
|
||||
endfunction
|
18
vim/.vim/autoload/ale/fixers/ocp_indent.vim
Normal file
18
vim/.vim/autoload/ale/fixers/ocp_indent.vim
Normal file
@ -0,0 +1,18 @@
|
||||
" Author: Kanenobu Mitsuru
|
||||
" Description: Integration of ocp-indent with ALE.
|
||||
|
||||
call ale#Set('ocaml_ocp_indent_executable', 'ocp-indent')
|
||||
call ale#Set('ocaml_ocp_indent_options', '')
|
||||
call ale#Set('ocaml_ocp_indent_config', '')
|
||||
|
||||
function! ale#fixers#ocp_indent#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'ocaml_ocp_indent_executable')
|
||||
let l:config = ale#Var(a:buffer, 'ocaml_ocp_indent_config')
|
||||
let l:options = ale#Var(a:buffer, 'ocaml_ocp_indent_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (empty(l:config) ? '' : ' --config=' . ale#Escape(l:config))
|
||||
\ . (empty(l:options) ? '': ' ' . l:options)
|
||||
\}
|
||||
endfunction
|
15
vim/.vim/autoload/ale/fixers/opafmt.vim
Normal file
15
vim/.vim/autoload/ale/fixers/opafmt.vim
Normal file
@ -0,0 +1,15 @@
|
||||
" Description: Fixer for rego files
|
||||
|
||||
call ale#Set('opa_fmt_executable', 'opa')
|
||||
call ale#Set('opa_fmt_options', '')
|
||||
|
||||
function! ale#fixers#opafmt#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'opa_fmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'opa_fmt_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' fmt'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\}
|
||||
endfunction
|
12
vim/.vim/autoload/ale/fixers/ormolu.vim
Normal file
12
vim/.vim/autoload/ale/fixers/ormolu.vim
Normal file
@ -0,0 +1,12 @@
|
||||
call ale#Set('haskell_ormolu_executable', 'ormolu')
|
||||
call ale#Set('haskell_ormolu_options', '')
|
||||
|
||||
function! ale#fixers#ormolu#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'haskell_ormolu_executable')
|
||||
let l:options = ale#Var(a:buffer, 'haskell_ormolu_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options),
|
||||
\}
|
||||
endfunction
|
17
vim/.vim/autoload/ale/fixers/packer.vim
Normal file
17
vim/.vim/autoload/ale/fixers/packer.vim
Normal file
@ -0,0 +1,17 @@
|
||||
" Author: Zhuoyun Wei <wzyboy@wzyboy.org>
|
||||
" Description: Fixer for Packer HCL files
|
||||
|
||||
call ale#Set('packer_fmt_executable', 'packer')
|
||||
call ale#Set('packer_fmt_options', '')
|
||||
|
||||
function! ale#fixers#packer#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'packer_fmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'packer_fmt_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' fmt'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' -'
|
||||
\}
|
||||
endfunction
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user