1
0
Fork 0
mirror of synced 2024-11-22 08:45:34 -05:00

Updated plugins

This commit is contained in:
Amir Salihefendic 2019-11-16 16:28:42 +01:00
parent 96e10ed101
commit 72bdaba47e
204 changed files with 5936 additions and 1666 deletions

View file

@ -3,9 +3,14 @@
call ale#Set('c_clangd_executable', 'clangd') call ale#Set('c_clangd_executable', 'clangd')
call ale#Set('c_clangd_options', '') call ale#Set('c_clangd_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#c#clangd#GetCommand(buffer) abort function! ale_linters#c#clangd#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'c_clangd_options')) let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
return '%e'
\ . ale#Pad(ale#Var(a:buffer, 'c_clangd_options'))
\ . (!empty(l:build_dir) ? ' -compile-commands-dir=' . ale#Escape(l:build_dir) : '')
endfunction endfunction
call ale#linter#Define('c', { call ale#linter#Define('c', {

View file

@ -19,14 +19,17 @@ call ale#Set('c_clangtidy_options', '')
call ale#Set('c_clangtidy_extra_options', '') call ale#Set('c_clangtidy_extra_options', '')
call ale#Set('c_build_dir', '') call ale#Set('c_build_dir', '')
function! ale_linters#c#clangtidy#GetCommand(buffer) abort function! ale_linters#c#clangtidy#GetCommand(buffer, output) abort
let l:checks = join(ale#Var(a:buffer, 'c_clangtidy_checks'), ',') let l:checks = join(ale#Var(a:buffer, 'c_clangtidy_checks'), ',')
let l:build_dir = ale#c#GetBuildDirectory(a:buffer) let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
let l:options = ''
" Get the extra options if we couldn't find a build directory. " Get the extra options if we couldn't find a build directory.
let l:options = empty(l:build_dir) if empty(l:build_dir)
\ ? ale#Var(a:buffer, 'c_clangtidy_options') let l:options = ale#Var(a:buffer, 'c_clangtidy_options')
\ : '' let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags
endif
" Get the options to pass directly to clang-tidy " Get the options to pass directly to clang-tidy
let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options') let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options')
@ -43,7 +46,7 @@ call ale#linter#Define('c', {
\ 'name': 'clangtidy', \ 'name': 'clangtidy',
\ 'output_stream': 'stdout', \ 'output_stream': 'stdout',
\ 'executable': {b -> ale#Var(b, 'c_clangtidy_executable')}, \ 'executable': {b -> ale#Var(b, 'c_clangtidy_executable')},
\ 'command': function('ale_linters#c#clangtidy#GetCommand'), \ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#c#clangtidy#GetCommand'))},
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat', \ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'lint_file': 1, \ 'lint_file': 1,
\}) \})

View file

@ -20,7 +20,7 @@ function! ale_linters#cpp#clangcheck#GetCommand(buffer) abort
" being generated. These are only added if no build directory can be " being generated. These are only added if no build directory can be
" detected. " detected.
return '%e -analyze %s' return '%e -analyze %s'
\ . (empty(l:build_dir) ? ' -extra-arg -Xclang -extra-arg -analyzer-output=text' : '') \ . (empty(l:build_dir) ? ' --extra-arg=-Xclang --extra-arg=-analyzer-output=text --extra-arg=-fno-color-diagnostics': '')
\ . ale#Pad(l:user_options) \ . ale#Pad(l:user_options)
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '') \ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
endfunction endfunction

View file

@ -3,9 +3,14 @@
call ale#Set('cpp_clangd_executable', 'clangd') call ale#Set('cpp_clangd_executable', 'clangd')
call ale#Set('cpp_clangd_options', '') call ale#Set('cpp_clangd_options', '')
call ale#Set('c_build_dir', '')
function! ale_linters#cpp#clangd#GetCommand(buffer) abort function! ale_linters#cpp#clangd#GetCommand(buffer) abort
return '%e' . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options')) let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
return '%e'
\ . ale#Pad(ale#Var(a:buffer, 'cpp_clangd_options'))
\ . (!empty(l:build_dir) ? ' -compile-commands-dir=' . ale#Escape(l:build_dir) : '')
endfunction endfunction
call ale#linter#Define('cpp', { call ale#linter#Define('cpp', {

View file

@ -13,14 +13,17 @@ call ale#Set('cpp_clangtidy_options', '')
call ale#Set('cpp_clangtidy_extra_options', '') call ale#Set('cpp_clangtidy_extra_options', '')
call ale#Set('c_build_dir', '') call ale#Set('c_build_dir', '')
function! ale_linters#cpp#clangtidy#GetCommand(buffer) abort function! ale_linters#cpp#clangtidy#GetCommand(buffer, output) abort
let l:checks = join(ale#Var(a:buffer, 'cpp_clangtidy_checks'), ',') let l:checks = join(ale#Var(a:buffer, 'cpp_clangtidy_checks'), ',')
let l:build_dir = ale#c#GetBuildDirectory(a:buffer) let l:build_dir = ale#c#GetBuildDirectory(a:buffer)
let l:options = ''
" Get the extra options if we couldn't find a build directory. " Get the extra options if we couldn't find a build directory.
let l:options = empty(l:build_dir) if empty(l:build_dir)
\ ? ale#Var(a:buffer, 'cpp_clangtidy_options') let l:options = ale#Var(a:buffer, 'cpp_clangtidy_options')
\ : '' let l:cflags = ale#c#GetCFlags(a:buffer, a:output)
let l:options .= !empty(l:options) ? ale#Pad(l:cflags) : l:cflags
endif
" Get the options to pass directly to clang-tidy " Get the options to pass directly to clang-tidy
let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options') let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options')
@ -37,7 +40,7 @@ call ale#linter#Define('cpp', {
\ 'name': 'clangtidy', \ 'name': 'clangtidy',
\ 'output_stream': 'stdout', \ 'output_stream': 'stdout',
\ 'executable': {b -> ale#Var(b, 'cpp_clangtidy_executable')}, \ 'executable': {b -> ale#Var(b, 'cpp_clangtidy_executable')},
\ 'command': function('ale_linters#cpp#clangtidy#GetCommand'), \ 'command': {b -> ale#c#RunMakeCommand(b, function('ale_linters#cpp#clangtidy#GetCommand'))},
\ 'callback': 'ale#handlers#gcc#HandleGCCFormat', \ 'callback': 'ale#handlers#gcc#HandleGCCFormat',
\ 'lint_file': 1, \ 'lint_file': 1,
\}) \})

View file

@ -5,6 +5,10 @@ function! ale_linters#crystal#crystal#Handle(buffer, lines) abort
let l:output = [] let l:output = []
for l:error in ale#util#FuzzyJSONDecode(a:lines, []) for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
if !has_key(l:error, 'file')
continue
endif
call add(l:output, { call add(l:output, {
\ 'lnum': l:error.line + 0, \ 'lnum': l:error.line + 0,
\ 'col': l:error.column + 0, \ 'col': l:error.column + 0,

View file

@ -3,9 +3,12 @@
call ale#Set('elm_ls_executable', 'elm-language-server') call ale#Set('elm_ls_executable', 'elm-language-server')
call ale#Set('elm_ls_use_global', get(g:, 'ale_use_global_executables', 1)) call ale#Set('elm_ls_use_global', get(g:, 'ale_use_global_executables', 1))
call ale#Set('elm_ls_elm_path', 'elm')
call ale#Set('elm_ls_elm_format_path', 'elm-format') " elm-language-server will search for local and global binaries, if empty
call ale#Set('elm_ls_elm_test_path', 'elm-test') call ale#Set('elm_ls_elm_path', '')
call ale#Set('elm_ls_elm_format_path', '')
call ale#Set('elm_ls_elm_test_path', '')
call ale#Set('elm_ls_elm_analyse_trigger', 'change')
function! elm_ls#GetRootDir(buffer) abort function! elm_ls#GetRootDir(buffer) abort
let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json') let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
@ -15,10 +18,10 @@ endfunction
function! elm_ls#GetOptions(buffer) abort function! elm_ls#GetOptions(buffer) abort
return { return {
\ 'runtime': 'node',
\ 'elmPath': ale#Var(a:buffer, 'elm_ls_elm_path'), \ 'elmPath': ale#Var(a:buffer, 'elm_ls_elm_path'),
\ 'elmFormatPath': ale#Var(a:buffer, 'elm_ls_elm_format_path'), \ 'elmFormatPath': ale#Var(a:buffer, 'elm_ls_elm_format_path'),
\ 'elmTestPath': ale#Var(a:buffer, 'elm_ls_elm_test_path'), \ 'elmTestPath': ale#Var(a:buffer, 'elm_ls_elm_test_path'),
\ 'elmAnalyseTrigger': ale#Var(a:buffer, 'elm_ls_elm_analyse_trigger'),
\} \}
endfunction endfunction

View file

@ -15,10 +15,10 @@ endfunction
function! ale_linters#erlang#dialyzer#FindPlt(buffer) abort function! ale_linters#erlang#dialyzer#FindPlt(buffer) abort
let l:plt_file = '' let l:plt_file = ''
let l:rebar3_profile = ale_linters#erlang#dialyzer#GetRebar3Profile(a:buffer) let l:rebar3_profile = ale_linters#erlang#dialyzer#GetRebar3Profile(a:buffer)
let l:plt_file_directory = ale#path#FindNearestDirectory(a:buffer, '_build' . l:rebar3_profile) let l:plt_file_directory = ale#path#FindNearestDirectory(a:buffer, '_build/' . l:rebar3_profile)
if !empty(l:plt_file_directory) if !empty(l:plt_file_directory)
let l:plt_file = split(globpath(l:plt_file_directory, '/*_plt'), '\n') let l:plt_file = globpath(l:plt_file_directory, '*_plt', 0, 1)
endif endif
if !empty(l:plt_file) if !empty(l:plt_file)

View file

@ -8,7 +8,7 @@ call ale#Set('eruby_ruumba_options', '')
function! ale_linters#eruby#ruumba#GetCommand(buffer) abort function! ale_linters#eruby#ruumba#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'eruby_ruumba_executable') let l:executable = ale#Var(a:buffer, 'eruby_ruumba_executable')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'ruumba') return ale#ruby#EscapeExecutable(l:executable, 'ruumba')
\ . ' --format json --force-exclusion ' \ . ' --format json --force-exclusion '
\ . ale#Var(a:buffer, 'eruby_ruumba_options') \ . ale#Var(a:buffer, 'eruby_ruumba_options')
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p')) \ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))

View file

@ -0,0 +1,35 @@
" Author: Andreww Hayworth <ahayworth@gmail.com>
" Description: Integrate ALE with ink-language-server
call ale#Set('ink_ls_executable', 'ink-language-server')
call ale#Set('ink_ls_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('ink_ls_initialization_options', {})
function! ale_linters#ink#ls#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'ink_ls', [
\ 'ink-language-server',
\ 'node_modules/.bin/ink-language-server',
\])
endfunction
function! ale_linters#ink#ls#GetCommand(buffer) abort
let l:executable = ale_linters#ink#ls#GetExecutable(a:buffer)
return ale#Escape(l:executable) . ' --stdio'
endfunction
function! ale_linters#ink#ls#FindProjectRoot(buffer) abort
let l:main_file = get(ale#Var(a:buffer, 'ink_ls_initialization_options'), 'mainStoryPath', 'main.ink')
let l:config = ale#path#ResolveLocalPath(a:buffer, l:main_file, expand('#' . a:buffer . ':p'))
return ale#path#Dirname(l:config)
endfunction
call ale#linter#Define('ink', {
\ 'name': 'ink-language-server',
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#ink#ls#GetExecutable'),
\ 'command': function('ale_linters#ink#ls#GetCommand'),
\ 'project_root': function('ale_linters#ink#ls#FindProjectRoot'),
\ 'initialization_options': {b -> ale#Var(b, 'ink_ls_initialization_options')},
\})

View file

@ -7,7 +7,9 @@ call ale#Set('javascript_standard_options', '')
function! ale_linters#javascript#standard#GetExecutable(buffer) abort function! ale_linters#javascript#standard#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'javascript_standard', [ return ale#node#FindExecutable(a:buffer, 'javascript_standard', [
\ 'node_modules/standardx/bin/cmd.js',
\ 'node_modules/standard/bin/cmd.js', \ 'node_modules/standard/bin/cmd.js',
\ 'node_modules/semistandard/bin/cmd.js',
\ 'node_modules/.bin/standard', \ 'node_modules/.bin/standard',
\]) \])
endfunction endfunction

View file

@ -17,18 +17,17 @@ function! ale_linters#markdown#mdl#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'markdown_mdl_options') let l:options = ale#Var(a:buffer, 'markdown_mdl_options')
return ale#Escape(l:executable) . l:exec_args return ale#Escape(l:executable) . l:exec_args
\ . (!empty(l:options) ? ' ' . l:options : '') \ . ' -j' . (!empty(l:options) ? ' ' . l:options : '')
endfunction endfunction
function! ale_linters#markdown#mdl#Handle(buffer, lines) abort function! ale_linters#markdown#mdl#Handle(buffer, lines) abort
" matches: '(stdin):173: MD004 Unordered list style'
let l:pattern = ':\(\d*\): \(.*\)$'
let l:output = [] let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern) for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
call add(l:output, { call add(l:output, {
\ 'lnum': l:match[1] + 0, \ 'lnum': l:error['line'],
\ 'text': l:match[2], \ 'code': l:error['rule'] . '/' . join(l:error['aliases'], '/'),
\ 'text': l:error['description'],
\ 'type': 'W', \ 'type': 'W',
\}) \})
endfor endfor

View file

@ -1,6 +1,15 @@
" Author: Baabelfish " Author: Baabelfish
" Description: Typechecking for nim files " Description: Typechecking for nim files
let s:end_col_patterns = [
\ '\v''([^'']+)'' is declared but not used.*',
\ '\videntifier expected, but found ''([^'']+)''',
\ '\vimported and not used: ''([^'']+)''.*',
\ '\vundeclared identifier: ''([^'']+)''',
\ '\v''([^'']+)'' cannot be assigned to',
\ '\vredefinition of ''([^'']+)'';',
\]
function! ale_linters#nim#nimcheck#Handle(buffer, lines) abort function! ale_linters#nim#nimcheck#Handle(buffer, lines) abort
let l:buffer_filename = fnamemodify(bufname(a:buffer), ':p:t') let l:buffer_filename = fnamemodify(bufname(a:buffer), ':p:t')
let l:pattern = '^\(.\+\.nim\)(\(\d\+\), \(\d\+\)) \(.\+\)' let l:pattern = '^\(.\+\.nim\)(\(\d\+\), \(\d\+\)) \(.\+\)'
@ -43,6 +52,11 @@ function! ale_linters#nim#nimcheck#Handle(buffer, lines) abort
let l:item.code = l:code_match[2] let l:item.code = l:code_match[2]
endif endif
" Find position end_col.
for l:col_match in ale#util#GetMatches(l:item.text, s:end_col_patterns)
let l:item.end_col = l:item.col + len(l:col_match[1]) - 1
endfor
call add(l:output, l:item) call add(l:output, l:item)
endfor endfor

View file

@ -0,0 +1,33 @@
" Author: jeremija <https://github.com/jeremija>
" Description: Support for nimlsp (language server for nim)
call ale#Set('nim_nimlsp_nim_sources', '')
function! ale_linters#nim#nimlsp#GetProjectRoot(buffer) abort
let l:project_root = ale#path#FindNearestDirectory(a:buffer, '.git')
if !empty(l:project_root)
return fnamemodify(l:project_root, ':h:h')
endif
return ''
endfunction
function! ale_linters#nim#nimlsp#GetCommand(buffer) abort
let l:nim_sources = ale#Var(a:buffer, 'nim_nimlsp_nim_sources')
if !empty(l:nim_sources)
let l:nim_sources = ale#Escape(l:nim_sources)
endif
return '%e' . ale#Pad(l:nim_sources)
endfunction
call ale#linter#Define('nim', {
\ 'name': 'nimlsp',
\ 'lsp': 'stdio',
\ 'executable': 'nimlsp',
\ 'command': function('ale_linters#nim#nimlsp#GetCommand'),
\ 'language': 'nim',
\ 'project_root': function('ale_linters#nim#nimlsp#GetProjectRoot'),
\})

View file

@ -1,7 +1,8 @@
" Author: Matt Brown <https://github.com/muglug> " Author: Matt Brown <https://github.com/muglug>
" Description: plugin for Psalm, static analyzer for PHP " Description: plugin for Psalm, static analyzer for PHP
call ale#Set('psalm_langserver_executable', 'psalm-language-server') call ale#Set('psalm_langserver_executable', 'psalm')
call ale#Set('psalm_langserver_options', '')
call ale#Set('psalm_langserver_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('psalm_langserver_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale_linters#php#psalm#GetProjectRoot(buffer) abort function! ale_linters#php#psalm#GetProjectRoot(buffer) abort
@ -10,12 +11,16 @@ function! ale_linters#php#psalm#GetProjectRoot(buffer) abort
return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : '' return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : ''
endfunction endfunction
function! ale_linters#php#psalm#GetCommand(buffer) abort
return '%e --language-server' . ale#Pad(ale#Var(a:buffer, 'psalm_langserver_options'))
endfunction
call ale#linter#Define('php', { call ale#linter#Define('php', {
\ 'name': 'psalm', \ 'name': 'psalm',
\ 'lsp': 'stdio', \ 'lsp': 'stdio',
\ 'executable': {b -> ale#node#FindExecutable(b, 'psalm_langserver', [ \ 'executable': {b -> ale#node#FindExecutable(b, 'psalm_langserver', [
\ 'vendor/bin/psalm-language-server', \ 'vendor/bin/psalm',
\ ])}, \ ])},
\ 'command': '%e', \ 'command': function('ale_linters#php#psalm#GetCommand'),
\ 'project_root': function('ale_linters#php#psalm#GetProjectRoot'), \ 'project_root': function('ale_linters#php#psalm#GetProjectRoot'),
\}) \})

View file

@ -12,6 +12,7 @@ endfunction
" https://rkeithhill.wordpress.com/2007/10/30/powershell-quicktip-preparsing-scripts-to-check-for-syntax-errors/ " https://rkeithhill.wordpress.com/2007/10/30/powershell-quicktip-preparsing-scripts-to-check-for-syntax-errors/
function! ale_linters#powershell#powershell#GetCommand(buffer) abort function! ale_linters#powershell#powershell#GetCommand(buffer) abort
let l:script = ['Param($Script); let l:script = ['Param($Script);
\ $ErrorView = "Normal";
\ trap {$_;continue} & { \ trap {$_;continue} & {
\ $Contents = Get-Content -Path $Script; \ $Contents = Get-Content -Path $Script;
\ $Contents = [string]::Join([Environment]::NewLine, $Contents); \ $Contents = [string]::Join([Environment]::NewLine, $Contents);

View file

@ -36,7 +36,7 @@ function! ale_linters#ruby#brakeman#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'ruby_brakeman_executable') let l:executable = ale#Var(a:buffer, 'ruby_brakeman_executable')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'brakeman') return ale#ruby#EscapeExecutable(l:executable, 'brakeman')
\ . ' -f json -q ' \ . ' -f json -q '
\ . ale#Var(a:buffer, 'ruby_brakeman_options') \ . ale#Var(a:buffer, 'ruby_brakeman_options')
\ . ' -p ' . ale#Escape(l:rails_root) \ . ' -p ' . ale#Escape(l:rails_root)

View file

@ -0,0 +1,42 @@
" Author: Eddie Lebow https://github.com/elebow
" Description: debride, a dead method detector for Ruby files
call ale#Set('ruby_debride_executable', 'debride')
call ale#Set('ruby_debride_options', '')
function! ale_linters#ruby#debride#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'ruby_debride_executable')
return ale#ruby#EscapeExecutable(l:executable, 'debride')
\ . ale#Var(a:buffer, 'ruby_debride_options')
\ . ' %s'
endfunction
function! ale_linters#ruby#debride#HandleOutput(buffer, lines) abort
let l:output = []
for l:line in a:lines
if l:line !~# '^ '
continue
endif
let l:elements = split(l:line)
let l:method_name = l:elements[0]
let l:lnum = split(l:elements[1], ':')[1]
call add(l:output, {
\ 'lnum': 0 + l:lnum,
\ 'text': 'Possible unused method: ' . l:method_name,
\ 'type': 'W',
\})
endfor
return l:output
endfunction
call ale#linter#Define('ruby', {
\ 'name': 'debride',
\ 'executable': {b -> ale#Var(b, 'ruby_debride_executable')},
\ 'command': function('ale_linters#ruby#debride#GetCommand'),
\ 'callback': 'ale_linters#ruby#debride#HandleOutput',
\})

View file

@ -33,7 +33,7 @@ function! ale_linters#ruby#rails_best_practices#GetCommand(buffer) abort
let l:output_file = has('win32') ? '%t ' : '/dev/stdout ' let l:output_file = has('win32') ? '%t ' : '/dev/stdout '
let l:cat_file = has('win32') ? '; type %t' : '' let l:cat_file = has('win32') ? '; type %t' : ''
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rails_best_practices') return ale#ruby#EscapeExecutable(l:executable, 'rails_best_practices')
\ . ' --silent -f json --output-file ' . l:output_file \ . ' --silent -f json --output-file ' . l:output_file
\ . ale#Var(a:buffer, 'ruby_rails_best_practices_options') \ . ale#Var(a:buffer, 'ruby_rails_best_practices_options')
\ . ale#Escape(l:rails_root) \ . ale#Escape(l:rails_root)

View file

@ -14,7 +14,7 @@ function! ale_linters#ruby#reek#GetCommand(buffer, version) abort
\ ? ' --stdin-filename %s' \ ? ' --stdin-filename %s'
\ : '' \ : ''
return ale#handlers#ruby#EscapeExecutable(l:executable, 'reek') return ale#ruby#EscapeExecutable(l:executable, 'reek')
\ . ' -f json --no-progress --no-color --force-exclusion' \ . ' -f json --no-progress --no-color --force-exclusion'
\ . l:display_name_args \ . l:display_name_args
endfunction endfunction

View file

@ -7,7 +7,7 @@ call ale#Set('ruby_rubocop_options', '')
function! ale_linters#ruby#rubocop#GetCommand(buffer) abort function! ale_linters#ruby#rubocop#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'ruby_rubocop_executable') let l:executable = ale#Var(a:buffer, 'ruby_rubocop_executable')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rubocop') return ale#ruby#EscapeExecutable(l:executable, 'rubocop')
\ . ' --format json --force-exclusion ' \ . ' --format json --force-exclusion '
\ . ale#Var(a:buffer, 'ruby_rubocop_options') \ . ale#Var(a:buffer, 'ruby_rubocop_options')
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p')) \ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))

View file

@ -5,7 +5,7 @@ function! ale_linters#ruby#sorbet#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable') let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable')
let l:options = ale#Var(a:buffer, 'ruby_sorbet_options') let l:options = ale#Var(a:buffer, 'ruby_sorbet_options')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'srb') return ale#ruby#EscapeExecutable(l:executable, 'srb')
\ . ' tc' \ . ' tc'
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --lsp --disable-watchman' \ . ' --lsp --disable-watchman'

View file

@ -8,7 +8,7 @@ call ale#Set('ruby_standardrb_options', '')
function! ale_linters#ruby#standardrb#GetCommand(buffer) abort function! ale_linters#ruby#standardrb#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'ruby_standardrb_executable') let l:executable = ale#Var(a:buffer, 'ruby_standardrb_executable')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'standardrb') return ale#ruby#EscapeExecutable(l:executable, 'standardrb')
\ . ' --format json --force-exclusion ' \ . ' --format json --force-exclusion '
\ . ale#Var(a:buffer, 'ruby_standardrb_options') \ . ale#Var(a:buffer, 'ruby_standardrb_options')
\ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p')) \ . ' --stdin ' . ale#Escape(expand('#' . a:buffer . ':p'))

View file

@ -0,0 +1,48 @@
" Author: Jeffrey Lau - https://github.com/zoonfafer
" Description: Metals Language Server for Scala https://scalameta.org/metals/
call ale#Set('scala_metals_executable', 'metals-vim')
call ale#Set('scala_metals_project_root', '')
function! ale_linters#scala#metals#GetProjectRoot(buffer) abort
let l:project_root = ale#Var(a:buffer, 'scala_metals_project_root')
if !empty(l:project_root)
return l:project_root
endif
let l:potential_roots = [
\ 'build.sc',
\ 'build.sbt',
\ '.bloop',
\ '.metals',
\]
for l:root in l:potential_roots
let l:project_root = ale#path#ResolveLocalPath(
\ a:buffer,
\ l:root,
\ ''
\)
if !empty(l:project_root)
return fnamemodify(
\ l:project_root,
\ ':h',
\)
endif
endfor
endfunction
function! ale_linters#scala#metals#GetCommand(buffer) abort
return '%e' . ale#Pad('stdio')
endfunction
call ale#linter#Define('scala', {
\ 'name': 'metals',
\ 'lsp': 'stdio',
\ 'language': 'scala',
\ 'executable': {b -> ale#Var(b, 'scala_metals_executable')},
\ 'command': function('ale_linters#scala#metals#GetCommand'),
\ 'project_root': function('ale_linters#scala#metals#GetProjectRoot'),
\})

