mirror of
1
0
Fork 0

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_options', '')
call ale#Set('c_build_dir', '')
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
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_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:build_dir = ale#c#GetBuildDirectory(a:buffer)
let l:options = ''
" Get the extra options if we couldn't find a build directory.
let l:options = empty(l:build_dir)
\ ? ale#Var(a:buffer, 'c_clangtidy_options')
\ : ''
if empty(l:build_dir)
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
let l:extra_options = ale#Var(a:buffer, 'c_clangtidy_extra_options')
@ -43,7 +46,7 @@ call ale#linter#Define('c', {
\ 'name': 'clangtidy',
\ 'output_stream': 'stdout',
\ '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',
\ '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
" detected.
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)
\ . (!empty(l:build_dir) ? ' -p ' . ale#Escape(l:build_dir) : '')
endfunction

View File

@ -3,9 +3,14 @@
call ale#Set('cpp_clangd_executable', 'clangd')
call ale#Set('cpp_clangd_options', '')
call ale#Set('c_build_dir', '')
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
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('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:build_dir = ale#c#GetBuildDirectory(a:buffer)
let l:options = ''
" Get the extra options if we couldn't find a build directory.
let l:options = empty(l:build_dir)
\ ? ale#Var(a:buffer, 'cpp_clangtidy_options')
\ : ''
if empty(l:build_dir)
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
let l:extra_options = ale#Var(a:buffer, 'cpp_clangtidy_extra_options')
@ -37,7 +40,7 @@ call ale#linter#Define('cpp', {
\ 'name': 'clangtidy',
\ 'output_stream': 'stdout',
\ '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',
\ 'lint_file': 1,
\})

View File

@ -5,6 +5,10 @@ function! ale_linters#crystal#crystal#Handle(buffer, lines) abort
let l:output = []
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
if !has_key(l:error, 'file')
continue
endif
call add(l:output, {
\ 'lnum': l:error.line + 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_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')
call ale#Set('elm_ls_elm_test_path', 'elm-test')
" elm-language-server will search for local and global binaries, if empty
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
let l:elm_json = ale#path#FindNearestFile(a:buffer, 'elm.json')
@ -15,10 +18,10 @@ endfunction
function! elm_ls#GetOptions(buffer) abort
return {
\ 'runtime': 'node',
\ 'elmPath': ale#Var(a:buffer, 'elm_ls_elm_path'),
\ 'elmFormatPath': ale#Var(a:buffer, 'elm_ls_elm_format_path'),
\ 'elmTestPath': ale#Var(a:buffer, 'elm_ls_elm_test_path'),
\ 'elmAnalyseTrigger': ale#Var(a:buffer, 'elm_ls_elm_analyse_trigger'),
\}
endfunction

View File

@ -15,10 +15,10 @@ endfunction
function! ale_linters#erlang#dialyzer#FindPlt(buffer) abort
let l:plt_file = ''
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)
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
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
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 '
\ . ale#Var(a:buffer, 'eruby_ruumba_options')
\ . ' --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
return ale#node#FindExecutable(a:buffer, 'javascript_standard', [
\ 'node_modules/standardx/bin/cmd.js',
\ 'node_modules/standard/bin/cmd.js',
\ 'node_modules/semistandard/bin/cmd.js',
\ 'node_modules/.bin/standard',
\])
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')
return ale#Escape(l:executable) . l:exec_args
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' -j' . (!empty(l:options) ? ' ' . l:options : '')
endfunction
function! ale_linters#markdown#mdl#Handle(buffer, lines) abort
" matches: '(stdin):173: MD004 Unordered list style'
let l:pattern = ':\(\d*\): \(.*\)$'
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, {
\ 'lnum': l:match[1] + 0,
\ 'text': l:match[2],
\ 'lnum': l:error['line'],
\ 'code': l:error['rule'] . '/' . join(l:error['aliases'], '/'),
\ 'text': l:error['description'],
\ 'type': 'W',
\})
endfor

View File

@ -1,6 +1,15 @@
" Author: Baabelfish
" 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
let l:buffer_filename = fnamemodify(bufname(a:buffer), ':p:t')
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]
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)
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>
" 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))
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') : ''
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', {
\ 'name': 'psalm',
\ 'lsp': 'stdio',
\ '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'),
\})