View file

@ -34,8 +34,10 @@ function! ale_linters#sh#shell#Handle(buffer, lines) abort
" Matches patterns line the following: " Matches patterns line the following:
" "
" bash: line 13: syntax error near unexpected token `d' " bash: line 13: syntax error near unexpected token `d'
" bash:行0: 未预期的符号“done”附近有语法错误
" bash: 列 90: 尋找匹配的「"」時遇到了未預期的檔案結束符
" sh: 11: Syntax error: "(" unexpected " sh: 11: Syntax error: "(" unexpected
let l:pattern = '\v(line |: ?)(\d+): (.+)$' let l:pattern = '\v([^:]+:\D*)(\d+): (.+)$'
let l:output = [] let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern) for l:match in ale#util#GetMatches(a:lines, l:pattern)

View file

@ -0,0 +1,35 @@
" Author: Karl Bartel <karl42@gmail.com> - http://karl.berlin/
" Description: Report solc compiler errors in Solidity code
call ale#Set('solidity_solc_options', '')
function! ale_linters#solidity#solc#Handle(buffer, lines) abort
" Matches patterns like the following:
" /path/to/file/file.sol:1:10: Error: Identifier not found or not unique.
let l:pattern = '\v^[^:]+:(\d+):(\d+): (Error|Warning): (.*)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
let l:isError = l:match[3] is? 'error'
call add(l:output, {
\ 'lnum': l:match[1] + 0,
\ 'col': l:match[2] + 0,
\ 'text': l:match[4],
\ 'type': l:isError ? 'E' : 'W',
\})
endfor
return l:output
endfunction
function! ale_linters#solidity#solc#GetCommand(buffer) abort
return 'solc' . ale#Pad(ale#Var(a:buffer, 'solidity_solc_options')) . ' %s'
endfunction
call ale#linter#Define('solidity', {
\ 'name': 'solc',
\ 'executable': 'solc',
\ 'command': function('ale_linters#solidity#solc#GetCommand'),
\ 'callback': 'ale_linters#solidity#solc#Handle',
\ 'output_stream': 'stderr',
\})

View file

@ -9,23 +9,69 @@ call ale#Set('terraform_tflint_executable', 'tflint')
function! ale_linters#terraform#tflint#Handle(buffer, lines) abort function! ale_linters#terraform#tflint#Handle(buffer, lines) abort
let l:output = [] let l:output = []
let l:pattern = '\v^(.*):(\d+),(\d+)-(\d+)?,?(\d+): (.{-1,}); (.+)$'
let l:json = ale#util#FuzzyJSONDecode(a:lines, {})
for l:error in ale#util#FuzzyJSONDecode(a:lines, []) " This is a rough test for tflint's output format
if l:error.type is# 'ERROR' " On versions prior to 0.11 it outputs all errors as a single level list
let l:type = 'E' if type(l:json) is v:t_list
elseif l:error.type is# 'NOTICE' for l:error in l:json
let l:type = 'I' if l:error.type is# 'ERROR'
else let l:type = 'E'
let l:type = 'W' elseif l:error.type is# 'NOTICE'
endif let l:type = 'I'
else
let l:type = 'W'
endif
call add(l:output, { call add(l:output, {
\ 'lnum': l:error.line, \ 'lnum': l:error.line,
\ 'text': l:error.message, \ 'text': l:error.message,
\ 'type': l:type, \ 'type': l:type,
\ 'code': l:error.detector, \ 'code': l:error.detector,
\}) \})
endfor endfor
else
for l:error in get(l:json, 'errors', [])
for l:match in ale#util#GetMatches(l:error.message, [l:pattern])
if l:match[4] is# ''
let l:match[4] = l:match[2]
endif
call add(l:output, {
\ 'filename': l:match[1],
\ 'lnum': str2nr(l:match[2]),
\ 'col': str2nr(l:match[3]),
\ 'end_lnum': str2nr(l:match[4]),
\ 'end_col': str2nr(l:match[5]),
\ 'text': l:match[7],
\ 'code': l:match[6],
\ 'type': 'E',
\})
endfor
endfor
for l:error in get(l:json, 'issues', [])
if l:error.rule.severity is# 'ERROR'
let l:type = 'E'
elseif l:error.rule.severity is# 'NOTICE'
let l:type = 'I'
else
let l:type = 'W'
endif
call add(l:output, {
\ 'filename': l:error.range.filename,
\ 'lnum': l:error.range.start.line,
\ 'col': l:error.range.start.column,
\ 'end_lnum': l:error.range.end.line,
\ 'end_col': l:error.range.end.column,
\ 'text': l:error.message,
\ 'code': l:error.rule.name,
\ 'type': l:type,
\})
endfor
endif
return l:output return l:output
endfunction endfunction

View file

@ -0,0 +1,31 @@
" Author: Ahmed El Gabri <@ahmedelgabri>
" Description: standardjs for typescript files
call ale#Set('typescript_standard_executable', 'standard')
call ale#Set('typescript_standard_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('typescript_standard_options', '')
function! ale_linters#typescript#standard#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'typescript_standard', [
\ 'node_modules/standardx/bin/cmd.js',
\ 'node_modules/standard/bin/cmd.js',
\ 'node_modules/.bin/standard',
\])
endfunction
function! ale_linters#typescript#standard#GetCommand(buffer) abort
let l:executable = ale_linters#typescript#standard#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'typescript_standard_options')
return ale#node#Executable(a:buffer, l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --stdin %s'
endfunction
" standard uses eslint and the output format is the same
call ale#linter#Define('typescript', {
\ 'name': 'standard',
\ 'executable': function('ale_linters#typescript#standard#GetExecutable'),
\ 'command': function('ale_linters#typescript#standard#GetCommand'),
\ 'callback': 'ale#handlers#eslint#Handle',
\})

View file

@ -24,6 +24,20 @@ function! ale_linters#verilog#vlog#Handle(buffer, lines) abort
\}) \})
endfor endfor
"Matches patterns like the following:
"** Warning: (vlog-2623) add.v(7): Undefined variable: C.
"** Error: (vlog-13294) file.v(1): Identifier must be declared with a port mode: C.
" let l:pattern = '^**\s\(\w*\):[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)'
let l:pattern = '^**\s\(\w*\):\s\([^)]*)\)[a-zA-Z0-9\-\.\_\/ ]\+(\(\d\+\)):\s\+\(.*\)'
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'lnum': l:match[3] + 0,
\ 'type': l:match[1] is? 'Error' ? 'E' : 'W',
\ 'text': l:match[2] . ' ' . l:match[4],
\})
endfor
return l:output return l:output
endfunction endfunction

View file

@ -5,11 +5,18 @@
" Strings used for severity in the echoed message " 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_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_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') let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
" Ignoring linters, for disabling some, or ignoring LSP diagnostics. " Ignoring linters, for disabling some, or ignoring LSP diagnostics.
let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {}) let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {})
let g:ale_disable_lsp = get(g:, 'ale_disable_lsp', 0) let g:ale_disable_lsp = get(g:, 'ale_disable_lsp', 0)
" LSP window/showMessage format
let g:ale_lsp_show_message_format = get(g:, 'ale_lsp_show_message_format', '%severity%:%linter%: %s')
" Valid values mimic LSP definitions (error, warning and information; log is
" never shown)
let g:ale_lsp_show_message_severity = get(g:, 'ale_lsp_show_message_severity', 'error')
let s:lint_timer = -1 let s:lint_timer = -1
let s:getcmdwintype_exists = exists('*getcmdwintype') let s:getcmdwintype_exists = exists('*getcmdwintype')
@ -156,7 +163,7 @@ function! ale#Queue(delay, ...) abort
endif endif
endfunction endfunction
let s:current_ale_version = [2, 5, 0] let s:current_ale_version = [2, 6, 0]
" A function used to check for ALE features in files outside of the project. " A function used to check for ALE features in files outside of the project.
function! ale#Has(feature) abort function! ale#Has(feature) abort

View file

@ -267,14 +267,22 @@ function! ale#assert#TearDownLinterTest() abort
endif endif
endfunction endfunction
function! ale#assert#SetUpFixerTest(filetype, name) abort function! ale#assert#SetUpFixerTest(filetype, name, ...) abort
" If the suffix of the option names format is different, an additional
" argument can be used for that instead.
if a:0 > 1
throw 'Too many arguments'
endif
" Set up a marker so ALE doesn't create real random temporary filenames. " Set up a marker so ALE doesn't create real random temporary filenames.
let g:ale_create_dummy_temporary_file = 1 let g:ale_create_dummy_temporary_file = 1
let l:function_name = ale#fix#registry#GetFunc(a:name) let l:function_name = ale#fix#registry#GetFunc(a:name)
let s:FixerFunction = function(l:function_name) let s:FixerFunction = function(l:function_name)
let l:prefix = 'ale_' . a:filetype . '_' . a:name let l:option_suffix = get(a:000, 0, a:name)
let l:prefix = 'ale_' . a:filetype . '_'
\ . substitute(l:option_suffix, '-', '_', 'g')
let b:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix' let b:filter_expr = 'v:val[: len(l:prefix) - 1] is# l:prefix'
for l:key in filter(keys(g:), b:filter_expr) for l:key in filter(keys(g:), b:filter_expr)
@ -286,7 +294,7 @@ function! ale#assert#SetUpFixerTest(filetype, name) abort
unlet b:[l:key] unlet b:[l:key]
endfor endfor
execute 'runtime autoload/ale/fixers/' . a:name . '.vim' execute 'runtime autoload/ale/fixers/' . substitute(a:name, '-', '_', 'g') . '.vim'
if !exists('g:dir') if !exists('g:dir')
call ale#test#SetDirectory('/testplugin/test/fixers') call ale#test#SetDirectory('/testplugin/test/fixers')

View file

@ -265,6 +265,16 @@ function! s:GetLookupFromCompileCommandsFile(compile_commands_file) abort
return l:empty return l:empty
endfunction endfunction
function! ale#c#GetCompileCommand(json_item) abort
if has_key(a:json_item, 'command')
return a:json_item.command
elseif has_key(a:json_item, 'arguments')
return join(a:json_item.arguments, ' ')
endif
return ''
endfunction
function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
" Search for an exact file match first. " Search for an exact file match first.
let l:basename = tolower(expand('#' . a:buffer . ':t')) let l:basename = tolower(expand('#' . a:buffer . ':t'))
@ -287,15 +297,14 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
for l:item in l:file_list for l:item in l:file_list
" Load the flags for this file, or for a source file matching the " Load the flags for this file, or for a source file matching the
" header file. " header file.
if has_key(l:item, 'command') if (
\&& (
\ bufnr(l:item.file) is a:buffer \ bufnr(l:item.file) is a:buffer
\ || ( \ || (
\ !empty(l:source_file) \ !empty(l:source_file)
\ && l:item.file[-len(l:source_file):] is? l:source_file \ && l:item.file[-len(l:source_file):] is? l:source_file
\ ) \ )
\) \)
return ale#c#ParseCFlags(l:item.directory, l:item.command) return ale#c#ParseCFlags(l:item.directory, ale#c#GetCompileCommand(l:item))
endif endif
endfor endfor
@ -307,8 +316,7 @@ function! ale#c#ParseCompileCommandsFlags(buffer, file_lookup, dir_lookup) abort
for l:item in l:dir_list for l:item in l:dir_list
if ale#path#Simplify(fnamemodify(l:item.file, ':h')) is? l:dir if ale#path#Simplify(fnamemodify(l:item.file, ':h')) is? l:dir
\&& has_key(l:item, 'command') return ale#c#ParseCFlags(l:item.directory, ale#c#GetCompileCommand(l:item))
return ale#c#ParseCFlags(l:item.directory, l:item.command)
endif endif
endfor endfor

View file

@ -0,0 +1,163 @@
" Author: Jerko Steiner <jerko.steiner@gmail.com>
" Description: Code action support for LSP / tsserver
function! ale#code_action#HandleCodeAction(code_action) abort
let l:current_buffer = bufnr('')
let l:changes = a:code_action.changes
for l:file_code_edit in l:changes
let l:buf = bufnr(l:file_code_edit.fileName)
if l:buf != -1 && l:buf != l:current_buffer && getbufvar(l:buf, '&mod')
call ale#util#Execute('echom ''Aborting action, file is unsaved''')
return
endif
endfor
for l:file_code_edit in l:changes
call ale#code_action#ApplyChanges(
\ l:file_code_edit.fileName, l:file_code_edit.textChanges)
endfor
endfunction
function! ale#code_action#ApplyChanges(filename, changes) abort
let l:current_buffer = bufnr('')
" The buffer is used to determine the fileformat, if available.
let l:buffer = bufnr(a:filename)
let l:is_current_buffer = l:buffer > 0 && l:buffer == l:current_buffer
if l:buffer > 0
let l:lines = getbufline(l:buffer, 1, '$')
else
let l:lines = readfile(a:filename, 'b')
endif
if l:is_current_buffer
let l:pos = getpos('.')[1:2]
else
let l:pos = [1, 1]
endif
" We have to keep track of how many lines we have added, and offset
" changes accordingly.
let l:line_offset = 0
let l:column_offset = 0
let l:last_end_line = 0
for l:code_edit in a:changes
if l:code_edit.start.line isnot l:last_end_line
let l:column_offset = 0
endif
let l:line = l:code_edit.start.line + l:line_offset
let l:column = l:code_edit.start.offset + l:column_offset
let l:end_line = l:code_edit.end.line + l:line_offset
let l:end_column = l:code_edit.end.offset + l:column_offset
let l:text = l:code_edit.newText
let l:cur_line = l:pos[0]
let l:cur_column = l:pos[1]
let l:last_end_line = l:end_line
" Adjust the ends according to previous edits.
if l:end_line > len(l:lines)
let l:end_line_len = 0
else
let l:end_line_len = len(l:lines[l:end_line - 1])
endif
let l:insertions = split(l:text, '\n', 1)
if l:line is 1
" Same logic as for column below. Vimscript's slice [:-1] will not
" be an empty list.
let l:start = []
else
let l:start = l:lines[: l:line - 2]
endif
if l:column is 1
" We need to handle column 1 specially, because we can't slice an
" empty string ending on index 0.
let l:middle = [l:insertions[0]]
else
let l:middle = [l:lines[l:line - 1][: l:column - 2] . l:insertions[0]]
endif
call extend(l:middle, l:insertions[1:])
let l:middle[-1] .= l:lines[l:end_line - 1][l:end_column - 1 :]
let l:lines_before_change = len(l:lines)
let l:lines = l:start + l:middle + l:lines[l:end_line :]
let l:current_line_offset = len(l:lines) - l:lines_before_change
let l:line_offset += l:current_line_offset
let l:column_offset = len(l:middle[-1]) - l:end_line_len
let l:pos = s:UpdateCursor(l:pos,
\ [l:line, l:column],
\ [l:end_line, l:end_column],
\ [l:current_line_offset, l:column_offset])
endfor
if l:lines[-1] is# ''
call remove(l:lines, -1)
endif
call ale#util#Writefile(l:buffer, l:lines, a:filename)
if l:is_current_buffer
call ale#util#Execute(':e!')
call setpos('.', [0, l:pos[0], l:pos[1], 0])
endif
endfunction
function! s:UpdateCursor(cursor, start, end, offset) abort
let l:cur_line = a:cursor[0]
let l:cur_column = a:cursor[1]
let l:line = a:start[0]
let l:column = a:start[1]
let l:end_line = a:end[0]
let l:end_column = a:end[1]
let l:line_offset = a:offset[0]
let l:column_offset = a:offset[1]
if l:end_line < l:cur_line
" both start and end lines are before the cursor. only line offset
" needs to be updated
let l:cur_line += l:line_offset
elseif l:end_line == l:cur_line
" end line is at the same location as cursor, which means
" l:line <= l:cur_line
if l:line < l:cur_line || l:column <= l:cur_column
" updates are happening either before or around the cursor
if l:end_column < l:cur_column
" updates are happening before the cursor, update the
" column offset for cursor
let l:cur_line += l:line_offset
let l:cur_column += l:column_offset
else
" updates are happening around the cursor, move the cursor
" to the end of the changes
let l:cur_line += l:line_offset
let l:cur_column = l:end_column + l:column_offset
endif
" else is not necessary, it means modifications are happening
" after the cursor so no cursor updates need to be done
endif
else
" end line is after the cursor
if l:line < l:cur_line || l:line == l:cur_line && l:column <= l:cur_column
" changes are happening around the cursor, move the cursor
" to the end of the changes
let l:cur_line = l:end_line + l:line_offset
let l:cur_column = l:end_column + l:column_offset
" else is not necesary, it means modifications are happening
" after the cursor so no cursor updates need to be done
endif
endif
return [l:cur_line, l:cur_column]
endfunction

View file

@ -1,5 +1,6 @@
" Author: w0rp <devw0rp@gmail.com> " Author: w0rp <devw0rp@gmail.com>
" Description: Completion support for LSP linters " Description: Completion support for LSP linters
scriptencoding utf-8
" The omnicompletion menu is shown through a special Plug mapping which is " The omnicompletion menu is shown through a special Plug mapping which is
" only valid in Insert mode. This way, feedkeys() won't send these keys if you " only valid in Insert mode. This way, feedkeys() won't send these keys if you
@ -15,29 +16,107 @@ onoremap <silent> <Plug>(ale_show_completion_menu) <Nop>
let g:ale_completion_delay = get(g:, 'ale_completion_delay', 100) let g:ale_completion_delay = get(g:, 'ale_completion_delay', 100)
let g:ale_completion_excluded_words = get(g:, 'ale_completion_excluded_words', []) let g:ale_completion_excluded_words = get(g:, 'ale_completion_excluded_words', [])
let g:ale_completion_max_suggestions = get(g:, 'ale_completion_max_suggestions', 50) let g:ale_completion_max_suggestions = get(g:, 'ale_completion_max_suggestions', 50)
let g:ale_completion_tsserver_autoimport = get(g:, 'ale_completion_tsserver_autoimport', 0)
let s:timer_id = -1 let s:timer_id = -1
let s:last_done_pos = [] let s:last_done_pos = []
" CompletionItemKind values from the LSP protocol. " CompletionItemKind values from the LSP protocol.
let s:LSP_COMPLETION_TEXT_KIND = 1 let g:ale_lsp_types = {
let s:LSP_COMPLETION_METHOD_KIND = 2 \ 1: 'text',
let s:LSP_COMPLETION_FUNCTION_KIND = 3 \ 2: 'method',
let s:LSP_COMPLETION_CONSTRUCTOR_KIND = 4 \ 3: 'function',
let s:LSP_COMPLETION_FIELD_KIND = 5 \ 4: 'constructor',
let s:LSP_COMPLETION_VARIABLE_KIND = 6 \ 5: 'field',
let s:LSP_COMPLETION_CLASS_KIND = 7 \ 6: 'variable',
let s:LSP_COMPLETION_INTERFACE_KIND = 8 \ 7: 'class',
let s:LSP_COMPLETION_MODULE_KIND = 9 \ 8: 'interface',
let s:LSP_COMPLETION_PROPERTY_KIND = 10 \ 9: 'module',
let s:LSP_COMPLETION_UNIT_KIND = 11 \ 10: 'property',
let s:LSP_COMPLETION_VALUE_KIND = 12 \ 11: 'unit',
let s:LSP_COMPLETION_ENUM_KIND = 13 \ 12: 'value',
let s:LSP_COMPLETION_KEYWORD_KIND = 14 \ 13: 'enum',
let s:LSP_COMPLETION_SNIPPET_KIND = 15 \ 14: 'keyword',
let s:LSP_COMPLETION_COLOR_KIND = 16 \ 15: 'snippet',
let s:LSP_COMPLETION_FILE_KIND = 17 \ 16: 'color',
let s:LSP_COMPLETION_REFERENCE_KIND = 18 \ 17: 'file',
\ 18: 'reference',
\ 19: 'folder',
\ 20: 'enum_member',
\ 21: 'constant',
\ 22: 'struct',
\ 23: 'event',
\ 24: 'operator',
\ 25: 'type_parameter',
\ }
" from https://github.com/microsoft/TypeScript/blob/29becf05012bfa7ba20d50b0d16813971e46b8a6/lib/protocol.d.ts#L2472
let g:ale_tsserver_types = {
\ 'warning': 'text',
\ 'keyword': 'keyword',
\ 'script': 'file',
\ 'module': 'module',
\ 'class': 'class',
\ 'local class': 'class',
\ 'interface': 'interface',
\ 'type': 'class',
\ 'enum': 'enum',
\ 'enum member': 'enum_member',
\ 'var': 'variable',
\ 'local var': 'variable',
\ 'function': 'function',
\ 'local function': 'function',
\ 'method': 'method',
\ 'getter': 'property',
\ 'setter': 'method',
\ 'property': 'property',
\ 'constructor': 'constructor',
\ 'call': 'method',
\ 'index': 'index',
\ 'construct': 'constructor',
\ 'parameter': 'parameter',
\ 'type parameter': 'type_parameter',
\ 'primitive type': 'unit',
\ 'label': 'text',
\ 'alias': 'class',
\ 'const': 'constant',
\ 'let': 'variable',
\ 'directory': 'folder',
\ 'external module name': 'text',
\ 'JSX attribute': 'parameter',
\ 'string': 'text'
\ }
" For compatibility reasons, we only use built in VIM completion kinds
" See :help complete-items for Vim completion kinds
let g:ale_completion_symbols = get(g:, 'ale_completion_symbols', {
\ 'text': 'v',
\ 'method': 'f',
\ 'function': 'f',
\ 'constructor': 'f',
\ 'field': 'm',
\ 'variable': 'v',
\ 'class': 't',
\ 'interface': 't',
\ 'module': 'd',
\ 'property': 'm',
\ 'unit': 'v',
\ 'value': 'v',
\ 'enum': 't',
\ 'keyword': 'v',
\ 'snippet': 'v',
\ 'color': 'v',
\ 'file': 'v',
\ 'reference': 'v',
\ 'folder': 'v',
\ 'enum_member': 'm',
\ 'constant': 'm',
\ 'struct': 't',
\ 'event': 'v',
\ 'operator': 'f',
\ 'type_parameter': 'p',
\ '<default>': 'v'
\ })
let s:LSP_INSERT_TEXT_FORMAT_PLAIN = 1 let s:LSP_INSERT_TEXT_FORMAT_PLAIN = 1
let s:LSP_INSERT_TEXT_FORMAT_SNIPPET = 2 let s:LSP_INSERT_TEXT_FORMAT_SNIPPET = 2
@ -277,6 +356,27 @@ function! ale#completion#GetAllTriggers() abort
return deepcopy(s:trigger_character_map) return deepcopy(s:trigger_character_map)
endfunction endfunction
function! ale#completion#GetCompletionKind(kind) abort
let l:lsp_symbol = get(g:ale_lsp_types, a:kind, '')
if !empty(l:lsp_symbol)
return l:lsp_symbol
endif
return get(g:ale_tsserver_types, a:kind, '')
endfunction
function! ale#completion#GetCompletionSymbols(kind) abort
let l:kind = ale#completion#GetCompletionKind(a:kind)
let l:symbol = get(g:ale_completion_symbols, l:kind, '')
if !empty(l:symbol)
return l:symbol
endif
return get(g:ale_completion_symbols, '<default>', 'v')
endfunction
function! s:CompletionStillValid(request_id) abort function! s:CompletionStillValid(request_id) abort
let [l:line, l:column] = getpos('.')[1:2] let [l:line, l:column] = getpos('.')[1:2]
@ -296,7 +396,10 @@ function! ale#completion#ParseTSServerCompletions(response) abort
let l:names = [] let l:names = []
for l:suggestion in a:response.body for l:suggestion in a:response.body
call add(l:names, l:suggestion.name) call add(l:names, {
\ 'word': l:suggestion.name,
\ 'source': get(l:suggestion, 'source', ''),
\})
endfor endfor
return l:names return l:names
@ -310,6 +413,10 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
for l:suggestion in a:response.body for l:suggestion in a:response.body
let l:displayParts = [] let l:displayParts = []
for l:action in get(l:suggestion, 'codeActions', [])
call add(l:displayParts, l:action.description . ' ')
endfor
for l:part in l:suggestion.displayParts for l:part in l:suggestion.displayParts
call add(l:displayParts, l:part.text) call add(l:displayParts, l:part.text)
endfor endfor
@ -321,22 +428,23 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
call add(l:documentationParts, l:part.text) call add(l:documentationParts, l:part.text)
endfor endfor
if l:suggestion.kind is# 'className'
let l:kind = 'f'
elseif l:suggestion.kind is# 'parameterName'
let l:kind = 'f'
else
let l:kind = 'v'
endif
" See :help complete-items " See :help complete-items
call add(l:results, { let l:result = {
\ 'word': l:suggestion.name, \ 'word': l:suggestion.name,
\ 'kind': l:kind, \ 'kind': ale#completion#GetCompletionSymbols(l:suggestion.kind),
\ 'icase': 1, \ 'icase': 1,
\ 'menu': join(l:displayParts, ''), \ 'menu': join(l:displayParts, ''),
\ 'dup': g:ale_completion_tsserver_autoimport,
\ 'info': join(l:documentationParts, ''), \ 'info': join(l:documentationParts, ''),
\}) \}
if has_key(l:suggestion, 'codeActions')
let l:result.user_data = json_encode({
\ 'codeActions': l:suggestion.codeActions,
\ })
endif
call add(l:results, l:result)
endfor endfor
let l:names = getbufvar(l:buffer, 'ale_tsserver_completion_names', []) let l:names = getbufvar(l:buffer, 'ale_tsserver_completion_names', [])
@ -345,12 +453,12 @@ function! ale#completion#ParseTSServerCompletionEntryDetails(response) abort
let l:names_with_details = map(copy(l:results), 'v:val.word') let l:names_with_details = map(copy(l:results), 'v:val.word')
let l:missing_names = filter( let l:missing_names = filter(
\ copy(l:names), \ copy(l:names),
\ 'index(l:names_with_details, v:val) < 0', \ 'index(l:names_with_details, v:val.word) < 0',
\) \)
for l:name in l:missing_names for l:name in l:missing_names
call add(l:results, { call add(l:results, {
\ 'word': l:name, \ 'word': l:name.word,
\ 'kind': 'v', \ 'kind': 'v',
\ 'icase': 1, \ 'icase': 1,
\ 'menu': '', \ 'menu': '',
@ -408,23 +516,6 @@ function! ale#completion#ParseLSPCompletions(response) abort
continue continue
endif endif
" See :help complete-items for Vim completion kinds
if !has_key(l:item, 'kind')
let l:kind = 'v'
elseif l:item.kind is s:LSP_COMPLETION_METHOD_KIND
let l:kind = 'm'
elseif l:item.kind is s:LSP_COMPLETION_CONSTRUCTOR_KIND
let l:kind = 'm'
elseif l:item.kind is s:LSP_COMPLETION_FUNCTION_KIND
let l:kind = 'f'
elseif l:item.kind is s:LSP_COMPLETION_CLASS_KIND
let l:kind = 'f'
elseif l:item.kind is s:LSP_COMPLETION_INTERFACE_KIND
let l:kind = 'f'
else
let l:kind = 'v'
endif
let l:doc = get(l:item, 'documentation', '') let l:doc = get(l:item, 'documentation', '')
if type(l:doc) is v:t_dict && has_key(l:doc, 'value') if type(l:doc) is v:t_dict && has_key(l:doc, 'value')
@ -433,7 +524,7 @@ function! ale#completion#ParseLSPCompletions(response) abort
call add(l:results, { call add(l:results, {
\ 'word': l:word, \ 'word': l:word,
\ 'kind': l:kind, \ 'kind': ale#completion#GetCompletionSymbols(get(l:item, 'kind', '')),
\ 'icase': 1, \ 'icase': 1,
\ 'menu': get(l:item, 'detail', ''), \ 'menu': get(l:item, 'detail', ''),
\ 'info': (type(l:doc) is v:t_string ? l:doc : ''), \ 'info': (type(l:doc) is v:t_string ? l:doc : ''),
@ -472,13 +563,29 @@ function! ale#completion#HandleTSServerResponse(conn_id, response) abort
call setbufvar(l:buffer, 'ale_tsserver_completion_names', l:names) call setbufvar(l:buffer, 'ale_tsserver_completion_names', l:names)
if !empty(l:names) if !empty(l:names)
let l:identifiers = []
for l:name in l:names
let l:identifier = {
\ 'name': l:name.word,
\}
let l:source = get(l:name, 'source', '')
" Empty source results in no details for the completed item
if !empty(l:source)
call extend(l:identifier, { 'source': l:source })
endif
call add(l:identifiers, l:identifier)
endfor
let b:ale_completion_info.request_id = ale#lsp#Send( let b:ale_completion_info.request_id = ale#lsp#Send(
\ b:ale_completion_info.conn_id, \ b:ale_completion_info.conn_id,
\ ale#lsp#tsserver_message#CompletionEntryDetails( \ ale#lsp#tsserver_message#CompletionEntryDetails(
\ l:buffer, \ l:buffer,
\ b:ale_completion_info.line, \ b:ale_completion_info.line,
\ b:ale_completion_info.column, \ b:ale_completion_info.column,
\ l:names, \ l:identifiers,
\ ), \ ),
\) \)
endif endif
@ -525,6 +632,7 @@ function! s:OnReady(linter, lsp_details) abort
\ b:ale_completion_info.line, \ b:ale_completion_info.line,
\ b:ale_completion_info.column, \ b:ale_completion_info.column,
\ b:ale_completion_info.prefix, \ b:ale_completion_info.prefix,
\ g:ale_completion_tsserver_autoimport,
\) \)
else else
" Send a message saying the buffer has changed first, otherwise " Send a message saying the buffer has changed first, otherwise
@ -692,6 +800,30 @@ function! ale#completion#Queue() abort
let s:timer_id = timer_start(g:ale_completion_delay, function('s:TimerHandler')) let s:timer_id = timer_start(g:ale_completion_delay, function('s:TimerHandler'))
endfunction endfunction
function! ale#completion#HandleUserData(completed_item) abort
let l:source = get(get(b:, 'ale_completion_info', {}), 'source', '')
if l:source isnot# 'ale-automatic' && l:source isnot# 'ale-manual' && l:source isnot# 'ale-callback'
return
endif
let l:user_data_json = get(a:completed_item, 'user_data', '')
if empty(l:user_data_json)
return
endif
let l:user_data = json_decode(l:user_data_json)
if type(l:user_data) isnot v:t_dict
return
endif
for l:code_action in get(l:user_data, 'codeActions', [])
call ale#code_action#HandleCodeAction(l:code_action)
endfor
endfunction
function! ale#completion#Done() abort function! ale#completion#Done() abort
silent! pclose silent! pclose
@ -700,6 +832,10 @@ function! ale#completion#Done() abort
let s:last_done_pos = getpos('.')[1:2] let s:last_done_pos = getpos('.')[1:2]
endfunction endfunction
augroup ALECompletionActions
autocmd CompleteDone * call ale#completion#HandleUserData(v:completed_item)
augroup END
function! s:Setup(enabled) abort function! s:Setup(enabled) abort
augroup ALECompletionGroup augroup ALECompletionGroup
autocmd! autocmd!

View file

@ -50,6 +50,7 @@ let s:global_variable_list = [
\ 'ale_sign_style_error', \ 'ale_sign_style_error',
\ 'ale_sign_style_warning', \ 'ale_sign_style_warning',
\ 'ale_sign_warning', \ 'ale_sign_warning',
\ 'ale_sign_highlight_linenrs',
\ 'ale_statusline_format', \ 'ale_statusline_format',
\ 'ale_type_map', \ 'ale_type_map',
\ 'ale_use_global_executables', \ 'ale_use_global_executables',

View file

@ -47,7 +47,7 @@ function! ale#fix#ApplyQueuedFixes(buffer) abort
set nomodified set nomodified
endif endif
else else
call writefile(l:new_lines, expand(a:buffer . ':p')) " no-custom-checks call writefile(l:new_lines, expand('#' . a:buffer . ':p')) " no-custom-checks
call setbufvar(a:buffer, '&modified', 0) call setbufvar(a:buffer, '&modified', 0)
endif endif
endif endif
@ -74,7 +74,7 @@ endfunction
function! ale#fix#ApplyFixes(buffer, output) abort function! ale#fix#ApplyFixes(buffer, output) abort
let l:data = g:ale_fix_buffer_data[a:buffer] let l:data = g:ale_fix_buffer_data[a:buffer]
let l:data.output = a:output let l:data.output = a:output
let l:data.changes_made = l:data.lines_before != l:data.output let l:data.changes_made = l:data.lines_before !=# l:data.output " no-custom-checks
let l:data.done = 1 let l:data.done = 1
call ale#command#RemoveManagedFiles(a:buffer) call ale#command#RemoveManagedFiles(a:buffer)

View file

@ -27,6 +27,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['python'], \ 'suggested_filetypes': ['python'],
\ 'description': 'Fix PEP8 issues with black.', \ 'description': 'Fix PEP8 issues with black.',
\ }, \ },
\ 'dfmt': {
\ 'function': 'ale#fixers#dfmt#Fix',
\ 'suggested_filetypes': ['d'],
\ 'description': 'Fix D files with dfmt.',
\ },
\ 'fecs': { \ 'fecs': {
\ 'function': 'ale#fixers#fecs#Fix', \ 'function': 'ale#fixers#fecs#Fix',
\ 'suggested_filetypes': ['javascript', 'css', 'html'], \ 'suggested_filetypes': ['javascript', 'css', 'html'],
@ -49,6 +54,11 @@ let s:default_registry = {
\ 'description': 'Apply elm-format to a file.', \ 'description': 'Apply elm-format to a file.',
\ 'aliases': ['format'], \ 'aliases': ['format'],
\ }, \ },
\ 'nimpretty': {
\ 'function': 'ale#fixers#nimpretty#Fix',
\ 'suggested_filetypes': ['nim'],
\ 'description': 'Apply nimpretty to a file.',
\ },
\ 'eslint': { \ 'eslint': {
\ 'function': 'ale#fixers#eslint#Fix', \ 'function': 'ale#fixers#eslint#Fix',
\ 'suggested_filetypes': ['javascript', 'typescript'], \ 'suggested_filetypes': ['javascript', 'typescript'],
@ -230,6 +240,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['haskell'], \ 'suggested_filetypes': ['haskell'],
\ 'description': 'Refactor Haskell files with stylish-haskell.', \ 'description': 'Refactor Haskell files with stylish-haskell.',
\ }, \ },
\ 'purty': {
\ 'function': 'ale#fixers#purty#Fix',
\ 'suggested_filetypes': ['purescript'],
\ 'description': 'Format PureScript files with purty.',
\ },
\ 'ocamlformat': { \ 'ocamlformat': {
\ 'function': 'ale#fixers#ocamlformat#Fix', \ 'function': 'ale#fixers#ocamlformat#Fix',
\ 'suggested_filetypes': ['ocaml'], \ 'suggested_filetypes': ['ocaml'],
@ -255,6 +270,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['sql'], \ 'suggested_filetypes': ['sql'],
\ 'description': 'Fix SQL files with sqlfmt.', \ 'description': 'Fix SQL files with sqlfmt.',
\ }, \ },
\ 'sqlformat': {
\ 'function': 'ale#fixers#sqlformat#Fix',
\ 'suggested_filetypes': ['sql'],
\ 'description': 'Fix SQL files with sqlformat.',
\ },
\ 'google_java_format': { \ 'google_java_format': {
\ 'function': 'ale#fixers#google_java_format#Fix', \ 'function': 'ale#fixers#google_java_format#Fix',
\ 'suggested_filetypes': ['java'], \ 'suggested_filetypes': ['java'],
@ -312,7 +332,7 @@ let s:default_registry = {
\ }, \ },
\ 'styler': { \ 'styler': {
\ 'function': 'ale#fixers#styler#Fix', \ 'function': 'ale#fixers#styler#Fix',
\ 'suggested_filetypes': ['r', 'rmarkdown'], \ 'suggested_filetypes': ['r', 'rmarkdown', 'rmd'],
\ 'description': 'Fix R files with styler.', \ 'description': 'Fix R files with styler.',
\ }, \ },
\ 'latexindent': { \ 'latexindent': {
@ -335,6 +355,16 @@ let s:default_registry = {
\ 'suggested_filetypes': ['ada'], \ 'suggested_filetypes': ['ada'],
\ 'description': 'Format Ada files with gnatpp.', \ 'description': 'Format Ada files with gnatpp.',
\ }, \ },
\ 'nixpkgs-fmt': {
\ 'function': 'ale#fixers#nixpkgsfmt#Fix',
\ 'suggested_filetypes': ['nix'],
\ 'description': 'A formatter for Nix code',
\ },
\ 'html-beautify': {
\ 'function': 'ale#fixers#html_beautify#Fix',
\ 'suggested_filetypes': ['html', 'htmldjango'],
\ 'description': 'Fix HTML files with html-beautify.',
\ },
\} \}
" Reset the function registry to the default entries. " Reset the function registry to the default entries.

View 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

View file

@ -0,0 +1,21 @@
" Author: WhyNotHugo <hugo@barrera.io>
" Description: Lint HTML files with html-beautify.
"
call ale#Set('html_beautify_executable', 'html-beautify')
call ale#Set('html_beautify_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('html_beautify_options', '')
call ale#Set('html_beautify_change_directory', 1)
function! ale#fixers#html_beautify#Fix(buffer) abort
let l:executable = ale#python#FindExecutable(
\ a:buffer,
\ 'html_beautify',
\ ['html-beautify']
\)
let l:options = ale#Var(a:buffer, 'html_beautify_options')
return {
\ 'command': ale#Escape(l:executable). ' ' . l:options . ' -',
\}
endfunction

View 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

View 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

View file

@ -0,0 +1,22 @@
" Author: iclanzan <sorin@iclanzan.com>
" Description: Integration of purty with ALE.
call ale#Set('purescript_purty_executable', 'purty')
function! ale#fixers#purty#GetExecutable(buffer) abort
let l:executable = ale#Var(a:buffer, 'purescript_purty_executable')
return ale#Escape(l:executable)
endfunction
function! ale#fixers#purty#Fix(buffer) abort
let l:executable = ale#fixers#purty#GetExecutable(a:buffer)
return {
\ 'command': l:executable
\ . ' --write'
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View file

@ -6,7 +6,7 @@ function! ale#fixers#rubocop#GetCommand(buffer) abort
let l:config = ale#path#FindNearestFile(a:buffer, '.rubocop.yml') let l:config = ale#path#FindNearestFile(a:buffer, '.rubocop.yml')
let l:options = ale#Var(a:buffer, 'ruby_rubocop_options') let l:options = ale#Var(a:buffer, 'ruby_rubocop_options')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rubocop') return ale#ruby#EscapeExecutable(l:executable, 'rubocop')
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '') \ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --auto-correct --force-exclusion %t' \ . ' --auto-correct --force-exclusion %t'

View file

@ -5,7 +5,7 @@ function! ale#fixers#sorbet#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable') let l:executable = ale#Var(a:buffer, 'ruby_sorbet_executable')
let l:options = ale#Var(a:buffer, 'ruby_sorbet_options') let l:options = ale#Var(a:buffer, 'ruby_sorbet_options')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'srb') return ale#ruby#EscapeExecutable(l:executable, 'srb')
\ . ' tc' \ . ' tc'
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --autocorrect --file %t' \ . ' --autocorrect --file %t'

View file

@ -0,0 +1,16 @@
" Author: Cluas <Cluas@live.cn>
" Description: Fixing files with sqlformat.
call ale#Set('sql_sqlformat_executable', 'sqlformat')
call ale#Set('sql_sqlformat_options', '')
function! ale#fixers#sqlformat#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'sql_sqlformat_executable')
let l:options = ale#Var(a:buffer, 'sql_sqlformat_options')
return {
\ 'command': ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -'
\}
endfunction

View file

@ -7,6 +7,7 @@ call ale#Set('javascript_standard_options', '')
function! ale#fixers#standard#GetExecutable(buffer) abort function! ale#fixers#standard#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'javascript_standard', [ return ale#node#FindExecutable(a:buffer, 'javascript_standard', [
\ 'node_modules/standardx/bin/cmd.js',
\ 'node_modules/standard/bin/cmd.js', \ 'node_modules/standard/bin/cmd.js',
\ 'node_modules/.bin/standard', \ 'node_modules/.bin/standard',
\]) \])
@ -14,7 +15,14 @@ endfunction
function! ale#fixers#standard#Fix(buffer) abort function! ale#fixers#standard#Fix(buffer) abort
let l:executable = ale#fixers#standard#GetExecutable(a:buffer) let l:executable = ale#fixers#standard#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'javascript_standard_options') let l:filetype = getbufvar(a:buffer, '&filetype')
let l:options_type = 'javascript_standard_options'
if l:filetype =~# 'typescript'
let l:options_type = 'typescript_standard_options'
endif
let l:options = ale#Var(a:buffer, l:options_type)
return { return {
\ 'command': ale#node#Executable(a:buffer, l:executable) \ 'command': ale#node#Executable(a:buffer, l:executable)

View file

@ -9,7 +9,7 @@ function! ale#fixers#standardrb#GetCommand(buffer) abort
let l:config = ale#path#FindNearestFile(a:buffer, '.standard.yml') let l:config = ale#path#FindNearestFile(a:buffer, '.standard.yml')
let l:options = ale#Var(a:buffer, 'ruby_standardrb_options') let l:options = ale#Var(a:buffer, 'ruby_standardrb_options')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'standardrb') return ale#ruby#EscapeExecutable(l:executable, 'standardrb')
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '') \ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
\ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --fix --force-exclusion %t' \ . ' --fix --force-exclusion %t'

View file

@ -3,6 +3,7 @@
call ale#Set('stylelint_executable', 'stylelint') call ale#Set('stylelint_executable', 'stylelint')
call ale#Set('stylelint_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('stylelint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('stylelint_options', '')
function! ale#fixers#stylelint#GetExecutable(buffer) abort function! ale#fixers#stylelint#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'stylelint', [ return ale#node#FindExecutable(a:buffer, 'stylelint', [
@ -13,10 +14,14 @@ endfunction
function! ale#fixers#stylelint#Fix(buffer) abort function! ale#fixers#stylelint#Fix(buffer) abort
let l:executable = ale#fixers#stylelint#GetExecutable(a:buffer) let l:executable = ale#fixers#stylelint#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'stylelint_options')
return { return {
\ 'command': ale#node#Executable(a:buffer, l:executable) \ 'command': ale#path#BufferCdString(a:buffer)
\ . ' --fix %t', \ . ale#node#Executable(a:buffer, l:executable)
\ . ' %t'
\ . ale#Pad(l:options)
\ . ' --fix',
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,
\} \}
endfunction endfunction

View file

@ -2,13 +2,13 @@
" Description: Fixing R files with styler. " Description: Fixing R files with styler.
call ale#Set('r_styler_executable', 'Rscript') call ale#Set('r_styler_executable', 'Rscript')
call ale#Set('r_styler_options', 'tidyverse_style') call ale#Set('r_styler_options', 'tidyverse_style()')
function! ale#fixers#styler#Fix(buffer) abort function! ale#fixers#styler#Fix(buffer) abort
return { return {
\ 'command': 'Rscript --vanilla -e ' \ 'command': 'Rscript --vanilla -e '
\ . '"suppressPackageStartupMessages(library(styler));' \ . '"suppressPackageStartupMessages(library(styler));'
\ . 'style_file(commandArgs(TRUE), style = ' \ . 'style_file(commandArgs(TRUE), transformers = '
\ . ale#Var(a:buffer, 'r_styler_options') . ')"' \ . ale#Var(a:buffer, 'r_styler_options') . ')"'
\ . ' %t', \ . ' %t',
\ 'read_temporary_file': 1, \ 'read_temporary_file': 1,

View file

@ -2,6 +2,7 @@
" Description: languagetool for markdown files " Description: languagetool for markdown files
" "
call ale#Set('languagetool_executable', 'languagetool') call ale#Set('languagetool_executable', 'languagetool')
call ale#Set('languagetool_options', '--autoDetect')
function! ale#handlers#languagetool#GetExecutable(buffer) abort function! ale#handlers#languagetool#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'languagetool_executable') return ale#Var(a:buffer, 'languagetool_executable')
@ -9,8 +10,10 @@ endfunction
function! ale#handlers#languagetool#GetCommand(buffer) abort function! ale#handlers#languagetool#GetCommand(buffer) abort
let l:executable = ale#handlers#languagetool#GetExecutable(a:buffer) let l:executable = ale#handlers#languagetool#GetExecutable(a:buffer)
let l:options = ale#Var(a:buffer, 'languagetool_options')
return ale#Escape(l:executable) . ' --autoDetect %s' return ale#Escape(l:executable)
\ . (empty(l:options) ? '' : ' ' . l:options) . ' %s'
endfunction endfunction
function! ale#handlers#languagetool#HandleOutput(buffer, lines) abort function! ale#handlers#languagetool#HandleOutput(buffer, lines) abort

View file

@ -36,11 +36,3 @@ endfunction
function! ale#handlers#ruby#HandleSyntaxErrors(buffer, lines) abort function! ale#handlers#ruby#HandleSyntaxErrors(buffer, lines) abort
return s:HandleSyntaxError(a:buffer, a:lines) return s:HandleSyntaxError(a:buffer, a:lines)
endfunction endfunction
function! ale#handlers#ruby#EscapeExecutable(executable, bundle_exec) abort
let l:exec_args = a:executable =~? 'bundle'
\ ? ' exec ' . a:bundle_exec
\ : ''
return ale#Escape(a:executable) . l:exec_args
endfunction

View file

@ -26,6 +26,25 @@ endif
let s:MAX_POS_VALUES = 8 let s:MAX_POS_VALUES = 8
let s:MAX_COL_SIZE = 1073741824 " pow(2, 30) let s:MAX_COL_SIZE = 1073741824 " pow(2, 30)
let s:has_nvim_highlight = exists('*nvim_buf_add_highlight') && exists('*nvim_buf_clear_namespace')
if s:has_nvim_highlight
let s:ns_id = nvim_create_namespace('ale_highlight')
endif
" Wrappers are necessary to test this functionality by faking the calls in tests.
function! ale#highlight#nvim_buf_add_highlight(buffer, ns_id, hl_group, line, col_start, col_end) abort
" Ignore all errors for adding highlights.
try
call nvim_buf_add_highlight(a:buffer, a:ns_id, a:hl_group, a:line, a:col_start, a:col_end)
catch
endtry
endfunction
function! ale#highlight#nvim_buf_clear_namespace(buffer, ns_id, line_start, line_end) abort
call nvim_buf_clear_namespace(a:buffer, a:ns_id, a:line_start, a:line_end)
endfunction
function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort function! ale#highlight#CreatePositions(line, col, end_line, end_col) abort
if a:line >= a:end_line if a:line >= a:end_line
" For single lines, just return the one position. " For single lines, just return the one position.
@ -51,15 +70,53 @@ endfunction
" except these which have matching loclist item entries. " except these which have matching loclist item entries.
function! ale#highlight#RemoveHighlights() abort function! ale#highlight#RemoveHighlights() abort
for l:match in getmatches() if s:has_nvim_highlight
if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$' call ale#highlight#nvim_buf_clear_namespace(bufnr(''), s:ns_id, 0, -1)
call matchdelete(l:match.id) else
endif for l:match in getmatches()
endfor if l:match.group =~? '\v^ALE(Style)?(Error|Warning|Info)(Line)?$'
call matchdelete(l:match.id)
endif
endfor
endif
endfunction
" Same semantics of matchaddpos but will use nvim_buf_add_highlight if
" available. This involves iterating over the position list, switching from
" 1-based indexing to 0-based indexing, and translating the multiple ways
" that position can be specified for matchaddpos into line + col_start +
" col_end.
function! s:matchaddpos(group, pos_list) abort
if s:has_nvim_highlight
for l:pos in a:pos_list
let l:line = type(l:pos) == v:t_number
\ ? l:pos - 1
\ : l:pos[0] - 1
if type(l:pos) == v:t_number || len(l:pos) == 1
let l:col_start = 0
let l:col_end = s:MAX_COL_SIZE
else
let l:col_start = l:pos[1] - 1
let l:col_end = l:col_start + get(l:pos, 2, 1)
endif
call ale#highlight#nvim_buf_add_highlight(
\ bufnr(''),
\ s:ns_id,
\ a:group,
\ l:line,
\ l:col_start,
\ l:col_end,
\)
endfor
else
call matchaddpos(a:group, a:pos_list)
endif
endfunction endfunction
function! s:highlight_line(bufnr, lnum, group) abort function! s:highlight_line(bufnr, lnum, group) abort
call matchaddpos(a:group, [a:lnum]) call s:matchaddpos(a:group, [a:lnum])
endfunction endfunction
function! s:highlight_range(bufnr, range, group) abort function! s:highlight_range(bufnr, range, group) abort
@ -72,7 +129,7 @@ function! s:highlight_range(bufnr, range, group) abort
\ a:range.end_lnum, \ a:range.end_lnum,
\ a:range.end_col \ a:range.end_col
\ ), \ ),
\ 'matchaddpos(a:group, v:val)' \ 's:matchaddpos(a:group, v:val)'
\) \)
endfunction endfunction

View file

@ -12,9 +12,12 @@ let s:linters = {}
let s:default_ale_linter_aliases = { let s:default_ale_linter_aliases = {
\ 'Dockerfile': 'dockerfile', \ 'Dockerfile': 'dockerfile',
\ 'csh': 'sh', \ 'csh': 'sh',
\ 'javascriptreact': ['javascript', 'jsx'],
\ 'plaintex': 'tex', \ 'plaintex': 'tex',
\ 'rmarkdown': 'r', \ 'rmarkdown': 'r',
\ 'rmd': 'r',
\ 'systemverilog': 'verilog', \ 'systemverilog': 'verilog',
\ 'typescriptreact': ['typescript', 'tsx'],
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'], \ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
\ 'vimwiki': 'markdown', \ 'vimwiki': 'markdown',
\ 'vue': ['vue', 'javascript'], \ 'vue': ['vue', 'javascript'],

View file

@ -37,6 +37,7 @@ function! ale#lsp#Register(executable_or_address, project, init_options) abort
\ 'init_queue': [], \ 'init_queue': [],
\ 'capabilities': { \ 'capabilities': {
\ 'hover': 0, \ 'hover': 0,
\ 'rename': 0,
\ 'references': 0, \ 'references': 0,
\ 'completion': 0, \ 'completion': 0,
\ 'completion_trigger_characters': [], \ 'completion_trigger_characters': [],
@ -199,6 +200,10 @@ function! s:UpdateCapabilities(conn, capabilities) abort
let a:conn.capabilities.references = 1 let a:conn.capabilities.references = 1
endif endif
if get(a:capabilities, 'renameProvider') is v:true
let a:conn.capabilities.rename = 1
endif
if !empty(get(a:capabilities, 'completionProvider')) if !empty(get(a:capabilities, 'completionProvider'))
let a:conn.capabilities.completion = 1 let a:conn.capabilities.completion = 1
endif endif
@ -317,6 +322,7 @@ function! ale#lsp#MarkConnectionAsTsserver(conn_id) abort
let l:conn.capabilities.completion_trigger_characters = ['.'] let l:conn.capabilities.completion_trigger_characters = ['.']
let l:conn.capabilities.definition = 1 let l:conn.capabilities.definition = 1
let l:conn.capabilities.symbol_search = 1 let l:conn.capabilities.symbol_search = 1
let l:conn.capabilities.rename = 1
endfunction endfunction
function! s:SendInitMessage(conn) abort function! s:SendInitMessage(conn) abort

View file

@ -162,3 +162,13 @@ function! ale#lsp#message#DidChangeConfiguration(buffer, config) abort
\ 'settings': a:config, \ 'settings': a:config,
\}] \}]
endfunction endfunction
function! ale#lsp#message#Rename(buffer, line, column, new_name) abort
return [0, 'textDocument/rename', {
\ 'textDocument': {
\ 'uri': ale#path#ToURI(expand('#' . a:buffer . ':p')),
\ },
\ 'position': {'line': a:line - 1, 'character': a:column - 1},
\ 'newName': a:new_name,
\}]
endfunction

View file

@ -36,12 +36,14 @@ function! ale#lsp#tsserver_message#Geterr(buffer) abort
return [1, 'ts@geterr', {'files': [expand('#' . a:buffer . ':p')]}] return [1, 'ts@geterr', {'files': [expand('#' . a:buffer . ':p')]}]
endfunction endfunction
function! ale#lsp#tsserver_message#Completions(buffer, line, column, prefix) abort function! ale#lsp#tsserver_message#Completions(
\ buffer, line, column, prefix, include_external) abort
return [0, 'ts@completions', { return [0, 'ts@completions', {
\ 'line': a:line, \ 'line': a:line,
\ 'offset': a:column, \ 'offset': a:column,
\ 'file': expand('#' . a:buffer . ':p'), \ 'file': expand('#' . a:buffer . ':p'),
\ 'prefix': a:prefix, \ 'prefix': a:prefix,
\ 'includeExternalModuleExports': a:include_external,
\}] \}]
endfunction endfunction
@ -77,3 +79,27 @@ function! ale#lsp#tsserver_message#Quickinfo(buffer, line, column) abort
\ 'file': expand('#' . a:buffer . ':p'), \ 'file': expand('#' . a:buffer . ':p'),
\}] \}]
endfunction endfunction
function! ale#lsp#tsserver_message#Rename(
\ buffer, line, column, find_in_comments, find_in_strings) abort
return [0, 'ts@rename', {
\ 'line': a:line,
\ 'offset': a:column,
\ 'file': expand('#' . a:buffer . ':p'),
\ 'arguments': {
\ 'findInComments': a:find_in_comments,
\ 'findInStrings': a:find_in_strings,
\ }
\}]
endfunction
function! ale#lsp#tsserver_message#OrganizeImports(buffer) abort
return [0, 'ts@organizeImports', {
\ 'scope': {
\ 'type': 'file',
\ 'args': {
\ 'file': expand('#' . a:buffer . ':p'),
\ },
\ },
\}]
endfunction

View file

@ -130,6 +130,12 @@ function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort
call s:HandleLSPErrorMessage(l:linter_name, a:response) call s:HandleLSPErrorMessage(l:linter_name, a:response)
elseif l:method is# 'textDocument/publishDiagnostics' elseif l:method is# 'textDocument/publishDiagnostics'
call s:HandleLSPDiagnostics(a:conn_id, a:response) call s:HandleLSPDiagnostics(a:conn_id, a:response)
elseif l:method is# 'window/showMessage'
call ale#lsp_window#HandleShowMessage(
\ s:lsp_linter_map[a:conn_id],
\ g:ale_lsp_show_message_format,
\ a:response.params
\)
elseif get(a:response, 'type', '') is# 'event' elseif get(a:response, 'type', '') is# 'event'
\&& get(a:response, 'event', '') is# 'semanticDiag' \&& get(a:response, 'event', '') is# 'semanticDiag'
call s:HandleTSServerDiagnostics(a:response, 'semantic') call s:HandleTSServerDiagnostics(a:response, 'semantic')

View file

@ -0,0 +1,58 @@
" Author: suoto <andre820@gmail.com>
" Description: Handling of window/* LSP methods, although right now only
" handles window/showMessage
" Constants for message type codes
let s:LSP_MESSAGE_TYPE_DISABLED = 0
let s:LSP_MESSAGE_TYPE_ERROR = 1
let s:LSP_MESSAGE_TYPE_WARNING = 2
let s:LSP_MESSAGE_TYPE_INFORMATION = 3
let s:LSP_MESSAGE_TYPE_LOG = 4
" Translate strings from the user config to a number so we can check
" severities
let s:CFG_TO_LSP_SEVERITY = {
\ 'disabled': s:LSP_MESSAGE_TYPE_DISABLED,
\ 'error': s:LSP_MESSAGE_TYPE_ERROR,
\ 'warning': s:LSP_MESSAGE_TYPE_WARNING,
\ 'information': s:LSP_MESSAGE_TYPE_INFORMATION,
\ 'info': s:LSP_MESSAGE_TYPE_INFORMATION,
\ 'log': s:LSP_MESSAGE_TYPE_LOG
\}
" Handle window/showMessage response.
" - details: dict containing linter name and format (g:ale_lsp_show_message_format)
" - params: dict with the params for the call in the form of {type: number, message: string}
function! ale#lsp_window#HandleShowMessage(linter_name, format, params) abort
let l:message = a:params.message
let l:type = a:params.type
" Get the configured severity level threshold and check if the message
" should be displayed or not
let l:configured_severity = tolower(get(g:, 'ale_lsp_show_message_severity', 'error'))
" If the user has configured with a value we can't find on the conversion
" dict, fall back to warning
let l:cfg_severity_threshold = get(s:CFG_TO_LSP_SEVERITY, l:configured_severity, s:LSP_MESSAGE_TYPE_WARNING)
if l:type > l:cfg_severity_threshold
return
endif
" Severity will depend on the message type
if l:type is# s:LSP_MESSAGE_TYPE_ERROR
let l:severity = g:ale_echo_msg_error_str
elseif l:type is# s:LSP_MESSAGE_TYPE_INFORMATION
let l:severity = g:ale_echo_msg_info_str
elseif l:type is# s:LSP_MESSAGE_TYPE_LOG
let l:severity = g:ale_echo_msg_log_str
else
" Default to warning just in case
let l:severity = g:ale_echo_msg_warning_str
endif
let l:string = substitute(a:format, '\V%severity%', l:severity, 'g')
let l:string = substitute(l:string, '\V%linter%', a:linter_name, 'g')
let l:string = substitute(l:string, '\V%s\>', l:message, 'g')
call ale#util#ShowMessage(l:string)
endfunction

View file

@ -0,0 +1,59 @@
" Author: Jerko Steiner <jerko.steiner@gmail.com>
" Description: Organize imports support for tsserver
"
function! ale#organize_imports#HandleTSServerResponse(conn_id, response) abort
if get(a:response, 'command', '') isnot# 'organizeImports'
return
endif
if get(a:response, 'success', v:false) isnot v:true
return
endif
let l:file_code_edits = a:response.body
call ale#code_action#HandleCodeAction({
\ 'description': 'Organize Imports',
\ 'changes': l:file_code_edits,
\})
endfunction
function! s:OnReady(linter, lsp_details) abort
let l:id = a:lsp_details.connection_id
if a:linter.lsp isnot# 'tsserver'
call ale#util#Execute('echom ''OrganizeImports currently only works with tsserver''')
return
endif
let l:buffer = a:lsp_details.buffer
let l:Callback = function('ale#organize_imports#HandleTSServerResponse')
call ale#lsp#RegisterCallback(l:id, l:Callback)
let l:message = ale#lsp#tsserver_message#OrganizeImports(l:buffer)
let l:request_id = ale#lsp#Send(l:id, l:message)
endfunction
function! s:OrganizeImports(linter) abort
let l:buffer = bufnr('')
let [l:line, l:column] = getpos('.')[1:2]
if a:linter.lsp isnot# 'tsserver'
let l:column = min([l:column, len(getline(l:line))])
endif
let l:Callback = function('s:OnReady')
call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
endfunction
function! ale#organize_imports#Execute() abort
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call s:OrganizeImports(l:linter)
endif
endfor
endfunction

View file

@ -54,14 +54,14 @@ function! ale#path#FindNearestDirectory(buffer, directory_name) abort
return '' return ''
endfunction endfunction
" Given a buffer, a string to search for, an a global fallback for when " Given a buffer, a string to search for, and a global fallback for when
" the search fails, look for a file in parent paths, and if that fails, " the search fails, look for a file in parent paths, and if that fails,
" use the global fallback path instead. " use the global fallback path instead.
function! ale#path#ResolveLocalPath(buffer, search_string, global_fallback) abort function! ale#path#ResolveLocalPath(buffer, search_string, global_fallback) abort
" Search for a locally installed file first. " Search for a locally installed file first.
let l:path = ale#path#FindNearestFile(a:buffer, a:search_string) let l:path = ale#path#FindNearestFile(a:buffer, a:search_string)
" If the serach fails, try the global executable instead. " If the search fails, try the global executable instead.
if empty(l:path) if empty(l:path)
let l:path = a:global_fallback let l:path = a:global_fallback
endif endif

View file

@ -0,0 +1,225 @@
" Author: Jerko Steiner <jerko.steiner@gmail.com>
" Description: Rename symbol support for LSP / tsserver
let s:rename_map = {}
" Used to get the rename map in tests.
function! ale#rename#GetMap() abort
return deepcopy(s:rename_map)
endfunction
" Used to set the rename map in tests.
function! ale#rename#SetMap(map) abort
let s:rename_map = a:map
endfunction
function! ale#rename#ClearLSPData() abort
let s:rename_map = {}
endfunction
let g:ale_rename_tsserver_find_in_comments = get(g:, 'ale_rename_tsserver_find_in_comments')
let g:ale_rename_tsserver_find_in_strings = get(g:, 'ale_rename_tsserver_find_in_strings')
function! s:message(message) abort
call ale#util#Execute('echom ' . string(a:message))
endfunction
function! ale#rename#HandleTSServerResponse(conn_id, response) abort
if get(a:response, 'command', '') isnot# 'rename'
return
endif
if !has_key(s:rename_map, a:response.request_seq)
return
endif
let l:old_name = s:rename_map[a:response.request_seq].old_name
let l:new_name = s:rename_map[a:response.request_seq].new_name
call remove(s:rename_map, a:response.request_seq)
if get(a:response, 'success', v:false) is v:false
let l:message = get(a:response, 'message', 'unknown')
call s:message('Error renaming "' . l:old_name . '" to: "' . l:new_name
\ . '". Reason: ' . l:message)
return
endif
let l:changes = []
for l:response_item in a:response.body.locs
let l:filename = l:response_item.file
let l:text_changes = []
for l:loc in l:response_item.locs
call add(l:text_changes, {
\ 'start': {
\ 'line': l:loc.start.line,
\ 'offset': l:loc.start.offset,
\ },
\ 'end': {
\ 'line': l:loc.end.line,
\ 'offset': l:loc.end.offset,
\ },
\ 'newText': l:new_name,
\})
endfor
call add(l:changes, {
\ 'fileName': l:filename,
\ 'textChanges': l:text_changes,
\})
endfor
if empty(l:changes)
call s:message('Error renaming "' . l:old_name . '" to: "' . l:new_name . '"')
return
endif
call ale#code_action#HandleCodeAction({
\ 'description': 'rename',
\ 'changes': l:changes,
\})
endfunction
function! ale#rename#HandleLSPResponse(conn_id, response) abort
if has_key(a:response, 'id')
\&& has_key(s:rename_map, a:response.id)
call remove(s:rename_map, a:response.id)
if !has_key(a:response, 'result')
call s:message('No rename result received from server')
return
endif
let l:workspace_edit = a:response.result
if !has_key(l:workspace_edit, 'changes') || empty(l:workspace_edit.changes)
call s:message('No changes received from server')
return
endif
let l:changes = []
for l:file_name in keys(l:workspace_edit.changes)
let l:text_edits = l:workspace_edit.changes[l:file_name]
let l:text_changes = []
for l:edit in l:text_edits
let l:range = l:edit.range
let l:new_text = l:edit.newText
call add(l:text_changes, {
\ 'start': {
\ 'line': l:range.start.line + 1,
\ 'offset': l:range.start.character + 1,
\ },
\ 'end': {
\ 'line': l:range.end.line + 1,
\ 'offset': l:range.end.character + 1,
\ },
\ 'newText': l:new_text,
\})
endfor
call add(l:changes, {
\ 'fileName': ale#path#FromURI(l:file_name),
\ 'textChanges': l:text_changes,
\})
endfor
call ale#code_action#HandleCodeAction({
\ 'description': 'rename',
\ 'changes': l:changes,
\})
endif
endfunction
function! s:OnReady(line, column, old_name, new_name, linter, lsp_details) abort
let l:id = a:lsp_details.connection_id
if !ale#lsp#HasCapability(l:id, 'rename')
return
endif
let l:buffer = a:lsp_details.buffer
let l:Callback = a:linter.lsp is# 'tsserver'
\ ? function('ale#rename#HandleTSServerResponse')
\ : function('ale#rename#HandleLSPResponse')
call ale#lsp#RegisterCallback(l:id, l:Callback)
if a:linter.lsp is# 'tsserver'
let l:message = ale#lsp#tsserver_message#Rename(
\ l:buffer,
\ a:line,
\ a:column,
\ g:ale_rename_tsserver_find_in_comments,
\ g:ale_rename_tsserver_find_in_strings,
\)
else
" Send a message saying the buffer has changed first, or the
" rename position probably won't make sense.
call ale#lsp#NotifyForChanges(l:id, l:buffer)
let l:message = ale#lsp#message#Rename(
\ l:buffer,
\ a:line,
\ a:column,
\ a:new_name
\)
endif
let l:request_id = ale#lsp#Send(l:id, l:message)
let s:rename_map[l:request_id] = {
\ 'new_name': a:new_name,
\ 'old_name': a:old_name,
\}
endfunction
function! s:ExecuteRename(linter, old_name, new_name) abort
let l:buffer = bufnr('')
let [l:line, l:column] = getpos('.')[1:2]
if a:linter.lsp isnot# 'tsserver'
let l:column = min([l:column, len(getline(l:line))])
endif
let l:Callback = function(
\ 's:OnReady', [l:line, l:column, a:old_name, a:new_name])
call ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
endfunction
function! ale#rename#Execute() abort
let l:lsp_linters = []
for l:linter in ale#linter#Get(&filetype)
if !empty(l:linter.lsp)
call add(l:lsp_linters, l:linter)
endif
endfor
if empty(l:lsp_linters)
call s:message('No active LSPs')
return
endif
let l:old_name = expand('<cword>')
let l:new_name = ale#util#Input('New name: ', l:old_name)
if empty(l:new_name)
call s:message('New name cannot be empty!')
return
endif
for l:lsp_linter in l:lsp_linters
call s:ExecuteRename(l:lsp_linter, l:old_name, l:new_name)
endfor
endfunction

View file

@ -74,3 +74,10 @@ function! ale#ruby#HandleRubocopOutput(buffer, lines) abort
return l:output return l:output
endfunction endfunction
function! ale#ruby#EscapeExecutable(executable, bundle_exec) abort
let l:exec_args = a:executable =~? 'bundle'
\ ? ' exec ' . a:bundle_exec
\ : ''
return ale#Escape(a:executable) . l:exec_args
endfunction

View file

@ -14,12 +14,16 @@ let g:ale_sign_style_error = get(g:, 'ale_sign_style_error', g:ale_sign_error)
let g:ale_sign_warning = get(g:, 'ale_sign_warning', '--') let g:ale_sign_warning = get(g:, 'ale_sign_warning', '--')
let g:ale_sign_style_warning = get(g:, 'ale_sign_style_warning', g:ale_sign_warning) let g:ale_sign_style_warning = get(g:, 'ale_sign_style_warning', g:ale_sign_warning)
let g:ale_sign_info = get(g:, 'ale_sign_info', g:ale_sign_warning) let g:ale_sign_info = get(g:, 'ale_sign_info', g:ale_sign_warning)
let g:ale_sign_priority = get(g:, 'ale_sign_priority', 30)
" This variable sets an offset which can be set for sign IDs. " This variable sets an offset which can be set for sign IDs.
" This ID can be changed depending on what IDs are set for other plugins. " This ID can be changed depending on what IDs are set for other plugins.
" The dummy sign will use the ID exactly equal to the offset. " The dummy sign will use the ID exactly equal to the offset.
let g:ale_sign_offset = get(g:, 'ale_sign_offset', 1000000) let g:ale_sign_offset = get(g:, 'ale_sign_offset', 1000000)
" This flag can be set to 1 to keep sign gutter always open " This flag can be set to 1 to keep sign gutter always open
let g:ale_sign_column_always = get(g:, 'ale_sign_column_always', 0) let g:ale_sign_column_always = get(g:, 'ale_sign_column_always', 0)
let g:ale_sign_highlight_linenrs = get(g:, 'ale_sign_highlight_linenrs', 0)
let s:supports_sign_groups = has('nvim-0.4.2') || (v:version >= 801 && has('patch614'))
if !hlexists('ALEErrorSign') if !hlexists('ALEErrorSign')
highlight link ALEErrorSign error highlight link ALEErrorSign error
@ -82,7 +86,7 @@ execute 'sign define ALEInfoSign text=' . s:EscapeSignText(g:ale_sign_info)
\ . ' texthl=ALEInfoSign linehl=ALEInfoLine' \ . ' texthl=ALEInfoSign linehl=ALEInfoLine'
sign define ALEDummySign sign define ALEDummySign
if has('nvim-0.3.2') if g:ale_sign_highlight_linenrs && has('nvim-0.3.2')
if !hlexists('ALEErrorSignLineNr') if !hlexists('ALEErrorSignLineNr')
highlight link ALEErrorSignLineNr CursorLineNr highlight link ALEErrorSignLineNr CursorLineNr
endif endif
@ -146,24 +150,59 @@ function! ale#sign#GetSignName(sublist) abort
return 'ALEErrorSign' return 'ALEErrorSign'
endfunction endfunction
function! s:PriorityCmd() abort
if s:supports_sign_groups
return ' priority=' . g:ale_sign_priority . ' '
else
return ''
endif
endfunction
function! s:GroupCmd() abort
if s:supports_sign_groups
return ' group=ale '
else
return ' '
endif
endfunction
" Read sign data for a buffer to a list of lines. " Read sign data for a buffer to a list of lines.
function! ale#sign#ReadSigns(buffer) abort function! ale#sign#ReadSigns(buffer) abort
redir => l:output redir => l:output
silent execute 'sign place buffer=' . a:buffer silent execute 'sign place ' . s:GroupCmd() . s:PriorityCmd()
\ . ' buffer=' . a:buffer
redir end redir end
return split(l:output, "\n") return split(l:output, "\n")
endfunction endfunction
function! ale#sign#ParsePattern() abort
if s:supports_sign_groups
" Matches output like :
" line=4 id=1 group=ale name=ALEErrorSign
" строка=1 id=1000001 группа=ale имя=ALEErrorSign
" 行=1 識別子=1000001 グループ=ale 名前=ALEWarningSign
" línea=12 id=1000001 grupo=ale nombre=ALEWarningSign
" riga=1 id=1000001 gruppo=ale nome=ALEWarningSign
" Zeile=235 id=1000001 Gruppe=ale Name=ALEErrorSign
let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=ale>.*\=(ALE[a-zA-Z]+Sign)'
else
" Matches output like :
" line=4 id=1 name=ALEErrorSign
" строка=1 id=1000001 имя=ALEErrorSign
" 行=1 識別子=1000001 名前=ALEWarningSign
" línea=12 id=1000001 nombre=ALEWarningSign
" riga=1 id=1000001 nome=ALEWarningSign
" Zeile=235 id=1000001 Name=ALEErrorSign
let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=(ALE[a-zA-Z]+Sign)'
endif
return l:pattern
endfunction
" Given a list of lines for sign output, return a List of [line, id, group] " Given a list of lines for sign output, return a List of [line, id, group]
function! ale#sign#ParseSigns(line_list) abort function! ale#sign#ParseSigns(line_list) abort
" Matches output like : let l:pattern =ale#sign#ParsePattern()
" line=4 id=1 name=ALEErrorSign
" строка=1 id=1000001 имя=ALEErrorSign
" 行=1 識別子=1000001 名前=ALEWarningSign
" línea=12 id=1000001 nombre=ALEWarningSign
" riga=1 id=1000001, nome=ALEWarningSign
let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=(ALE[a-zA-Z]+Sign)'
let l:result = [] let l:result = []
let l:is_dummy_sign_set = 0 let l:is_dummy_sign_set = 0
@ -318,8 +357,10 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
if !l:is_dummy_sign_set && (!empty(a:sign_map) || g:ale_sign_column_always) if !l:is_dummy_sign_set && (!empty(a:sign_map) || g:ale_sign_column_always)
call add(l:command_list, 'sign place ' call add(l:command_list, 'sign place '
\ . g:ale_sign_offset \ . g:ale_sign_offset
\ . ' line=1 name=ALEDummySign buffer=' \ . s:GroupCmd()
\ . a:buffer \ . s:PriorityCmd()
\ . ' line=1 name=ALEDummySign '
\ . ' buffer=' . a:buffer
\) \)
let l:is_dummy_sign_set = 1 let l:is_dummy_sign_set = 1
endif endif
@ -336,6 +377,8 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
if index(l:info.current_id_list, l:info.new_id) < 0 if index(l:info.current_id_list, l:info.new_id) < 0
call add(l:command_list, 'sign place ' call add(l:command_list, 'sign place '
\ . (l:info.new_id) \ . (l:info.new_id)
\ . s:GroupCmd()
\ . s:PriorityCmd()
\ . ' line=' . l:line_str \ . ' line=' . l:line_str
\ . ' name=' . (l:info.new_name) \ . ' name=' . (l:info.new_name)
\ . ' buffer=' . a:buffer \ . ' buffer=' . a:buffer
@ -350,6 +393,7 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
if l:current_id isnot l:info.new_id if l:current_id isnot l:info.new_id
call add(l:command_list, 'sign unplace ' call add(l:command_list, 'sign unplace '
\ . l:current_id \ . l:current_id
\ . s:GroupCmd()
\ . ' buffer=' . a:buffer \ . ' buffer=' . a:buffer
\) \)
endif endif
@ -360,6 +404,7 @@ function! ale#sign#GetSignCommands(buffer, was_sign_set, sign_map) abort
if l:is_dummy_sign_set && !g:ale_sign_column_always if l:is_dummy_sign_set && !g:ale_sign_column_always
call add(l:command_list, 'sign unplace ' call add(l:command_list, 'sign unplace '
\ . g:ale_sign_offset \ . g:ale_sign_offset
\ . s:GroupCmd()
\ . ' buffer=' . a:buffer \ . ' buffer=' . a:buffer
\) \)
endif endif
@ -414,3 +459,12 @@ function! ale#sign#SetSigns(buffer, loclist) abort
highlight link SignColumn ALESignColumnWithoutErrors highlight link SignColumn ALESignColumnWithoutErrors
endif endif
endfunction endfunction
" Remove all signs.
function! ale#sign#Clear() abort
if s:supports_sign_groups
sign unplace group=ale *
else
sign unplace *
endif
endfunction

View file

@ -477,3 +477,6 @@ function! ale#util#FindItemAtCursor(buffer) abort
return [l:info, l:loc] return [l:info, l:loc]
endfunction endfunction
function! ale#util#Input(message, value) abort
return input(a:message, a:value)
endfunction

View file

@ -15,18 +15,17 @@ csc *ale-cs-csc*
See |ale-lint-file-linters| for more information on linters which do not See |ale-lint-file-linters| for more information on linters which do not
check for problems while you type. check for problems while you type.
The csc linter uses the mono csc compiler providing full c# 7 and newer The csc linter uses the mono csc compiler, providing full C# 7 and newer
support to generate a temporary module target file (/t:module). The module support, to generate a temporary module target file (/t:module). The module
includes including all '*.cs' files contained in the directory tree rooted includes all '*.cs' files contained in the directory tree rooted at the path
at the path defined by the |g:ale_cs_csc_source| or |b:ale_cs_csc_source| defined by the |g:ale_cs_csc_source| or |b:ale_cs_csc_source| variable and
variabl and all sub directories. all sub directories.
It will in future replace the |ale-cs-mcs| and |ale-cs-mcsc| linters as both It will in future replace the |ale-cs-mcs| and |ale-cs-mcsc| linters as both
utilizer the mcsc compiler which according to mono porject ist further utilize the mcsc compiler which, according to the mono project, is no longer
developed and as of writint these lines only receives maintenance updates. actively developed, and only receives maintenance updates. However, because
The down is that the csc compiler does not support the -sytax option any more the csc compiler does not support the -syntax option, this linter does not
and therefore |ale-cs-csc| linter doese not offer any as you type syntax offer any as-you-type syntax checking, similar to the |ale-cs-mcsc| linter.
checking like the |ale-cs-mcsc| linter doesn't.
The paths to search for additional assembly files can be specified using the The paths to search for additional assembly files can be specified using the
|g:ale_cs_csc_assembly_path| or |b:ale_cs_csc_assembly_path| variables. |g:ale_cs_csc_assembly_path| or |b:ale_cs_csc_assembly_path| variables.

View file

@ -1,6 +1,15 @@
=============================================================================== ===============================================================================
ALE D Integration *ale-d-options* ALE D Integration *ale-d-options*
===============================================================================
dfmt *ale-d-dfmt*
g:ale_d_dfmt_options *g:ale_d_dfmt_options*
*b:ale_d_dfmt_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to the dfmt fixer.
=============================================================================== ===============================================================================
dls *ale-d-dls* dls *ale-d-dls*

View file

@ -184,13 +184,12 @@ tests: https://github.com/junegunn/vader.vim
See |ale-development-linter-tests| for more information on how to write linter See |ale-development-linter-tests| for more information on how to write linter
tests. tests.
When you add new linters or fixers, make sure to add them into the table in When you add new linters or fixers, make sure to add them into the tables in
the README, and also into the |ale-support| list in the main help file. If you supported-tools.md and |ale-supported-languages-and-tools.txt|. If you forget to
forget to keep them both in sync, you should see an error like the following keep them both in sync, you should see an error like the following in Travis CI.
in Travis CI. > >
======================================== ========================================
diff README.md and doc/ale.txt tables diff supported-tools.md and doc/ale-supported-languages-and-tools.txt tables
======================================== ========================================
Differences follow: Differences follow:

View file

@ -50,7 +50,7 @@ g:ale_elm_ls_use_global *g:ale_elm_ls_use_global*
g:ale_elm_ls_elm_path *g:ale_elm_ls_elm_path* g:ale_elm_ls_elm_path *g:ale_elm_ls_elm_path*
*b:ale_elm_ls_elm_path* *b:ale_elm_ls_elm_path*
Type: |String| Type: |String|
Default: `'elm'` Default: `''`
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
@ -58,7 +58,7 @@ g:ale_elm_ls_elm_path *g:ale_elm_ls_elm_path*
g:ale_elm_ls_elm_format_path *g:ale_elm_ls_elm_format_path* g:ale_elm_ls_elm_format_path *g:ale_elm_ls_elm_format_path*
*b:ale_elm_ls_elm_format_path* *b:ale_elm_ls_elm_format_path*
Type: |String| Type: |String|
Default: `'elm-format'` Default: `''`
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
@ -66,10 +66,18 @@ g:ale_elm_ls_elm_format_path *g:ale_elm_ls_elm_format_path*
g:ale_elm_ls_elm_test_path *g:ale_elm_ls_elm_test_path* g:ale_elm_ls_elm_test_path *g:ale_elm_ls_elm_test_path*
*b:ale_elm_ls_elm_test_path* *b:ale_elm_ls_elm_test_path*
Type: |String| Type: |String|
Default: `'elm-test'` Default: `''`
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
g:ale_elm_ls_elm_analyse_trigger *g:ale_elm_ls_elm_analyse_trigger*
*b:ale_elm_ls_elm_analyse_trigger*
Type: |String|
Default: `'change'`
One of 'change', 'save' or 'never'
=============================================================================== ===============================================================================
elm-make *ale-elm-elm-make* elm-make *ale-elm-elm-make*

View file

@ -9,6 +9,16 @@ fecs *ale-html-fecs*
and both of them reads `./.fecsrc` as the default configuration file. and both of them reads `./.fecsrc` as the default configuration file.
See: |ale-javascript-fecs|. See: |ale-javascript-fecs|.
===============================================================================
html-beautify *ale-html-beautify*
g:ale_html_beautify_options *g:ale_html_beautify_options*
*b:ale_html_beautify_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to html-beautify.
=============================================================================== ===============================================================================
htmlhint *ale-html-htmlhint* htmlhint *ale-html-htmlhint*

View file

@ -0,0 +1,40 @@
===============================================================================
ALE Ink Integration *ale-ink-options*
===============================================================================
ink-language-server *ale-ink-language-server*
Ink Language Server
(https://github.com/ephraim/ink-language-server)
g:ale_ink_ls_executable g:ale_ink_ls_executable
b:ale_ink_ls_executable
Type: |String|
Default: `'ink-language-server'`
Ink language server executable.
g:ale_ink_ls_initialization_options
g:ale_ink_ls_initialization_options
b:ale_ink_ls_initialization_options
Type: |Dictionary|
Default: `{}`
Dictionary containing configuration settings that will be passed to the
language server at startup. For certain platforms and certain story
structures, the defaults will suffice. However, many projects will need to
change these settings - see the ink-language-server website for more
information.
An example of setting non-default options:
{
\ 'ink': {
\ 'mainStoryPath': 'init.ink',
\ 'inklecateExecutablePath': '/usr/local/bin/inklecate',
\ 'runThroughMono': v:false
\ }
\}
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View file

@ -0,0 +1,45 @@
===============================================================================
ALE Nim Integration *ale-nim-options*
===============================================================================
nimcheck *ale-nim-nimcheck*
ALE does not provide additional configuration options for `nimcheck` at this
point.
===============================================================================
nimlsp *ale-nim-nimlsp*
g:nim_nimlsp_nim_sources *g:nim_nimlsp_nim_sources*
Type: |String|
Default: `''`
Sets the path to Nim source repository as the first argument to `nimlsp`
command.
===============================================================================
nimpretty *ale-nim-nimpretty*
g:ale_nim_nimpretty_executable *g:ale_nim_nimpretty_executable*
*b:ale_nim_nimpretty_executable*
Type: |String|
Default: `'nimpretty'`
This variable can be changed to use a different executable for nimpretty.
g:ale_nim_nimpretty_options *g:ale_nim_nimpretty_options*
*b:ale_nim_nimpretty_options*
Type: |String|
Default: `'--maxLineLen:80'`
This variable can be changed to modify flags given to nimpretty.
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View file

@ -0,0 +1,24 @@
===============================================================================
ALE Nix Integration *ale-nix-options*
===============================================================================
nixpkgs-fmt *ale-nix-nixpkgs-fmt*
g:ale_nix_nixpkgsfmt_executable *g:ale_nix_nixpkgsfmt_executable*
*b:ale_nix_nixpkgsfmt_executable*
Type: |String|
Default: `'nixpkgs-fmt'`
This variable sets executable used for nixpkgs-fmt.
g:ale_nix_nixpkgsfmt_options *g:ale_nix_nixpkgsfmt_options*
*b:ale_nix_nixpkgsfmt_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to the nixpkgs-fmt fixer.
===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View file

@ -157,9 +157,9 @@ g:ale_php_phpstan_level *g:ale_php_phpstan_level*
Type: |String| Type: |String|
Default: `''` Default: `''`
This variable controls the rule levels. 0 is the loosest and 4 is the This variable controls the rule levels. 0 is the loosest and 7 is the
strictest. If this option isn't set, the rule level will be controlled by strictest. If this option isn't set, the rule level will be controlled by
the configuration file. If no configuration file can be detected, `'4'` will the configuration file. If no configuration file can be detected, `'7'` will
be used instead. be used instead.
@ -189,6 +189,13 @@ g:ale_php_psalm_executable *g:ale_php_psalm_executable*
This variable sets the executable used for psalm. This variable sets the executable used for psalm.
g:ale_psalm_langserver_options *g:ale_psalm_langserver_options*
*b:ale_psalm_langserver_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to psalm.
=============================================================================== ===============================================================================
php-cs-fixer *ale-php-php-cs-fixer* php-cs-fixer *ale-php-php-cs-fixer*

View file

@ -29,5 +29,14 @@ g:ale_purescript_ls_config g:ale_purescript_ls_config
\ 'buildCommand': 'spago build -- --json-errors' \ 'buildCommand': 'spago build -- --json-errors'
\ } \ }
\} \}
===============================================================================
purty *ale-purescript-purty*
g:ale_purescript_purty_executable *g:ale_purescript_purty_executable*
*b:ale_purescript_purty_executable*
Type: |String|
Default: `'purty'`
This variable can be changed to use a different executable for purty.
=============================================================================== ===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View file

@ -21,6 +21,26 @@ g:ale_ruby_brakeman_options *g:ale_ruby_brakeman_options*
The contents of this variable will be passed through to brakeman. The contents of this variable will be passed through to brakeman.
===============================================================================
debride *ale-ruby-debride*
g:ale_ruby_debride_executable *g:ale_ruby_debride_executable*
*b:ale_ruby_debride_executable*
Type: String
Default: `'debride'`
Override the invoked debride binary. Set this to `'bundle'` to invoke
`'bundle` `exec` debride'.
g:ale_ruby_debride_options *g:ale_ruby_debride_options*
*b:ale_ruby_debride_options*
Type: |String|
Default: `''`
This variable can be changed to modify flags given to debride.
=============================================================================== ===============================================================================
rails_best_practices *ale-ruby-rails_best_practices* rails_best_practices *ale-ruby-rails_best_practices*
@ -91,7 +111,7 @@ g:ale_ruby_rubocop_options *g:ale_ruby_rubocop_options*
Type: |String| Type: |String|
Default: `''` Default: `''`
This variable can be change to modify flags given to rubocop. This variable can be changed to modify flags given to rubocop.
=============================================================================== ===============================================================================
@ -146,7 +166,7 @@ g:ale_ruby_sorbet_options *g:ale_ruby_sorbet_options*
Type: |String| Type: |String|
Default: `''` Default: `''`
This variable can be change to modify flags given to sorbet. This variable can be changed to modify flags given to sorbet.
=============================================================================== ===============================================================================
@ -166,7 +186,7 @@ g:ale_ruby_standardrb_options *g:ale_ruby_standardrb_options*
Type: |String| Type: |String|
Default: `''` Default: `''`
This variable can be change to modify flags given to standardrb. This variable can be changed to modify flags given to standardrb.
=============================================================================== ===============================================================================

View file

@ -2,6 +2,32 @@
ALE Scala Integration *ale-scala-options* ALE Scala Integration *ale-scala-options*
===============================================================================
metals *ale-scala-metals*
`metals` requires either an SBT project, a Mill project, or a running Bloop
server.
g:ale_scala_metals_executable *g:ale_scala_metals_executable*
*b:ale_scala_metals_executable*
Type: |String|
Default: `'metals-vim'`
Override the invoked `metals` binary.
g:ale_scala_metals_project_root *g:ale_scala_metals_project_root*
*b:ale_scala_metals_project_root*
Type: |String|
Default: `''`
By default the project root is found by searching upwards for `build.sbt`,
`build.sc`, `.bloop` or `.metals`.
If the project root is elsewhere, you can override the project root
directory.
=============================================================================== ===============================================================================
sbtserver *ale-scala-sbtserver* sbtserver *ale-scala-sbtserver*

View file

@ -2,6 +2,18 @@
ALE Solidity Integration *ale-solidity-options* ALE Solidity Integration *ale-solidity-options*
===============================================================================
solc *ale-solidity-solc*
g:ale_solidity_solc_options *g:ale_solidity_solc_options*
*b:ale_solidity_solc_options*
Type: |String|
Default: `''`
This variable can be set to pass extra options to solc.
=============================================================================== ===============================================================================
solhint *ale-solidity-solhint* solhint *ale-solidity-solhint*