View File

@ -12,6 +12,7 @@ endfunction
" https://rkeithhill.wordpress.com/2007/10/30/powershell-quicktip-preparsing-scripts-to-check-for-syntax-errors/
function! ale_linters#powershell#powershell#GetCommand(buffer) abort
let l:script = ['Param($Script);
\ $ErrorView = "Normal";
\ trap {$_;continue} & {
\ $Contents = Get-Content -Path $Script;
\ $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')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'brakeman')
return ale#ruby#EscapeExecutable(l:executable, 'brakeman')
\ . ' -f json -q '
\ . ale#Var(a:buffer, 'ruby_brakeman_options')
\ . ' -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: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
\ . ale#Var(a:buffer, 'ruby_rails_best_practices_options')
\ . ale#Escape(l:rails_root)

View File

@ -14,7 +14,7 @@ function! ale_linters#ruby#reek#GetCommand(buffer, version) abort
\ ? ' --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'
\ . l:display_name_args
endfunction

View File

@ -7,7 +7,7 @@ call ale#Set('ruby_rubocop_options', '')
function! ale_linters#ruby#rubocop#GetCommand(buffer) abort
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 '
\ . ale#Var(a:buffer, 'ruby_rubocop_options')
\ . ' --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:options = ale#Var(a:buffer, 'ruby_sorbet_options')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'srb')
return ale#ruby#EscapeExecutable(l:executable, 'srb')
\ . ' tc'
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --lsp --disable-watchman'

View File

@ -8,7 +8,7 @@ call ale#Set('ruby_standardrb_options', '')
function! ale_linters#ruby#standardrb#GetCommand(buffer) abort
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 '
\ . ale#Var(a:buffer, 'ruby_standardrb_options')
\ . ' --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:
"
" bash: line 13: syntax error near unexpected token `d'
" bash:行0: 未预期的符号“done”附近有语法错误
" bash: 列 90: 尋找匹配的「"」時遇到了未預期的檔案結束符
" sh: 11: Syntax error: "(" unexpected
let l:pattern = '\v(line |: ?)(\d+): (.+)$'
let l:pattern = '\v([^:]+:\D*)(\d+): (.+)$'
let l:output = []
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,8 +9,13 @@ call ale#Set('terraform_tflint_executable', 'tflint')
function! ale_linters#terraform#tflint#Handle(buffer, lines) abort
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
" On versions prior to 0.11 it outputs all errors as a single level list
if type(l:json) is v:t_list
for l:error in l:json
if l:error.type is# 'ERROR'
let l:type = 'E'
elseif l:error.type is# 'NOTICE'
@ -26,6 +31,47 @@ function! ale_linters#terraform#tflint#Handle(buffer, lines) abort
\ 'code': l:error.detector,
\})
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
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
"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
endfunction

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

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:options = ale#Var(a:buffer, 'ruby_rubocop_options')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rubocop')
return ale#ruby#EscapeExecutable(l:executable, 'rubocop')
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --auto-correct --force-exclusion %t'

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:options = ale#Var(a:buffer, 'ruby_sorbet_options')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'srb')
return ale#ruby#EscapeExecutable(l:executable, 'srb')
\ . ' tc'
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --autocorrect --file %t'

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

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:options = ale#Var(a:buffer, 'ruby_standardrb_options')
return ale#handlers#ruby#EscapeExecutable(l:executable, 'standardrb')
return ale#ruby#EscapeExecutable(l:executable, 'standardrb')
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --fix --force-exclusion %t'

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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 ''
endfunction
" Given a buffer, a string to search for, an a global fallback for when
" Given a buffer, a string to search for, and a global fallback for when
" the search fails, look for a file in parent paths, and if that fails,
" use the global fallback path instead.
function! ale#path#ResolveLocalPath(buffer, search_string, global_fallback) abort
" Search for a locally installed file first.
let l:path = ale#path#FindNearestFile(a:buffer, a:search_string)
" If the serach fails, try the global executable instead.
" If the search fails, try the global executable instead.
if empty(l:path)
let l:path = a:global_fallback
endif

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

View File

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

View File

@ -15,18 +15,17 @@ csc *ale-cs-csc*
See |ale-lint-file-linters| for more information on linters which do not
check for problems while you type.
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
includes including all '*.cs' files contained in the directory tree rooted
at the path defined by the |g:ale_cs_csc_source| or |b:ale_cs_csc_source|
variabl and all sub directories.
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
includes all '*.cs' files contained in the directory tree rooted at the path
defined by the |g:ale_cs_csc_source| or |b:ale_cs_csc_source| variable and
all sub directories.
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
developed and as of writint these lines only receives maintenance updates.
The down is that the csc compiler does not support the -sytax option any more
and therefore |ale-cs-csc| linter doese not offer any as you type syntax
checking like the |ale-cs-mcsc| linter doesn't.
utilize the mcsc compiler which, according to the mono project, is no longer
actively developed, and only receives maintenance updates. However, because
the csc compiler does not support the -syntax option, this linter does not
offer any as-you-type syntax checking, similar to the |ale-cs-mcsc| linter.
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.

View File

@ -1,6 +1,15 @@
===============================================================================
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*

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
tests.
When you add new linters or fixers, make sure to add them into the table in
the README, and also into the |ale-support| list in the main help file. If you
forget to keep them both in sync, you should see an error like the following
in Travis CI. >
When you add new linters or fixers, make sure to add them into the tables in
supported-tools.md and |ale-supported-languages-and-tools.txt|. If you forget to
keep them both in sync, you should see an error like the following 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:

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*
*b:ale_elm_ls_elm_path*
Type: |String|
Default: `'elm'`
Default: `''`
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*
*b:ale_elm_ls_elm_format_path*
Type: |String|
Default: `'elm-format'`
Default: `''`
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*
*b:ale_elm_ls_elm_test_path*
Type: |String|
Default: `'elm-test'`
Default: `''`
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*

View File

@ -9,6 +9,16 @@ fecs *ale-html-fecs*
and both of them reads `./.fecsrc` as the default configuration file.
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*

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|
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
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.
@ -189,6 +189,13 @@ g:ale_php_psalm_executable *g:ale_php_psalm_executable*
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*

View File

@ -29,5 +29,14 @@ g:ale_purescript_ls_config g:ale_purescript_ls_config
\ '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:

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.
===============================================================================
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*
@ -91,7 +111,7 @@ g:ale_ruby_rubocop_options *g:ale_ruby_rubocop_options*
Type: |String|
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|
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|
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*
===============================================================================
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*

View File

@ -2,6 +2,18 @@
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*

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.
===============================================================================
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:

View File

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

View File

@ -16,6 +16,33 @@ prettier *ale-typescript-prettier*
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*

View File

@ -9,7 +9,8 @@ CONTENTS *ale-contents*
1. Introduction.........................|ale-introduction|
2. Supported Languages & Tools..........|ale-support|
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|
5. Language Server Protocol Support.....|ale-lsp|
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.
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
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 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
<
*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*
@ -597,6 +678,16 @@ b:ale_completion_enabled *b:ale_completion_enabled*
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*
*b:ale_completion_excluded_words*
Type: |List|
@ -615,6 +706,47 @@ g:ale_completion_excluded_words *g:ale_completion_excluded_words*
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*
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|
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*
Type: |String|
@ -1027,9 +1168,12 @@ g:ale_linter_aliases *g:ale_linter_aliases*
{
\ 'Dockerfile': 'dockerfile',
\ 'csh': 'sh',
\ 'javascriptreact': ['javascript', 'jsx'],
\ 'plaintex': 'tex',
\ 'rmarkdown': 'r',
\ 'rmd': 'r',
\ 'systemverilog': 'verilog',
\ 'typescriptreact': ['typescript', 'tsx'],
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
\ 'vimwiki': 'markdown',
\ 'vue': ['vue', 'javascript'],
@ -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.
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*
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|.
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*
*b:ale_set_balloons*
@ -1437,8 +1643,8 @@ g:ale_set_signs *g:ale_set_signs*
|ALEWarningLine| - All items with `'type': 'W'`
|ALEInfoLine| - All items with `'type': 'I'`
With Neovim 0.3.2 or higher, ALE uses `numhl` option to highlight 'number'
column. It uses the following highlight groups.
With Neovim 0.3.2 or higher, ALE can use the `numhl` option to highlight the
'number' column. It uses the following highlight groups.
|ALEErrorSignLineNr| - Items with `'type': 'E'`
|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'`
|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:
|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|.
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*
Type: |String|
@ -1552,6 +1771,16 @@ g:ale_sign_warning *g:ale_sign_warning*
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*
*b:ale_update_tagstack*
Type: |Number|
@ -1606,6 +1835,8 @@ g:ale_virtualtext_cursor *g:ale_virtualtext_cursor*
Type: |Number|
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
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
@ -1954,6 +2185,14 @@ g:ale_languagetool_executable *g:ale_languagetool_executable*
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*
@ -2053,6 +2292,7 @@ documented in additional help files.
nvcc..................................|ale-cuda-nvcc|
clang-format..........................|ale-cuda-clangformat|
d.......................................|ale-d-options|
dfmt..................................|ale-d-dfmt|
dls...................................|ale-d-dls|
uncrustify............................|ale-d-uncrustify|
dart....................................|ale-dart-options|
@ -2129,6 +2369,7 @@ documented in additional help files.
terraform-fmt.........................|ale-hcl-terraform-fmt|
html....................................|ale-html-options|
fecs..................................|ale-html-fecs|
html-beautify.........................|ale-html-beautify|
htmlhint..............................|ale-html-htmlhint|
tidy..................................|ale-html-tidy|
prettier..............................|ale-html-prettier|
@ -2136,6 +2377,8 @@ documented in additional help files.
write-good............................|ale-html-write-good|
idris...................................|ale-idris-options|
idris.................................|ale-idris-idris|
ink.....................................|ale-ink-options|
ink-language-server...................|ale-ink-language-server|
ispc....................................|ale-ispc-options|
ispc..................................|ale-ispc-ispc|
java....................................|ale-java-options|
@ -2191,6 +2434,12 @@ documented in additional help files.
mmc...................................|ale-mercury-mmc|
nasm....................................|ale-nasm-options|
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|
write-good............................|ale-nroff-write-good|
objc....................................|ale-objc-options|
@ -2246,6 +2495,7 @@ documented in additional help files.
puppet-languageserver.................|ale-puppet-languageserver|
purescript..............................|ale-purescript-options|
purescript-language-server............|ale-purescript-language-server|
purty.................................|ale-purescript-purty|
pyrex (cython)..........................|ale-pyrex-options|
cython................................|ale-pyrex-cython|
python..................................|ale-python-options|
@ -2281,6 +2531,7 @@ documented in additional help files.
write-good............................|ale-restructuredtext-write-good|
ruby....................................|ale-ruby-options|
brakeman..............................|ale-ruby-brakeman|
debride...............................|ale-ruby-debride|
rails_best_practices..................|ale-ruby-rails_best_practices|
reek..................................|ale-ruby-reek|
rubocop...............................|ale-ruby-rubocop|
@ -2298,6 +2549,7 @@ documented in additional help files.
sasslint..............................|ale-sass-sasslint|
stylelint.............................|ale-sass-stylelint|
scala...................................|ale-scala-options|
metals................................|ale-scala-metals|
sbtserver.............................|ale-scala-sbtserver|
scalafmt..............................|ale-scala-scalafmt|
scalastyle............................|ale-scala-scalastyle|
@ -2313,6 +2565,7 @@ documented in additional help files.
sml.....................................|ale-sml-options|
smlnj.................................|ale-sml-smlnj|
solidity................................|ale-solidity-options|
solc..................................|ale-solidity-solc|
solhint...............................|ale-solidity-solhint|
solium................................|ale-solidity-solium|
spec....................................|ale-spec-options|
@ -2320,6 +2573,7 @@ documented in additional help files.
sql.....................................|ale-sql-options|
pgformatter...........................|ale-sql-pgformatter|
sqlfmt................................|ale-sql-sqlfmt|
sqlformat.............................|ale-sql-sqlformat|
stylus..................................|ale-stylus-options|
stylelint.............................|ale-stylus-stylelint|
sugarss.................................|ale-sugarss-options|
@ -2347,6 +2601,7 @@ documented in additional help files.
typescript..............................|ale-typescript-options|
eslint................................|ale-typescript-eslint|
prettier..............................|ale-typescript-prettier|
standard..............................|ale-typescript-standard|
tslint................................|ale-typescript-tslint|
tsserver..............................|ale-typescript-tsserver|
vala....................................|ale-vala-options|
@ -2521,6 +2776,18 @@ ALEHover *ALEHover*
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*
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')
" 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
nnoremap <silent> <Plug>(ale_previous) :ALEPrevious<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_documentation) :ALEDocumentation<Return>
inoremap <silent> <Plug>(ale_complete) <C-\><C-O>:ALEComplete<Return>
nnoremap <silent> <Plug>(ale_rename) :ALERename<Return>
" Set up autocmd groups now.
call ale#events#Init()

View File

@ -112,6 +112,7 @@ formatting.
* Cython (pyrex filetype)
* [cython](http://cython.org/)
* D
* [dfmt](https://github.com/dlang-community/dfmt)
* [dls](https://github.com/d-language-server/dls)
* [dmd](https://dlang.org/dmd-linux.html)
* [uncrustify](https://github.com/uncrustify/uncrustify)
@ -132,7 +133,7 @@ formatting.
* [mix](https://hexdocs.pm/mix/Mix.html) :warning: :floppy_disk:
* Elm
* [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)
* Erb
* [erb](https://apidock.com/ruby/ERB)
@ -202,6 +203,7 @@ formatting.
* HTML
* [alex](https://github.com/wooorm/alex) :floppy_disk:
* [fecs](http://fecs.baidu.com/)
* [html-beautify](https://beautifier.io/)
* [HTMLHint](http://htmlhint.com/)
* [prettier](https://github.com/prettier/prettier)
* [proselint](http://proselint.com/)
@ -209,6 +211,8 @@ formatting.
* [write-good](https://github.com/btford/write-good)
* Idris
* [idris](http://www.idris-lang.org/)
* Ink
* [ink-language-server](https://github.com/ephread/ink-language-server)
* ISPC
* [ispc](https://ispc.github.io/) :floppy_disk:
* Java
@ -223,7 +227,7 @@ formatting.
* [eslint](http://eslint.org/)
* [fecs](http://fecs.baidu.com/)
* [flow](https://flowtype.org/)
* [jscs](http://jscs.info/)
* [jscs](https://jscs-dev.github.io/)
* [jshint](http://jshint.com/)
* [prettier](https://github.com/prettier/prettier)
* [prettier-eslint](https://github.com/prettier/prettier-eslint-cli)
@ -248,7 +252,7 @@ formatting.
* [lacheck](https://www.ctan.org/pkg/lacheck)
* [proselint](http://proselint.com/)
* [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/)
* [vale](https://github.com/ValeLint/vale)
* [write-good](https://github.com/btford/write-good)
@ -288,8 +292,11 @@ formatting.
* [nasm](https://www.nasm.us/) :floppy_disk:
* Nim
* [nim check](https://nim-lang.org/docs/nimc.html) :floppy_disk:
* [nimlsp](https://github.com/PMunch/nimlsp)
* nimpretty
* nix
* [nix-instantiate](http://nixos.org/nix/manual/#sec-nix-instantiate)
* [nixpkgs-fmt](https://github.com/nix-community/nixpkgs-fmt)
* nroff
* [alex](https://github.com/wooorm/alex) :floppy_disk:
* [proselint](http://proselint.com/)
@ -338,8 +345,8 @@ formatting.
* Pony
* [ponyc](https://github.com/ponylang/ponyc)
* PowerShell
* [powershell](https://github.com/PowerShell/PowerShell) :floppy_disk
* [psscriptanalyzer](https://github.com/PowerShell/PSScriptAnalyzer) :floppy_disk
* [powershell](https://github.com/PowerShell/PowerShell) :floppy_disk:
* [psscriptanalyzer](https://github.com/PowerShell/PSScriptAnalyzer) :floppy_disk:
* Prolog
* [swipl](https://github.com/SWI-Prolog/swipl-devel)
* proto
@ -352,6 +359,7 @@ formatting.
* [puppet-lint](https://puppet-lint.com)
* PureScript
* [purescript-language-server](https://github.com/nwolverson/purescript-language-server)
* [purty](https://gitlab.com/joneshf/purty)
* Python
* [autopep8](https://github.com/hhatto/autopep8)
* [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`)
* Ruby
* [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:
* [reek](https://github.com/troessner/reek)
* [rubocop](https://github.com/bbatsov/rubocop)
@ -415,6 +424,7 @@ formatting.
* [stylelint](https://github.com/stylelint/stylelint)
* Scala
* [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)
* [scalac](http://scala-lang.org)
* [scalafmt](https://scalameta.org/scalafmt/)
@ -429,11 +439,13 @@ formatting.
* SML
* [smlnj](http://www.smlnj.org/)
* Solidity
* [solc](https://solidity.readthedocs.io/)
* [solhint](https://github.com/protofire/solhint)
* [solium](https://github.com/duaraghav8/Solium)
* SQL
* [pgformatter](https://github.com/darold/pgFormatter)
* [sqlfmt](https://github.com/jackc/sqlfmt)
* [sqlformat](https://github.com/andialbrecht/sqlparse)
* [sqlint](https://github.com/purcell/sqlint)
* Stylus
* [stylelint](https://github.com/stylelint/stylelint)
@ -466,6 +478,7 @@ formatting.
* [eslint](http://eslint.org/)
* [fecs](http://fecs.baidu.com/)
* [prettier](https://github.com/prettier/prettier)
* [standard](http://standardjs.com/)
* [tslint](https://github.com/palantir/tslint)
* [tsserver](https://github.com/Microsoft/TypeScript/wiki/Standalone-Server-%28tsserver%29)
* typecheck

View File

@ -330,6 +330,7 @@ fu! s:Open()
endf
fu! s:Close()
cal s:async_glob_abort()
cal s:buffunc(0)
if winnr('$') == 1
bw!
@ -434,9 +435,62 @@ fu! s:GlobPath(dirs, depth)
en
endf
fu! ctrlp#addfile(ch, file)
call add(g:ctrlp_allfiles, a:file)
cal s:BuildPrompt(1)
fu! s:async_glob_update_progress(timer)
let s:must_wait = 0
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
fu! s:safe_printf(format, ...)
@ -462,12 +516,26 @@ fu! s:UserCmd(lscmd)
if (has('win32') || has('win64')) && match(&shell, 'sh') != -1
let path = tr(path, '\', '/')
en
if s:usrcmdasync && v:version >= 800 && exists('*job_start')
if exists('s:job')
call job_stop(s:job)
en
if s:usrcmdasync && (v:version >= 800 || has('nvim')) && (exists('*job_start') || exists('*jobstart'))
cal s:stop_job_if_exists()
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'))
let g:ctrlp_allfiles = systemlist(s:safe_printf(lscmd, path))
el
@ -997,7 +1065,7 @@ fu! s:MapSpecs()
if !( exists('s:smapped') && s:smapped == s:bufnr )
" Correct arrow keys in terminal
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>']
exe s:lcmap.' <esc>['.each
endfo
@ -1054,6 +1122,7 @@ fu! s:ToggleByFname()
endf
fu! s:ToggleType(dir)
cal s:async_glob_abort()
let max = len(g:ctrlp_ext_vars) + len(s:coretypes) - 1
let next = s:walker(max, s:itemtype, a:dir)
cal ctrlp#setlines(next)
@ -1563,6 +1632,9 @@ fu! ctrlp#statusline()
let slider = ' <'.prv.'>={'.item.'}=<'.nxt.'>'
let dir = ' %=%<%#CtrlPMode2# %{getcwd()} %*'
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
endf
@ -2571,6 +2643,7 @@ endf
fu! s:setlines_pre(...)
if a:0 | let s:itemtype = a:1 | en
cal s:modevar()
let s:setlines_post_ended = 0
let g:ctrlp_lines = []
endf
@ -2581,6 +2654,7 @@ fu! s:setlines_post()
cal map(copy(g:ctrlp_ext_vars), 'add(types, v:val["init"])')
en
let g:ctrlp_lines = eval(types[s:itemtype])
let s:setlines_post_ended = 1
endf
fu! ctrlp#setlines(...)

View File

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

View File

@ -1505,7 +1505,7 @@ Before 2016/11/28~
+ New command: |YankLine()| to yank current line.
+ New option: |g:ctrlp_types| to select builtin modes.
+ 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.
+ New option: |g:ctrlp_brief_prompt|,
|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
For screenshots of all available colorshemes, see [this file](colorscheme.md).
## Why yet another clone of powerline?
+ [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.
+ [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
+ 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
export TERM=xterm-256color
```
and then add the following configure to your `.vimrc`.
and then add the following configuration to your `.vimrc`.
```vim
if !has('gui_running')
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.
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.
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.
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.
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

View File

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

View File

@ -2,11 +2,10 @@
" Filename: autoload/lightline/colorscheme/one.vim
" Author: Zoltan Dalmadi
" License: MIT License
" Last Change: 2019/05/12 20:30:51.
" Last Change: 2019/09/09 22:42:48.
" =============================================================================
" Common colors
let s:fg = [ '#abb2bf', 145 ]
let s:blue = [ '#61afef', 75 ]
let s:green = [ '#98c379', 76 ]
let s:purple = [ '#c678dd', 176 ]
@ -18,44 +17,41 @@ let s:p = {'normal': {}, 'inactive': {}, 'insert': {}, 'replace': {}, 'visual':
if lightline#colorscheme#background() ==# 'light'
" Light variant
let s:fg = [ '#494b53', 238 ]
let s:bg = [ '#fafafa', 255 ]
let s:gray1 = [ '#494b53', 238 ]
let s:gray2 = [ '#f0f0f0', 255 ]
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.middle = [ [ s:gray3, s:gray2 ] ]
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
" Dark variant
let s:fg = [ '#abb2bf', 145 ]
let s:bg = [ '#282c34', 235 ]
let s:gray1 = [ '#5c6370', 241 ]
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.middle = [ [ s:gray1, s:gray2 ] ]
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
" 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.error = [ [ s:red2, 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.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.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.left = [ [ s:bg, s:purple, 'bold' ], [ 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.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
- [ ] Derive a new version number. Increment the:
- [ ] `MAJOR` version when you make incompatible API changes
- [ ] `MINOR` version when you add functionality in a backwards-compatible manner
- [ ] `PATCH` version when you make backwards-compatible bug fixes
#### Author's Instructions
- [ ] Derive a new `MAJOR.MINOR.PATCH` version number. Increment the:
- `MAJOR` version when you make incompatible API changes
- `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.
- [ ] 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)
#### 5.2...
- **.9**: Suppress events for intermediate window/tab/buffer changes [#1026](https://github.com/scrooloose/nerdtree/pull/1026)
<!--
Introduce a new MAJOR.MINOR version with a 4-hash header.
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)
- **.7**: Use :mode only in neovim. MacVim still needs to use :redraw! [#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)
- **.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. (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)
- **.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)
- **.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)
- **.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)
- **.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)

View File

@ -17,27 +17,62 @@ included documentation.
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)
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)
```bash
apt-vim install -y https://github.com/scrooloose/nerdtree.git
```
F.A.Q.
F.A.Q. (here, and in the [Wiki](https://github.com/scrooloose/nerdtree/wiki))
------
> 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).
---
> 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
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)
---
> 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`
---
> 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:
```vim
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
```
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
```
---
#### 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.
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):
```vim
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:
```vim
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
---
> 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
```vim
let g:NERDTreeDirArrowExpandable = '▸'
let g:NERDTreeDirArrowCollapsible = '▾'
```

View File

@ -4,9 +4,15 @@ endif
let g:loaded_nerdtree_autoload = 1
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(...)
let l:changelog = readfile(join([s:rootNERDTreePath, "CHANGELOG.md"], nerdtree#slash()))
let l:text = 'Unknown'
try
let l:changelog = readfile(join([s:rootNERDTreePath, "CHANGELOG.md"], nerdtree#slash()))
let l:line = 0
while l:line <= len(l:changelog)
if l:changelog[l:line] =~ '\d\+\.\d\+'
@ -16,12 +22,15 @@ function! nerdtree#version(...)
endif
let l:line += 1
endwhile
catch
endtry
return l:text
endfunction
" SECTION: General Functions {{{1
"============================================================
"FUNCTION: nerdtree#slash() {{{2
function! nerdtree#slash()
if nerdtree#runningWindows()
@ -49,7 +58,6 @@ function! nerdtree#and(x,y)
if (l:x % 2) && (l:y % 2)
let l:result += float2nr(pow(2, l:n))
endif
echomsg l:x . ", " . l:y . " => " l:result
let l:x = float2nr(l:x / 2)
let l:y = float2nr(l:y / 2)
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: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" })
endfunction
@ -283,6 +284,9 @@ endfunction
" FUNCTION: s:findAndRevealPath(pathStr) {{{1
function! s:findAndRevealPath(pathStr)
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)
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
<
------------------------------------------------------------------------------
*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.
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
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*
Values: 0 or 1.
@ -980,7 +991,6 @@ then (to single click activate it) you must click somewhere in
------------------------------------------------------------------------------
*NERDTreeQuitOnOpen*
Values: 0,1,2 or 3.
Default: 0

View File

@ -62,9 +62,10 @@ function! s:MenuController._echoPrompt()
if self.isMinimal()
let selection = self.menuItems[self.selection].text
let keyword = matchstr(selection, "\([^ ]*")
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): "
else

View File

@ -20,7 +20,7 @@ function! s:NERDTree.changeRoot(node)
call self.root.open()
"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()
endif
@ -52,7 +52,7 @@ function! s:NERDTree.Close()
endif
call nerdtree#exec(s:NERDTree.GetWinNum() . " wincmd w", 1)
call nerdtree#exec("close", 1)
call nerdtree#exec("close", 0)
if l:useWinId
call nerdtree#exec("call win_gotoid(" . l:activeBufOrWin . ")", 0)
else
@ -148,12 +148,19 @@ function! s:NERDTree.GetWinNum()
return bufwinnr(t:NERDTreeBufName)
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
endfunction
"FUNCTION: s:NERDTree.IsOpen() {{{1
function! s:NERDTree.IsOpen()
return s:NERDTree.GetWinNum() != -1 || bufname('%') =~# '^' . g:NERDTreeCreator.BufNamePrefix() . '\d\+$'
return s:NERDTree.GetWinNum() != -1
endfunction
"FUNCTION: s:NERDTree.isTabTree() {{{1

View File

@ -71,9 +71,9 @@ endfunction
function! s:Opener._gotoTargetWin()
if b:NERDTree.isWinTree()
if self._where == 'v'
vsplit
call self._newVSplit()
elseif self._where == 'h'
split
call self._newSplit()
elseif self._where == 't'
tabnew
endif
@ -153,44 +153,18 @@ endfunction
" FUNCTION: Opener._newSplit() {{{1
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)
" If no adjacent window, set splitright and splitbelow appropriately
let savesplitright = &splitright
if onlyOneWin
let &splitright=right
let &splitbelow=below
else
" found adjacent window - invert split direction
let &splitright=!right
let &splitbelow=!below
let &splitright = (g:NERDTreeWinPos ==# "left")
endif
" If only one window (ie. NERDTree), split vertically instead.
let splitMode = onlyOneWin ? "vertical" : ""
" Open the new window
try
exec(splitMode." sp ")
call nerdtree#exec('wincmd p', 1)
call nerdtree#exec(splitMode . " split",1)
catch /^Vim\%((\a\+)\)\=:E37/
call g:NERDTree.CursorToTreeWin()
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
if onlyOneWin
let size = exists("b:NERDTreeOldWindowSize") ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize
call nerdtree#exec(there, 1)
exec("silent ". splitMode ." resize ". size)
let size = exists('b:NERDTreeOldWindowSize') ? b:NERDTreeOldWindowSize : g:NERDTreeWinSize
call nerdtree#exec('wincmd p', 1)
call nerdtree#exec('silent '. splitMode .' resize '. size, 1)
call nerdtree#exec('wincmd p', 0)
endif
" Restore splitmode settings
let &splitbelow=savesplitbelow
let &splitright=savesplitright
endfunction
@ -215,7 +187,10 @@ endfunction
function! s:Opener._newVSplit()
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
endif
@ -229,6 +204,7 @@ function! s:Opener._newVSplit()
execute 'silent vertical resize ' . l:winwidth
call nerdtree#exec(l:currentWindowNumber . 'wincmd w', 0)
let &splitright=savesplitright
endfunction
" FUNCTION: Opener.open(target) {{{1

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