View file

@ -39,5 +39,23 @@ g:ale_sql_sqlfmt_options *g:ale_sql_sqlfmt_options*
At this time only the -u flag is available to format with upper-case. At this time only the -u flag is available to format with upper-case.
===============================================================================
sqlformat *ale-sql-sqlformat*
g:ale_sql_sqlformat_executable *g:ale_sql_sqlformat_executable*
*b:ale_sql_sqlformat_executable*
Type: |String|
Default: `'sqlformat'`
This variable sets executable used for sqlformat.
g:ale_sql_sqlformat_options *g:ale_sql_sqlformat_options*
*b:ale_sql_sqlformat_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to the sqlformat fixer.
=============================================================================== ===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View file

@ -103,6 +103,7 @@ Notes:
* Cython (pyrex filetype) * Cython (pyrex filetype)
* `cython` * `cython`
* D * D
* `dfmt`
* `dls` * `dls`
* `dmd` * `dmd`
* `uncrustify` * `uncrustify`
@ -123,7 +124,7 @@ Notes:
* `mix`!! * `mix`!!
* Elm * Elm
* `elm-format` * `elm-format`
* `elm-lsp` * `elm-ls`
* `elm-make` * `elm-make`
* Erb * Erb
* `erb` * `erb`
@ -193,6 +194,7 @@ Notes:
* HTML * HTML
* `alex`!! * `alex`!!
* `fecs` * `fecs`
* `html-beautify`
* `HTMLHint` * `HTMLHint`
* `prettier` * `prettier`
* `proselint` * `proselint`
@ -200,6 +202,8 @@ Notes:
* `write-good` * `write-good`
* Idris * Idris
* `idris` * `idris`
* Ink
* `ink-language-server`
* ISPC * ISPC
* `ispc`!! * `ispc`!!
* Java * Java
@ -279,8 +283,11 @@ Notes:
* `nasm`!! * `nasm`!!
* Nim * Nim
* `nim check`!! * `nim check`!!
* `nimlsp`
* `nimpretty`
* nix * nix
* `nix-instantiate` * `nix-instantiate`
* `nixpkgs-fmt`
* nroff * nroff
* `alex`!! * `alex`!!
* `proselint` * `proselint`
@ -343,6 +350,7 @@ Notes:
* `puppet-lint` * `puppet-lint`
* PureScript * PureScript
* `purescript-language-server` * `purescript-language-server`
* `purty`
* Python * Python
* `autopep8` * `autopep8`
* `bandit` * `bandit`
@ -388,6 +396,7 @@ Notes:
* `rpmlint` * `rpmlint`
* Ruby * Ruby
* `brakeman` * `brakeman`
* `debride`
* `rails_best_practices`!! * `rails_best_practices`!!
* `reek` * `reek`
* `rubocop` * `rubocop`
@ -406,6 +415,7 @@ Notes:
* `stylelint` * `stylelint`
* Scala * Scala
* `fsc` * `fsc`
* `metals`
* `sbtserver` * `sbtserver`
* `scalac` * `scalac`
* `scalafmt` * `scalafmt`
@ -420,11 +430,13 @@ Notes:
* SML * SML
* `smlnj` * `smlnj`
* Solidity * Solidity
* `solc`
* `solhint` * `solhint`
* `solium` * `solium`
* SQL * SQL
* `pgformatter` * `pgformatter`
* `sqlfmt` * `sqlfmt`
* `sqlformat`
* `sqlint` * `sqlint`
* Stylus * Stylus
* `stylelint` * `stylelint`
@ -457,6 +469,7 @@ Notes:
* `eslint` * `eslint`
* `fecs` * `fecs`
* `prettier` * `prettier`
* `standard`
* `tslint` * `tslint`
* `tsserver` * `tsserver`
* `typecheck` * `typecheck`

View file

@ -16,6 +16,33 @@ prettier *ale-typescript-prettier*
See |ale-javascript-prettier| for information about the available options. See |ale-javascript-prettier| for information about the available options.
===============================================================================
standard *ale-typescript-standard*
g:ale_typescript_standard_executable *g:ale_typescript_standard_executable*
*b:ale_typescript_standard_executable*
Type: |String|
Default: `'standard'`
See |ale-integrations-local-executables|
g:ale_typescript_standard_options *g:ale_typescript_standard_options*
*b:ale_typescript_standard_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to standard.
g:ale_typescript_standard_use_global *g:ale_typescript_standard_use_global*
*b:ale_typescript_standard_use_global*
Type: |Number|
Default: `get(g:, 'ale_use_global_executables', 0)`
See |ale-integrations-local-executables|
=============================================================================== ===============================================================================
tslint *ale-typescript-tslint* tslint *ale-typescript-tslint*

View file

@ -9,7 +9,8 @@ CONTENTS *ale-contents*
1. Introduction.........................|ale-introduction| 1. Introduction.........................|ale-introduction|
2. Supported Languages & Tools..........|ale-support| 2. Supported Languages & Tools..........|ale-support|
3. Linting..............................|ale-lint| 3. Linting..............................|ale-lint|
3.1 Other Sources.....................|ale-lint-other-sources| 3.1 Adding Language Servers...........|ale-lint-language-servers|
3.2 Other Sources.....................|ale-lint-other-sources|
4. Fixing Problems......................|ale-fix| 4. Fixing Problems......................|ale-fix|
5. Language Server Protocol Support.....|ale-lsp| 5. Language Server Protocol Support.....|ale-lsp|
5.1 Completion........................|ale-completion| 5.1 Completion........................|ale-completion|
@ -147,7 +148,48 @@ ALE offers several options for controlling which linters are run.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
3.1 Other Sources *ale-lint-other-sources* 3.1 Adding Language Servers *ale-lint-language-servers*
ALE comes with many default configurations for language servers, so they can
be detected and run automatically. ALE can connect to other language servers
by defining a new linter for a filetype. New linters can be defined in |vimrc|,
in plugin files, or `ale_linters` directories in |runtimepath|.
See |ale-linter-loading-behavior| for more information on loading linters.
A minimal configuration for a language server linter might look so. >
call ale#linter#Define('filetype_here', {
\ 'name': 'any_name_you_want',
\ 'lsp': 'stdio',
\ 'executable': '/path/to/executable',
\ 'command': '%e run',
\ 'project_root': '/path/to/root_of_project',
\})
<
For language servers that use a TCP socket connection, you should define the
address to connect to instead. >
call ale#linter#Define('filetype_here', {
\ 'name': 'any_name_you_want',
\ 'lsp': 'socket',
\ 'address': 'servername:1234',
\ 'project_root': '/path/to/root_of_project',
\})
<
Most of the options for a language server can be replaced with a |Funcref|
for a function accepting a buffer number for dynamically computing values
such as the executable path, the project path, the server address, etc,
most of which can also be determined based on executing some other
asynchronous task. See |ale#command#Run()| for computing linter options
based on asynchronous results.
See |ale#linter#Define()| for a detailed explanation of all of the options
for configuring linters.
-------------------------------------------------------------------------------
3.2 Other Sources *ale-lint-other-sources*
Problems for a buffer can be taken from other sources and rendered by ALE. Problems for a buffer can be taken from other sources and rendered by ALE.
This allows ALE to be used in combination with other plugins which also want This allows ALE to be used in combination with other plugins which also want
@ -376,6 +418,10 @@ The |ALEComplete| command can be used to show completion suggestions manually,
even when |g:ale_completion_enabled| is set to `0`. For manually requesting even when |g:ale_completion_enabled| is set to `0`. For manually requesting
completion information with Deoplete, consult Deoplete's documentation. completion information with Deoplete, consult Deoplete's documentation.
When working with TypeScript files, ALE by can support automatic imports
from external modules. This behavior can be enabled by setting the
|g:ale_completion_tsserver_autoimport| variable to `1`.
*ale-completion-completeopt-bug* *ale-completion-completeopt-bug*
ALE Automatic completion implementation replaces |completeopt| before opening ALE Automatic completion implementation replaces |completeopt| before opening
@ -386,7 +432,42 @@ vimrc, and your issues should go away. >
set completeopt=menu,menuone,preview,noselect,noinsert set completeopt=menu,menuone,preview,noselect,noinsert
< <
*ale-symbols*
ALE provides a set of basic completion symbols. If you want to replace those
symbols with others, you can set the variable |g:ale_completion_symbols| with
a mapping of the type of completion to the symbol or other string that you
would like to use. An example here shows the available options for symbols >
let g:ale_completion_symbols = {
\ 'text': '',
\ 'method': '',
\ 'function': '',
\ 'constructor': '',
\ 'field': '',
\ 'variable': '',
\ 'class': '',
\ 'interface': '',
\ 'module': '',
\ 'property': '',
\ 'unit': 'unit',
\ 'value': 'val',
\ 'enum': '',
\ 'keyword': 'keyword',
\ 'snippet': '',
\ 'color': 'color',
\ 'file': '',
\ 'reference': 'ref',
\ 'folder': '',
\ 'enum member': '',
\ 'constant': '',
\ 'struct': '',
\ 'event': 'event',
\ 'operator': '',
\ 'type_parameter': 'type param',
\ '<default>': 'v'
\ }
<
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
5.2 Go To Definition *ale-go-to-definition* 5.2 Go To Definition *ale-go-to-definition*
@ -597,6 +678,16 @@ b:ale_completion_enabled *b:ale_completion_enabled*
See |ale-completion| See |ale-completion|
g:ale_completion_tsserver_autoimport *g:ale_completion_tsserver_autoimport*
Type: Number
Default: `0`
When this option is set to `0`, ALE will not try to automatically import
completion results from external modules. It can be enabled by setting it
to `1`.
g:ale_completion_excluded_words *g:ale_completion_excluded_words* g:ale_completion_excluded_words *g:ale_completion_excluded_words*
*b:ale_completion_excluded_words* *b:ale_completion_excluded_words*
Type: |List| Type: |List|
@ -615,6 +706,47 @@ g:ale_completion_excluded_words *g:ale_completion_excluded_words*
let b:ale_completion_excluded_words = ['it', 'describe'] let b:ale_completion_excluded_words = ['it', 'describe']
< <
g:ale_completion_symbols *g:ale_completion_symbols*
Type: |Dictionary|
A mapping from completion types to symbols for completions. See
|ale-symbols| for more information.
By default, this mapping only uses built in Vim completion kinds, but it can
be updated to use any unicode character for the completion kind. For
example: >
let g:ale_completion_symbols = {
\ 'text': '',
\ 'method': '',
\ 'function': '',
\ 'constructor': '',
\ 'field': '',
\ 'variable': '',
\ 'class': '',
\ 'interface': '',
\ 'module': '',
\ 'property': '',
\ 'unit': 'v',
\ 'value': 'v',
\ 'enum': 't',
\ 'keyword': 'v',
\ 'snippet': 'v',
\ 'color': 'v',
\ 'file': 'v',
\ 'reference': 'v',
\ 'folder': 'v',
\ 'enum_member': 'm',
\ 'constant': 'm',
\ 'struct': 't',
\ 'event': 'v',
\ 'operator': 'f',
\ 'type_parameter': 'p',
\ '<default>': 'v'
\ })
<
g:ale_completion_max_suggestions *g:ale_completion_max_suggestions* g:ale_completion_max_suggestions *g:ale_completion_max_suggestions*
Type: |Number| Type: |Number|
@ -745,6 +877,15 @@ g:ale_echo_msg_info_str *g:ale_echo_msg_info_str*
The string used for `%severity%` for info. See |g:ale_echo_msg_format| The string used for `%severity%` for info. See |g:ale_echo_msg_format|
g:ale_echo_msg_log_str *g:ale_echo_msg_log_str*
Type: |String|
Default: `'Log'`
The string used for `%severity%` for log, used only for handling LSP show
message requests. See |g:ale_lsp_show_message_format|
g:ale_echo_msg_warning_str *g:ale_echo_msg_warning_str* g:ale_echo_msg_warning_str *g:ale_echo_msg_warning_str*
Type: |String| Type: |String|
@ -1027,9 +1168,12 @@ g:ale_linter_aliases *g:ale_linter_aliases*
{ {
\ 'Dockerfile': 'dockerfile', \ 'Dockerfile': 'dockerfile',
\ 'csh': 'sh', \ 'csh': 'sh',
\ 'javascriptreact': ['javascript', 'jsx'],
\ 'plaintex': 'tex', \ 'plaintex': 'tex',
\ 'rmarkdown': 'r', \ 'rmarkdown': 'r',
\ 'rmd': 'r',
\ 'systemverilog': 'verilog', \ 'systemverilog': 'verilog',
\ 'typescriptreact': ['typescript', 'tsx'],
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'], \ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
\ 'vimwiki': 'markdown', \ 'vimwiki': 'markdown',
\ 'vue': ['vue', 'javascript'], \ 'vue': ['vue', 'javascript'],
@ -1192,6 +1336,47 @@ b:ale_loclist_msg_format *b:ale_loclist_msg_format*
The strings for configuring `%severity%` are also used for this option. The strings for configuring `%severity%` are also used for this option.
g:ale_lsp_show_message_format *g:ale_lsp_show_message_format*
Type: |String|
Default: `'%severity%:%linter%: %s'`
This variable defines the format that messages received from an LSP will
have when echoed. The following sequences of characters will be replaced.
`%s` - replaced with the message text
`%linter%` - replaced with the name of the linter
`%severity%` - replaced with the severity of the message
The strings for `%severity%` levels "error", "info" and "warning" are shared
with |g:ale_echo_msg_format|. Severity "log" is unique to
|g:ale_lsp_show_message_format| and it can be configured via
|g:ale_echo_msg_log_str| - Defaults to `'Log'`
Please note that |g:ale_lsp_show_message_format| *can not* be configured
separately for each buffer like |g:ale_echo_msg_format| can.
g:ale_lsp_show_message_severity *g:ale_lsp_show_message_severity*
Type: |String|
Default: `'error'`
This variable defines the minimum severity level an LSP message needs to be
displayed. Messages below this level are discarded; please note that
messages with `Log` severity level are always discarded.
Possible values follow the LSP spec `MessageType` definition:
`'error'` - Displays only errors.
`'warning'` - Displays errors and warnings.
`'information'` - Displays errors, warnings and infos
`'log'` - Same as `'information'`
`'disabled'` - Doesn't display any information at all.
g:ale_lsp_root *g:ale_lsp_root* g:ale_lsp_root *g:ale_lsp_root*
b:ale_lsp_root *b:ale_lsp_root* b:ale_lsp_root *b:ale_lsp_root*
@ -1317,6 +1502,27 @@ g:ale_pattern_options_enabled *g:ale_pattern_options_enabled*
will not set buffer variables per |g:ale_pattern_options|. will not set buffer variables per |g:ale_pattern_options|.
g:ale_rename_tsserver_find_in_comments *g:ale_rename_tsserver_find_in_comments*
Type: |Number|
Default: `0`
If enabled, this option will tell tsserver to find and replace text in
comments when calling |ALERename|. It can be enabled by settings the value
to `1`.
g:ale_rename_tsserver_find_in_strings *g:ale_rename_tsserver_find_in_strings*
Type: |Number|
Default: `0`
If enabled, this option will tell tsserver to find and replace text in
strings when calling |ALERename|. It can be enabled by settings the value to
`1`.
g:ale_set_balloons *g:ale_set_balloons* g:ale_set_balloons *g:ale_set_balloons*
*b:ale_set_balloons* *b:ale_set_balloons*
@ -1437,8 +1643,8 @@ g:ale_set_signs *g:ale_set_signs*
|ALEWarningLine| - All items with `'type': 'W'` |ALEWarningLine| - All items with `'type': 'W'`
|ALEInfoLine| - All items with `'type': 'I'` |ALEInfoLine| - All items with `'type': 'I'`
With Neovim 0.3.2 or higher, ALE uses `numhl` option to highlight 'number' With Neovim 0.3.2 or higher, ALE can use the `numhl` option to highlight the
column. It uses the following highlight groups. 'number' column. It uses the following highlight groups.
|ALEErrorSignLineNr| - Items with `'type': 'E'` |ALEErrorSignLineNr| - Items with `'type': 'E'`
|ALEWarningSignLineNr| - Items with `'type': 'W'` |ALEWarningSignLineNr| - Items with `'type': 'W'`
@ -1446,6 +1652,9 @@ g:ale_set_signs *g:ale_set_signs*
|ALEStyleErrorSignLineNr| - Items with `'type': 'E'` and `'sub_type': 'style'` |ALEStyleErrorSignLineNr| - Items with `'type': 'E'` and `'sub_type': 'style'`
|ALEStyleWarningSignLineNr| - Items with `'type': 'W'` and `'sub_type': 'style'` |ALEStyleWarningSignLineNr| - Items with `'type': 'W'` and `'sub_type': 'style'`
To enable line number highlighting |g:ale_sign_highlight_linenrs| must be
set to `1` before ALE is loaded.
The markers for the highlights can be customized with the following options: The markers for the highlights can be customized with the following options:
|g:ale_sign_error| |g:ale_sign_error|
@ -1460,6 +1669,16 @@ g:ale_set_signs *g:ale_set_signs*
To limit the number of signs ALE will set, see |g:ale_max_signs|. To limit the number of signs ALE will set, see |g:ale_max_signs|.
g:ale_sign_priority *g:ale_sign_priority*
Type: |Number|
Default: `30`
From Neovim 0.4.0 and Vim 8.1, ALE can set sign priority to all signs. The
larger this value is, the higher priority ALE signs have over other plugin
signs. See |sign-priority| for further details on how priority works.
g:ale_shell *g:ale_shell* g:ale_shell *g:ale_shell*
Type: |String| Type: |String|
@ -1552,6 +1771,16 @@ g:ale_sign_warning *g:ale_sign_warning*
The sign for warnings in the sign gutter. The sign for warnings in the sign gutter.
g:ale_sign_highlight_linenrs *g:ale_sign_highlight_linenrs*
Type: |Number|
Default: `0`
When set to `1`, this option enables highlighting problems on the 'number'
column in Vim versions that support `numhl` highlights. This option must be
configured before ALE is loaded.
g:ale_update_tagstack *g:ale_update_tagstack* g:ale_update_tagstack *g:ale_update_tagstack*
*b:ale_update_tagstack* *b:ale_update_tagstack*
Type: |Number| Type: |Number|
@ -1606,6 +1835,8 @@ g:ale_virtualtext_cursor *g:ale_virtualtext_cursor*
Type: |Number| Type: |Number|
Default: `0` Default: `0`
This option only has any effect in NeoVim.
When this option is set to `1`, a message will be shown when a cursor is When this option is set to `1`, a message will be shown when a cursor is
near a warning or error. ALE will attempt to find the warning or error at a near a warning or error. ALE will attempt to find the warning or error at a
column nearest to the cursor when the cursor is resting on a line which column nearest to the cursor when the cursor is resting on a line which
@ -1954,6 +2185,14 @@ g:ale_languagetool_executable *g:ale_languagetool_executable*
The executable to run for languagetool. The executable to run for languagetool.
g:ale_languagetool_options *g:ale_languagetool_options*
*b:ale_languagetool_options*
Type: |String|
Default: `'--autoDetect'`
This variable can be set to pass additional options to languagetool.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
7.3. Options for write-good *ale-write-good-options* 7.3. Options for write-good *ale-write-good-options*
@ -2053,6 +2292,7 @@ documented in additional help files.
nvcc..................................|ale-cuda-nvcc| nvcc..................................|ale-cuda-nvcc|
clang-format..........................|ale-cuda-clangformat| clang-format..........................|ale-cuda-clangformat|
d.......................................|ale-d-options| d.......................................|ale-d-options|
dfmt..................................|ale-d-dfmt|
dls...................................|ale-d-dls| dls...................................|ale-d-dls|
uncrustify............................|ale-d-uncrustify| uncrustify............................|ale-d-uncrustify|
dart....................................|ale-dart-options| dart....................................|ale-dart-options|
@ -2129,6 +2369,7 @@ documented in additional help files.
terraform-fmt.........................|ale-hcl-terraform-fmt| terraform-fmt.........................|ale-hcl-terraform-fmt|
html....................................|ale-html-options| html....................................|ale-html-options|
fecs..................................|ale-html-fecs| fecs..................................|ale-html-fecs|
html-beautify.........................|ale-html-beautify|
htmlhint..............................|ale-html-htmlhint| htmlhint..............................|ale-html-htmlhint|
tidy..................................|ale-html-tidy| tidy..................................|ale-html-tidy|
prettier..............................|ale-html-prettier| prettier..............................|ale-html-prettier|
@ -2136,6 +2377,8 @@ documented in additional help files.
write-good............................|ale-html-write-good| write-good............................|ale-html-write-good|
idris...................................|ale-idris-options| idris...................................|ale-idris-options|
idris.................................|ale-idris-idris| idris.................................|ale-idris-idris|
ink.....................................|ale-ink-options|
ink-language-server...................|ale-ink-language-server|
ispc....................................|ale-ispc-options| ispc....................................|ale-ispc-options|
ispc..................................|ale-ispc-ispc| ispc..................................|ale-ispc-ispc|
java....................................|ale-java-options| java....................................|ale-java-options|
@ -2191,6 +2434,12 @@ documented in additional help files.
mmc...................................|ale-mercury-mmc| mmc...................................|ale-mercury-mmc|
nasm....................................|ale-nasm-options| nasm....................................|ale-nasm-options|
nasm..................................|ale-nasm-nasm| nasm..................................|ale-nasm-nasm|
nim.....................................|ale-nim-options|
nimcheck..............................|ale-nim-nimcheck|
nimlsp................................|ale-nim-nimlsp|
nimpretty.............................|ale-nim-nimpretty|
nix.....................................|ale-nix-options|
nixpkgs-fmt...........................|ale-nix-nixpkgs-fmt|
nroff...................................|ale-nroff-options| nroff...................................|ale-nroff-options|
write-good............................|ale-nroff-write-good| write-good............................|ale-nroff-write-good|
objc....................................|ale-objc-options| objc....................................|ale-objc-options|
@ -2246,6 +2495,7 @@ documented in additional help files.
puppet-languageserver.................|ale-puppet-languageserver| puppet-languageserver.................|ale-puppet-languageserver|
purescript..............................|ale-purescript-options| purescript..............................|ale-purescript-options|
purescript-language-server............|ale-purescript-language-server| purescript-language-server............|ale-purescript-language-server|
purty.................................|ale-purescript-purty|
pyrex (cython)..........................|ale-pyrex-options| pyrex (cython)..........................|ale-pyrex-options|
cython................................|ale-pyrex-cython| cython................................|ale-pyrex-cython|
python..................................|ale-python-options| python..................................|ale-python-options|
@ -2281,6 +2531,7 @@ documented in additional help files.
write-good............................|ale-restructuredtext-write-good| write-good............................|ale-restructuredtext-write-good|
ruby....................................|ale-ruby-options| ruby....................................|ale-ruby-options|
brakeman..............................|ale-ruby-brakeman| brakeman..............................|ale-ruby-brakeman|
debride...............................|ale-ruby-debride|
rails_best_practices..................|ale-ruby-rails_best_practices| rails_best_practices..................|ale-ruby-rails_best_practices|
reek..................................|ale-ruby-reek| reek..................................|ale-ruby-reek|
rubocop...............................|ale-ruby-rubocop| rubocop...............................|ale-ruby-rubocop|
@ -2298,6 +2549,7 @@ documented in additional help files.
sasslint..............................|ale-sass-sasslint| sasslint..............................|ale-sass-sasslint|
stylelint.............................|ale-sass-stylelint| stylelint.............................|ale-sass-stylelint|
scala...................................|ale-scala-options| scala...................................|ale-scala-options|
metals................................|ale-scala-metals|
sbtserver.............................|ale-scala-sbtserver| sbtserver.............................|ale-scala-sbtserver|
scalafmt..............................|ale-scala-scalafmt| scalafmt..............................|ale-scala-scalafmt|
scalastyle............................|ale-scala-scalastyle| scalastyle............................|ale-scala-scalastyle|
@ -2313,6 +2565,7 @@ documented in additional help files.
sml.....................................|ale-sml-options| sml.....................................|ale-sml-options|
smlnj.................................|ale-sml-smlnj| smlnj.................................|ale-sml-smlnj|
solidity................................|ale-solidity-options| solidity................................|ale-solidity-options|
solc..................................|ale-solidity-solc|
solhint...............................|ale-solidity-solhint| solhint...............................|ale-solidity-solhint|
solium................................|ale-solidity-solium| solium................................|ale-solidity-solium|
spec....................................|ale-spec-options| spec....................................|ale-spec-options|
@ -2320,6 +2573,7 @@ documented in additional help files.
sql.....................................|ale-sql-options| sql.....................................|ale-sql-options|
pgformatter...........................|ale-sql-pgformatter| pgformatter...........................|ale-sql-pgformatter|
sqlfmt................................|ale-sql-sqlfmt| sqlfmt................................|ale-sql-sqlfmt|
sqlformat.............................|ale-sql-sqlformat|
stylus..................................|ale-stylus-options| stylus..................................|ale-stylus-options|
stylelint.............................|ale-stylus-stylelint| stylelint.............................|ale-stylus-stylelint|
sugarss.................................|ale-sugarss-options| sugarss.................................|ale-sugarss-options|
@ -2347,6 +2601,7 @@ documented in additional help files.
typescript..............................|ale-typescript-options| typescript..............................|ale-typescript-options|
eslint................................|ale-typescript-eslint| eslint................................|ale-typescript-eslint|
prettier..............................|ale-typescript-prettier| prettier..............................|ale-typescript-prettier|
standard..............................|ale-typescript-standard|
tslint................................|ale-typescript-tslint| tslint................................|ale-typescript-tslint|
tsserver..............................|ale-typescript-tsserver| tsserver..............................|ale-typescript-tsserver|
vala....................................|ale-vala-options| vala....................................|ale-vala-options|
@ -2521,6 +2776,18 @@ ALEHover *ALEHover*
A plug mapping `<Plug>(ale_hover)` is defined for this command. A plug mapping `<Plug>(ale_hover)` is defined for this command.
ALEOrganizeImports *ALEOrganizeImports*
Organize imports using tsserver. Currently not implemented for LSPs.
ALERename *ALERename*
Rename a symbol using TypeScript server or Language Server.
The user will be prompted for a new name.
ALESymbolSearch `<query>` *ALESymbolSearch* ALESymbolSearch `<query>` *ALESymbolSearch*
Search for symbols in the workspace, taken from any available LSP linters. Search for symbols in the workspace, taken from any available LSP linters.

View file

@ -221,6 +221,12 @@ command! -nargs=1 ALESymbolSearch :call ale#symbol#Search(<q-args>)
command! -bar ALEComplete :call ale#completion#GetCompletions('ale-manual') command! -bar ALEComplete :call ale#completion#GetCompletions('ale-manual')
" Rename symbols using tsserver and LSP
command! -bar ALERename :call ale#rename#Execute()
" Organize import statements using tsserver
command! -bar ALEOrganizeImports :call ale#organize_imports#Execute()
" <Plug> mappings for commands " <Plug> mappings for commands
nnoremap <silent> <Plug>(ale_previous) :ALEPrevious<Return> nnoremap <silent> <Plug>(ale_previous) :ALEPrevious<Return>
nnoremap <silent> <Plug>(ale_previous_wrap) :ALEPreviousWrap<Return> nnoremap <silent> <Plug>(ale_previous_wrap) :ALEPreviousWrap<Return>
@ -259,6 +265,7 @@ nnoremap <silent> <Plug>(ale_find_references) :ALEFindReferences<Return>
nnoremap <silent> <Plug>(ale_hover) :ALEHover<Return> nnoremap <silent> <Plug>(ale_hover) :ALEHover<Return>
nnoremap <silent> <Plug>(ale_documentation) :ALEDocumentation<Return> nnoremap <silent> <Plug>(ale_documentation) :ALEDocumentation<Return>
inoremap <silent> <Plug>(ale_complete) <C-\><C-O>:ALEComplete<Return> inoremap <silent> <Plug>(ale_complete) <C-\><C-O>:ALEComplete<Return>
nnoremap <silent> <Plug>(ale_rename) :ALERename<Return>
" Set up autocmd groups now. " Set up autocmd groups now.
call ale#events#Init() call ale#events#Init()

View file

@ -112,6 +112,7 @@ formatting.
* Cython (pyrex filetype) * Cython (pyrex filetype)
* [cython](http://cython.org/) * [cython](http://cython.org/)
* D * D
* [dfmt](https://github.com/dlang-community/dfmt)
* [dls](https://github.com/d-language-server/dls) * [dls](https://github.com/d-language-server/dls)
* [dmd](https://dlang.org/dmd-linux.html) * [dmd](https://dlang.org/dmd-linux.html)
* [uncrustify](https://github.com/uncrustify/uncrustify) * [uncrustify](https://github.com/uncrustify/uncrustify)
@ -132,7 +133,7 @@ formatting.
* [mix](https://hexdocs.pm/mix/Mix.html) :warning: :floppy_disk: * [mix](https://hexdocs.pm/mix/Mix.html) :warning: :floppy_disk:
* Elm * Elm
* [elm-format](https://github.com/avh4/elm-format) * [elm-format](https://github.com/avh4/elm-format)
* [elm-lsp](https://github.com/antew/elm-lsp) * [elm-ls](https://github.com/elm-tooling/elm-language-server)
* [elm-make](https://github.com/elm/compiler) * [elm-make](https://github.com/elm/compiler)
* Erb * Erb
* [erb](https://apidock.com/ruby/ERB) * [erb](https://apidock.com/ruby/ERB)
@ -202,6 +203,7 @@ formatting.
* HTML * HTML
* [alex](https://github.com/wooorm/alex) :floppy_disk: * [alex](https://github.com/wooorm/alex) :floppy_disk:
* [fecs](http://fecs.baidu.com/) * [fecs](http://fecs.baidu.com/)
* [html-beautify](https://beautifier.io/)
* [HTMLHint](http://htmlhint.com/) * [HTMLHint](http://htmlhint.com/)
* [prettier](https://github.com/prettier/prettier) * [prettier](https://github.com/prettier/prettier)
* [proselint](http://proselint.com/) * [proselint](http://proselint.com/)
@ -209,6 +211,8 @@ formatting.
* [write-good](https://github.com/btford/write-good) * [write-good](https://github.com/btford/write-good)
* Idris * Idris
* [idris](http://www.idris-lang.org/) * [idris](http://www.idris-lang.org/)
* Ink
* [ink-language-server](https://github.com/ephread/ink-language-server)
* ISPC * ISPC
* [ispc](https://ispc.github.io/) :floppy_disk: * [ispc](https://ispc.github.io/) :floppy_disk:
* Java * Java
@ -223,7 +227,7 @@ formatting.
* [eslint](http://eslint.org/) * [eslint](http://eslint.org/)
* [fecs](http://fecs.baidu.com/) * [fecs](http://fecs.baidu.com/)
* [flow](https://flowtype.org/) * [flow](https://flowtype.org/)
* [jscs](http://jscs.info/) * [jscs](https://jscs-dev.github.io/)
* [jshint](http://jshint.com/) * [jshint](http://jshint.com/)
* [prettier](https://github.com/prettier/prettier) * [prettier](https://github.com/prettier/prettier)
* [prettier-eslint](https://github.com/prettier/prettier-eslint-cli) * [prettier-eslint](https://github.com/prettier/prettier-eslint-cli)
@ -248,7 +252,7 @@ formatting.
* [lacheck](https://www.ctan.org/pkg/lacheck) * [lacheck](https://www.ctan.org/pkg/lacheck)
* [proselint](http://proselint.com/) * [proselint](http://proselint.com/)
* [redpen](http://redpen.cc/) * [redpen](http://redpen.cc/)
* [texlab](https://texlab.netlify.com) ([Rust rewrite](https://github.com/latex-lsp/texlab/tree/rust)) * [texlab](https://texlab.netlify.com)
* [textlint](https://textlint.github.io/) * [textlint](https://textlint.github.io/)
* [vale](https://github.com/ValeLint/vale) * [vale](https://github.com/ValeLint/vale)
* [write-good](https://github.com/btford/write-good) * [write-good](https://github.com/btford/write-good)
@ -288,8 +292,11 @@ formatting.
* [nasm](https://www.nasm.us/) :floppy_disk: * [nasm](https://www.nasm.us/) :floppy_disk:
* Nim * Nim
* [nim check](https://nim-lang.org/docs/nimc.html) :floppy_disk: * [nim check](https://nim-lang.org/docs/nimc.html) :floppy_disk:
* [nimlsp](https://github.com/PMunch/nimlsp)
* nimpretty
* nix * nix
* [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate) * [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate)
* [nixpkgs-fmt](https://github.com/nix-community/nixpkgs-fmt)
* nroff * nroff
* [alex](https://github.com/wooorm/alex) :floppy_disk: * [alex](https://github.com/wooorm/alex) :floppy_disk:
* [proselint](http://proselint.com/) * [proselint](http://proselint.com/)
@ -338,8 +345,8 @@ formatting.
* Pony * Pony
* [ponyc](https://github.com/ponylang/ponyc) * [ponyc](https://github.com/ponylang/ponyc)
* PowerShell * PowerShell
* [powershell](https://github.com/PowerShell/PowerShell) :floppy_disk * [powershell](https://github.com/PowerShell/PowerShell) :floppy_disk:
* [psscriptanalyzer](https://github.com/PowerShell/PSScriptAnalyzer) :floppy_disk * [psscriptanalyzer](https://github.com/PowerShell/PSScriptAnalyzer) :floppy_disk:
* Prolog * Prolog
* [swipl](https://github.com/SWI-Prolog/swipl-devel) * [swipl](https://github.com/SWI-Prolog/swipl-devel)
* proto * proto
@ -352,6 +359,7 @@ formatting.
* [puppet-lint](https://puppet-lint.com) * [puppet-lint](https://puppet-lint.com)
* PureScript * PureScript
* [purescript-language-server](https://github.com/nwolverson/purescript-language-server) * [purescript-language-server](https://github.com/nwolverson/purescript-language-server)
* [purty](https://gitlab.com/joneshf/purty)
* Python * Python
* [autopep8](https://github.com/hhatto/autopep8) * [autopep8](https://github.com/hhatto/autopep8)
* [bandit](https://github.com/PyCQA/bandit) :warning: * [bandit](https://github.com/PyCQA/bandit) :warning:
@ -397,6 +405,7 @@ formatting.
* [rpmlint](https://github.com/rpm-software-management/rpmlint) :warning: (see `:help ale-integration-spec`) * [rpmlint](https://github.com/rpm-software-management/rpmlint) :warning: (see `:help ale-integration-spec`)
* Ruby * Ruby
* [brakeman](http://brakemanscanner.org/) :floppy_disk: * [brakeman](http://brakemanscanner.org/) :floppy_disk:
* [debride](https://github.com/seattlerb/debride) :floppy_disk:
* [rails_best_practices](https://github.com/flyerhzm/rails_best_practices) :floppy_disk: * [rails_best_practices](https://github.com/flyerhzm/rails_best_practices) :floppy_disk:
* [reek](https://github.com/troessner/reek) * [reek](https://github.com/troessner/reek)
* [rubocop](https://github.com/bbatsov/rubocop) * [rubocop](https://github.com/bbatsov/rubocop)
@ -415,6 +424,7 @@ formatting.
* [stylelint](https://github.com/stylelint/stylelint) * [stylelint](https://github.com/stylelint/stylelint)
* Scala * Scala
* [fsc](https://www.scala-lang.org/old/sites/default/files/linuxsoft_archives/docu/files/tools/fsc.html) * [fsc](https://www.scala-lang.org/old/sites/default/files/linuxsoft_archives/docu/files/tools/fsc.html)
* [metals](https://scalameta.org/metals/)
* [sbtserver](https://www.scala-sbt.org/1.x/docs/sbt-server.html) * [sbtserver](https://www.scala-sbt.org/1.x/docs/sbt-server.html)
* [scalac](http://scala-lang.org) * [scalac](http://scala-lang.org)
* [scalafmt](https://scalameta.org/scalafmt/) * [scalafmt](https://scalameta.org/scalafmt/)
@ -429,11 +439,13 @@ formatting.
* SML * SML
* [smlnj](http://www.smlnj.org/) * [smlnj](http://www.smlnj.org/)
* Solidity * Solidity
* [solc](https://solidity.readthedocs.io/)
* [solhint](https://github.com/protofire/solhint) * [solhint](https://github.com/protofire/solhint)
* [solium](https://github.com/duaraghav8/Solium) * [solium](https://github.com/duaraghav8/Solium)
* SQL * SQL
* [pgformatter](https://github.com/darold/pgFormatter) * [pgformatter](https://github.com/darold/pgFormatter)
* [sqlfmt](https://github.com/jackc/sqlfmt) * [sqlfmt](https://github.com/jackc/sqlfmt)
* [sqlformat](https://github.com/andialbrecht/sqlparse)
* [sqlint](https://github.com/purcell/sqlint) * [sqlint](https://github.com/purcell/sqlint)
* Stylus * Stylus
* [stylelint](https://github.com/stylelint/stylelint) * [stylelint](https://github.com/stylelint/stylelint)
@ -466,6 +478,7 @@ formatting.
* [eslint](http://eslint.org/) * [eslint](http://eslint.org/)
* [fecs](http://fecs.baidu.com/) * [fecs](http://fecs.baidu.com/)
* [prettier](https://github.com/prettier/prettier) * [prettier](https://github.com/prettier/prettier)
* [standard](http://standardjs.com/)
* [tslint](https://github.com/palantir/tslint) * [tslint](https://github.com/palantir/tslint)
* [tsserver](https://github.com/Microsoft/TypeScript/wiki/Standalone-Server-%28tsserver%29) * [tsserver](https://github.com/Microsoft/TypeScript/wiki/Standalone-Server-%28tsserver%29)
* typecheck * typecheck

View file

@ -330,6 +330,7 @@ fu! s:Open()
endf endf
fu! s:Close() fu! s:Close()
cal s:async_glob_abort()
cal s:buffunc(0) cal s:buffunc(0)
if winnr('$') == 1 if winnr('$') == 1
bw! bw!
@ -434,9 +435,62 @@ fu! s:GlobPath(dirs, depth)
en en
endf endf
fu! ctrlp#addfile(ch, file) fu! s:async_glob_update_progress(timer)
call add(g:ctrlp_allfiles, a:file) let s:must_wait = 0
cal s:BuildPrompt(1) if exists('s:focus') && get(s:, 'setlines_post_ended', 0)
cal s:ForceUpdate()
en
if exists('s:timer')
sil! cal ctrlp#statusline()
endif
if !exists('s:job')
call s:stop_timer_if_exists()
endif
endf
fu! s:async_glob_on_stdout(job, data, ...)
if type(a:data) ==# type([])
call extend(g:ctrlp_allfiles, filter(a:data, 'v:val !=# ""'))
else
call add(g:ctrlp_allfiles, a:data)
endif
endf
fu! s:async_glob_on_exit(...)
let s:must_wait = 0
if exists('s:job')
unlet s:job
endif
cal s:stop_timer_if_exists()
if exists('s:focus') && get(s:, 'setlines_post_ended', 0)
sil! cal ctrlp#statusline()
cal s:ForceUpdate()
en
endf
fu! s:async_glob_abort()
cal s:stop_job_if_exists()
cal s:stop_timer_if_exists()
cal s:ForceUpdate()
endf
fu! s:stop_timer_if_exists()
if exists('s:timer')
call timer_stop(s:timer)
unlet s:timer
en
endf
fu! s:stop_job_if_exists()
if exists('s:job')
if !has('nvim')
cal job_stop(s:job)
else
cal jobstop(s:job)
endif
unlet s:job
en
endf endf
fu! s:safe_printf(format, ...) fu! s:safe_printf(format, ...)
@ -462,12 +516,26 @@ fu! s:UserCmd(lscmd)
if (has('win32') || has('win64')) && match(&shell, 'sh') != -1 if (has('win32') || has('win64')) && match(&shell, 'sh') != -1
let path = tr(path, '\', '/') let path = tr(path, '\', '/')
en en
if s:usrcmdasync && v:version >= 800 && exists('*job_start') if s:usrcmdasync && (v:version >= 800 || has('nvim')) && (exists('*job_start') || exists('*jobstart'))
if exists('s:job') cal s:stop_job_if_exists()
call job_stop(s:job)
en
let g:ctrlp_allfiles = [] let g:ctrlp_allfiles = []
let s:job = job_start([&shell, &shellcmdflag, printf(lscmd, path)], {'callback': 'ctrlp#addfile'}) let s:must_wait = 1
let argv = [&shell, &shellcmdflag, printf(lscmd, path)]
if !has('nvim')
let s:job = job_start(argv, {
\ 'out_cb': function('s:async_glob_on_stdout'),
\ 'exit_cb': function('s:async_glob_on_exit')
\ })
else
let s:job = jobstart(argv, {
\ 'on_stdout': function('s:async_glob_on_stdout'),
\ 'on_exit': function('s:async_glob_on_exit')
\ })
endif
let s:timer = timer_start(250, function('s:async_glob_update_progress'), {'repeat': -1})
while s:must_wait
sleep 50m
endwhile
elsei has('patch-7.4-597') && !(has('win32') || has('win64')) elsei has('patch-7.4-597') && !(has('win32') || has('win64'))
let g:ctrlp_allfiles = systemlist(s:safe_printf(lscmd, path)) let g:ctrlp_allfiles = systemlist(s:safe_printf(lscmd, path))
el el
@ -997,7 +1065,7 @@ fu! s:MapSpecs()
if !( exists('s:smapped') && s:smapped == s:bufnr ) if !( exists('s:smapped') && s:smapped == s:bufnr )
" Correct arrow keys in terminal " Correct arrow keys in terminal
if ( has('termresponse') && v:termresponse =~ "\<ESC>" ) if ( has('termresponse') && v:termresponse =~ "\<ESC>" )
\ || &term =~? '\vxterm|<k?vt|gnome|screen|linux|ansi|tmux|st(-[-a-z0-9]*)?$' \ || &term =~? '\vxterm|<k?vt|gnome|screen|linux|ansi|tmux|st(-[-a-z0-9]*)?(\:tc)?$'
for each in ['\A <up>','\B <down>','\C <right>','\D <left>'] for each in ['\A <up>','\B <down>','\C <right>','\D <left>']
exe s:lcmap.' <esc>['.each exe s:lcmap.' <esc>['.each
endfo endfo
@ -1054,6 +1122,7 @@ fu! s:ToggleByFname()
endf endf
fu! s:ToggleType(dir) fu! s:ToggleType(dir)
cal s:async_glob_abort()
let max = len(g:ctrlp_ext_vars) + len(s:coretypes) - 1 let max = len(g:ctrlp_ext_vars) + len(s:coretypes) - 1
let next = s:walker(max, s:itemtype, a:dir) let next = s:walker(max, s:itemtype, a:dir)
cal ctrlp#setlines(next) cal ctrlp#setlines(next)
@ -1563,6 +1632,9 @@ fu! ctrlp#statusline()
let slider = ' <'.prv.'>={'.item.'}=<'.nxt.'>' let slider = ' <'.prv.'>={'.item.'}=<'.nxt.'>'
let dir = ' %=%<%#CtrlPMode2# %{getcwd()} %*' let dir = ' %=%<%#CtrlPMode2# %{getcwd()} %*'
let &l:stl = focus.byfname.regex.slider.marked.dir let &l:stl = focus.byfname.regex.slider.marked.dir
if exists('s:timer')
let &l:stl = '%#CtrlPStats# '.len(g:ctrlp_allfiles).' '.&l:stl
en
en en
endf endf
@ -2571,6 +2643,7 @@ endf
fu! s:setlines_pre(...) fu! s:setlines_pre(...)
if a:0 | let s:itemtype = a:1 | en if a:0 | let s:itemtype = a:1 | en
cal s:modevar() cal s:modevar()
let s:setlines_post_ended = 0
let g:ctrlp_lines = [] let g:ctrlp_lines = []
endf endf
@ -2581,6 +2654,7 @@ fu! s:setlines_post()
cal map(copy(g:ctrlp_ext_vars), 'add(types, v:val["init"])') cal map(copy(g:ctrlp_ext_vars), 'add(types, v:val["init"])')
en en
let g:ctrlp_lines = eval(types[s:itemtype]) let g:ctrlp_lines = eval(types[s:itemtype])
let s:setlines_post_ended = 1
endf endf
fu! ctrlp#setlines(...) fu! ctrlp#setlines(...)

View file

@ -1439,7 +1439,7 @@ Before 2016/11/28~
+ 新命令: |YankLine()| 来复制整个文件。 + 新命令: |YankLine()| 来复制整个文件。
+ 新选项: |g:ctrlp_types| 来选择內建类型。 + 新选项: |g:ctrlp_types| 来选择內建类型。
+ 新特性: 异步在新线程中调用 |g:ctrlp_user_command| 。 设置 + 新特性: 异步在新线程中调用 |g:ctrlp_user_command| 。 设置
|g:user_command_async| 为1来启用。 |g:ctrlp_user_command_async| 为1来启用。
+ 为 delphi, rust 和 golang提供buffertag支持。 + 为 delphi, rust 和 golang提供buffertag支持。
+ 新选项: |g:ctrlp_brief_prompt|, + 新选项: |g:ctrlp_brief_prompt|,
|g:match_current_file|, |g:match_current_file|,

View file

@ -1505,7 +1505,7 @@ Before 2016/11/28~
+ New command: |YankLine()| to yank current line. + New command: |YankLine()| to yank current line.
+ New option: |g:ctrlp_types| to select builtin modes. + New option: |g:ctrlp_types| to select builtin modes.
+ New feature: asynchronized spawn of |g:ctrlp_user_command|. This enable + New feature: asynchronized spawn of |g:ctrlp_user_command|. This enable
with set |g:user_command_async| to 1. with set |g:ctrlp_user_command_async| to 1.
+ Support buffertag for delphi, rust and golang. + Support buffertag for delphi, rust and golang.
+ New option: |g:ctrlp_brief_prompt|, + New option: |g:ctrlp_brief_prompt|,
|g:match_current_file|, |g:match_current_file|,

View file

@ -41,10 +41,13 @@ https://github.com/itchyny/lightline.vim
landscape is my colorscheme, which is a high-contrast cterm-supported colorscheme, available at https://github.com/itchyny/landscape.vim landscape is my colorscheme, which is a high-contrast cterm-supported colorscheme, available at https://github.com/itchyny/landscape.vim
For screenshots of all available colorshemes, see [this file](colorscheme.md).
## Why yet another clone of powerline? ## Why yet another clone of powerline?
+ [vim-powerline](https://github.com/Lokaltog/vim-powerline) is a nice plugin, but deprecated. + [vim-powerline](https://github.com/Lokaltog/vim-powerline) is a nice plugin, but deprecated.
+ [powerline](https://github.com/powerline/powerline) is a nice plugin, but difficult to configure. + [powerline](https://github.com/powerline/powerline) is a nice plugin, but difficult to configure.
+ [vim-airline](https://github.com/vim-airline/vim-airline) is a nice plugin, but it uses too much functions of other plugins, which should be done by users in `.vimrc`. + [vim-airline](https://github.com/vim-airline/vim-airline) is a nice plugin, but it uses too many functions of other plugins, which should be done by users in `.vimrc`.
## Spirit of this plugin ## Spirit of this plugin
+ Minimalism. The core script is very small to achieve enough functions as a statusline plugin. + Minimalism. The core script is very small to achieve enough functions as a statusline plugin.
@ -105,7 +108,7 @@ then modify `TERM` in your shell configuration (`.zshrc` for example)
```sh ```sh
export TERM=xterm-256color export TERM=xterm-256color
``` ```
and then add the following configure to your `.vimrc`. and then add the following configuration to your `.vimrc`.
```vim ```vim
if !has('gui_running') if !has('gui_running')
set t_Co=256 set t_Co=256
@ -154,7 +157,7 @@ Instead, lightline.vim provides a simple API that user can easily integrate with
Once you understand how to configure and how it will be displayed in the statusline, you can also tell how to integrate with your favorite plugins. Once you understand how to configure and how it will be displayed in the statusline, you can also tell how to integrate with your favorite plugins.
Let's start to configure the appearance. Let's start to configure the appearance.
The statusline is composed by multiple components. The statusline is composed of multiple components.
It shows the current mode, filename, modified status on the left, and file format, encoding, filetype and cursor positions on the right. It shows the current mode, filename, modified status on the left, and file format, encoding, filetype and cursor positions on the right.
So in order to add something in the statusline, you firstly create a new component and specify the place. So in order to add something in the statusline, you firstly create a new component and specify the place.
@ -225,7 +228,7 @@ Now let's add some integrations with other plugin.
The name of the git branch is important these days. The name of the git branch is important these days.
But lightline.vim does not provide this information by default because it is also one of plugin crossing configurations, and not all people want the integration. But lightline.vim does not provide this information by default because it is also one of plugin crossing configurations, and not all people want the integration.
In order to show the branch name in the statusline, install some plugins which provides the branch information. In order to show the branch name in the statusline, install some plugins which provide the branch information.
The [vim-fugitive](https://github.com/tpope/vim-fugitive) plugin is a famous plugin so let's integrate lightline.vim with it. The [vim-fugitive](https://github.com/tpope/vim-fugitive) plugin is a famous plugin so let's integrate lightline.vim with it.
If you don't like to install full git integration but just want to display the branch name in the statusline, you can use the [vim-gitbranch](https://github.com/itchyny/vim-gitbranch) plugin which provides `gitbranch#name` function. If you don't like to install full git integration but just want to display the branch name in the statusline, you can use the [vim-gitbranch](https://github.com/itchyny/vim-gitbranch) plugin which provides `gitbranch#name` function.
```vim ```vim

View file

@ -2,7 +2,7 @@
" Filename: autoload/lightline/colorscheme.vim " Filename: autoload/lightline/colorscheme.vim
" Author: itchyny " Author: itchyny
" License: MIT License " License: MIT License
" Last Change: 2018/09/01 22:48:24. " Last Change: 2019/09/07 11:20:37.
" ============================================================================= " =============================================================================
let s:save_cpo = &cpo let s:save_cpo = &cpo
@ -243,7 +243,7 @@ else
endif endif
let fg_color = synIDattr(synIDtrans(hlID('Normal')), 'fg', 'cterm') let fg_color = synIDattr(synIDtrans(hlID('Normal')), 'fg', 'cterm')
if fg_color !=# '' if fg_color !=# ''
if fg_color < 8 || 232 <= fg_color && fg_color < 244 if fg_color < 7 || 232 <= fg_color && fg_color < 244
return 'light' return 'light'
elseif 8 <= fg_color && fg_color < 16 || 244 <= fg_color elseif 8 <= fg_color && fg_color < 16 || 244 <= fg_color
return 'dark' return 'dark'

View file

@ -2,11 +2,10 @@
" Filename: autoload/lightline/colorscheme/one.vim " Filename: autoload/lightline/colorscheme/one.vim
" Author: Zoltan Dalmadi " Author: Zoltan Dalmadi
" License: MIT License " License: MIT License
" Last Change: 2019/05/12 20:30:51. " Last Change: 2019/09/09 22:42:48.
" ============================================================================= " =============================================================================
" Common colors " Common colors
let s:fg = [ '#abb2bf', 145 ]
let s:blue = [ '#61afef', 75 ] let s:blue = [ '#61afef', 75 ]
let s:green = [ '#98c379', 76 ] let s:green = [ '#98c379', 76 ]
let s:purple = [ '#c678dd', 176 ] let s:purple = [ '#c678dd', 176 ]
@ -18,44 +17,41 @@ let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual':
if lightline#colorscheme#background() ==# 'light' if lightline#colorscheme#background() ==# 'light'
" Light variant " Light variant
let s:bg = [ '#fafafa', 255 ] let s:fg = [ '#494b53', 238 ]
let s:gray1 = [ '#494b53', 238 ] let s:bg = [ '#fafafa', 255 ]
let s:gray2 = [ '#f0f0f0', 255 ] let s:gray1 = [ '#494b53', 238 ]
let s:gray3 = [ '#d0d0d0', 250 ] let s:gray2 = [ '#f0f0f0', 255 ]
let s:green = [ '#98c379', 35 ] let s:gray3 = [ '#d0d0d0', 250 ]
let s:green = [ '#98c379', 35 ]
let s:p.normal.left = [ [ s:bg, s:green, 'bold' ], [ s:gray1, s:gray3 ] ]
let s:p.normal.middle = [ [ s:gray1, s:gray2 ] ]
let s:p.inactive.left = [ [ s:bg, s:gray3 ], [ s:bg, s:gray3 ] ] let s:p.inactive.left = [ [ s:bg, s:gray3 ], [ s:bg, s:gray3 ] ]
let s:p.inactive.middle = [ [ s:gray3, s:gray2 ] ] let s:p.inactive.middle = [ [ s:gray3, s:gray2 ] ]
let s:p.inactive.right = [ [ s:bg, s:gray3 ] ] let s:p.inactive.right = [ [ s:bg, s:gray3 ] ]
let s:p.insert.left = [ [ s:bg, s:blue, 'bold' ], [ s:gray1, s:gray3 ] ]
let s:p.replace.left = [ [ s:bg, s:red1, 'bold' ], [ s:gray1, s:gray3 ] ]
let s:p.visual.left = [ [ s:bg, s:purple, 'bold' ], [ s:gray1, s:gray3 ] ]
else else
" Dark variant " Dark variant
let s:bg = [ '#282c34', 235 ] let s:fg = [ '#abb2bf', 145 ]
let s:gray1 = [ '#5c6370', 241 ] let s:bg = [ '#282c34', 235 ]
let s:gray2 = [ '#2c323d', 235 ] let s:gray1 = [ '#5c6370', 241 ]
let s:gray3 = [ '#3e4452', 240 ] let s:gray2 = [ '#2c323d', 235 ]
let s:gray3 = [ '#3e4452', 240 ]
let s:p.normal.left = [ [ s:bg, s:green, 'bold' ], [ s:fg, s:gray3 ] ]
let s:p.normal.middle = [ [ s:fg, s:gray2 ] ]
let s:p.inactive.left = [ [ s:gray1, s:bg ], [ s:gray1, s:bg ] ] let s:p.inactive.left = [ [ s:gray1, s:bg ], [ s:gray1, s:bg ] ]
let s:p.inactive.middle = [ [ s:gray1, s:gray2 ] ] let s:p.inactive.middle = [ [ s:gray1, s:gray2 ] ]
let s:p.inactive.right = [ [ s:gray1, s:bg ] ] let s:p.inactive.right = [ [ s:gray1, s:bg ] ]
let s:p.insert.left = [ [ s:bg, s:blue, 'bold' ], [ s:fg, s:gray3 ] ]
let s:p.replace.left = [ [ s:bg, s:red1, 'bold' ], [ s:fg, s:gray3 ] ]
let s:p.visual.left = [ [ s:bg, s:purple, 'bold' ], [ s:fg, s:gray3 ] ]
endif endif
" Common " Common
let s:p.normal.left = [ [ s:bg, s:green, 'bold' ], [ s:fg, s:gray3 ] ]
let s:p.normal.middle = [ [ s:fg, s:gray2 ] ]
let s:p.normal.right = [ [ s:bg, s:green, 'bold' ], [ s:fg, s:gray3 ] ] let s:p.normal.right = [ [ s:bg, s:green, 'bold' ], [ s:fg, s:gray3 ] ]
let s:p.normal.error = [ [ s:red2, s:bg ] ] let s:p.normal.error = [ [ s:red2, s:bg ] ]
let s:p.normal.warning = [ [ s:yellow, s:bg ] ] let s:p.normal.warning = [ [ s:yellow, s:bg ] ]
let s:p.insert.right = [ [ s:bg, s:blue, 'bold' ], [ s:fg, s:gray3 ] ] let s:p.insert.right = [ [ s:bg, s:blue, 'bold' ], [ s:fg, s:gray3 ] ]
let s:p.insert.left = [ [ s:bg, s:blue, 'bold' ], [ s:fg, s:gray3 ] ]
let s:p.replace.right = [ [ s:bg, s:red1, 'bold' ], [ s:fg, s:gray3 ] ] let s:p.replace.right = [ [ s:bg, s:red1, 'bold' ], [ s:fg, s:gray3 ] ]
let s:p.replace.left = [ [ s:bg, s:red1, 'bold' ], [ s:fg, s:gray3 ] ]
let s:p.visual.right = [ [ s:bg, s:purple, 'bold' ], [ s:fg, s:gray3 ] ] let s:p.visual.right = [ [ s:bg, s:purple, 'bold' ], [ s:fg, s:gray3 ] ]
let s:p.visual.left = [ [ s:bg, s:purple, 'bold' ], [ s:fg, s:gray3 ] ]
let s:p.tabline.left = [ [ s:fg, s:gray3 ] ] let s:p.tabline.left = [ [ s:fg, s:gray3 ] ]
let s:p.tabline.tabsel = [ [ s:bg, s:purple, 'bold' ] ] let s:p.tabline.tabsel = [ [ s:bg, s:purple, 'bold' ] ]
let s:p.tabline.middle = [ [ s:gray3, s:gray2 ] ] let s:p.tabline.middle = [ [ s:gray3, s:gray2 ] ]

View file

@ -0,0 +1,43 @@
" =============================================================================
" Filename: autoload/lightline/colorscheme/simpleblack.vim
" Author: lucasprag
" License: MIT License
" Last Change: 2019/10/28 22:54:01.
" =============================================================================
let s:black = [ '#000000', '0' ]
let s:black2 = [ '#121212', '233' ]
let s:gray = [ '#262626', '235' ]
let s:gray2 = [ '#3a3a3a', '237' ]
let s:gray3 = [ '#4e4e4e', '239' ]
let s:gray4 = [ '#626262', '241' ]
let s:violet = [ '#cf73e6', '170' ]
let s:blue = [ '#5f87af', '67' ]
let s:blue2 = [ '#91aadf', '110' ]
let s:green = [ '#57ba37', '71' ]
let s:gold = [ '#f0d50c', '220' ]
let s:red = [ '#d70000', '160' ]
let s:none = [ 'NONE', 'NONE' ]
let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual': {}, 'tabline': {}}
let s:p.normal.left = [ [ s:black, s:blue ], [ s:gray4, s:black2 ] ]
let s:p.normal.right = [ [ s:gray, s:gray4 ], [ s:gray3, s:gray ], [ s:gray2, s:black2 ] ]
let s:p.inactive.right = [ [ s:black, s:black2 ], [ s:gray, s:black ] ]
let s:p.inactive.left = [ [ s:gray, s:black ], [ s:black2, s:black ] ]
let s:p.insert.left = [ [ s:black, s:green ], [ s:gray4, s:black2 ] ]
let s:p.replace.left = [ [ s:black, s:red ], [ s:gray4, s:black2 ] ]
let s:p.visual.left = [ [ s:black, s:violet ], [ s:gray4, s:black2 ] ]
let s:p.normal.middle = [ [ s:gray, s:black ] ]
let s:p.inactive.middle = [ [ s:black2, s:black ] ]
let s:p.tabline.left = [ [ s:gray4, s:black ] ]
let s:p.tabline.tabsel = [ [ s:blue, s:black ] ]
let s:p.tabline.middle = [ [ s:black2, s:black ] ]
let s:p.tabline.right = copy(s:p.normal.right)
let s:p.normal.error = [ [ s:red, s:black ] ]
let s:p.normal.warning = [ [ s:gold, s:black2 ] ]
let g:lightline#colorscheme#simpleblack#palette = lightline#colorscheme#flatten(s:p)

View file

@ -0,0 +1,113 @@
# Available Colorschemes
### powerline (default)
![lightline.vim - powerline](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/powerline.png)
### powerlineish
![lightline.vim - powerlineish](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/powerlineish.png)
### wombat
![lightline.vim - wombat](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/wombat.png)
### OldHope
![lightline.vim - OldHope](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/OldHope.png)
### PaperColor dark
![lightline.vim - PaperColor dark](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/PaperColor_dark.png)
### PaperColor light
![lightline.vim - PaperColor light](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/PaperColor.png)
### Tomorrow
![lightline.vim - Tomorrow](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/Tomorrow.png)
### Tomorrow Night
![lightline.vim - Tomorrow Night](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/Tomorrow_Night.png)
### Tomorrow Night Blue
![lightline.vim - Tomorrow Night Blue](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/Tomorrow_Night_Blue.png)
### Tomorrow Night Bright
![lightline.vim - Tomorrow Night Bright](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/Tomorrow_Night_Bright.png)
### Tomorrow Night Eighties
![lightline.vim - Tomorrow Night Eighties](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/Tomorrow_Night_Eighties.png)
### ayu_mirage
![lightline.vim - ayu mirage](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/ayu_mirage.png)
### darcula
![lightline.vim - darcula](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/darcula.png)
### deus
![lightline.vim - deus](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/deus.png)
### jellybeans
![lightline.vim - jellybeans](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/jellybeans.png)
### selenized dark
![lightline.vim - selenized dark](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/selenized_dark.png)
### solarized dark
![lightline.vim - solarized_dark](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/solarized_dark.png)
### solarized light
![lightline.vim - solarized_light](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/solarized_light.png)
### materia
![lightline.vim - materia](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/materia.png)
### material
![lightline.vim - material](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/material.png)
### molokai
![lightline.vim - molokai](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/molokai.png)
### nord
![lightline.vim - nord](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/nord.png)
### seoul256
![lightline.vim - seoul256](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/seoul256.png)
### one
![lightline.vim - one](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/one.png)
### srcery_drk
![lightline.vim - srcery_drk](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/srcery_drk.png)
### simpleblack
![lightline.vim - simpleblack](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/simpleblack.png)
### landscape
![lightline.vim - landscape](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/landscape.png)
### 16color
![lightline.vim - 16color](https://raw.githubusercontent.com/wiki/itchyny/lightline.vim/image/16color.png)

View file

@ -5,9 +5,12 @@ Closes # <!-- Issue number this PR addresses. If none, remove this line. -->
--- ---
### New Version Info ### New Version Info
- [ ] Derive a new version number. Increment the: #### Author's Instructions
- [ ] `MAJOR` version when you make incompatible API changes - [ ] Derive a new `MAJOR.MINOR.PATCH` version number. Increment the:
- [ ] `MINOR` version when you add functionality in a backwards-compatible manner - `MAJOR` version when you make incompatible API changes
- [ ] `PATCH` version when you make backwards-compatible bug fixes - `MINOR` version when you add functionality in a backwards-compatible manner
- `PATCH` version when you make backwards-compatible bug fixes
- [ ] Update [CHANGELOG.md](https://github.com/scrooloose/nerdtree/blob/master/CHANGELOG.md), following the established pattern. - [ ] Update [CHANGELOG.md](https://github.com/scrooloose/nerdtree/blob/master/CHANGELOG.md), following the established pattern.
- [ ] Tag the merge commit, e.g. `git tag -a 3.1.4 -m "v3.1.4" && git push origin --tags` #### Collaborator's Instructions
- [ ] Review [CHANGELOG.md](https://github.com/scrooloose/nerdtree/blob/master/CHANGELOG.md), suggesting a different version number if necessary.
- [ ] After merge, tag the merge commit, e.g. `git tag -a 3.1.4 -m "v3.1.4" && git push origin --tags`

View file

@ -1,19 +1,42 @@
# Change Log # NERDTree Change Log
#### 5.3... <!--
- **.0**: Add file extension and size to sorting capabilities [#1029](https://github.com/scrooloose/nerdtree/pull/1029) Introduce a new MAJOR.MINOR version with a 4-hash header.
#### 5.2...
- **.9**: Suppress events for intermediate window/tab/buffer changes [#1026](https://github.com/scrooloose/nerdtree/pull/1026) PATCH versions are listed from newest to oldest under their respective MAJOR.MINOR version
in an unordered list. The format is:
- **.PATCH**: Pull Request Title (PR Author) [PR Number](Link to PR)
-->
#### 6.2
- **.1**: Menu option, 'copy path to clipboard' is aware of VIM clipboard option (jhzn) [#1056](https://github.com/scrooloose/nerdtree/pull/1056)
- **.0**: Support tab-specific CWDs (PhilRunninger) [#1032](https://github.com/scrooloose/nerdtree/pull/1032)
#### 6.1
- **.4**: Add VIM built-in package management to read me file. (pesarkhobeee) [#1049](https://github.com/scrooloose/nerdtree/pull/1049)
- **.3**: Save/Set screen state also on WinLeave and WinEnter. (PhilRunninger) [#1048](https://github.com/scrooloose/nerdtree/pull/1048)
- **.2**: Wrap saveScreenState's statements in a try-catch block. (PhilRunninger) [#1047](https://github.com/scrooloose/nerdtree/pull/1047)
- **.1**: Catch errors when trying to read CHANGELOG.md. (PhilRunninger) [#1045](https://github.com/scrooloose/nerdtree/pull/1045)
- **.0**: If file path doesn't exist, :NERDTreeFind its parent directory instead. (PhilRunninger) [#1043](https://github.com/scrooloose/nerdtree/pull/1043)
#### 6.0
- **.1**: Reintroduce necessary variable mistakenly removed. (PhilRunninger) [#1040](https://github.com/scrooloose/nerdtree/pull/1040)
- **.0**: Make the behavior of window splits consistent (dragonxlwang, PhilRunninger) [#1035](https://github.com/scrooloose/nerdtree/pull/1035)
#### 5.3
- **.3**: Fix (p)ath not displaying in the minimal menu (tuzz) [#1038](https://github.com/scrooloose/nerdtree/pull/1038)
- **.2**: Enable events when closing NerdTree window. (PhilRunninger) [#1037](https://github.com/scrooloose/nerdtree/pull/1037)
- **.1**: Fix the `e` key mapping to use netrw if desired (PhilRunninger) [#1031](https://github.com/scrooloose/nerdtree/pull/1031)
- **.0**: Add file extension and size to sorting capabilities (PhilRunninger) [#1029](https://github.com/scrooloose/nerdtree/pull/1029)
#### 5.2
- **.9**: Suppress events for intermediate window/tab/buffer changes (PhilRunninger) [#1026](https://github.com/scrooloose/nerdtree/pull/1026)
- **.8**: Revert [#1019](https://github.com/scrooloose/nerdtree/pull/1019) to fix nvim artifacts and flickering. (PhilRunninger) [#1021](https://github.com/scrooloose/nerdtree/pull/1021) - **.8**: Revert [#1019](https://github.com/scrooloose/nerdtree/pull/1019) to fix nvim artifacts and flickering. (PhilRunninger) [#1021](https://github.com/scrooloose/nerdtree/pull/1021)
- **.7**: Use :mode only in neovim. MacVim still needs to use :redraw! [#1019](https://github.com/scrooloose/nerdtree/pull/1019) - **.7**: Use :mode only in neovim. MacVim still needs to use :redraw! (PhilRunninger) [#1019](https://github.com/scrooloose/nerdtree/pull/1019)
- **.6**: In CHANGELOG.md and PR template, make reference to PR a true HTML link. [#1017](https://github.com/scrooloose/nerdtree/pull/1017) - **.6**: In CHANGELOG.md and PR template, make reference to PR a true HTML link. (PhilRunninger) [#1017](https://github.com/scrooloose/nerdtree/pull/1017)
- **.5**: Use `:mode` instead of `:redraw!` when updating menu. (PhilRunninger) [#1016](https://github.com/scrooloose/nerdtree/pull/1016) - **.5**: Use `:mode` instead of `:redraw!` when updating menu. (PhilRunninger) [#1016](https://github.com/scrooloose/nerdtree/pull/1016)
- **.4**: When searching for root line num, stop at end of file. (PhilRunninger) [#1015](https://github.com/scrooloose/nerdtree/pull/1015) - **.4**: When searching for root line num, stop at end of file. (PhilRunninger) [#1015](https://github.com/scrooloose/nerdtree/pull/1015)
- **.3**: Fix `<CR>` key map on the bookmark (lkebin) [#1014](https://github.com/scrooloose/nerdtree/pull/1014) - **.3**: Fix `<CR>` key map on the bookmark (lkebin) [#1014](https://github.com/scrooloose/nerdtree/pull/1014)
- **.2**: Make Enter work on the `.. ( up a dir )` line (PhilRunninger) [#1013](https://github.com/scrooloose/nerdtree/pull/1013) - **.2**: Make Enter work on the `.. ( up a dir )` line (PhilRunninger) [#1013](https://github.com/scrooloose/nerdtree/pull/1013)
- **.1**: Fix nerdtree#version() on Windows. (PhilRunninger) - **.1**: Fix nerdtree#version() on Windows. (PhilRunninger)
- **.0**: Expand functionality of `<CR>` mapping. (PhilRunninger) [#1011](https://github.com/scrooloose/nerdtree/pull/1011) - **.0**: Expand functionality of `<CR>` mapping. (PhilRunninger) [#1011](https://github.com/scrooloose/nerdtree/pull/1011)
#### 5.1... #### 5.1
- **.3**: Remove @mentions from PR template and change log. They weren't working. (PhilRunninger) [#1009](https://github.com/scrooloose/nerdtree/pull/1009) - **.3**: Remove @mentions from PR template and change log. They weren't working. (PhilRunninger) [#1009](https://github.com/scrooloose/nerdtree/pull/1009)
- **.2**: Fix NERDTree opening with the wrong size. (PhilRunninger) [#1008](https://github.com/scrooloose/nerdtree/pull/1008) - **.2**: Fix NERDTree opening with the wrong size. (PhilRunninger) [#1008](https://github.com/scrooloose/nerdtree/pull/1008)
- **.1**: Update Changelog and create PR Template (PhilRunninger) [#1007](https://github.com/scrooloose/nerdtree/pull/1007) - **.1**: Update Changelog and create PR Template (PhilRunninger) [#1007](https://github.com/scrooloose/nerdtree/pull/1007)

View file

@ -17,27 +17,62 @@ included documentation.
Installation Installation
------------ ------------
Below are just some of the methods for installing NERDTree. Do not follow all of these instructions; just pick your favorite one. Other plugin managers exist, and NERDTree should install just fine with any of them.
#### Vim 8+ packages
If you are using VIM version 8 or higher you can use its built-in package management; see `:help packages` for more information. Just run these commands in your terminal:
```bash
git clone https://github.com/scrooloose/nerdtree.git ~/.vim/pack/vendor/start/nerdtree
vim -u NONE -c "helptags ~/.vim/pack/vendor/start/nerdtree/doc" -c q
```
Otherwise, these are some of the several 3rd-party plugin managers you can choose from. Be sure you read the instructions for your chosen plugin, as there typically are additional steps you nee d to take.
#### [pathogen.vim](https://github.com/tpope/vim-pathogen) #### [pathogen.vim](https://github.com/tpope/vim-pathogen)
git clone https://github.com/scrooloose/nerdtree.git ~/.vim/bundle/nerdtree In the terminal,
```bash
git clone https://github.com/scrooloose/nerdtree.git ~/.vim/bundle/nerdtree
```
In your vimrc,
```vim
call pathogen#infect()
syntax on
filetype plugin indent on
```
Then reload Vim, run `:helptags ~/.vim/bundle/nerdtree/doc/` or `:Helptags`, and check out `:help NERDTree.txt`. Then reload vim, run `:helptags ~/.vim/bundle/nerdtree/doc/` or `:Helptags`.
#### [Vundle.vim](https://github.com/VundleVim/Vundle.vim)
```vim
call vundle#begin()
Plugin 'scrooloose/nerdtree'
call vundle#end()
```
#### [vim-plug](https://github.com/junegunn/vim-plug)
```vim
call plug#begin()
Plug 'scrooloose/nerdtree'
call plug#end()
```
#### [apt-vim](https://github.com/egalpin/apt-vim) #### [apt-vim](https://github.com/egalpin/apt-vim)
```bash
apt-vim install -y https://github.com/scrooloose/nerdtree.git
```
apt-vim install -y https://github.com/scrooloose/nerdtree.git F.A.Q. (here, and in the [Wiki](https://github.com/scrooloose/nerdtree/wiki))
F.A.Q.
------ ------
> Is there any support for `git` flags? #### Is there any support for `git` flags?
Yes, install [nerdtree-git-plugin](https://github.com/Xuyuanp/nerdtree-git-plugin). Yes, install [nerdtree-git-plugin](https://github.com/Xuyuanp/nerdtree-git-plugin).
--- ---
#### Can I have the nerdtree on every tab automatically?
> Can I have the nerdtree on every tab automatically?
Nope. If this is something you want then chances are you aren't using tabs and Nope. If this is something you want then chances are you aren't using tabs and
buffers as they were intended to be used. Read this buffers as they were intended to be used. Read this
@ -46,53 +81,65 @@ http://stackoverflow.com/questions/102384/using-vims-tabs-like-buffers
If you are interested in this behaviour then consider [vim-nerdtree-tabs](https://github.com/jistr/vim-nerdtree-tabs) If you are interested in this behaviour then consider [vim-nerdtree-tabs](https://github.com/jistr/vim-nerdtree-tabs)
--- ---
> How can I open a NERDTree automatically when vim starts up? #### How can I open a NERDTree automatically when vim starts up?
Stick this in your vimrc: `autocmd vimenter * NERDTree` Stick this in your vimrc: `autocmd vimenter * NERDTree`
--- ---
> How can I open a NERDTree automatically when vim starts up if no files were specified? #### How can I open a NERDTree automatically when vim starts up if no files were specified?
Stick this in your vimrc: Stick this in your vimrc:
```vim
autocmd StdinReadPre * let s:std_in=1 autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
```
Note: Now start vim with plain `vim`, not `vim .` Note: Now start vim with plain `vim`, not `vim .`
--- ---
> How can I open NERDTree automatically when vim starts up on opening a directory? #### What if I'm also opening a saved session, for example `vim -S session_file.vim`? I don't want NERDTree to open in that scenario.
```vim
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 0 && !exists("s:std_in") && v:this_session == "" | NERDTree | endif
```
autocmd StdinReadPre * let s:std_in=1 ---
autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists("s:std_in") | exe 'NERDTree' argv()[0] | wincmd p | ene | exe 'cd '.argv()[0] | endif #### How can I open NERDTree automatically when vim starts up on opening a directory?
```vim
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists("s:std_in") | exe 'NERDTree' argv()[0] | wincmd p | ene | exe 'cd '.argv()[0] | endif
```
This window is tab-specific, meaning it's used by all windows in the tab. This trick also prevents NERDTree from hiding when first selecting a file. This window is tab-specific, meaning it's used by all windows in the tab. This trick also prevents NERDTree from hiding when first selecting a file.
Note: Executing `vim ~/some-directory` will open NERDTree and a new edit window. `exe 'cd '.argv()[0]` sets the `pwd` of the new edit window to `~/some-directory` Note: Executing `vim ~/some-directory` will open NERDTree and a new edit window. `exe 'cd '.argv()[0]` sets the `pwd` of the new edit window to `~/some-directory`
--- ---
> How can I map a specific key or shortcut to open NERDTree? #### How can I map a specific key or shortcut to open NERDTree?
Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want): Stick this in your vimrc to open NERDTree with `Ctrl+n` (you can set whatever key you want):
```vim
map <C-n> :NERDTreeToggle<CR> map <C-n> :NERDTreeToggle<CR>
```
--- ---
> How can I close vim if the only window left open is a NERDTree? #### How can I close vim if the only window left open is a NERDTree?
Stick this in your vimrc: Stick this in your vimrc:
```vim
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
```
--- ---
> Can I have different highlighting for different file extensions? #### Can I have different highlighting for different file extensions?
See here: https://github.com/scrooloose/nerdtree/issues/433#issuecomment-92590696 See here: https://github.com/scrooloose/nerdtree/issues/433#issuecomment-92590696
--- ---
> How can I change default arrows? #### How can I change default arrows?
Use these variables in your vimrc. Note that below are default arrow symbols Use these variables in your vimrc. Note that below are default arrow symbols
```vim
let g:NERDTreeDirArrowExpandable = '▸' let g:NERDTreeDirArrowExpandable = '▸'
let g:NERDTreeDirArrowCollapsible = '▾' let g:NERDTreeDirArrowCollapsible = '▾'
```

View file

@ -4,24 +4,33 @@ endif
let g:loaded_nerdtree_autoload = 1 let g:loaded_nerdtree_autoload = 1
let s:rootNERDTreePath = resolve(expand("<sfile>:p:h:h")) let s:rootNERDTreePath = resolve(expand("<sfile>:p:h:h"))
"FUNCTION: nerdtree#version(...) {{{1
" If any value is given as an argument, the entire line of text from the
" change log is shown for the current version; otherwise, only the version
" number is shown.
function! nerdtree#version(...) function! nerdtree#version(...)
let l:changelog = readfile(join([s:rootNERDTreePath, "CHANGELOG.md"], nerdtree#slash()))
let l:text = 'Unknown' let l:text = 'Unknown'
let l:line = 0 try
while l:line <= len(l:changelog) let l:changelog = readfile(join([s:rootNERDTreePath, "CHANGELOG.md"], nerdtree#slash()))
if l:changelog[l:line] =~ '\d\+\.\d\+' let l:line = 0
let l:text = substitute(l:changelog[l:line], '.*\(\d\+.\d\+\).*', '\1', '') while l:line <= len(l:changelog)
let l:text .= substitute(l:changelog[l:line+1], '^.\{-}\(\.\d\+\).\{-}:\(.*\)', a:0>0 ? '\1:\2' : '\1', '') if l:changelog[l:line] =~ '\d\+\.\d\+'
break let l:text = substitute(l:changelog[l:line], '.*\(\d\+.\d\+\).*', '\1', '')
endif let l:text .= substitute(l:changelog[l:line+1], '^.\{-}\(\.\d\+\).\{-}:\(.*\)', a:0>0 ? '\1:\2' : '\1', '')
let l:line += 1 break
endwhile endif
let l:line += 1
endwhile
catch
endtry
return l:text return l:text
endfunction endfunction
" SECTION: General Functions {{{1 " SECTION: General Functions {{{1
"============================================================ "============================================================
"FUNCTION: nerdtree#slash() {{{2
function! nerdtree#slash() function! nerdtree#slash()
if nerdtree#runningWindows() if nerdtree#runningWindows()
@ -49,7 +58,6 @@ function! nerdtree#and(x,y)
if (l:x % 2) && (l:y % 2) if (l:x % 2) && (l:y % 2)
let l:result += float2nr(pow(2, l:n)) let l:result += float2nr(pow(2, l:n))
endif endif
echomsg l:x . ", " . l:y . " => " l:result
let l:x = float2nr(l:x / 2) let l:x = float2nr(l:x / 2)
let l:y = float2nr(l:y / 2) let l:y = float2nr(l:y / 2)
let l:n += 1 let l:n += 1

View file

@ -72,6 +72,7 @@ function! nerdtree#ui_glue#createDefaultBindings()
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': 'Bookmark', 'callback': s . 'openInNewTabSilent' }) call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenInTabSilent, 'scope': 'Bookmark', 'callback': s . 'openInNewTabSilent' })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenExpl, 'scope': "DirNode", 'callback': s."openExplorer" }) call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenExpl, 'scope': "DirNode", 'callback': s."openExplorer" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapOpenExpl, 'scope': "FileNode", 'callback': s."openExplorer" })
call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapDeleteBookmark, 'scope': "Bookmark", 'callback': s."deleteBookmark" }) call NERDTreeAddKeyMap({ 'key': g:NERDTreeMapDeleteBookmark, 'scope': "Bookmark", 'callback': s."deleteBookmark" })
endfunction endfunction
@ -283,6 +284,9 @@ endfunction
" FUNCTION: s:findAndRevealPath(pathStr) {{{1 " FUNCTION: s:findAndRevealPath(pathStr) {{{1
function! s:findAndRevealPath(pathStr) function! s:findAndRevealPath(pathStr)
let l:pathStr = !empty(a:pathStr) ? a:pathStr : expand('%:p') let l:pathStr = !empty(a:pathStr) ? a:pathStr : expand('%:p')
if !filereadable(l:pathStr)
let l:pathStr = fnamemodify(l:pathStr, ':h')
endif
if empty(l:pathStr) if empty(l:pathStr)
call nerdtree#echoWarning('no file for the current buffer') call nerdtree#echoWarning('no file for the current buffer')

View file

@ -849,9 +849,17 @@ above nodes would then be sorted like this: >
z110.txt z110.txt
< <
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*NERDTreeChDirMode* *NERDTreeUseTCD*
Values: 0 or 1.
Default: 0.
Values: 0, 1 or 2. By default, NERDTree will use the `:cd` command to change the current working
directory. If this setting is turned on, and the `:tcd` command is available, it
will be used instead.
------------------------------------------------------------------------------
*NERDTreeChDirMode*
Values: 0, 1, 2, or 3.
Default: 0. Default: 0.
Use this setting to tell the script when (if at all) to change the current Use this setting to tell the script when (if at all) to change the current
@ -871,6 +879,9 @@ the CWD is changed whenever the tree root is changed. For example, if the CWD
is /home/marty/foobar and you make the node for /home/marty/foobar/baz the new is /home/marty/foobar and you make the node for /home/marty/foobar/baz the new
root then the CWD will become /home/marty/foobar/baz. root then the CWD will become /home/marty/foobar/baz.
If the set to 3, then it behaves the same as if set to 2, and the CWD is
changed whenever changing tabs to whatever the tree root is on that tab.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*NERDTreeHighlightCursorline* *NERDTreeHighlightCursorline*
Values: 0 or 1. Values: 0 or 1.
@ -980,7 +991,6 @@ then (to single click activate it) you must click somewhere in
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*NERDTreeQuitOnOpen* *NERDTreeQuitOnOpen*
Values: 0,1,2 or 3. Values: 0,1,2 or 3.
Default: 0 Default: 0

View file

@ -62,9 +62,10 @@ function! s:MenuController._echoPrompt()
if self.isMinimal() if self.isMinimal()
let selection = self.menuItems[self.selection].text let selection = self.menuItems[self.selection].text
let keyword = matchstr(selection, "\([^ ]*")
let shortcuts = map(copy(self.menuItems), "v:val['shortcut']") let shortcuts = map(copy(self.menuItems), "v:val['shortcut']")
let shortcuts[self.selection] = " " . split(selection)[0] . " " let shortcuts[self.selection] = " " . keyword . " "
echo "Menu: [" . join(shortcuts, ",") . "] (" . navHelp . " or shortcut): " echo "Menu: [" . join(shortcuts, ",") . "] (" . navHelp . " or shortcut): "
else else

View file

@ -20,7 +20,7 @@ function! s:NERDTree.changeRoot(node)
call self.root.open() call self.root.open()
"change dir to the dir of the new root if instructed to "change dir to the dir of the new root if instructed to
if g:NERDTreeChDirMode ==# 2 if g:NERDTreeChDirMode >= 2
call self.root.path.changeToDir() call self.root.path.changeToDir()
endif endif
@ -52,7 +52,7 @@ function! s:NERDTree.Close()
endif endif
call nerdtree#exec(s:NERDTree.GetWinNum() . " wincmd w", 1) call nerdtree#exec(s:NERDTree.GetWinNum() . " wincmd w", 1)
call nerdtree#exec("close", 1) call nerdtree#exec("close", 0)
if l:useWinId if l:useWinId
call nerdtree#exec("call win_gotoid(" . l:activeBufOrWin . ")", 0) call nerdtree#exec("call win_gotoid(" . l:activeBufOrWin . ")", 0)
else else
@ -148,12 +148,19 @@ function! s:NERDTree.GetWinNum()
return bufwinnr(t:NERDTreeBufName) return bufwinnr(t:NERDTreeBufName)
endif endif
" If WindowTree, there is no t:NERDTreeBufName variable. Search all windows.
for w in range(1,winnr('$'))
if bufname(winbufnr(w)) =~# '^' . g:NERDTreeCreator.BufNamePrefix() . '\d\+$'
return w
endif
endfor
return -1 return -1
endfunction endfunction
"FUNCTION: s:NERDTree.IsOpen() {{{1 "FUNCTION: s:NERDTree.IsOpen() {{{1
function! s:NERDTree.IsOpen() function! s:NERDTree.IsOpen()
return s:NERDTree.GetWinNum() != -1 || bufname('%') =~# '^' . g:NERDTreeCreator.BufNamePrefix() . '\d\+$' return s:NERDTree.GetWinNum() != -1
endfunction endfunction
"FUNCTION: s:NERDTree.isTabTree() {{{1 "FUNCTION: s:NERDTree.isTabTree() {{{1

View file

@ -71,9 +71,9 @@ endfunction
function! s:Opener._gotoTargetWin() function! s:Opener._gotoTargetWin()
if b:NERDTree.isWinTree() if b:NERDTree.isWinTree()
if self._where == 'v' if self._where == 'v'
vsplit call self._newVSplit()
elseif self._where == 'h' elseif self._where == 'h'
split call self._newSplit()
elseif self._where == 't' elseif self._where == 't'
tabnew tabnew
endif endif
@ -153,44 +153,18 @@ endfunction
" FUNCTION: Opener._newSplit() {{{1 " FUNCTION: Opener._newSplit() {{{1
function! s:Opener._newSplit() function! s:Opener._newSplit()
" Save the user's settings for splitbelow and splitright
let savesplitbelow=&splitbelow
let savesplitright=&splitright
" 'there' will be set to a command to move from the split window
" back to the explorer window
"
" 'back' will be set to a command to move from the explorer window
" back to the newly split window
"
" 'right' and 'below' will be set to the settings needed for
" splitbelow and splitright IF the explorer is the only window.
"
let there= g:NERDTreeWinPos ==# "left" ? "wincmd h" : "wincmd l"
let back = g:NERDTreeWinPos ==# "left" ? "wincmd l" : "wincmd h"
let right= g:NERDTreeWinPos ==# "left"
let below=0
" Attempt to go to adjacent window
call nerdtree#exec(back, 1)
let onlyOneWin = (winnr("$") ==# 1) let onlyOneWin = (winnr("$") ==# 1)
let savesplitright = &splitright
" If no adjacent window, set splitright and splitbelow appropriately
if onlyOneWin if onlyOneWin
let &splitright=right let &splitright = (g:NERDTreeWinPos ==# "left")
let &splitbelow=below
else
" found adjacent window - invert split direction
let &splitright=!right
let &splitbelow=!below
endif endif
" If only one window (ie. NERDTree), split vertically instead.
let splitMode = onlyOneWin ? "vertical" : "" let splitMode = onlyOneWin ? "vertical" : ""
" Open the new window " Open the new window
try try
exec(splitMode." sp ") call nerdtree#exec('wincmd p', 1)
call nerdtree#exec(splitMode . " split",1)
catch /^Vim\%((\a\+)\)\=:E37/ catch /^Vim\%((\a\+)\)\=:E37/
call g:NERDTree.CursorToTreeWin() call g:NERDTree.CursorToTreeWin()
throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified." throw "NERDTree.FileAlreadyOpenAndModifiedError: ". self._path.str() ." is already open and modified."
@ -200,14 +174,12 @@ function! s:Opener._newSplit()
"resize the tree window if no other window was open before "resize the tree window if no other window was open before
if onlyOneWin if onlyOneWin
let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize let size = exists('b:NERDTreeOldWindowSize') ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize
call nerdtree#exec(there, 1) call nerdtree#exec('wincmd p', 1)
exec("silent ". splitMode ." resize ". size) call nerdtree#exec('silent '. splitMode .' resize '. size, 1)
call nerdtree#exec('wincmd p', 0) call nerdtree#exec('wincmd p', 0)
endif endif
" Restore splitmode settings
let &splitbelow=savesplitbelow
let &splitright=savesplitright let &splitright=savesplitright
endfunction endfunction
@ -215,7 +187,10 @@ endfunction
function! s:Opener._newVSplit() function! s:Opener._newVSplit()
let l:winwidth = winwidth('.') let l:winwidth = winwidth('.')
if winnr('$') == 1 let onlyOneWin = (winnr("$") ==# 1)
let savesplitright = &splitright
if onlyOneWin
let &splitright = (g:NERDTreeWinPos ==# "left")
let l:winwidth = g:NERDTreeWinSize let l:winwidth = g:NERDTreeWinSize
endif endif
@ -229,6 +204,7 @@ function! s:Opener._newVSplit()
execute 'silent vertical resize ' . l:winwidth execute 'silent vertical resize ' . l:winwidth
call nerdtree#exec(l:currentWindowNumber . 'wincmd w', 0) call nerdtree#exec(l:currentWindowNumber . 'wincmd w', 0)
let &splitright=savesplitright
endfunction endfunction
" FUNCTION: Opener.open(target) {{{1 " FUNCTION: Opener.open(target) {{{1

Some files were not shown because too many files have changed in this diff Show more