Updated plugins
This commit is contained in:
parent
993ed55304
commit
2f164fee9b
70 changed files with 2044 additions and 761 deletions
|
@ -0,0 +1,35 @@
|
||||||
|
" Author: Yasuhiro Kiyota <yasuhiroki.duck@gmail.com>
|
||||||
|
" Description: Support cfn-python-lint for AWS Cloudformation template file
|
||||||
|
|
||||||
|
function! ale_linters#cloudformation#cfn_python_lint#Handle(buffer, lines) abort
|
||||||
|
" Matches patterns line the following:
|
||||||
|
"
|
||||||
|
" sample.template.yaml:96:7:96:15:E3012:Property Resources/Sample/Properties/FromPort should be of type Integer
|
||||||
|
let l:pattern = '\v^(.*):(\d+):(\d+):(\d+):(\d+):([[:alnum:]]+):(.*)$'
|
||||||
|
let l:output = []
|
||||||
|
|
||||||
|
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||||
|
let l:code = l:match[6]
|
||||||
|
|
||||||
|
if ale#path#IsBufferPath(a:buffer, l:match[1])
|
||||||
|
call add(l:output, {
|
||||||
|
\ 'lnum': l:match[2],
|
||||||
|
\ 'col': l:match[3],
|
||||||
|
\ 'end_lnum': l:match[4],
|
||||||
|
\ 'end_col': l:match[5],
|
||||||
|
\ 'code': l:code,
|
||||||
|
\ 'type': l:code[:0] is# 'E' ? 'E' : 'W',
|
||||||
|
\ 'text': l:match[7]
|
||||||
|
\})
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:output
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('cloudformation', {
|
||||||
|
\ 'name': 'cloudformation',
|
||||||
|
\ 'executable': 'cfn-lint',
|
||||||
|
\ 'command': 'cfn-lint --template %t --format parseable',
|
||||||
|
\ 'callback': 'ale_linters#cloudformation#cfn_python_lint#Handle',
|
||||||
|
\})
|
61
sources_non_forked/ale/ale_linters/elixir/mix.vim
Normal file
61
sources_non_forked/ale/ale_linters/elixir/mix.vim
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
" Author: evnu - https://github.com/evnu
|
||||||
|
" Author: colbydehart - https://github.com/colbydehart
|
||||||
|
" Description: Mix compile checking for Elixir files
|
||||||
|
|
||||||
|
function! ale_linters#elixir#mix#Handle(buffer, lines) abort
|
||||||
|
" Matches patterns like the following:
|
||||||
|
"
|
||||||
|
" Error format
|
||||||
|
" ** (CompileError) apps/sim/lib/sim/server.ex:87: undefined function update_in/4
|
||||||
|
"
|
||||||
|
" TODO: Warning format
|
||||||
|
" warning: variable "foobar" does not exist and is being expanded to "foobar()", please use parentheses to remove the ambiguity or change the variable name
|
||||||
|
|
||||||
|
let l:pattern = '\v\(([^\)]+Error)\) ([^:]+):([^:]+): (.+)$'
|
||||||
|
let l:output = []
|
||||||
|
|
||||||
|
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||||
|
let l:type = 'E'
|
||||||
|
let l:text = l:match[4]
|
||||||
|
|
||||||
|
call add(l:output, {
|
||||||
|
\ 'bufnr': a:buffer,
|
||||||
|
\ 'lnum': l:match[3] + 0,
|
||||||
|
\ 'col': 0,
|
||||||
|
\ 'type': l:type,
|
||||||
|
\ 'text': l:text,
|
||||||
|
\})
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:output
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#elixir#mix#FindProjectRoot(buffer) abort
|
||||||
|
let l:mix_file = ale#path#FindNearestFile(a:buffer, 'mix.exs')
|
||||||
|
if !empty(l:mix_file)
|
||||||
|
return fnamemodify(l:mix_file, ':p:h')
|
||||||
|
endif
|
||||||
|
return '.'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#elixir#mix#GetCommand(buffer) abort
|
||||||
|
let l:project_root = ale_linters#elixir#mix#FindProjectRoot(a:buffer)
|
||||||
|
|
||||||
|
let l:temp_dir = ale#engine#CreateDirectory(a:buffer)
|
||||||
|
|
||||||
|
let l:mix_build_path = has('win32')
|
||||||
|
\ ? 'set MIX_BUILD_PATH=' . ale#Escape(l:temp_dir) . ' &&'
|
||||||
|
\ : 'MIX_BUILD_PATH=' . ale#Escape(l:temp_dir)
|
||||||
|
|
||||||
|
return ale#path#CdString(l:project_root)
|
||||||
|
\ . l:mix_build_path
|
||||||
|
\ . ' mix compile %s'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('elixir', {
|
||||||
|
\ 'name': 'mix',
|
||||||
|
\ 'executable': 'mix',
|
||||||
|
\ 'command_callback': 'ale_linters#elixir#mix#GetCommand',
|
||||||
|
\ 'callback': 'ale_linters#elixir#mix#Handle',
|
||||||
|
\ 'lint_file': 1,
|
||||||
|
\})
|
|
@ -1,21 +1,10 @@
|
||||||
" Author: KabbAmine <amine.kabb@gmail.com>
|
" Author: KabbAmine <amine.kabb@gmail.com>
|
||||||
" Description: This file adds support for checking HTML code with tidy.
|
" Description: This file adds support for checking HTML code with tidy.
|
||||||
|
|
||||||
" CLI options
|
|
||||||
let g:ale_html_tidy_executable = get(g:, 'ale_html_tidy_executable', 'tidy')
|
let g:ale_html_tidy_executable = get(g:, 'ale_html_tidy_executable', 'tidy')
|
||||||
" remove in 2.0
|
let g:ale_html_tidy_options = get(g:, 'ale_html_tidy_options', '-q -e -language en')
|
||||||
" Look for the old _args variable first.
|
|
||||||
let s:deprecation_warning_echoed = 0
|
|
||||||
let s:default_options = get(g:, 'ale_html_tidy_args', '-q -e -language en')
|
|
||||||
let g:ale_html_tidy_options = get(g:, 'ale_html_tidy_options', s:default_options)
|
|
||||||
|
|
||||||
function! ale_linters#html#tidy#GetCommand(buffer) abort
|
function! ale_linters#html#tidy#GetCommand(buffer) abort
|
||||||
" remove in 2.0
|
|
||||||
if exists('g:ale_html_tidy_args') && !s:deprecation_warning_echoed
|
|
||||||
execute 'echom ''Rename your g:ale_html_tidy_args setting to g:ale_html_tidy_options instead. Support for this will removed in ALE 2.0.'''
|
|
||||||
let s:deprecation_warning_echoed = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Specify file encoding in options
|
" Specify file encoding in options
|
||||||
" (Idea taken from https://github.com/scrooloose/syntastic/blob/master/syntax_checkers/html/tidy.vim)
|
" (Idea taken from https://github.com/scrooloose/syntastic/blob/master/syntax_checkers/html/tidy.vim)
|
||||||
let l:file_encoding = get({
|
let l:file_encoding = get({
|
||||||
|
|
26
sources_non_forked/ale/ale_linters/javascript/tsserver.vim
Normal file
26
sources_non_forked/ale/ale_linters/javascript/tsserver.vim
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
" Author: Chaucerbao, w0rp <devw0rp@gmail.com>
|
||||||
|
" Description: tsserver integration for ALE
|
||||||
|
|
||||||
|
call ale#Set('javascript_tsserver_executable', 'tsserver')
|
||||||
|
call ale#Set('javascript_tsserver_config_path', '')
|
||||||
|
call ale#Set('javascript_tsserver_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||||
|
|
||||||
|
" These functions need to be defined just to comply with the API for LSP.
|
||||||
|
function! ale_linters#javascript#tsserver#GetProjectRoot(buffer) abort
|
||||||
|
return ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#javascript#tsserver#GetExecutable(buffer) abort
|
||||||
|
return ale#node#FindExecutable(a:buffer, 'javascript_tsserver', [
|
||||||
|
\ 'node_modules/.bin/tsserver',
|
||||||
|
\])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('javascript', {
|
||||||
|
\ 'name': 'tsserver',
|
||||||
|
\ 'lsp': 'tsserver',
|
||||||
|
\ 'executable_callback': 'ale_linters#javascript#tsserver#GetExecutable',
|
||||||
|
\ 'command_callback': 'ale_linters#javascript#tsserver#GetExecutable',
|
||||||
|
\ 'project_root_callback': 'ale_linters#javascript#tsserver#GetProjectRoot',
|
||||||
|
\ 'language': '',
|
||||||
|
\})
|
|
@ -1,10 +1,43 @@
|
||||||
" Author: w0rp <devw0rp@gmail.com>
|
" Author: w0rp <devw0rp@gmail.com>,
|
||||||
|
" Nicolas Pauss <https://github.com/nicopauss>
|
||||||
" Description: cython syntax checking for cython files.
|
" Description: cython syntax checking for cython files.
|
||||||
|
|
||||||
|
call ale#Set('pyrex_cython_executable', 'cython')
|
||||||
|
call ale#Set('pyrex_cython_options', '--warning-extra')
|
||||||
|
|
||||||
|
function! ale_linters#pyrex#cython#GetExecutable(buffer) abort
|
||||||
|
return ale#Var(a:buffer, 'pyrex_cython_executable')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#pyrex#cython#GetCommand(buffer) abort
|
||||||
|
let l:local_dir = ale#Escape(fnamemodify(bufname(a:buffer), ':p:h'))
|
||||||
|
|
||||||
|
return ale#Escape(ale_linters#pyrex#cython#GetExecutable(a:buffer))
|
||||||
|
\ . ' --working ' . l:local_dir . ' --include-dir ' . l:local_dir
|
||||||
|
\ . ' ' . ale#Var(a:buffer, 'pyrex_cython_options')
|
||||||
|
\ . ' --output-file ' . g:ale#util#nul_file . ' %t'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#pyrex#cython#Handle(buffer, lines) abort
|
||||||
|
let l:pattern = '\v^(\w+: )?[^:]+:(\d+):?(\d+)?:? ?(.+)$'
|
||||||
|
let l:output = []
|
||||||
|
|
||||||
|
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||||
|
call add(l:output, {
|
||||||
|
\ 'lnum': l:match[2] + 0,
|
||||||
|
\ 'col': l:match[3] + 0,
|
||||||
|
\ 'text': l:match[4],
|
||||||
|
\ 'type': l:match[1][0] is# 'w' ? 'W' : 'E',
|
||||||
|
\})
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:output
|
||||||
|
endfunction
|
||||||
|
|
||||||
call ale#linter#Define('pyrex', {
|
call ale#linter#Define('pyrex', {
|
||||||
\ 'name': 'cython',
|
\ 'name': 'cython',
|
||||||
\ 'output_stream': 'stderr',
|
\ 'output_stream': 'stderr',
|
||||||
\ 'executable': 'cython',
|
\ 'executable_callback': 'ale_linters#pyrex#cython#GetExecutable',
|
||||||
\ 'command': 'cython --warning-extra -o ' . g:ale#util#nul_file . ' %t',
|
\ 'command_callback': 'ale_linters#pyrex#cython#GetCommand',
|
||||||
\ 'callback': 'ale#handlers#unix#HandleAsError',
|
\ 'callback': 'ale_linters#pyrex#cython#Handle',
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
" Author: w0rp <devw0rp@gmail.com>
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
" Description: flake8 for python files
|
" Description: flake8 for python files
|
||||||
|
|
||||||
" remove in 2.0
|
|
||||||
" Support an old setting as a fallback.
|
|
||||||
let s:deprecation_warning_echoed = 0
|
|
||||||
let s:default_options = get(g:, 'ale_python_flake8_args', '')
|
|
||||||
|
|
||||||
call ale#Set('python_flake8_executable', 'flake8')
|
call ale#Set('python_flake8_executable', 'flake8')
|
||||||
call ale#Set('python_flake8_options', s:default_options)
|
call ale#Set('python_flake8_options', '')
|
||||||
call ale#Set('python_flake8_use_global', get(g:, 'ale_use_global_executables', 0))
|
call ale#Set('python_flake8_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||||
call ale#Set('python_flake8_change_directory', 1)
|
call ale#Set('python_flake8_change_directory', 1)
|
||||||
|
|
||||||
|
@ -40,12 +35,6 @@ function! ale_linters#python#flake8#VersionCheck(buffer) abort
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort
|
function! ale_linters#python#flake8#GetCommand(buffer, version_output) abort
|
||||||
" remove in 2.0
|
|
||||||
if exists('g:ale_python_flake8_args') && !s:deprecation_warning_echoed
|
|
||||||
execute 'echom ''Rename your g:ale_python_flake8_args setting to g:ale_python_flake8_options instead. Support for this will removed in ALE 2.0.'''
|
|
||||||
let s:deprecation_warning_echoed = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:cd_string = ale#Var(a:buffer, 'python_flake8_change_directory')
|
let l:cd_string = ale#Var(a:buffer, 'python_flake8_change_directory')
|
||||||
\ ? ale#path#BufferCdString(a:buffer)
|
\ ? ale#path#BufferCdString(a:buffer)
|
||||||
\ : ''
|
\ : ''
|
||||||
|
|
|
@ -30,6 +30,10 @@ endfunction
|
||||||
function! ale_linters#python#prospector#Handle(buffer, lines) abort
|
function! ale_linters#python#prospector#Handle(buffer, lines) abort
|
||||||
let l:output = []
|
let l:output = []
|
||||||
|
|
||||||
|
if empty(a:lines)
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
|
||||||
let l:prospector_error = json_decode(join(a:lines, ''))
|
let l:prospector_error = json_decode(join(a:lines, ''))
|
||||||
|
|
||||||
for l:error in l:prospector_error.messages
|
for l:error in l:prospector_error.messages
|
||||||
|
|
29
sources_non_forked/ale/ale_linters/python/pyre.vim
Normal file
29
sources_non_forked/ale/ale_linters/python/pyre.vim
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
" Author: dsifford <dereksifford@gmail.com>
|
||||||
|
" Description: A performant type-checker supporting LSP for Python 3 created by Facebook
|
||||||
|
|
||||||
|
call ale#Set('python_pyre_executable', 'pyre')
|
||||||
|
call ale#Set('python_pyre_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||||
|
|
||||||
|
function! ale_linters#python#pyre#GetExecutable(buffer) abort
|
||||||
|
return ale#python#FindExecutable(a:buffer, 'python_pyre', ['pyre'])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#python#pyre#GetCommand(buffer) abort
|
||||||
|
let l:executable = ale_linters#python#pyre#GetExecutable(a:buffer)
|
||||||
|
|
||||||
|
let l:exec_args = l:executable =~? 'pipenv$'
|
||||||
|
\ ? ' run pyre persistent'
|
||||||
|
\ : ' persistent'
|
||||||
|
|
||||||
|
return ale#Escape(l:executable) . l:exec_args
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('python', {
|
||||||
|
\ 'name': 'pyre',
|
||||||
|
\ 'lsp': 'stdio',
|
||||||
|
\ 'executable_callback': 'ale_linters#python#pyre#GetExecutable',
|
||||||
|
\ 'command_callback': 'ale_linters#python#pyre#GetCommand',
|
||||||
|
\ 'language': 'python',
|
||||||
|
\ 'project_root_callback': 'ale#python#FindProjectRoot',
|
||||||
|
\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
|
||||||
|
\})
|
|
@ -4,21 +4,27 @@
|
||||||
call ale#Set('ruby_reek_show_context', 0)
|
call ale#Set('ruby_reek_show_context', 0)
|
||||||
call ale#Set('ruby_reek_show_wiki_link', 0)
|
call ale#Set('ruby_reek_show_wiki_link', 0)
|
||||||
|
|
||||||
function! ale_linters#ruby#reek#Handle(buffer, lines) abort
|
function! ale_linters#ruby#reek#VersionCheck(buffer) abort
|
||||||
let l:output = []
|
" If we have previously stored the version number in a cache, then
|
||||||
|
" don't look it up again.
|
||||||
|
if ale#semver#HasVersion('reek')
|
||||||
|
" Returning an empty string skips this command.
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
|
||||||
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
|
return 'reek --version'
|
||||||
for l:location in l:error.lines
|
endfunction
|
||||||
call add(l:output, {
|
|
||||||
\ 'lnum': l:location,
|
|
||||||
\ 'type': 'W',
|
|
||||||
\ 'text': s:BuildText(a:buffer, l:error),
|
|
||||||
\ 'code': l:error.smell_type,
|
|
||||||
\})
|
|
||||||
endfor
|
|
||||||
endfor
|
|
||||||
|
|
||||||
return l:output
|
function! ale_linters#ruby#reek#GetCommand(buffer, version_output) abort
|
||||||
|
let l:version = ale#semver#GetVersion('reek', a:version_output)
|
||||||
|
|
||||||
|
" Tell reek what the filename is if the version of reek is new enough.
|
||||||
|
let l:display_name_args = ale#semver#GTE(l:version, [5, 0, 0])
|
||||||
|
\ ? ' --stdin-filename %s'
|
||||||
|
\ : ''
|
||||||
|
|
||||||
|
return 'reek -f json --no-progress --no-color'
|
||||||
|
\ . l:display_name_args
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:BuildText(buffer, error) abort
|
function! s:BuildText(buffer, error) abort
|
||||||
|
@ -37,9 +43,29 @@ function! s:BuildText(buffer, error) abort
|
||||||
return join(l:parts, ' ')
|
return join(l:parts, ' ')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#ruby#reek#Handle(buffer, lines) abort
|
||||||
|
let l:output = []
|
||||||
|
|
||||||
|
for l:error in ale#util#FuzzyJSONDecode(a:lines, [])
|
||||||
|
for l:location in l:error.lines
|
||||||
|
call add(l:output, {
|
||||||
|
\ 'lnum': l:location,
|
||||||
|
\ 'type': 'W',
|
||||||
|
\ 'text': s:BuildText(a:buffer, l:error),
|
||||||
|
\ 'code': l:error.smell_type,
|
||||||
|
\})
|
||||||
|
endfor
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:output
|
||||||
|
endfunction
|
||||||
|
|
||||||
call ale#linter#Define('ruby', {
|
call ale#linter#Define('ruby', {
|
||||||
\ 'name': 'reek',
|
\ 'name': 'reek',
|
||||||
\ 'executable': 'reek',
|
\ 'executable': 'reek',
|
||||||
\ 'command': 'reek -f json --no-progress --no-color',
|
\ 'command_chain': [
|
||||||
|
\ {'callback': 'ale_linters#ruby#reek#VersionCheck'},
|
||||||
|
\ {'callback': 'ale_linters#ruby#reek#GetCommand'},
|
||||||
|
\ ],
|
||||||
\ 'callback': 'ale_linters#ruby#reek#Handle',
|
\ 'callback': 'ale_linters#ruby#reek#Handle',
|
||||||
\})
|
\})
|
||||||
|
|
|
@ -6,6 +6,7 @@ call ale#Set('rust_cargo_use_check', 1)
|
||||||
call ale#Set('rust_cargo_check_all_targets', 0)
|
call ale#Set('rust_cargo_check_all_targets', 0)
|
||||||
call ale#Set('rust_cargo_check_examples', 0)
|
call ale#Set('rust_cargo_check_examples', 0)
|
||||||
call ale#Set('rust_cargo_check_tests', 0)
|
call ale#Set('rust_cargo_check_tests', 0)
|
||||||
|
call ale#Set('rust_cargo_avoid_whole_workspace', 1)
|
||||||
call ale#Set('rust_cargo_default_feature_behavior', 'default')
|
call ale#Set('rust_cargo_default_feature_behavior', 'default')
|
||||||
call ale#Set('rust_cargo_include_features', '')
|
call ale#Set('rust_cargo_include_features', '')
|
||||||
|
|
||||||
|
@ -45,6 +46,18 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort
|
||||||
let l:include_features = ' --features ' . ale#Escape(l:include_features)
|
let l:include_features = ' --features ' . ale#Escape(l:include_features)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
let l:avoid_whole_workspace = ale#Var(a:buffer, 'rust_cargo_avoid_whole_workspace')
|
||||||
|
let l:nearest_cargo_prefix = ''
|
||||||
|
|
||||||
|
if l:avoid_whole_workspace
|
||||||
|
let l:nearest_cargo = ale#path#FindNearestFile(a:buffer, 'Cargo.toml')
|
||||||
|
let l:nearest_cargo_dir = fnamemodify(l:nearest_cargo, ':h')
|
||||||
|
|
||||||
|
if l:nearest_cargo_dir isnot# '.'
|
||||||
|
let l:nearest_cargo_prefix = 'cd '. ale#Escape(l:nearest_cargo_dir) .' && '
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
let l:default_feature_behavior = ale#Var(a:buffer, 'rust_cargo_default_feature_behavior')
|
let l:default_feature_behavior = ale#Var(a:buffer, 'rust_cargo_default_feature_behavior')
|
||||||
if l:default_feature_behavior is# 'all'
|
if l:default_feature_behavior is# 'all'
|
||||||
let l:include_features = ''
|
let l:include_features = ''
|
||||||
|
@ -55,7 +68,7 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort
|
||||||
let l:default_feature = ''
|
let l:default_feature = ''
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return 'cargo '
|
return l:nearest_cargo_prefix . 'cargo '
|
||||||
\ . (l:use_check ? 'check' : 'build')
|
\ . (l:use_check ? 'check' : 'build')
|
||||||
\ . (l:use_all_targets ? ' --all-targets' : '')
|
\ . (l:use_all_targets ? ' --all-targets' : '')
|
||||||
\ . (l:use_examples ? ' --examples' : '')
|
\ . (l:use_examples ? ' --examples' : '')
|
||||||
|
|
33
sources_non_forked/ale/ale_linters/sh/language_server.vim
Normal file
33
sources_non_forked/ale/ale_linters/sh/language_server.vim
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
" Author: Christian Höltje (https://docwhat.org/)
|
||||||
|
" Description: BASH Language server integration for ALE
|
||||||
|
scriptencoding utf-8
|
||||||
|
|
||||||
|
call ale#Set('sh_language_server_executable', 'bash-language-server')
|
||||||
|
call ale#Set('sh_language_server_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||||
|
|
||||||
|
function! ale_linters#sh#language_server#GetExecutable(buffer) abort
|
||||||
|
return ale#node#FindExecutable(a:buffer, 'sh_language_server', [
|
||||||
|
\ 'node_modules/.bin/bash-language-server',
|
||||||
|
\])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#sh#language_server#GetCommand(buffer) abort
|
||||||
|
let l:exe = ale#Escape(ale_linters#sh#language_server#GetExecutable(a:buffer))
|
||||||
|
|
||||||
|
return l:exe . ' start'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale_linters#sh#language_server#GetProjectRoot(buffer) abort
|
||||||
|
let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git')
|
||||||
|
|
||||||
|
return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('sh', {
|
||||||
|
\ 'name': 'language_server',
|
||||||
|
\ 'lsp': 'stdio',
|
||||||
|
\ 'executable_callback': 'ale_linters#sh#language_server#GetExecutable',
|
||||||
|
\ 'command_callback': 'ale_linters#sh#language_server#GetCommand',
|
||||||
|
\ 'language': 'sh',
|
||||||
|
\ 'project_root_callback': 'ale_linters#sh#language_server#GetProjectRoot',
|
||||||
|
\})
|
|
@ -20,21 +20,31 @@ function! ale_linters#yaml#yamllint#Handle(buffer, lines) abort
|
||||||
" Matches patterns line the following:
|
" Matches patterns line the following:
|
||||||
" something.yaml:1:1: [warning] missing document start "---" (document-start)
|
" something.yaml:1:1: [warning] missing document start "---" (document-start)
|
||||||
" something.yml:2:1: [error] syntax error: expected the node content, but found '<stream end>'
|
" something.yml:2:1: [error] syntax error: expected the node content, but found '<stream end>'
|
||||||
let l:pattern = '^.*:\(\d\+\):\(\d\+\): \[\(error\|warning\)\] \(.\+\)$'
|
let l:pattern = '\v^.*:(\d+):(\d+): \[(error|warning)\] (.+)$'
|
||||||
let l:output = []
|
let l:output = []
|
||||||
|
|
||||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||||
let l:line = l:match[1] + 0
|
let l:item = {
|
||||||
let l:col = l:match[2] + 0
|
\ 'lnum': l:match[1] + 0,
|
||||||
let l:type = l:match[3]
|
\ 'col': l:match[2] + 0,
|
||||||
let l:text = l:match[4]
|
\ 'text': l:match[4],
|
||||||
|
\ 'type': l:match[3] is# 'error' ? 'E' : 'W',
|
||||||
|
\}
|
||||||
|
|
||||||
call add(l:output, {
|
let l:code_match = matchlist(l:item.text, '\v^(.+) \(([^)]+)\)$')
|
||||||
\ 'lnum': l:line,
|
|
||||||
\ 'col': l:col,
|
if !empty(l:code_match)
|
||||||
\ 'text': l:text,
|
if l:code_match[2] is# 'trailing-spaces'
|
||||||
\ 'type': l:type is# 'error' ? 'E' : 'W',
|
\&& !ale#Var(a:buffer, 'warn_about_trailing_whitespace')
|
||||||
\})
|
" Skip warnings for trailing whitespace if the option is off.
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:item.text = l:code_match[1]
|
||||||
|
let l:item.code = l:code_match[2]
|
||||||
|
endif
|
||||||
|
|
||||||
|
call add(l:output, l:item)
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
return l:output
|
return l:output
|
||||||
|
|
|
@ -6,35 +6,12 @@
|
||||||
let g:ale_echo_msg_error_str = get(g:, 'ale_echo_msg_error_str', 'Error')
|
let g:ale_echo_msg_error_str = get(g:, 'ale_echo_msg_error_str', 'Error')
|
||||||
let g:ale_echo_msg_info_str = get(g:, 'ale_echo_msg_info_str', 'Info')
|
let g:ale_echo_msg_info_str = get(g:, 'ale_echo_msg_info_str', 'Info')
|
||||||
let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
|
let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
|
||||||
|
" Ignoring linters, for disabling some, or ignoring LSP diagnostics.
|
||||||
|
let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {})
|
||||||
|
|
||||||
let s:lint_timer = -1
|
let s:lint_timer = -1
|
||||||
let s:queued_buffer_number = -1
|
let s:queued_buffer_number = -1
|
||||||
let s:should_lint_file_for_buffer = {}
|
let s:should_lint_file_for_buffer = {}
|
||||||
let s:error_delay_ms = 1000 * 60 * 2
|
|
||||||
|
|
||||||
let s:timestamp_map = {}
|
|
||||||
|
|
||||||
" Given a key for a script variable for tracking the time to wait until
|
|
||||||
" a given function should be called, a funcref for a function to call, and
|
|
||||||
" a List of arguments, call the function and return whatever value it returns.
|
|
||||||
"
|
|
||||||
" If the function throws an exception, then the function will not be called
|
|
||||||
" for a while, and 0 will be returned instead.
|
|
||||||
function! ale#CallWithCooldown(timestamp_key, func, arglist) abort
|
|
||||||
let l:now = ale#util#ClockMilliseconds()
|
|
||||||
|
|
||||||
if l:now < get(s:timestamp_map, a:timestamp_key, -1)
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
let s:timestamp_map[a:timestamp_key] = l:now + s:error_delay_ms
|
|
||||||
|
|
||||||
let l:return_value = call(a:func, a:arglist)
|
|
||||||
|
|
||||||
let s:timestamp_map[a:timestamp_key] = -1
|
|
||||||
|
|
||||||
return l:return_value
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Return 1 if a file is too large for ALE to handle.
|
" Return 1 if a file is too large for ALE to handle.
|
||||||
function! ale#FileTooLarge(buffer) abort
|
function! ale#FileTooLarge(buffer) abort
|
||||||
|
@ -114,30 +91,22 @@ function! ale#Queue(delay, ...) abort
|
||||||
let l:linting_flag = get(a:000, 0, '')
|
let l:linting_flag = get(a:000, 0, '')
|
||||||
let l:buffer = get(a:000, 1, bufnr(''))
|
let l:buffer = get(a:000, 1, bufnr(''))
|
||||||
|
|
||||||
return ale#CallWithCooldown(
|
if l:linting_flag isnot# '' && l:linting_flag isnot# 'lint_file'
|
||||||
\ 'dont_queue_until',
|
|
||||||
\ function('s:ALEQueueImpl'),
|
|
||||||
\ [a:delay, l:linting_flag, l:buffer],
|
|
||||||
\)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:ALEQueueImpl(delay, linting_flag, buffer) abort
|
|
||||||
if a:linting_flag isnot# '' && a:linting_flag isnot# 'lint_file'
|
|
||||||
throw "linting_flag must be either '' or 'lint_file'"
|
throw "linting_flag must be either '' or 'lint_file'"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if type(a:buffer) != type(0)
|
if type(l:buffer) != type(0)
|
||||||
throw 'buffer_number must be a Number'
|
throw 'buffer_number must be a Number'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ale#ShouldDoNothing(a:buffer)
|
if ale#ShouldDoNothing(l:buffer)
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Remember that we want to check files for this buffer.
|
" Remember that we want to check files for this buffer.
|
||||||
" We will remember this until we finally run the linters, via any event.
|
" We will remember this until we finally run the linters, via any event.
|
||||||
if a:linting_flag is# 'lint_file'
|
if l:linting_flag is# 'lint_file'
|
||||||
let s:should_lint_file_for_buffer[a:buffer] = 1
|
let s:should_lint_file_for_buffer[l:buffer] = 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if s:lint_timer != -1
|
if s:lint_timer != -1
|
||||||
|
@ -145,24 +114,24 @@ function! s:ALEQueueImpl(delay, linting_flag, buffer) abort
|
||||||
let s:lint_timer = -1
|
let s:lint_timer = -1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:linters = ale#linter#Get(getbufvar(a:buffer, '&filetype'))
|
let l:linters = ale#linter#Get(getbufvar(l:buffer, '&filetype'))
|
||||||
|
|
||||||
" Don't set up buffer data and so on if there are no linters to run.
|
" Don't set up buffer data and so on if there are no linters to run.
|
||||||
if empty(l:linters)
|
if empty(l:linters)
|
||||||
" If we have some previous buffer data, then stop any jobs currently
|
" If we have some previous buffer data, then stop any jobs currently
|
||||||
" running and clear everything.
|
" running and clear everything.
|
||||||
if has_key(g:ale_buffer_info, a:buffer)
|
if has_key(g:ale_buffer_info, l:buffer)
|
||||||
call ale#engine#RunLinters(a:buffer, [], 1)
|
call ale#engine#RunLinters(l:buffer, [], 1)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if a:delay > 0
|
if a:delay > 0
|
||||||
let s:queued_buffer_number = a:buffer
|
let s:queued_buffer_number = l:buffer
|
||||||
let s:lint_timer = timer_start(a:delay, function('ale#Lint'))
|
let s:lint_timer = timer_start(a:delay, function('ale#Lint'))
|
||||||
else
|
else
|
||||||
call ale#Lint(-1, a:buffer)
|
call ale#Lint(-1, l:buffer)
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@ -178,30 +147,29 @@ function! ale#Lint(...) abort
|
||||||
let l:buffer = bufnr('')
|
let l:buffer = bufnr('')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return ale#CallWithCooldown(
|
if ale#ShouldDoNothing(l:buffer)
|
||||||
\ 'dont_lint_until',
|
|
||||||
\ function('s:ALELintImpl'),
|
|
||||||
\ [l:buffer],
|
|
||||||
\)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:ALELintImpl(buffer) abort
|
|
||||||
if ale#ShouldDoNothing(a:buffer)
|
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Use the filetype from the buffer
|
" Use the filetype from the buffer
|
||||||
let l:linters = ale#linter#Get(getbufvar(a:buffer, '&filetype'))
|
let l:filetype = getbufvar(l:buffer, '&filetype')
|
||||||
|
let l:linters = ale#linter#Get(l:filetype)
|
||||||
let l:should_lint_file = 0
|
let l:should_lint_file = 0
|
||||||
|
|
||||||
" Check if we previously requested checking the file.
|
" Check if we previously requested checking the file.
|
||||||
if has_key(s:should_lint_file_for_buffer, a:buffer)
|
if has_key(s:should_lint_file_for_buffer, l:buffer)
|
||||||
unlet s:should_lint_file_for_buffer[a:buffer]
|
unlet s:should_lint_file_for_buffer[l:buffer]
|
||||||
" Lint files if they exist.
|
" Lint files if they exist.
|
||||||
let l:should_lint_file = filereadable(expand('#' . a:buffer . ':p'))
|
let l:should_lint_file = filereadable(expand('#' . l:buffer . ':p'))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call ale#engine#RunLinters(a:buffer, l:linters, l:should_lint_file)
|
" Apply ignore lists for linters only if needed.
|
||||||
|
let l:ignore_config = ale#Var(l:buffer, 'linters_ignore')
|
||||||
|
let l:linters = !empty(l:ignore_config)
|
||||||
|
\ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config)
|
||||||
|
\ : l:linters
|
||||||
|
|
||||||
|
call ale#engine#RunLinters(l:buffer, l:linters, l:should_lint_file)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Reset flags indicating that files should be checked for all buffers.
|
" Reset flags indicating that files should be checked for all buffers.
|
||||||
|
@ -209,10 +177,6 @@ function! ale#ResetLintFileMarkers() abort
|
||||||
let s:should_lint_file_for_buffer = {}
|
let s:should_lint_file_for_buffer = {}
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#ResetErrorDelays() abort
|
|
||||||
let s:timestamp_map = {}
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
let g:ale_has_override = get(g:, 'ale_has_override', {})
|
let g:ale_has_override = get(g:, 'ale_has_override', {})
|
||||||
|
|
||||||
" Call has(), but check a global Dictionary so we can force flags on or off
|
" Call has(), but check a global Dictionary so we can force flags on or off
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
function! ale#autocmd#InitAuGroups() abort
|
|
||||||
" This value used to be a Boolean as a Number, and is now a String.
|
|
||||||
let l:text_changed = '' . g:ale_lint_on_text_changed
|
|
||||||
|
|
||||||
augroup ALEPatternOptionsGroup
|
|
||||||
autocmd!
|
|
||||||
autocmd BufEnter,BufRead * call ale#pattern_options#SetOptions(str2nr(expand('<abuf>')))
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
augroup ALERunOnTextChangedGroup
|
|
||||||
autocmd!
|
|
||||||
if g:ale_enabled
|
|
||||||
if l:text_changed is? 'always' || l:text_changed is# '1'
|
|
||||||
autocmd TextChanged,TextChangedI * call ale#Queue(g:ale_lint_delay)
|
|
||||||
elseif l:text_changed is? 'normal'
|
|
||||||
autocmd TextChanged * call ale#Queue(g:ale_lint_delay)
|
|
||||||
elseif l:text_changed is? 'insert'
|
|
||||||
autocmd TextChangedI * call ale#Queue(g:ale_lint_delay)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
augroup ALERunOnEnterGroup
|
|
||||||
autocmd!
|
|
||||||
if g:ale_enabled
|
|
||||||
" Handle everything that needs to happen when buffers are entered.
|
|
||||||
autocmd BufEnter * call ale#events#EnterEvent(str2nr(expand('<abuf>')))
|
|
||||||
endif
|
|
||||||
if g:ale_enabled && g:ale_lint_on_enter
|
|
||||||
autocmd BufWinEnter,BufRead * call ale#Queue(0, 'lint_file', str2nr(expand('<abuf>')))
|
|
||||||
" Track when the file is changed outside of Vim.
|
|
||||||
autocmd FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand('<abuf>')))
|
|
||||||
endif
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
augroup ALERunOnFiletypeChangeGroup
|
|
||||||
autocmd!
|
|
||||||
if g:ale_enabled && g:ale_lint_on_filetype_changed
|
|
||||||
" Only start linting if the FileType actually changes after
|
|
||||||
" opening a buffer. The FileType will fire when buffers are opened.
|
|
||||||
autocmd FileType * call ale#events#FileTypeEvent(
|
|
||||||
\ str2nr(expand('<abuf>')),
|
|
||||||
\ expand('<amatch>')
|
|
||||||
\)
|
|
||||||
endif
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
augroup ALERunOnSaveGroup
|
|
||||||
autocmd!
|
|
||||||
autocmd BufWritePost * call ale#events#SaveEvent(str2nr(expand('<abuf>')))
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
augroup ALERunOnInsertLeave
|
|
||||||
autocmd!
|
|
||||||
if g:ale_enabled && g:ale_lint_on_insert_leave
|
|
||||||
autocmd InsertLeave * call ale#Queue(0)
|
|
||||||
endif
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
augroup ALECursorGroup
|
|
||||||
autocmd!
|
|
||||||
if g:ale_enabled && g:ale_echo_cursor
|
|
||||||
autocmd CursorMoved,CursorHold * call ale#cursor#EchoCursorWarningWithDelay()
|
|
||||||
" Look for a warning to echo as soon as we leave Insert mode.
|
|
||||||
" The script's position variable used when moving the cursor will
|
|
||||||
" not be changed here.
|
|
||||||
autocmd InsertLeave * call ale#cursor#EchoCursorWarning()
|
|
||||||
endif
|
|
||||||
augroup END
|
|
||||||
|
|
||||||
if !g:ale_enabled
|
|
||||||
augroup! ALERunOnTextChangedGroup
|
|
||||||
augroup! ALERunOnEnterGroup
|
|
||||||
augroup! ALERunOnInsertLeave
|
|
||||||
augroup! ALECursorGroup
|
|
||||||
endif
|
|
||||||
endfunction
|
|
|
@ -34,7 +34,11 @@ function! ale#balloon#Expr() abort
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#balloon#Disable() abort
|
function! ale#balloon#Disable() abort
|
||||||
set noballooneval noballoonevalterm
|
if has('balloon_eval_term')
|
||||||
|
set noballoonevalterm
|
||||||
|
endif
|
||||||
|
|
||||||
|
set noballooneval
|
||||||
set balloonexpr=
|
set balloonexpr=
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,11 @@ function! s:ReplaceCompleteopt() abort
|
||||||
let b:ale_old_completopt = &l:completeopt
|
let b:ale_old_completopt = &l:completeopt
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if &l:completeopt =~# 'preview'
|
||||||
let &l:completeopt = 'menu,menuone,preview,noselect,noinsert'
|
let &l:completeopt = 'menu,menuone,preview,noselect,noinsert'
|
||||||
|
else
|
||||||
|
let &l:completeopt = 'menu,menuone,noselect,noinsert'
|
||||||
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#completion#OmniFunc(findstart, base) abort
|
function! ale#completion#OmniFunc(findstart, base) abort
|
||||||
|
@ -389,14 +393,13 @@ function! s:GetLSPCompletions(linter) abort
|
||||||
\ ? function('ale#completion#HandleTSServerResponse')
|
\ ? function('ale#completion#HandleTSServerResponse')
|
||||||
\ : function('ale#completion#HandleLSPResponse')
|
\ : function('ale#completion#HandleLSPResponse')
|
||||||
|
|
||||||
let l:lsp_details = ale#linter#StartLSP(l:buffer, a:linter, l:Callback)
|
let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||||
|
|
||||||
if empty(l:lsp_details)
|
if empty(l:lsp_details)
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:id = l:lsp_details.connection_id
|
let l:id = l:lsp_details.connection_id
|
||||||
let l:root = l:lsp_details.project_root
|
|
||||||
|
|
||||||
if a:linter.lsp is# 'tsserver'
|
if a:linter.lsp is# 'tsserver'
|
||||||
let l:message = ale#lsp#tsserver_message#Completions(
|
let l:message = ale#lsp#tsserver_message#Completions(
|
||||||
|
@ -408,7 +411,7 @@ function! s:GetLSPCompletions(linter) abort
|
||||||
else
|
else
|
||||||
" Send a message saying the buffer has changed first, otherwise
|
" Send a message saying the buffer has changed first, otherwise
|
||||||
" completions won't know what text is nearby.
|
" completions won't know what text is nearby.
|
||||||
call ale#lsp#Send(l:id, ale#lsp#message#DidChange(l:buffer), l:root)
|
call ale#lsp#NotifyForChanges(l:lsp_details)
|
||||||
|
|
||||||
" For LSP completions, we need to clamp the column to the length of
|
" For LSP completions, we need to clamp the column to the length of
|
||||||
" the line. python-language-server and perhaps others do not implement
|
" the line. python-language-server and perhaps others do not implement
|
||||||
|
@ -424,7 +427,7 @@ function! s:GetLSPCompletions(linter) abort
|
||||||
\)
|
\)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
|
let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root)
|
||||||
|
|
||||||
if l:request_id
|
if l:request_id
|
||||||
let b:ale_completion_info.conn_id = l:id
|
let b:ale_completion_info.conn_id = l:id
|
||||||
|
|
|
@ -56,10 +56,6 @@ function! s:StopCursorTimer() abort
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#cursor#EchoCursorWarning(...) abort
|
function! ale#cursor#EchoCursorWarning(...) abort
|
||||||
return ale#CallWithCooldown('dont_echo_until', function('s:EchoImpl'), [])
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:EchoImpl() abort
|
|
||||||
if !g:ale_echo_cursor
|
if !g:ale_echo_cursor
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -214,10 +214,15 @@ function! ale#debugging#Info() abort
|
||||||
" This must be done after linters are loaded.
|
" This must be done after linters are loaded.
|
||||||
let l:variable_list = s:GetLinterVariables(l:filetype, l:enabled_names)
|
let l:variable_list = s:GetLinterVariables(l:filetype, l:enabled_names)
|
||||||
|
|
||||||
|
let l:fixers = ale#fix#registry#SuggestedFixers(l:filetype)
|
||||||
|
let l:fixers = uniq(sort(l:fixers[0] + l:fixers[1]))
|
||||||
|
let l:fixers_string = join(map(copy(l:fixers), '"\n " . v:val'), '')
|
||||||
|
|
||||||
call s:Echo(' Current Filetype: ' . l:filetype)
|
call s:Echo(' Current Filetype: ' . l:filetype)
|
||||||
call s:Echo('Available Linters: ' . string(l:all_names))
|
call s:Echo('Available Linters: ' . string(l:all_names))
|
||||||
call s:EchoLinterAliases(l:all_linters)
|
call s:EchoLinterAliases(l:all_linters)
|
||||||
call s:Echo(' Enabled Linters: ' . string(l:enabled_names))
|
call s:Echo(' Enabled Linters: ' . string(l:enabled_names))
|
||||||
|
call s:Echo(' Suggested Fixers: ' . l:fixers_string)
|
||||||
call s:Echo(' Linter Variables:')
|
call s:Echo(' Linter Variables:')
|
||||||
call s:Echo('')
|
call s:Echo('')
|
||||||
call s:EchoLinterVariables(l:variable_list)
|
call s:EchoLinterVariables(l:variable_list)
|
||||||
|
|
|
@ -65,14 +65,13 @@ function! s:GoToLSPDefinition(linter, options) abort
|
||||||
\ ? function('ale#definition#HandleTSServerResponse')
|
\ ? function('ale#definition#HandleTSServerResponse')
|
||||||
\ : function('ale#definition#HandleLSPResponse')
|
\ : function('ale#definition#HandleLSPResponse')
|
||||||
|
|
||||||
let l:lsp_details = ale#linter#StartLSP(l:buffer, a:linter, l:Callback)
|
let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||||
|
|
||||||
if empty(l:lsp_details)
|
if empty(l:lsp_details)
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:id = l:lsp_details.connection_id
|
let l:id = l:lsp_details.connection_id
|
||||||
let l:root = l:lsp_details.project_root
|
|
||||||
|
|
||||||
if a:linter.lsp is# 'tsserver'
|
if a:linter.lsp is# 'tsserver'
|
||||||
let l:message = ale#lsp#tsserver_message#Definition(
|
let l:message = ale#lsp#tsserver_message#Definition(
|
||||||
|
@ -83,7 +82,7 @@ function! s:GoToLSPDefinition(linter, options) abort
|
||||||
else
|
else
|
||||||
" Send a message saying the buffer has changed first, or the
|
" Send a message saying the buffer has changed first, or the
|
||||||
" definition position probably won't make sense.
|
" definition position probably won't make sense.
|
||||||
call ale#lsp#Send(l:id, ale#lsp#message#DidChange(l:buffer), l:root)
|
call ale#lsp#NotifyForChanges(l:lsp_details)
|
||||||
|
|
||||||
let l:column = min([l:column, len(getline(l:line))])
|
let l:column = min([l:column, len(getline(l:line))])
|
||||||
|
|
||||||
|
@ -93,7 +92,7 @@ function! s:GoToLSPDefinition(linter, options) abort
|
||||||
let l:message = ale#lsp#message#Definition(l:buffer, l:line, l:column)
|
let l:message = ale#lsp#message#Definition(l:buffer, l:line, l:column)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
|
let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root)
|
||||||
|
|
||||||
let s:go_to_definition_map[l:request_id] = {
|
let s:go_to_definition_map[l:request_id] = {
|
||||||
\ 'open_in_tab': get(a:options, 'open_in_tab', 0),
|
\ 'open_in_tab': get(a:options, 'open_in_tab', 0),
|
||||||
|
|
|
@ -14,11 +14,6 @@ if !has_key(s:, 'job_info_map')
|
||||||
let s:job_info_map = {}
|
let s:job_info_map = {}
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Associates LSP connection IDs with linter names.
|
|
||||||
if !has_key(s:, 'lsp_linter_map')
|
|
||||||
let s:lsp_linter_map = {}
|
|
||||||
endif
|
|
||||||
|
|
||||||
if !has_key(s:, 'executable_cache_map')
|
if !has_key(s:, 'executable_cache_map')
|
||||||
let s:executable_cache_map = {}
|
let s:executable_cache_map = {}
|
||||||
endif
|
endif
|
||||||
|
@ -79,16 +74,6 @@ function! ale#engine#InitBufferInfo(buffer) abort
|
||||||
return 0
|
return 0
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Clear LSP linter data for the linting engine.
|
|
||||||
function! ale#engine#ClearLSPData() abort
|
|
||||||
let s:lsp_linter_map = {}
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Just for tests.
|
|
||||||
function! ale#engine#SetLSPLinterMap(replacement_map) abort
|
|
||||||
let s:lsp_linter_map = a:replacement_map
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" This function is documented and part of the public API.
|
" This function is documented and part of the public API.
|
||||||
"
|
"
|
||||||
" Return 1 if ALE is busy checking a given buffer
|
" Return 1 if ALE is busy checking a given buffer
|
||||||
|
@ -241,88 +226,6 @@ function! s:HandleExit(job_id, exit_code) abort
|
||||||
call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist)
|
call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:HandleLSPDiagnostics(conn_id, response) abort
|
|
||||||
let l:linter_name = s:lsp_linter_map[a:conn_id]
|
|
||||||
let l:filename = ale#path#FromURI(a:response.params.uri)
|
|
||||||
let l:buffer = bufnr(l:filename)
|
|
||||||
|
|
||||||
if l:buffer <= 0
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:loclist = ale#lsp#response#ReadDiagnostics(a:response)
|
|
||||||
|
|
||||||
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:HandleTSServerDiagnostics(response, error_type) abort
|
|
||||||
let l:buffer = bufnr(a:response.body.file)
|
|
||||||
let l:info = get(g:ale_buffer_info, l:buffer, {})
|
|
||||||
|
|
||||||
if empty(l:info)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:thislist = ale#lsp#response#ReadTSServerDiagnostics(a:response)
|
|
||||||
|
|
||||||
" tsserver sends syntax and semantic errors in separate messages, so we
|
|
||||||
" have to collect the messages separately for each buffer and join them
|
|
||||||
" back together again.
|
|
||||||
if a:error_type is# 'syntax'
|
|
||||||
let l:info.syntax_loclist = l:thislist
|
|
||||||
else
|
|
||||||
let l:info.semantic_loclist = l:thislist
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:loclist = get(l:info, 'semantic_loclist', [])
|
|
||||||
\ + get(l:info, 'syntax_loclist', [])
|
|
||||||
|
|
||||||
call ale#engine#HandleLoclist('tsserver', l:buffer, l:loclist)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:HandleLSPErrorMessage(linter_name, response) abort
|
|
||||||
if !g:ale_history_enabled || !g:ale_history_log_output
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
if empty(a:linter_name)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:message = ale#lsp#response#GetErrorMessage(a:response)
|
|
||||||
|
|
||||||
if empty(l:message)
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
" This global variable is set here so we don't load the debugging.vim file
|
|
||||||
" until someone uses :ALEInfo.
|
|
||||||
let g:ale_lsp_error_messages = get(g:, 'ale_lsp_error_messages', {})
|
|
||||||
|
|
||||||
if !has_key(g:ale_lsp_error_messages, a:linter_name)
|
|
||||||
let g:ale_lsp_error_messages[a:linter_name] = []
|
|
||||||
endif
|
|
||||||
|
|
||||||
call add(g:ale_lsp_error_messages[a:linter_name], l:message)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! ale#engine#HandleLSPResponse(conn_id, response) abort
|
|
||||||
let l:method = get(a:response, 'method', '')
|
|
||||||
let l:linter_name = get(s:lsp_linter_map, a:conn_id, '')
|
|
||||||
|
|
||||||
if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error')
|
|
||||||
call s:HandleLSPErrorMessage(l:linter_name, a:response)
|
|
||||||
elseif l:method is# 'textDocument/publishDiagnostics'
|
|
||||||
call s:HandleLSPDiagnostics(a:conn_id, a:response)
|
|
||||||
elseif get(a:response, 'type', '') is# 'event'
|
|
||||||
\&& get(a:response, 'event', '') is# 'semanticDiag'
|
|
||||||
call s:HandleTSServerDiagnostics(a:response, 'semantic')
|
|
||||||
elseif get(a:response, 'type', '') is# 'event'
|
|
||||||
\&& get(a:response, 'event', '') is# 'syntaxDiag'
|
|
||||||
call s:HandleTSServerDiagnostics(a:response, 'syntax')
|
|
||||||
endif
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! ale#engine#SetResults(buffer, loclist) abort
|
function! ale#engine#SetResults(buffer, loclist) abort
|
||||||
let l:linting_is_done = !ale#engine#IsCheckingBuffer(a:buffer)
|
let l:linting_is_done = !ale#engine#IsCheckingBuffer(a:buffer)
|
||||||
|
|
||||||
|
@ -367,9 +270,6 @@ function! ale#engine#SetResults(buffer, loclist) abort
|
||||||
|
|
||||||
" Call user autocommands. This allows users to hook into ALE's lint cycle.
|
" Call user autocommands. This allows users to hook into ALE's lint cycle.
|
||||||
silent doautocmd <nomodeline> User ALELintPost
|
silent doautocmd <nomodeline> User ALELintPost
|
||||||
" remove in 2.0
|
|
||||||
" Old DEPRECATED name; call it for backwards compatibility.
|
|
||||||
silent doautocmd <nomodeline> User ALELint
|
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@ -739,44 +639,6 @@ function! s:StopCurrentJobs(buffer, include_lint_file_jobs) abort
|
||||||
let l:info.active_linter_list = l:new_active_linter_list
|
let l:info.active_linter_list = l:new_active_linter_list
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:CheckWithLSP(buffer, linter) abort
|
|
||||||
let l:info = g:ale_buffer_info[a:buffer]
|
|
||||||
let l:lsp_details = ale#linter#StartLSP(
|
|
||||||
\ a:buffer,
|
|
||||||
\ a:linter,
|
|
||||||
\ function('ale#engine#HandleLSPResponse'),
|
|
||||||
\)
|
|
||||||
|
|
||||||
if empty(l:lsp_details)
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:id = l:lsp_details.connection_id
|
|
||||||
let l:root = l:lsp_details.project_root
|
|
||||||
|
|
||||||
" Remember the linter this connection is for.
|
|
||||||
let s:lsp_linter_map[l:id] = a:linter.name
|
|
||||||
|
|
||||||
let l:change_message = a:linter.lsp is# 'tsserver'
|
|
||||||
\ ? ale#lsp#tsserver_message#Geterr(a:buffer)
|
|
||||||
\ : ale#lsp#message#DidChange(a:buffer)
|
|
||||||
let l:request_id = ale#lsp#Send(l:id, l:change_message, l:root)
|
|
||||||
|
|
||||||
" If this was a file save event, also notify the server of that.
|
|
||||||
if a:linter.lsp isnot# 'tsserver'
|
|
||||||
\&& getbufvar(a:buffer, 'ale_save_event_fired', 0)
|
|
||||||
let l:save_message = ale#lsp#message#DidSave(a:buffer)
|
|
||||||
let l:request_id = ale#lsp#Send(l:id, l:save_message, l:root)
|
|
||||||
endif
|
|
||||||
|
|
||||||
if l:request_id != 0
|
|
||||||
if index(l:info.active_linter_list, a:linter.name) < 0
|
|
||||||
call add(l:info.active_linter_list, a:linter.name)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
return l:request_id != 0
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort
|
function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort
|
||||||
" Figure out which linters are still enabled, and remove
|
" Figure out which linters are still enabled, and remove
|
||||||
|
@ -832,7 +694,7 @@ endfunction
|
||||||
" Returns 1 if the linter was successfully run.
|
" Returns 1 if the linter was successfully run.
|
||||||
function! s:RunLinter(buffer, linter) abort
|
function! s:RunLinter(buffer, linter) abort
|
||||||
if !empty(a:linter.lsp)
|
if !empty(a:linter.lsp)
|
||||||
return s:CheckWithLSP(a:buffer, a:linter)
|
return ale#lsp_linter#CheckWithLSP(a:buffer, a:linter)
|
||||||
else
|
else
|
||||||
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
|
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
|
||||||
|
|
||||||
|
@ -914,7 +776,7 @@ endfunction
|
||||||
" The time taken will be a very rough approximation, and more time may be
|
" The time taken will be a very rough approximation, and more time may be
|
||||||
" permitted than is specified.
|
" permitted than is specified.
|
||||||
function! ale#engine#WaitForJobs(deadline) abort
|
function! ale#engine#WaitForJobs(deadline) abort
|
||||||
let l:start_time = ale#util#ClockMilliseconds()
|
let l:start_time = ale#events#ClockMilliseconds()
|
||||||
|
|
||||||
if l:start_time == 0
|
if l:start_time == 0
|
||||||
throw 'Failed to read milliseconds from the clock!'
|
throw 'Failed to read milliseconds from the clock!'
|
||||||
|
@ -945,7 +807,7 @@ function! ale#engine#WaitForJobs(deadline) abort
|
||||||
|
|
||||||
for l:job_id in l:job_list
|
for l:job_id in l:job_list
|
||||||
if ale#job#IsRunning(l:job_id)
|
if ale#job#IsRunning(l:job_id)
|
||||||
let l:now = ale#util#ClockMilliseconds()
|
let l:now = ale#events#ClockMilliseconds()
|
||||||
|
|
||||||
if l:now - l:start_time > a:deadline
|
if l:now - l:start_time > a:deadline
|
||||||
" Stop waiting after a timeout, so we don't wait forever.
|
" Stop waiting after a timeout, so we don't wait forever.
|
||||||
|
@ -982,7 +844,7 @@ function! ale#engine#WaitForJobs(deadline) abort
|
||||||
|
|
||||||
if l:has_new_jobs
|
if l:has_new_jobs
|
||||||
" We have to wait more. Offset the timeout by the time taken so far.
|
" We have to wait more. Offset the timeout by the time taken so far.
|
||||||
let l:now = ale#util#ClockMilliseconds()
|
let l:now = ale#events#ClockMilliseconds()
|
||||||
let l:new_deadline = a:deadline - (l:now - l:start_time)
|
let l:new_deadline = a:deadline - (l:now - l:start_time)
|
||||||
|
|
||||||
if l:new_deadline <= 0
|
if l:new_deadline <= 0
|
||||||
|
|
46
sources_non_forked/ale/autoload/ale/engine/ignore.vim
Normal file
46
sources_non_forked/ale/autoload/ale/engine/ignore.vim
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" Description: Code for ignoring linters. Only loaded and if configured.
|
||||||
|
|
||||||
|
" Given a filetype and a configuration for ignoring linters, return a List of
|
||||||
|
" Strings for linter names to ignore.
|
||||||
|
function! ale#engine#ignore#GetList(filetype, config) abort
|
||||||
|
if type(a:config) is type([])
|
||||||
|
return a:config
|
||||||
|
endif
|
||||||
|
|
||||||
|
if type(a:config) is type({})
|
||||||
|
let l:names_to_remove = []
|
||||||
|
|
||||||
|
for l:part in split(a:filetype , '\.')
|
||||||
|
call extend(l:names_to_remove, get(a:config, l:part, []))
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:names_to_remove
|
||||||
|
endif
|
||||||
|
|
||||||
|
return []
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Given a List of linter descriptions, exclude the linters to be ignored.
|
||||||
|
function! ale#engine#ignore#Exclude(filetype, all_linters, config) abort
|
||||||
|
let l:names_to_remove = ale#engine#ignore#GetList(a:filetype, a:config)
|
||||||
|
let l:filtered_linters = []
|
||||||
|
|
||||||
|
for l:linter in a:all_linters
|
||||||
|
let l:name_list = [l:linter.name] + l:linter.aliases
|
||||||
|
let l:should_include = 1
|
||||||
|
|
||||||
|
for l:name in l:name_list
|
||||||
|
if index(l:names_to_remove, l:name) >= 0
|
||||||
|
let l:should_include = 0
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
if l:should_include
|
||||||
|
call add(l:filtered_linters, l:linter)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:filtered_linters
|
||||||
|
endfunction
|
|
@ -1,14 +1,25 @@
|
||||||
" Author: w0rp <devw0rp@gmail.com>
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" Description: ALE functions for autocmd events.
|
||||||
|
|
||||||
|
" Get the number of milliseconds since some vague, but consistent, point in
|
||||||
|
" the past.
|
||||||
|
"
|
||||||
|
" This function can be used for timing execution, etc.
|
||||||
|
"
|
||||||
|
" The time will be returned as a Number.
|
||||||
|
function! ale#events#ClockMilliseconds() abort
|
||||||
|
return float2nr(reltimefloat(reltime()) * 1000)
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! ale#events#QuitEvent(buffer) abort
|
function! ale#events#QuitEvent(buffer) abort
|
||||||
" Remember when ALE is quitting for BufWrite, etc.
|
" Remember when ALE is quitting for BufWrite, etc.
|
||||||
call setbufvar(a:buffer, 'ale_quitting', ale#util#ClockMilliseconds())
|
call setbufvar(a:buffer, 'ale_quitting', ale#events#ClockMilliseconds())
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#events#QuitRecently(buffer) abort
|
function! ale#events#QuitRecently(buffer) abort
|
||||||
let l:time = getbufvar(a:buffer, 'ale_quitting', 0)
|
let l:time = getbufvar(a:buffer, 'ale_quitting', 0)
|
||||||
|
|
||||||
return l:time && ale#util#ClockMilliseconds() - l:time < 1000
|
return l:time && ale#events#ClockMilliseconds() - l:time < 1000
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#events#SaveEvent(buffer) abort
|
function! ale#events#SaveEvent(buffer) abort
|
||||||
|
@ -67,3 +78,56 @@ function! ale#events#FileChangedEvent(buffer) abort
|
||||||
call s:LintOnEnter(a:buffer)
|
call s:LintOnEnter(a:buffer)
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ale#events#Init() abort
|
||||||
|
" This value used to be a Boolean as a Number, and is now a String.
|
||||||
|
let l:text_changed = '' . g:ale_lint_on_text_changed
|
||||||
|
|
||||||
|
augroup ALEEvents
|
||||||
|
autocmd!
|
||||||
|
|
||||||
|
" These events always need to be set up.
|
||||||
|
autocmd BufEnter,BufRead * call ale#pattern_options#SetOptions(str2nr(expand('<abuf>')))
|
||||||
|
autocmd BufWritePost * call ale#events#SaveEvent(str2nr(expand('<abuf>')))
|
||||||
|
|
||||||
|
if g:ale_enabled
|
||||||
|
if l:text_changed is? 'always' || l:text_changed is# '1'
|
||||||
|
autocmd TextChanged,TextChangedI * call ale#Queue(g:ale_lint_delay)
|
||||||
|
elseif l:text_changed is? 'normal'
|
||||||
|
autocmd TextChanged * call ale#Queue(g:ale_lint_delay)
|
||||||
|
elseif l:text_changed is? 'insert'
|
||||||
|
autocmd TextChangedI * call ale#Queue(g:ale_lint_delay)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Handle everything that needs to happen when buffers are entered.
|
||||||
|
autocmd BufEnter * call ale#events#EnterEvent(str2nr(expand('<abuf>')))
|
||||||
|
|
||||||
|
if g:ale_lint_on_enter
|
||||||
|
autocmd BufWinEnter,BufRead * call ale#Queue(0, 'lint_file', str2nr(expand('<abuf>')))
|
||||||
|
" Track when the file is changed outside of Vim.
|
||||||
|
autocmd FileChangedShellPost * call ale#events#FileChangedEvent(str2nr(expand('<abuf>')))
|
||||||
|
endif
|
||||||
|
|
||||||
|
if g:ale_lint_on_filetype_changed
|
||||||
|
" Only start linting if the FileType actually changes after
|
||||||
|
" opening a buffer. The FileType will fire when buffers are opened.
|
||||||
|
autocmd FileType * call ale#events#FileTypeEvent(
|
||||||
|
\ str2nr(expand('<abuf>')),
|
||||||
|
\ expand('<amatch>')
|
||||||
|
\)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if g:ale_lint_on_insert_leave
|
||||||
|
autocmd InsertLeave * call ale#Queue(0)
|
||||||
|
endif
|
||||||
|
|
||||||
|
if g:ale_echo_cursor
|
||||||
|
autocmd CursorMoved,CursorHold * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarningWithDelay() | endif
|
||||||
|
" Look for a warning to echo as soon as we leave Insert mode.
|
||||||
|
" The script's position variable used when moving the cursor will
|
||||||
|
" not be changed here.
|
||||||
|
autocmd InsertLeave * if exists('*ale#engine#Cleanup') | call ale#cursor#EchoCursorWarning() | endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
augroup END
|
||||||
|
endfunction
|
||||||
|
|
|
@ -356,9 +356,21 @@ function! s:RunFixer(options) abort
|
||||||
call ale#fix#ApplyFixes(l:buffer, l:input)
|
call ale#fix#ApplyFixes(l:buffer, l:input)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:GetCallbacks(buffer, linters) abort
|
function! s:AddSubCallbacks(full_list, callbacks) abort
|
||||||
if len(a:linters)
|
if type(a:callbacks) == type('')
|
||||||
let l:callback_list = a:linters
|
call add(a:full_list, a:callbacks)
|
||||||
|
elseif type(a:callbacks) == type([])
|
||||||
|
call extend(a:full_list, a:callbacks)
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
return 1
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:GetCallbacks(buffer, fixers) abort
|
||||||
|
if len(a:fixers)
|
||||||
|
let l:callback_list = a:fixers
|
||||||
elseif type(get(b:, 'ale_fixers')) is type([])
|
elseif type(get(b:, 'ale_fixers')) is type([])
|
||||||
" Lists can be used for buffer-local variables only
|
" Lists can be used for buffer-local variables only
|
||||||
let l:callback_list = b:ale_fixers
|
let l:callback_list = b:ale_fixers
|
||||||
|
@ -367,16 +379,18 @@ function! s:GetCallbacks(buffer, linters) abort
|
||||||
" callbacks to run.
|
" callbacks to run.
|
||||||
let l:fixers = ale#Var(a:buffer, 'fixers')
|
let l:fixers = ale#Var(a:buffer, 'fixers')
|
||||||
let l:callback_list = []
|
let l:callback_list = []
|
||||||
|
let l:matched = 0
|
||||||
|
|
||||||
for l:sub_type in split(&filetype, '\.')
|
for l:sub_type in split(&filetype, '\.')
|
||||||
let l:sub_type_callacks = get(l:fixers, l:sub_type, [])
|
if s:AddSubCallbacks(l:callback_list, get(l:fixers, l:sub_type))
|
||||||
|
let l:matched = 1
|
||||||
if type(l:sub_type_callacks) == type('')
|
|
||||||
call add(l:callback_list, l:sub_type_callacks)
|
|
||||||
else
|
|
||||||
call extend(l:callback_list, l:sub_type_callacks)
|
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
|
" If we couldn't find fixers for a filetype, default to '*' fixers.
|
||||||
|
if !l:matched
|
||||||
|
call s:AddSubCallbacks(l:callback_list, get(l:fixers, '*'))
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if empty(l:callback_list)
|
if empty(l:callback_list)
|
||||||
|
|
|
@ -22,6 +22,11 @@ let s:default_registry = {
|
||||||
\ 'suggested_filetypes': ['python'],
|
\ 'suggested_filetypes': ['python'],
|
||||||
\ 'description': 'Fix PEP8 issues with black.',
|
\ 'description': 'Fix PEP8 issues with black.',
|
||||||
\ },
|
\ },
|
||||||
|
\ 'tidy': {
|
||||||
|
\ 'function': 'ale#fixers#tidy#Fix',
|
||||||
|
\ 'suggested_filetypes': ['html'],
|
||||||
|
\ 'description': 'Fix HTML files with tidy.',
|
||||||
|
\ },
|
||||||
\ 'prettier_standard': {
|
\ 'prettier_standard': {
|
||||||
\ 'function': 'ale#fixers#prettier_standard#Fix',
|
\ 'function': 'ale#fixers#prettier_standard#Fix',
|
||||||
\ 'suggested_filetypes': ['javascript'],
|
\ 'suggested_filetypes': ['javascript'],
|
||||||
|
@ -51,7 +56,7 @@ let s:default_registry = {
|
||||||
\ },
|
\ },
|
||||||
\ 'prettier': {
|
\ 'prettier': {
|
||||||
\ 'function': 'ale#fixers#prettier#Fix',
|
\ 'function': 'ale#fixers#prettier#Fix',
|
||||||
\ 'suggested_filetypes': ['javascript', 'typescript', 'json', 'css', 'scss', 'less', 'markdown', 'graphql', 'vue'],
|
\ 'suggested_filetypes': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue'],
|
||||||
\ 'description': 'Apply prettier to a file.',
|
\ 'description': 'Apply prettier to a file.',
|
||||||
\ },
|
\ },
|
||||||
\ 'prettier_eslint': {
|
\ 'prettier_eslint': {
|
||||||
|
@ -205,6 +210,11 @@ let s:default_registry = {
|
||||||
\ 'suggested_filetypes': ['qml'],
|
\ 'suggested_filetypes': ['qml'],
|
||||||
\ 'description': 'Fix QML files with qmlfmt.',
|
\ 'description': 'Fix QML files with qmlfmt.',
|
||||||
\ },
|
\ },
|
||||||
|
\ 'dartfmt': {
|
||||||
|
\ 'function': 'ale#fixers#dartfmt#Fix',
|
||||||
|
\ 'suggested_filetypes': ['dart'],
|
||||||
|
\ 'description': 'Fix Dart files with dartfmt.',
|
||||||
|
\ },
|
||||||
\}
|
\}
|
||||||
|
|
||||||
" Reset the function registry to the default entries.
|
" Reset the function registry to the default entries.
|
||||||
|
@ -345,8 +355,7 @@ function! ale#fix#registry#CompleteFixers(ArgLead, CmdLine, CursorPos) abort
|
||||||
return filter(ale#fix#registry#GetApplicableFixers(&filetype), 'v:val =~? a:ArgLead')
|
return filter(ale#fix#registry#GetApplicableFixers(&filetype), 'v:val =~? a:ArgLead')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Suggest functions to use from the registry.
|
function! ale#fix#registry#SuggestedFixers(filetype) abort
|
||||||
function! ale#fix#registry#Suggest(filetype) abort
|
|
||||||
let l:type_list = split(a:filetype, '\.')
|
let l:type_list = split(a:filetype, '\.')
|
||||||
let l:filetype_fixer_list = []
|
let l:filetype_fixer_list = []
|
||||||
|
|
||||||
|
@ -372,6 +381,15 @@ function! ale#fix#registry#Suggest(filetype) abort
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
|
return [l:filetype_fixer_list, l:generic_fixer_list]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Suggest functions to use from the registry.
|
||||||
|
function! ale#fix#registry#Suggest(filetype) abort
|
||||||
|
let l:suggested = ale#fix#registry#SuggestedFixers(a:filetype)
|
||||||
|
let l:filetype_fixer_list = l:suggested[0]
|
||||||
|
let l:generic_fixer_list = l:suggested[1]
|
||||||
|
|
||||||
let l:filetype_fixer_header = !empty(l:filetype_fixer_list)
|
let l:filetype_fixer_header = !empty(l:filetype_fixer_list)
|
||||||
\ ? ['Try the following fixers appropriate for the filetype:', '']
|
\ ? ['Try the following fixers appropriate for the filetype:', '']
|
||||||
\ : []
|
\ : []
|
||||||
|
|
18
sources_non_forked/ale/autoload/ale/fixers/dartfmt.vim
Normal file
18
sources_non_forked/ale/autoload/ale/fixers/dartfmt.vim
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
" Author: reisub0 <reisub0@gmail.com>
|
||||||
|
" Description: Integration of dartfmt with ALE.
|
||||||
|
|
||||||
|
call ale#Set('dart_dartfmt_executable', 'dartfmt')
|
||||||
|
call ale#Set('dart_dartfmt_options', '')
|
||||||
|
|
||||||
|
function! ale#fixers#dartfmt#Fix(buffer) abort
|
||||||
|
let l:executable = ale#Var(a:buffer, 'dart_dartfmt_executable')
|
||||||
|
let l:options = ale#Var(a:buffer, 'dart_dartfmt_options')
|
||||||
|
|
||||||
|
return {
|
||||||
|
\ 'command': ale#Escape(l:executable)
|
||||||
|
\ . ' -w'
|
||||||
|
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||||
|
\ . ' %t',
|
||||||
|
\ 'read_temporary_file': 1,
|
||||||
|
\}
|
||||||
|
endfunction
|
|
@ -30,8 +30,26 @@ endfunction
|
||||||
function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort
|
function! ale#fixers#prettier#ApplyFixForVersion(buffer, version_output) abort
|
||||||
let l:executable = ale#fixers#prettier#GetExecutable(a:buffer)
|
let l:executable = ale#fixers#prettier#GetExecutable(a:buffer)
|
||||||
let l:options = ale#Var(a:buffer, 'javascript_prettier_options')
|
let l:options = ale#Var(a:buffer, 'javascript_prettier_options')
|
||||||
|
|
||||||
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
|
let l:version = ale#semver#GetVersion(l:executable, a:version_output)
|
||||||
|
let l:parser = ''
|
||||||
|
|
||||||
|
" Append the --parser flag depending on the current filetype (unless it's
|
||||||
|
" already set in g:javascript_prettier_options).
|
||||||
|
if empty(expand('#' . a:buffer . ':e')) && match(l:options, '--parser') == -1
|
||||||
|
let l:prettier_parsers = ['typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue']
|
||||||
|
let l:parser = 'babylon'
|
||||||
|
|
||||||
|
for l:filetype in split(getbufvar(a:buffer, '&filetype'), '\.')
|
||||||
|
if index(l:prettier_parsers, l:filetype) > -1
|
||||||
|
let l:parser = l:filetype
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
|
||||||
|
if !empty(l:parser)
|
||||||
|
let l:options = (!empty(l:options) ? l:options . ' ' : '') . '--parser ' . l:parser
|
||||||
|
endif
|
||||||
|
|
||||||
" 1.4.0 is the first version with --stdin-filepath
|
" 1.4.0 is the first version with --stdin-filepath
|
||||||
if ale#semver#GTE(l:version, [1, 4, 0])
|
if ale#semver#GTE(l:version, [1, 4, 0])
|
||||||
|
|
26
sources_non_forked/ale/autoload/ale/fixers/tidy.vim
Normal file
26
sources_non_forked/ale/autoload/ale/fixers/tidy.vim
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
" Author: meain <abinsimon10@gmail.com>
|
||||||
|
" Description: Fixing HTML files with tidy.
|
||||||
|
|
||||||
|
call ale#Set('html_tidy_executable', 'tidy')
|
||||||
|
call ale#Set('html_tidy_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||||
|
|
||||||
|
function! ale#fixers#tidy#Fix(buffer) abort
|
||||||
|
let l:executable = ale#node#FindExecutable(
|
||||||
|
\ a:buffer,
|
||||||
|
\ 'html_tidy',
|
||||||
|
\ ['tidy'],
|
||||||
|
\)
|
||||||
|
|
||||||
|
if !executable(l:executable)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:config = ale#path#FindNearestFile(a:buffer, '.tidyrc')
|
||||||
|
let l:config_options = !empty(l:config)
|
||||||
|
\ ? ' -q --tidy-mark no --show-errors 0 --show-warnings 0 -config ' . ale#Escape(l:config)
|
||||||
|
\ : ' -q --tidy-mark no --show-errors 0 --show-warnings 0'
|
||||||
|
|
||||||
|
return {
|
||||||
|
\ 'command': ale#Escape(l:executable) . l:config_options,
|
||||||
|
\}
|
||||||
|
endfunction
|
|
@ -97,14 +97,14 @@ function! s:ShowDetails(linter, buffer, line, column, opt) abort
|
||||||
\ ? function('ale#hover#HandleTSServerResponse')
|
\ ? function('ale#hover#HandleTSServerResponse')
|
||||||
\ : function('ale#hover#HandleLSPResponse')
|
\ : function('ale#hover#HandleLSPResponse')
|
||||||
|
|
||||||
let l:lsp_details = ale#linter#StartLSP(a:buffer, a:linter, l:Callback)
|
let l:lsp_details = ale#lsp_linter#StartLSP(a:buffer, a:linter, l:Callback)
|
||||||
|
|
||||||
if empty(l:lsp_details)
|
if empty(l:lsp_details)
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:id = l:lsp_details.connection_id
|
let l:id = l:lsp_details.connection_id
|
||||||
let l:root = l:lsp_details.project_root
|
let l:language_id = l:lsp_details.language_id
|
||||||
|
|
||||||
if a:linter.lsp is# 'tsserver'
|
if a:linter.lsp is# 'tsserver'
|
||||||
let l:column = a:column
|
let l:column = a:column
|
||||||
|
@ -117,14 +117,14 @@ function! s:ShowDetails(linter, buffer, line, column, opt) abort
|
||||||
else
|
else
|
||||||
" Send a message saying the buffer has changed first, or the
|
" Send a message saying the buffer has changed first, or the
|
||||||
" hover position probably won't make sense.
|
" hover position probably won't make sense.
|
||||||
call ale#lsp#Send(l:id, ale#lsp#message#DidChange(a:buffer), l:root)
|
call ale#lsp#NotifyForChanges(l:lsp_details)
|
||||||
|
|
||||||
let l:column = min([a:column, len(getbufline(a:buffer, a:line)[0])])
|
let l:column = min([a:column, len(getbufline(a:buffer, a:line)[0])])
|
||||||
|
|
||||||
let l:message = ale#lsp#message#Hover(a:buffer, a:line, l:column)
|
let l:message = ale#lsp#message#Hover(a:buffer, a:line, l:column)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
|
let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root)
|
||||||
|
|
||||||
let s:hover_map[l:request_id] = {
|
let s:hover_map[l:request_id] = {
|
||||||
\ 'buffer': a:buffer,
|
\ 'buffer': a:buffer,
|
||||||
|
|
|
@ -26,34 +26,11 @@ function! s:KillHandler(timer) abort
|
||||||
call job_stop(l:job, 'kill')
|
call job_stop(l:job, 'kill')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Note that jobs and IDs are the same thing on NeoVim.
|
|
||||||
function! ale#job#JoinNeovimOutput(job, last_line, data, mode, callback) abort
|
|
||||||
if a:mode is# 'raw'
|
|
||||||
call a:callback(a:job, join(a:data, "\n"))
|
|
||||||
return ''
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:lines = a:data[:-2]
|
|
||||||
|
|
||||||
if len(a:data) > 1
|
|
||||||
let l:lines[0] = a:last_line . l:lines[0]
|
|
||||||
let l:new_last_line = a:data[-1]
|
|
||||||
else
|
|
||||||
let l:new_last_line = a:last_line . get(a:data, 0, '')
|
|
||||||
endif
|
|
||||||
|
|
||||||
for l:line in l:lines
|
|
||||||
call a:callback(a:job, l:line)
|
|
||||||
endfor
|
|
||||||
|
|
||||||
return l:new_last_line
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function! s:NeoVimCallback(job, data, event) abort
|
function! s:NeoVimCallback(job, data, event) abort
|
||||||
let l:info = s:job_map[a:job]
|
let l:info = s:job_map[a:job]
|
||||||
|
|
||||||
if a:event is# 'stdout'
|
if a:event is# 'stdout'
|
||||||
let l:info.out_cb_line = ale#job#JoinNeovimOutput(
|
let l:info.out_cb_line = ale#util#JoinNeovimOutput(
|
||||||
\ a:job,
|
\ a:job,
|
||||||
\ l:info.out_cb_line,
|
\ l:info.out_cb_line,
|
||||||
\ a:data,
|
\ a:data,
|
||||||
|
@ -61,7 +38,7 @@ function! s:NeoVimCallback(job, data, event) abort
|
||||||
\ ale#util#GetFunction(l:info.out_cb),
|
\ ale#util#GetFunction(l:info.out_cb),
|
||||||
\)
|
\)
|
||||||
elseif a:event is# 'stderr'
|
elseif a:event is# 'stderr'
|
||||||
let l:info.err_cb_line = ale#job#JoinNeovimOutput(
|
let l:info.err_cb_line = ale#util#JoinNeovimOutput(
|
||||||
\ a:job,
|
\ a:job,
|
||||||
\ l:info.err_cb_line,
|
\ l:info.err_cb_line,
|
||||||
\ a:data,
|
\ a:data,
|
||||||
|
|
|
@ -15,6 +15,7 @@ let s:default_ale_linter_aliases = {
|
||||||
\ 'csh': 'sh',
|
\ 'csh': 'sh',
|
||||||
\ 'plaintex': 'tex',
|
\ 'plaintex': 'tex',
|
||||||
\ 'systemverilog': 'verilog',
|
\ 'systemverilog': 'verilog',
|
||||||
|
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
|
||||||
\ 'vimwiki': 'markdown',
|
\ 'vimwiki': 'markdown',
|
||||||
\ 'zsh': 'sh',
|
\ 'zsh': 'sh',
|
||||||
\}
|
\}
|
||||||
|
@ -451,81 +452,3 @@ function! ale#linter#GetAddress(buffer, linter) abort
|
||||||
\ ? ale#util#GetFunction(a:linter.address_callback)(a:buffer)
|
\ ? ale#util#GetFunction(a:linter.address_callback)(a:buffer)
|
||||||
\ : a:linter.address
|
\ : a:linter.address
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Given a buffer, an LSP linter, and a callback to register for handling
|
|
||||||
" messages, start up an LSP linter and get ready to receive errors or
|
|
||||||
" completions.
|
|
||||||
function! ale#linter#StartLSP(buffer, linter, callback) abort
|
|
||||||
let l:command = ''
|
|
||||||
let l:address = ''
|
|
||||||
let l:root = ale#util#GetFunction(a:linter.project_root_callback)(a:buffer)
|
|
||||||
|
|
||||||
if empty(l:root) && a:linter.lsp isnot# 'tsserver'
|
|
||||||
" If there's no project root, then we can't check files with LSP,
|
|
||||||
" unless we are using tsserver, which doesn't use project roots.
|
|
||||||
return {}
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:initialization_options = {}
|
|
||||||
if has_key(a:linter, 'initialization_options_callback')
|
|
||||||
let l:initialization_options = ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer)
|
|
||||||
elseif has_key(a:linter, 'initialization_options')
|
|
||||||
let l:initialization_options = a:linter.initialization_options
|
|
||||||
endif
|
|
||||||
|
|
||||||
if a:linter.lsp is# 'socket'
|
|
||||||
let l:address = ale#linter#GetAddress(a:buffer, a:linter)
|
|
||||||
let l:conn_id = ale#lsp#ConnectToAddress(
|
|
||||||
\ l:address,
|
|
||||||
\ l:root,
|
|
||||||
\ a:callback,
|
|
||||||
\ l:initialization_options,
|
|
||||||
\)
|
|
||||||
else
|
|
||||||
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
|
|
||||||
|
|
||||||
if !executable(l:executable)
|
|
||||||
return {}
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:command = ale#job#PrepareCommand(
|
|
||||||
\ a:buffer,
|
|
||||||
\ ale#linter#GetCommand(a:buffer, a:linter),
|
|
||||||
\)
|
|
||||||
let l:conn_id = ale#lsp#StartProgram(
|
|
||||||
\ l:executable,
|
|
||||||
\ l:command,
|
|
||||||
\ l:root,
|
|
||||||
\ a:callback,
|
|
||||||
\ l:initialization_options,
|
|
||||||
\)
|
|
||||||
endif
|
|
||||||
|
|
||||||
let l:language_id = ale#util#GetFunction(a:linter.language_callback)(a:buffer)
|
|
||||||
|
|
||||||
if !l:conn_id
|
|
||||||
if g:ale_history_enabled && !empty(l:command)
|
|
||||||
call ale#history#Add(a:buffer, 'failed', l:conn_id, l:command)
|
|
||||||
endif
|
|
||||||
|
|
||||||
return {}
|
|
||||||
endif
|
|
||||||
|
|
||||||
if ale#lsp#OpenDocumentIfNeeded(l:conn_id, a:buffer, l:root, l:language_id)
|
|
||||||
if g:ale_history_enabled && !empty(l:command)
|
|
||||||
call ale#history#Add(a:buffer, 'started', l:conn_id, l:command)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
" The change message needs to be sent for tsserver before doing anything.
|
|
||||||
if a:linter.lsp is# 'tsserver'
|
|
||||||
call ale#lsp#Send(l:conn_id, ale#lsp#tsserver_message#Change(a:buffer))
|
|
||||||
endif
|
|
||||||
|
|
||||||
return {
|
|
||||||
\ 'connection_id': l:conn_id,
|
|
||||||
\ 'command': l:command,
|
|
||||||
\ 'project_root': l:root,
|
|
||||||
\ 'language_id': l:language_id,
|
|
||||||
\}
|
|
||||||
endfunction
|
|
||||||
|
|
|
@ -3,20 +3,23 @@
|
||||||
|
|
||||||
" A List of connections, used for tracking servers which have been connected
|
" A List of connections, used for tracking servers which have been connected
|
||||||
" to, and programs which are run.
|
" to, and programs which are run.
|
||||||
let s:connections = []
|
let s:connections = get(s:, 'connections', [])
|
||||||
let g:ale_lsp_next_message_id = 1
|
let g:ale_lsp_next_message_id = 1
|
||||||
|
|
||||||
function! s:NewConnection(initialization_options) abort
|
" Exposed only so tests can get at it.
|
||||||
|
" Do not call this function basically anywhere.
|
||||||
|
function! ale#lsp#NewConnection(initialization_options) abort
|
||||||
" id: The job ID as a Number, or the server address as a string.
|
" id: The job ID as a Number, or the server address as a string.
|
||||||
" data: The message data received so far.
|
" data: The message data received so far.
|
||||||
" executable: An executable only set for program connections.
|
" executable: An executable only set for program connections.
|
||||||
" open_documents: A list of buffers we told the server we opened.
|
" open_documents: A Dictionary mapping buffers to b:changedtick, keeping
|
||||||
|
" track of when documents were opened, and when we last changed them.
|
||||||
" callback_list: A list of callbacks for handling LSP responses.
|
" callback_list: A list of callbacks for handling LSP responses.
|
||||||
let l:conn = {
|
let l:conn = {
|
||||||
\ 'id': '',
|
\ 'id': '',
|
||||||
\ 'data': '',
|
\ 'data': '',
|
||||||
\ 'projects': {},
|
\ 'projects': {},
|
||||||
\ 'open_documents': [],
|
\ 'open_documents': {},
|
||||||
\ 'callback_list': [],
|
\ 'callback_list': [],
|
||||||
\ 'initialization_options': a:initialization_options,
|
\ 'initialization_options': a:initialization_options,
|
||||||
\}
|
\}
|
||||||
|
@ -26,9 +29,14 @@ function! s:NewConnection(initialization_options) abort
|
||||||
return l:conn
|
return l:conn
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" Remove an LSP connection with a given ID. This is only for tests.
|
||||||
|
function! ale#lsp#RemoveConnectionWithID(id) abort
|
||||||
|
call filter(s:connections, 'v:val.id isnot a:id')
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:FindConnection(key, value) abort
|
function! s:FindConnection(key, value) abort
|
||||||
for l:conn in s:connections
|
for l:conn in s:connections
|
||||||
if has_key(l:conn, a:key) && get(l:conn, a:key) == a:value
|
if has_key(l:conn, a:key) && get(l:conn, a:key) is# a:value
|
||||||
return l:conn
|
return l:conn
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
|
@ -233,9 +241,8 @@ function! ale#lsp#HandleMessage(conn, message) abort
|
||||||
endfor
|
endfor
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:HandleChannelMessage(channel, message) abort
|
function! s:HandleChannelMessage(channel_id, message) abort
|
||||||
let l:info = ch_info(a:channel)
|
let l:address = ale#socket#GetAddress(a:channel_id)
|
||||||
let l:address = l:info.hostname . l:info.address
|
|
||||||
let l:conn = s:FindConnection('id', l:address)
|
let l:conn = s:FindConnection('id', l:address)
|
||||||
|
|
||||||
call ale#lsp#HandleMessage(l:conn, a:message)
|
call ale#lsp#HandleMessage(l:conn, a:message)
|
||||||
|
@ -280,7 +287,7 @@ function! ale#lsp#StartProgram(executable, command, project_root, callback, init
|
||||||
let l:conn = s:FindConnection('executable', a:executable)
|
let l:conn = s:FindConnection('executable', a:executable)
|
||||||
|
|
||||||
" Get the current connection or a new one.
|
" Get the current connection or a new one.
|
||||||
let l:conn = !empty(l:conn) ? l:conn : s:NewConnection(a:initialization_options)
|
let l:conn = !empty(l:conn) ? l:conn : ale#lsp#NewConnection(a:initialization_options)
|
||||||
let l:conn.executable = a:executable
|
let l:conn.executable = a:executable
|
||||||
|
|
||||||
if !has_key(l:conn, 'id') || !ale#job#IsRunning(l:conn.id)
|
if !has_key(l:conn, 'id') || !ale#job#IsRunning(l:conn.id)
|
||||||
|
@ -309,18 +316,16 @@ endfunction
|
||||||
function! ale#lsp#ConnectToAddress(address, project_root, callback, initialization_options) abort
|
function! ale#lsp#ConnectToAddress(address, project_root, callback, initialization_options) abort
|
||||||
let l:conn = s:FindConnection('id', a:address)
|
let l:conn = s:FindConnection('id', a:address)
|
||||||
" Get the current connection or a new one.
|
" Get the current connection or a new one.
|
||||||
let l:conn = !empty(l:conn) ? l:conn : s:NewConnection(a:initialization_options)
|
let l:conn = !empty(l:conn) ? l:conn : ale#lsp#NewConnection(a:initialization_options)
|
||||||
|
|
||||||
if !has_key(l:conn, 'channel') || ch_status(l:conn.channel) isnot# 'open'
|
if !has_key(l:conn, 'channel_id') || !ale#socket#IsOpen(l:conn.channel_id)
|
||||||
let l:conn.channnel = ch_open(a:address, {
|
let l:conn.channel_id = ale#socket#Open(a:address, {
|
||||||
\ 'mode': 'raw',
|
|
||||||
\ 'waittime': 0,
|
|
||||||
\ 'callback': function('s:HandleChannelMessage'),
|
\ 'callback': function('s:HandleChannelMessage'),
|
||||||
\})
|
\})
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ch_status(l:conn.channnel) is# 'fail'
|
if l:conn.channel_id < 0
|
||||||
return 0
|
return ''
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:conn.id = a:address
|
let l:conn.id = a:address
|
||||||
|
@ -328,15 +333,15 @@ function! ale#lsp#ConnectToAddress(address, project_root, callback, initializati
|
||||||
call uniq(sort(add(l:conn.callback_list, a:callback)))
|
call uniq(sort(add(l:conn.callback_list, a:callback)))
|
||||||
call ale#lsp#RegisterProject(l:conn, a:project_root)
|
call ale#lsp#RegisterProject(l:conn, a:project_root)
|
||||||
|
|
||||||
return 1
|
return a:address
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Stop all LSP connections, closing all jobs and channels, and removing any
|
" Stop all LSP connections, closing all jobs and channels, and removing any
|
||||||
" queued messages.
|
" queued messages.
|
||||||
function! ale#lsp#StopAll() abort
|
function! ale#lsp#StopAll() abort
|
||||||
for l:conn in s:connections
|
for l:conn in s:connections
|
||||||
if has_key(l:conn, 'channel')
|
if has_key(l:conn, 'channel_id')
|
||||||
call ch_close(l:conn.channel)
|
call ale#socket#Close(l:conn.channel_id)
|
||||||
else
|
else
|
||||||
call ale#job#Stop(l:conn.id)
|
call ale#job#Stop(l:conn.id)
|
||||||
endif
|
endif
|
||||||
|
@ -348,9 +353,9 @@ endfunction
|
||||||
function! s:SendMessageData(conn, data) abort
|
function! s:SendMessageData(conn, data) abort
|
||||||
if has_key(a:conn, 'executable')
|
if has_key(a:conn, 'executable')
|
||||||
call ale#job#SendRaw(a:conn.id, a:data)
|
call ale#job#SendRaw(a:conn.id, a:data)
|
||||||
elseif has_key(a:conn, 'channel') && ch_status(a:conn.channnel) is# 'open'
|
elseif has_key(a:conn, 'channel_id') && ale#socket#IsOpen(a:conn.channel_id)
|
||||||
" Send the message to the server
|
" Send the message to the server
|
||||||
call ch_sendraw(a:conn.channel, a:data)
|
call ale#socket#Send(a:conn.channel_id, a:data)
|
||||||
else
|
else
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
@ -406,21 +411,72 @@ function! ale#lsp#Send(conn_id, message, ...) abort
|
||||||
return l:id == 0 ? -1 : l:id
|
return l:id == 0 ? -1 : l:id
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#lsp#OpenDocumentIfNeeded(conn_id, buffer, project_root, language_id) abort
|
" The Document details Dictionary should contain the following keys.
|
||||||
let l:conn = s:FindConnection('id', a:conn_id)
|
"
|
||||||
|
" buffer - The buffer number for the document.
|
||||||
|
" connection_id - The connection ID for the LSP server.
|
||||||
|
" command - The command to run to start the LSP connection.
|
||||||
|
" project_root - The project root for the LSP project.
|
||||||
|
" language_id - The language ID for the project, like 'python', 'rust', etc.
|
||||||
|
|
||||||
|
" Create a new Dictionary containing more connection details, with the
|
||||||
|
" following information added:
|
||||||
|
"
|
||||||
|
" conn - An existing LSP connection for the document.
|
||||||
|
" document_open - 1 if the document is currently open, 0 otherwise.
|
||||||
|
function! s:ExtendDocumentDetails(details) abort
|
||||||
|
let l:extended = copy(a:details)
|
||||||
|
let l:conn = s:FindConnection('id', a:details.connection_id)
|
||||||
|
|
||||||
|
let l:extended.conn = l:conn
|
||||||
|
let l:extended.document_open = !empty(l:conn)
|
||||||
|
\ && has_key(l:conn.open_documents, a:details.buffer)
|
||||||
|
|
||||||
|
return l:extended
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Notify LSP servers or tsserver if a document is opened, if needed.
|
||||||
|
" If a document is opened, 1 will be returned, otherwise 0 will be returned.
|
||||||
|
function! ale#lsp#OpenDocument(basic_details) abort
|
||||||
|
let l:d = s:ExtendDocumentDetails(a:basic_details)
|
||||||
let l:opened = 0
|
let l:opened = 0
|
||||||
|
|
||||||
if !empty(l:conn) && index(l:conn.open_documents, a:buffer) < 0
|
if !empty(l:d.conn) && !l:d.document_open
|
||||||
if empty(a:language_id)
|
if empty(l:d.language_id)
|
||||||
let l:message = ale#lsp#tsserver_message#Open(a:buffer)
|
let l:message = ale#lsp#tsserver_message#Open(l:d.buffer)
|
||||||
else
|
else
|
||||||
let l:message = ale#lsp#message#DidOpen(a:buffer, a:language_id)
|
let l:message = ale#lsp#message#DidOpen(l:d.buffer, l:d.language_id)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call ale#lsp#Send(a:conn_id, l:message, a:project_root)
|
call ale#lsp#Send(l:d.connection_id, l:message, l:d.project_root)
|
||||||
call add(l:conn.open_documents, a:buffer)
|
let l:d.conn.open_documents[l:d.buffer] = getbufvar(l:d.buffer, 'changedtick')
|
||||||
let l:opened = 1
|
let l:opened = 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return l:opened
|
return l:opened
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" Notify LSP servers or tsserver that a document has changed, if needed.
|
||||||
|
" If a notification is sent, 1 will be returned, otherwise 0 will be returned.
|
||||||
|
function! ale#lsp#NotifyForChanges(basic_details) abort
|
||||||
|
let l:d = s:ExtendDocumentDetails(a:basic_details)
|
||||||
|
let l:notified = 0
|
||||||
|
|
||||||
|
if l:d.document_open
|
||||||
|
let l:new_tick = getbufvar(l:d.buffer, 'changedtick')
|
||||||
|
|
||||||
|
if l:d.conn.open_documents[l:d.buffer] < l:new_tick
|
||||||
|
if empty(l:d.language_id)
|
||||||
|
let l:message = ale#lsp#tsserver_message#Change(l:d.buffer)
|
||||||
|
else
|
||||||
|
let l:message = ale#lsp#message#DidChange(l:d.buffer)
|
||||||
|
endif
|
||||||
|
|
||||||
|
call ale#lsp#Send(l:d.connection_id, l:message, l:d.project_root)
|
||||||
|
let l:d.conn.open_documents[l:d.buffer] = l:new_tick
|
||||||
|
let l:notified = 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:notified
|
||||||
|
endfunction
|
||||||
|
|
|
@ -7,9 +7,9 @@ function! ale#lsp#reset#StopAllLSPs() abort
|
||||||
call ale#definition#ClearLSPData()
|
call ale#definition#ClearLSPData()
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if exists('*ale#engine#ClearLSPData')
|
if exists('*ale#lsp_linter#ClearLSPData')
|
||||||
" Clear the mapping for connections, etc.
|
" Clear the mapping for connections, etc.
|
||||||
call ale#engine#ClearLSPData()
|
call ale#lsp_linter#ClearLSPData()
|
||||||
|
|
||||||
" Remove the problems for all of the LSP linters in every buffer.
|
" Remove the problems for all of the LSP linters in every buffer.
|
||||||
for l:buffer_string in keys(g:ale_buffer_info)
|
for l:buffer_string in keys(g:ale_buffer_info)
|
||||||
|
|
252
sources_non_forked/ale/autoload/ale/lsp_linter.vim
Normal file
252
sources_non_forked/ale/autoload/ale/lsp_linter.vim
Normal file
|
@ -0,0 +1,252 @@
|
||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" Description: Integration between linters and LSP/tsserver.
|
||||||
|
|
||||||
|
" This code isn't loaded if a user never users LSP features or linters.
|
||||||
|
|
||||||
|
" Associates LSP connection IDs with linter names.
|
||||||
|
if !has_key(s:, 'lsp_linter_map')
|
||||||
|
let s:lsp_linter_map = {}
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Check if diagnostics for a particular linter should be ignored.
|
||||||
|
function! s:ShouldIgnore(buffer, linter_name) abort
|
||||||
|
let l:config = ale#Var(a:buffer, 'linters_ignore')
|
||||||
|
|
||||||
|
" Don't load code for ignoring diagnostics if there's nothing to ignore.
|
||||||
|
if empty(l:config)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:filetype = getbufvar(a:buffer, '&filetype')
|
||||||
|
let l:ignore_list = ale#engine#ignore#GetList(l:filetype, l:config)
|
||||||
|
|
||||||
|
return index(l:ignore_list, a:linter_name) >= 0
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:HandleLSPDiagnostics(conn_id, response) abort
|
||||||
|
let l:linter_name = s:lsp_linter_map[a:conn_id]
|
||||||
|
let l:filename = ale#path#FromURI(a:response.params.uri)
|
||||||
|
let l:buffer = bufnr(l:filename)
|
||||||
|
|
||||||
|
if s:ShouldIgnore(l:buffer, l:linter_name)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:buffer <= 0
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:loclist = ale#lsp#response#ReadDiagnostics(a:response)
|
||||||
|
|
||||||
|
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:HandleTSServerDiagnostics(response, error_type) abort
|
||||||
|
let l:linter_name = 'tsserver'
|
||||||
|
let l:buffer = bufnr(a:response.body.file)
|
||||||
|
let l:info = get(g:ale_buffer_info, l:buffer, {})
|
||||||
|
|
||||||
|
if empty(l:info)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if s:ShouldIgnore(l:buffer, l:linter_name)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:thislist = ale#lsp#response#ReadTSServerDiagnostics(a:response)
|
||||||
|
|
||||||
|
" tsserver sends syntax and semantic errors in separate messages, so we
|
||||||
|
" have to collect the messages separately for each buffer and join them
|
||||||
|
" back together again.
|
||||||
|
if a:error_type is# 'syntax'
|
||||||
|
let l:info.syntax_loclist = l:thislist
|
||||||
|
else
|
||||||
|
let l:info.semantic_loclist = l:thislist
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:loclist = get(l:info, 'semantic_loclist', [])
|
||||||
|
\ + get(l:info, 'syntax_loclist', [])
|
||||||
|
|
||||||
|
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:HandleLSPErrorMessage(linter_name, response) abort
|
||||||
|
if !g:ale_history_enabled || !g:ale_history_log_output
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
if empty(a:linter_name)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:message = ale#lsp#response#GetErrorMessage(a:response)
|
||||||
|
|
||||||
|
if empty(l:message)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
" This global variable is set here so we don't load the debugging.vim file
|
||||||
|
" until someone uses :ALEInfo.
|
||||||
|
let g:ale_lsp_error_messages = get(g:, 'ale_lsp_error_messages', {})
|
||||||
|
|
||||||
|
if !has_key(g:ale_lsp_error_messages, a:linter_name)
|
||||||
|
let g:ale_lsp_error_messages[a:linter_name] = []
|
||||||
|
endif
|
||||||
|
|
||||||
|
call add(g:ale_lsp_error_messages[a:linter_name], l:message)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort
|
||||||
|
let l:method = get(a:response, 'method', '')
|
||||||
|
let l:linter_name = get(s:lsp_linter_map, a:conn_id, '')
|
||||||
|
|
||||||
|
if get(a:response, 'jsonrpc', '') is# '2.0' && has_key(a:response, 'error')
|
||||||
|
call s:HandleLSPErrorMessage(l:linter_name, a:response)
|
||||||
|
elseif l:method is# 'textDocument/publishDiagnostics'
|
||||||
|
call s:HandleLSPDiagnostics(a:conn_id, a:response)
|
||||||
|
elseif get(a:response, 'type', '') is# 'event'
|
||||||
|
\&& get(a:response, 'event', '') is# 'semanticDiag'
|
||||||
|
call s:HandleTSServerDiagnostics(a:response, 'semantic')
|
||||||
|
elseif get(a:response, 'type', '') is# 'event'
|
||||||
|
\&& get(a:response, 'event', '') is# 'syntaxDiag'
|
||||||
|
call s:HandleTSServerDiagnostics(a:response, 'syntax')
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Given a buffer, an LSP linter, and a callback to register for handling
|
||||||
|
" messages, start up an LSP linter and get ready to receive errors or
|
||||||
|
" completions.
|
||||||
|
function! ale#lsp_linter#StartLSP(buffer, linter, callback) abort
|
||||||
|
let l:command = ''
|
||||||
|
let l:address = ''
|
||||||
|
let l:root = ale#util#GetFunction(a:linter.project_root_callback)(a:buffer)
|
||||||
|
|
||||||
|
if empty(l:root) && a:linter.lsp isnot# 'tsserver'
|
||||||
|
" If there's no project root, then we can't check files with LSP,
|
||||||
|
" unless we are using tsserver, which doesn't use project roots.
|
||||||
|
return {}
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:initialization_options = {}
|
||||||
|
|
||||||
|
if has_key(a:linter, 'initialization_options_callback')
|
||||||
|
let l:initialization_options = ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer)
|
||||||
|
elseif has_key(a:linter, 'initialization_options')
|
||||||
|
let l:initialization_options = a:linter.initialization_options
|
||||||
|
endif
|
||||||
|
|
||||||
|
if a:linter.lsp is# 'socket'
|
||||||
|
let l:address = ale#linter#GetAddress(a:buffer, a:linter)
|
||||||
|
let l:conn_id = ale#lsp#ConnectToAddress(
|
||||||
|
\ l:address,
|
||||||
|
\ l:root,
|
||||||
|
\ a:callback,
|
||||||
|
\ l:initialization_options,
|
||||||
|
\)
|
||||||
|
else
|
||||||
|
let l:executable = ale#linter#GetExecutable(a:buffer, a:linter)
|
||||||
|
|
||||||
|
if !executable(l:executable)
|
||||||
|
return {}
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:command = ale#job#PrepareCommand(
|
||||||
|
\ a:buffer,
|
||||||
|
\ ale#linter#GetCommand(a:buffer, a:linter),
|
||||||
|
\)
|
||||||
|
let l:conn_id = ale#lsp#StartProgram(
|
||||||
|
\ l:executable,
|
||||||
|
\ l:command,
|
||||||
|
\ l:root,
|
||||||
|
\ a:callback,
|
||||||
|
\ l:initialization_options,
|
||||||
|
\)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:language_id = ale#util#GetFunction(a:linter.language_callback)(a:buffer)
|
||||||
|
|
||||||
|
if empty(l:conn_id)
|
||||||
|
if g:ale_history_enabled && !empty(l:command)
|
||||||
|
call ale#history#Add(a:buffer, 'failed', l:conn_id, l:command)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return {}
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:details = {
|
||||||
|
\ 'buffer': a:buffer,
|
||||||
|
\ 'connection_id': l:conn_id,
|
||||||
|
\ 'command': l:command,
|
||||||
|
\ 'project_root': l:root,
|
||||||
|
\ 'language_id': l:language_id,
|
||||||
|
\}
|
||||||
|
|
||||||
|
if ale#lsp#OpenDocument(l:details)
|
||||||
|
if g:ale_history_enabled && !empty(l:command)
|
||||||
|
call ale#history#Add(a:buffer, 'started', l:conn_id, l:command)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
" The change message needs to be sent for tsserver before doing anything.
|
||||||
|
if a:linter.lsp is# 'tsserver'
|
||||||
|
call ale#lsp#NotifyForChanges(l:details)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:details
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! ale#lsp_linter#CheckWithLSP(buffer, linter) abort
|
||||||
|
let l:info = g:ale_buffer_info[a:buffer]
|
||||||
|
let l:lsp_details = ale#lsp_linter#StartLSP(
|
||||||
|
\ a:buffer,
|
||||||
|
\ a:linter,
|
||||||
|
\ function('ale#lsp_linter#HandleLSPResponse'),
|
||||||
|
\)
|
||||||
|
|
||||||
|
if empty(l:lsp_details)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:id = l:lsp_details.connection_id
|
||||||
|
let l:root = l:lsp_details.project_root
|
||||||
|
|
||||||
|
" Remember the linter this connection is for.
|
||||||
|
let s:lsp_linter_map[l:id] = a:linter.name
|
||||||
|
|
||||||
|
if a:linter.lsp is# 'tsserver'
|
||||||
|
let l:message = ale#lsp#tsserver_message#Geterr(a:buffer)
|
||||||
|
let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
|
||||||
|
|
||||||
|
let l:notified = l:request_id != 0
|
||||||
|
else
|
||||||
|
let l:notified = ale#lsp#NotifyForChanges(l:lsp_details)
|
||||||
|
endif
|
||||||
|
|
||||||
|
" If this was a file save event, also notify the server of that.
|
||||||
|
if a:linter.lsp isnot# 'tsserver'
|
||||||
|
\&& getbufvar(a:buffer, 'ale_save_event_fired', 0)
|
||||||
|
let l:save_message = ale#lsp#message#DidSave(a:buffer)
|
||||||
|
let l:request_id = ale#lsp#Send(l:id, l:save_message, l:root)
|
||||||
|
|
||||||
|
let l:notified = l:request_id != 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:notified
|
||||||
|
if index(l:info.active_linter_list, a:linter.name) < 0
|
||||||
|
call add(l:info.active_linter_list, a:linter.name)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:notified
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Clear LSP linter data for the linting engine.
|
||||||
|
function! ale#lsp_linter#ClearLSPData() abort
|
||||||
|
let s:lsp_linter_map = {}
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Just for tests.
|
||||||
|
function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort
|
||||||
|
let s:lsp_linter_map = a:replacement_map
|
||||||
|
endfunction
|
|
@ -2,22 +2,41 @@
|
||||||
" Description: Preview windows for showing whatever information in.
|
" Description: Preview windows for showing whatever information in.
|
||||||
|
|
||||||
" Open a preview window and show some lines in it.
|
" Open a preview window and show some lines in it.
|
||||||
" An optional second argument can set an alternative filetype for the window.
|
" A second argument can be passed as a Dictionary with options. They are...
|
||||||
|
"
|
||||||
|
" filetype - The filetype to use, defaulting to 'ale-preview'
|
||||||
|
" stay_here - If 1, stay in the window you came from.
|
||||||
function! ale#preview#Show(lines, ...) abort
|
function! ale#preview#Show(lines, ...) abort
|
||||||
let l:filetype = get(a:000, 0, 'ale-preview')
|
let l:options = get(a:000, 0, {})
|
||||||
|
|
||||||
silent pedit ALEPreviewWindow
|
silent pedit ALEPreviewWindow
|
||||||
wincmd P
|
wincmd P
|
||||||
|
|
||||||
setlocal modifiable
|
setlocal modifiable
|
||||||
setlocal noreadonly
|
setlocal noreadonly
|
||||||
setlocal nobuflisted
|
setlocal nobuflisted
|
||||||
let &l:filetype = l:filetype
|
let &l:filetype = get(l:options, 'filetype', 'ale-preview')
|
||||||
setlocal buftype=nofile
|
setlocal buftype=nofile
|
||||||
setlocal bufhidden=wipe
|
setlocal bufhidden=wipe
|
||||||
:%d
|
:%d
|
||||||
call setline(1, a:lines)
|
call setline(1, a:lines)
|
||||||
setlocal nomodifiable
|
setlocal nomodifiable
|
||||||
setlocal readonly
|
setlocal readonly
|
||||||
|
|
||||||
|
if get(l:options, 'stay_here')
|
||||||
|
wincmd p
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Close the preview window if the filetype matches the given one.
|
||||||
|
function! ale#preview#CloseIfTypeMatches(filetype) abort
|
||||||
|
for l:win in getwininfo()
|
||||||
|
let l:wintype = gettabwinvar(l:win.tabnr, l:win.winnr, '&filetype')
|
||||||
|
|
||||||
|
if l:wintype is# a:filetype
|
||||||
|
silent! pclose!
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Show a location selection preview window, given some items.
|
" Show a location selection preview window, given some items.
|
||||||
|
@ -35,7 +54,7 @@ function! ale#preview#ShowSelection(item_list) abort
|
||||||
\)
|
\)
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
call ale#preview#Show(l:lines, 'ale-preview-selection')
|
call ale#preview#Show(l:lines, {'filetype': 'ale-preview-selection'})
|
||||||
let b:ale_preview_item_list = a:item_list
|
let b:ale_preview_item_list = a:item_list
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
|
@ -72,14 +72,13 @@ function! s:FindReferences(linter) abort
|
||||||
\ ? function('ale#references#HandleTSServerResponse')
|
\ ? function('ale#references#HandleTSServerResponse')
|
||||||
\ : function('ale#references#HandleLSPResponse')
|
\ : function('ale#references#HandleLSPResponse')
|
||||||
|
|
||||||
let l:lsp_details = ale#linter#StartLSP(l:buffer, a:linter, l:Callback)
|
let l:lsp_details = ale#lsp_linter#StartLSP(l:buffer, a:linter, l:Callback)
|
||||||
|
|
||||||
if empty(l:lsp_details)
|
if empty(l:lsp_details)
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:id = l:lsp_details.connection_id
|
let l:id = l:lsp_details.connection_id
|
||||||
let l:root = l:lsp_details.project_root
|
|
||||||
|
|
||||||
if a:linter.lsp is# 'tsserver'
|
if a:linter.lsp is# 'tsserver'
|
||||||
let l:message = ale#lsp#tsserver_message#References(
|
let l:message = ale#lsp#tsserver_message#References(
|
||||||
|
@ -90,14 +89,14 @@ function! s:FindReferences(linter) abort
|
||||||
else
|
else
|
||||||
" Send a message saying the buffer has changed first, or the
|
" Send a message saying the buffer has changed first, or the
|
||||||
" references position probably won't make sense.
|
" references position probably won't make sense.
|
||||||
call ale#lsp#Send(l:id, ale#lsp#message#DidChange(l:buffer), l:root)
|
call ale#lsp#NotifyForChanges(l:lsp_details)
|
||||||
|
|
||||||
let l:column = min([l:column, len(getline(l:line))])
|
let l:column = min([l:column, len(getline(l:line))])
|
||||||
|
|
||||||
let l:message = ale#lsp#message#References(l:buffer, l:line, l:column)
|
let l:message = ale#lsp#message#References(l:buffer, l:line, l:column)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:request_id = ale#lsp#Send(l:id, l:message, l:root)
|
let l:request_id = ale#lsp#Send(l:id, l:message, l:lsp_details.project_root)
|
||||||
|
|
||||||
let s:references_map[l:request_id] = {}
|
let s:references_map[l:request_id] = {}
|
||||||
endfunction
|
endfunction
|
||||||
|
|
144
sources_non_forked/ale/autoload/ale/socket.vim
Normal file
144
sources_non_forked/ale/autoload/ale/socket.vim
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
" Author: w0rp <devw0rp@gmail.com>
|
||||||
|
" Description: APIs for working with asynchronous sockets, with an API
|
||||||
|
" normalised between Vim 8 and NeoVim. Socket connections only work in NeoVim
|
||||||
|
" 0.3+, and silently do nothing in earlier NeoVim versions.
|
||||||
|
"
|
||||||
|
" Important functions are described below. They are:
|
||||||
|
"
|
||||||
|
" ale#socket#Open(address, options) -> channel_id (>= 0 if successful)
|
||||||
|
" ale#socket#IsOpen(channel_id) -> 1 if open, 0 otherwise
|
||||||
|
" ale#socket#Close(channel_id)
|
||||||
|
" ale#socket#Send(channel_id, data)
|
||||||
|
" ale#socket#GetAddress(channel_id) -> Return the address for a job
|
||||||
|
|
||||||
|
let s:channel_map = get(s:, 'channel_map', {})
|
||||||
|
|
||||||
|
function! s:VimOutputCallback(channel, data) abort
|
||||||
|
let l:channel_id = ch_info(a:channel).id
|
||||||
|
|
||||||
|
" Only call the callbacks for jobs which are valid.
|
||||||
|
if l:channel_id >= 0 && has_key(s:channel_map, l:channel_id)
|
||||||
|
call ale#util#GetFunction(s:channel_map[l:channel_id].callback)(l:channel_id, a:data)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:NeoVimOutputCallback(channel_id, data, event) abort
|
||||||
|
let l:info = s:channel_map[a:channel_id]
|
||||||
|
|
||||||
|
if a:event is# 'data'
|
||||||
|
let l:info.last_line = ale#util#JoinNeovimOutput(
|
||||||
|
\ a:channel_id,
|
||||||
|
\ l:info.last_line,
|
||||||
|
\ a:data,
|
||||||
|
\ l:info.mode,
|
||||||
|
\ ale#util#GetFunction(l:info.callback),
|
||||||
|
\)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Open a socket for a given address. The following options are accepted:
|
||||||
|
"
|
||||||
|
" callback - A callback for receiving input. (required)
|
||||||
|
"
|
||||||
|
" A non-negative number representing a channel ID will be returned is the
|
||||||
|
" connection was successful. 0 is a valid channel ID in Vim, so test if the
|
||||||
|
" connection ID is >= 0.
|
||||||
|
function! ale#socket#Open(address, options) abort
|
||||||
|
let l:mode = get(a:options, 'mode', 'raw')
|
||||||
|
let l:Callback = a:options.callback
|
||||||
|
|
||||||
|
let l:channel_info = {
|
||||||
|
\ 'address': a:address,
|
||||||
|
\ 'mode': l:mode,
|
||||||
|
\ 'callback': a:options.callback,
|
||||||
|
\}
|
||||||
|
|
||||||
|
if !has('nvim')
|
||||||
|
" Vim
|
||||||
|
let l:channel_info.channel = ch_open(a:address, {
|
||||||
|
\ 'mode': l:mode,
|
||||||
|
\ 'waittime': 0,
|
||||||
|
\ 'callback': function('s:VimOutputCallback'),
|
||||||
|
\})
|
||||||
|
let l:vim_info = ch_info(l:channel_info.channel)
|
||||||
|
let l:channel_id = !empty(l:vim_info) ? l:vim_info.id : -1
|
||||||
|
elseif exists('*chansend') && exists('*sockconnect')
|
||||||
|
" NeoVim 0.3+
|
||||||
|
try
|
||||||
|
let l:channel_id = sockconnect('tcp', a:address, {
|
||||||
|
\ 'on_data': function('s:NeoVimOutputCallback'),
|
||||||
|
\})
|
||||||
|
let l:channel_info.last_line = ''
|
||||||
|
catch /connection failed/
|
||||||
|
let l:channel_id = -1
|
||||||
|
endtry
|
||||||
|
|
||||||
|
" 0 means the connection failed some times in NeoVim, so make the ID
|
||||||
|
" invalid to match Vim.
|
||||||
|
if l:channel_id is 0
|
||||||
|
let l:channel_id = -1
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:channel_info.channel = l:channel_id
|
||||||
|
else
|
||||||
|
" Other Vim versions.
|
||||||
|
let l:channel_id = -1
|
||||||
|
endif
|
||||||
|
|
||||||
|
if l:channel_id >= 0
|
||||||
|
let s:channel_map[l:channel_id] = l:channel_info
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:channel_id
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Return 1 is a channel is open, 0 otherwise.
|
||||||
|
function! ale#socket#IsOpen(channel_id) abort
|
||||||
|
if !has_key(s:channel_map, a:channel_id)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
if has('nvim')
|
||||||
|
" In NeoVim, we have to check if this channel is in the global list.
|
||||||
|
return index(map(nvim_list_chans(), 'v:val.id'), a:channel_id) >= 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:channel = s:channel_map[a:channel_id].channel
|
||||||
|
return ch_status(l:channel) is# 'open'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Close a socket, if it's still open.
|
||||||
|
function! ale#socket#Close(channel_id) abort
|
||||||
|
" IsRunning isn't called here, so we don't check nvim_list_chans()
|
||||||
|
if !has_key(s:channel_map, a:channel_id)
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:channel = remove(s:channel_map, a:channel_id).channel
|
||||||
|
|
||||||
|
if has('nvim')
|
||||||
|
silent! call chanclose(l:channel)
|
||||||
|
elseif ch_status(l:channel) is# 'open'
|
||||||
|
call ch_close(l:channel)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Send some data to a socket.
|
||||||
|
function! ale#socket#Send(channel_id, data) abort
|
||||||
|
if !has_key(s:channel_map, a:channel_id)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:channel = s:channel_map[a:channel_id].channel
|
||||||
|
|
||||||
|
if has('nvim')
|
||||||
|
call chansend(l:channel, a:data)
|
||||||
|
else
|
||||||
|
call ch_sendraw(l:channel, a:data)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Get an address for a channel, or an empty string.
|
||||||
|
function! ale#socket#GetAddress(channel_id) abort
|
||||||
|
return get(get(s:channel_map, a:channel_id, {}), 'address', '')
|
||||||
|
endfunction
|
|
@ -1,14 +1,6 @@
|
||||||
" Author: KabbAmine <amine.kabb@gmail.com>
|
" Author: KabbAmine <amine.kabb@gmail.com>
|
||||||
" Description: Statusline related function(s)
|
" Description: Statusline related function(s)
|
||||||
|
|
||||||
" remove in 2.0
|
|
||||||
"
|
|
||||||
" A deprecated setting for ale#statusline#Status()
|
|
||||||
" See :help ale#statusline#Count() for getting status reports.
|
|
||||||
let g:ale_statusline_format = get(g:, 'ale_statusline_format',
|
|
||||||
\ ['%d error(s)', '%d warning(s)', 'OK']
|
|
||||||
\)
|
|
||||||
|
|
||||||
function! s:CreateCountDict() abort
|
function! s:CreateCountDict() abort
|
||||||
" Keys 0 and 1 are for backwards compatibility.
|
" Keys 0 and 1 are for backwards compatibility.
|
||||||
" The count object used to be a List of [error_count, warning_count].
|
" The count object used to be a List of [error_count, warning_count].
|
||||||
|
@ -76,47 +68,3 @@ function! ale#statusline#Count(buffer) abort
|
||||||
" The Dictionary is copied here before exposing it to other plugins.
|
" The Dictionary is copied here before exposing it to other plugins.
|
||||||
return copy(s:GetCounts(a:buffer))
|
return copy(s:GetCounts(a:buffer))
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" This is the historical format setting which could be configured before.
|
|
||||||
function! s:StatusForListFormat() abort
|
|
||||||
let [l:error_format, l:warning_format, l:no_errors] = g:ale_statusline_format
|
|
||||||
let l:counts = s:GetCounts(bufnr(''))
|
|
||||||
|
|
||||||
" Build strings based on user formatting preferences.
|
|
||||||
let l:errors = l:counts[0] ? printf(l:error_format, l:counts[0]) : ''
|
|
||||||
let l:warnings = l:counts[1] ? printf(l:warning_format, l:counts[1]) : ''
|
|
||||||
|
|
||||||
" Different formats based on the combination of errors and warnings.
|
|
||||||
if empty(l:errors) && empty(l:warnings)
|
|
||||||
let l:res = l:no_errors
|
|
||||||
elseif !empty(l:errors) && !empty(l:warnings)
|
|
||||||
let l:res = printf('%s %s', l:errors, l:warnings)
|
|
||||||
else
|
|
||||||
let l:res = empty(l:errors) ? l:warnings : l:errors
|
|
||||||
endif
|
|
||||||
|
|
||||||
return l:res
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" remove in 2.0
|
|
||||||
"
|
|
||||||
" Returns a formatted string that can be integrated in the statusline.
|
|
||||||
"
|
|
||||||
" This function is deprecated, and should not be used. Use the airline plugin
|
|
||||||
" instead, or write your own status function with ale#statusline#Count()
|
|
||||||
function! ale#statusline#Status() abort
|
|
||||||
if !get(g:, 'ale_deprecation_ale_statusline_status', 0)
|
|
||||||
execute 'echom ''ale#statusline#Status() is deprecated, use ale#statusline#Count() to write your own function.'''
|
|
||||||
let g:ale_deprecation_ale_statusline_status = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
if !exists('g:ale_statusline_format')
|
|
||||||
return 'OK'
|
|
||||||
endif
|
|
||||||
|
|
||||||
if type(g:ale_statusline_format) == type([])
|
|
||||||
return s:StatusForListFormat()
|
|
||||||
endif
|
|
||||||
|
|
||||||
return ''
|
|
||||||
endfunction
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ function! ale#toggle#Toggle() abort
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
call ale#autocmd#InitAuGroups()
|
call ale#events#Init()
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#toggle#Enable() abort
|
function! ale#toggle#Enable() abort
|
||||||
|
|
|
@ -17,11 +17,18 @@ endfunction
|
||||||
" but NeoVim does. Small messages can be echoed in Vim 8, and larger messages
|
" but NeoVim does. Small messages can be echoed in Vim 8, and larger messages
|
||||||
" have to be shown in preview windows.
|
" have to be shown in preview windows.
|
||||||
function! ale#util#ShowMessage(string) abort
|
function! ale#util#ShowMessage(string) abort
|
||||||
|
if !has('nvim')
|
||||||
|
call ale#preview#CloseIfTypeMatches('ale-preview.message')
|
||||||
|
endif
|
||||||
|
|
||||||
" We have to assume the user is using a monospace font.
|
" We have to assume the user is using a monospace font.
|
||||||
if has('nvim') || (a:string !~? "\n" && len(a:string) < &columns)
|
if has('nvim') || (a:string !~? "\n" && len(a:string) < &columns)
|
||||||
execute 'echo a:string'
|
execute 'echo a:string'
|
||||||
else
|
else
|
||||||
call ale#preview#Show(split(a:string, "\n"))
|
call ale#preview#Show(split(a:string, "\n"), {
|
||||||
|
\ 'filetype': 'ale-preview.message',
|
||||||
|
\ 'stay_here': 1,
|
||||||
|
\})
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@ -39,6 +46,33 @@ if !exists('g:ale#util#nul_file')
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
" Given a job, a buffered line of data, a list of parts of lines, a mode data
|
||||||
|
" is being read in, and a callback, join the lines of output for a NeoVim job
|
||||||
|
" or socket together, and call the callback with the joined output.
|
||||||
|
"
|
||||||
|
" Note that jobs and IDs are the same thing on NeoVim.
|
||||||
|
function! ale#util#JoinNeovimOutput(job, last_line, data, mode, callback) abort
|
||||||
|
if a:mode is# 'raw'
|
||||||
|
call a:callback(a:job, join(a:data, "\n"))
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:lines = a:data[:-2]
|
||||||
|
|
||||||
|
if len(a:data) > 1
|
||||||
|
let l:lines[0] = a:last_line . l:lines[0]
|
||||||
|
let l:new_last_line = a:data[-1]
|
||||||
|
else
|
||||||
|
let l:new_last_line = a:last_line . get(a:data, 0, '')
|
||||||
|
endif
|
||||||
|
|
||||||
|
for l:line in l:lines
|
||||||
|
call a:callback(a:job, l:line)
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return l:new_last_line
|
||||||
|
endfunction
|
||||||
|
|
||||||
" Return the number of lines for a given buffer.
|
" Return the number of lines for a given buffer.
|
||||||
function! ale#util#GetLineCount(buffer) abort
|
function! ale#util#GetLineCount(buffer) abort
|
||||||
return len(getbufline(a:buffer, 1, '$'))
|
return len(getbufline(a:buffer, 1, '$'))
|
||||||
|
@ -56,8 +90,11 @@ function! ale#util#Open(filename, line, column, options) abort
|
||||||
if get(a:options, 'open_in_tab', 0)
|
if get(a:options, 'open_in_tab', 0)
|
||||||
call ale#util#Execute('tabedit ' . fnameescape(a:filename))
|
call ale#util#Execute('tabedit ' . fnameescape(a:filename))
|
||||||
else
|
else
|
||||||
|
" Open another file only if we need to.
|
||||||
|
if bufnr(a:filename) isnot bufnr('')
|
||||||
call ale#util#Execute('edit ' . fnameescape(a:filename))
|
call ale#util#Execute('edit ' . fnameescape(a:filename))
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
call cursor(a:line, a:column)
|
call cursor(a:line, a:column)
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -241,16 +278,6 @@ function! ale#util#InSandbox() abort
|
||||||
return 0
|
return 0
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
" Get the number of milliseconds since some vague, but consistent, point in
|
|
||||||
" the past.
|
|
||||||
"
|
|
||||||
" This function can be used for timing execution, etc.
|
|
||||||
"
|
|
||||||
" The time will be returned as a Number.
|
|
||||||
function! ale#util#ClockMilliseconds() abort
|
|
||||||
return float2nr(reltimefloat(reltime()) * 1000)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" Given a single line, or a List of lines, and a single pattern, or a List
|
" Given a single line, or a List of lines, and a single pattern, or a List
|
||||||
" of patterns, return all of the matches for the lines(s) from the given
|
" of patterns, return all of the matches for the lines(s) from the given
|
||||||
" patterns, using matchlist().
|
" patterns, using matchlist().
|
||||||
|
|
14
sources_non_forked/ale/doc/ale-cloudformation.txt
Normal file
14
sources_non_forked/ale/doc/ale-cloudformation.txt
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
===============================================================================
|
||||||
|
ALE CloudFormation Integration *ale-cloudformation-options*
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
cfn-python-lint *ale-cloudformation-cfn-python-lint*
|
||||||
|
|
||||||
|
cfn-python-lint is a linter for AWS CloudFormation template file.
|
||||||
|
|
||||||
|
https://github.com/awslabs/cfn-python-lint
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||||
|
|
|
@ -35,4 +35,37 @@ g:ale_dart_dartanalyzer_executable *g:ale_dart_dartanalyzer_executable*
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
dartfmt *ale-dart-dartfmt*
|
||||||
|
|
||||||
|
Installation
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Installing Dart should probably ensure that `dartfmt` is in your `$PATH`.
|
||||||
|
|
||||||
|
In case it is not, try to set the executable option to its absolute path. : >
|
||||||
|
" Set the executable path for dartfmt to the absolute path to it.
|
||||||
|
let g:ale_dart_dartfmt_executable = '/usr/lib/dart/bin/dartfmt'
|
||||||
|
>
|
||||||
|
|
||||||
|
Options
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
g:ale_dart_dartfmt_executable *g:ale_dart_dartfmt_executable*
|
||||||
|
*b:ale_dart_dartfmt_executable*
|
||||||
|
Type: |String|
|
||||||
|
Default: `''`
|
||||||
|
|
||||||
|
This variable can be set to specify an absolute path to the
|
||||||
|
dartfmt executable (or to specify an alternate executable).
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_dart_dartfmt_options *g:ale_dart_dartfmt_options*
|
||||||
|
*b:ale_dart_dartfmt_options*
|
||||||
|
Type: |String|
|
||||||
|
Default: `''`
|
||||||
|
|
||||||
|
This variable can be set to pass additional options to the dartfmt fixer.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||||
|
|
223
sources_non_forked/ale/doc/ale-development.txt
Normal file
223
sources_non_forked/ale/doc/ale-development.txt
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
*ale-development.txt* For Vim version 8.0.
|
||||||
|
*ale-development*
|
||||||
|
|
||||||
|
ALE Development Documentation
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
CONTENTS *ale-development-contents*
|
||||||
|
|
||||||
|
1. Introduction.........................|ale-development-introduction|
|
||||||
|
2. Design Goals.........................|ale-design-goals|
|
||||||
|
3. Coding Standards.....................|ale-coding-standards|
|
||||||
|
4. Testing ALE..........................|ale-development-tests|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
1. Introduction *ale-development-introduction*
|
||||||
|
|
||||||
|
This document contains helpful information for ALE developers, including
|
||||||
|
design goals, information on how to run the tests, coding standards, and so
|
||||||
|
on. You should read this document if you want to get involved with ALE
|
||||||
|
development.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
2. Design Goals *ale-design-goals*
|
||||||
|
|
||||||
|
This section lists design goals for ALE, in no particular order. They are as
|
||||||
|
follows.
|
||||||
|
|
||||||
|
ALE code should be almost 100% VimL. This makes the plugin as portable as
|
||||||
|
possible.
|
||||||
|
|
||||||
|
ALE should run without needing any other plugins to be installed, to make
|
||||||
|
installation simple. ALE can integrate with other plugins for more advanced
|
||||||
|
functionality, non-essential functionality, or improving on basic first party
|
||||||
|
functionality.
|
||||||
|
|
||||||
|
ALE should check files with as many tools as possible by default, except where
|
||||||
|
they cause security issues or make excessive use of resources on modern
|
||||||
|
machines.
|
||||||
|
|
||||||
|
ALE should be free of breaking changes to the public API, which is comprised of
|
||||||
|
documented functions and options, until a major version is planned. Breaking
|
||||||
|
changes should be preceded by a deprecation phase complete with warnings.
|
||||||
|
Changes required for security may be an exception.
|
||||||
|
|
||||||
|
ALE supports Vim 8 and above, and NeoVim 0.2.0 or newer. These are the
|
||||||
|
earliest versions of Vim and NeoVim which support |job|, |timer|, |closure|,
|
||||||
|
and |lambda| features. All ALE code should be written so it is compatible with
|
||||||
|
these versions of Vim, or with version checks so particular features can
|
||||||
|
degrade or fail gracefully.
|
||||||
|
|
||||||
|
Just about everything should be documented and covered with tests.
|
||||||
|
|
||||||
|
By and large, people shouldn't pay for the functionality they don't use. Care
|
||||||
|
should be taken when adding new features, so supporting new features doesn't
|
||||||
|
degrade the general performance of anything ALE does.
|
||||||
|
|
||||||
|
LSP support will become more important as time goes on. ALE should provide
|
||||||
|
better support for LSP features as time goes on.
|
||||||
|
|
||||||
|
When merging pull requests, you should respond with `Cheers! :beers:`, purely
|
||||||
|
for comedy value.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
3. Coding Standards *ale-coding-standards*
|
||||||
|
|
||||||
|
The following general coding standards should be adhered to for Vim code.
|
||||||
|
|
||||||
|
* Check your Vim code with `Vint` and do everything it says. ALE will check
|
||||||
|
your Vim code with Vint automatically. See: https://github.com/Kuniwak/vint
|
||||||
|
Read ALE's `Dockerfile` to see which version of `Vint` it uses.
|
||||||
|
* Try to write descriptive and concise names for variables and functions.
|
||||||
|
Names shouldn't be too short or too long. Think about others reading your
|
||||||
|
code later on.
|
||||||
|
* Use `snake_case` names for variables and arguments, and `PascalCase` names
|
||||||
|
for functions. Prefix every variable name with its scope. (`l:`, `g:`, etc.)
|
||||||
|
* Try to keep lines no longer than 80 characters, but this isn't an absolute
|
||||||
|
requirement.
|
||||||
|
* Use 4 spaces for every level of indentation in Vim code.
|
||||||
|
* Add a blank line before every `function`, `if`, `for`, `while`, or `return`,
|
||||||
|
which doesn't start a new level of indentation. This makes the logic in
|
||||||
|
your code easier to follow.
|
||||||
|
* End every file with a trailing newline character, but not with extra blank
|
||||||
|
lines. Remove trailing whitespace from the ends of lines.
|
||||||
|
* Write the full names of commands instead of abbreviations. For example, write
|
||||||
|
`function` instead of `func`, and `endif` instead of `end`.
|
||||||
|
* Write functions with `!`, so files can be reloaded. Use the |abort| keyword
|
||||||
|
for all functions, so functions exit on the first error.
|
||||||
|
* Make sure to credit yourself in files you have authored with `Author:`
|
||||||
|
and `Description:` comments.
|
||||||
|
|
||||||
|
In addition to the above general guidelines for the style of your code, you
|
||||||
|
should also follow some additional rules designed to prevent mistakes. Some of
|
||||||
|
these are reported with ALE's `custom-linting-rules` script. See
|
||||||
|
|ale-development-tests|.
|
||||||
|
|
||||||
|
* Don't leave stray `:echo` lines in code. Use `execute 'echo' ...` if you must
|
||||||
|
echo something.
|
||||||
|
* For strings use |is#| instead of |==#|, `is?` instead of `==?`, `isnot#`
|
||||||
|
instead of `!=#`, and `isnot?` instead of `!=?`. This is because `'x' ==# 0`
|
||||||
|
returns 1, while `'x' is# 0` returns 0, so you will experience fewer issues
|
||||||
|
when numbers are compared with strings. `is` and `isnot` also do not throw
|
||||||
|
errors when other objects like List or Dictionaries are compared with
|
||||||
|
strings.
|
||||||
|
* Don't use the `getcwd()` function in the ALE codebase. Most of ALE's code
|
||||||
|
runs from asynchronous callback functions, and these functions can execute
|
||||||
|
from essentially random buffers. Therefore, the `getcwd()` output is
|
||||||
|
useless. Use `expand('#' . a:buffer . ':p:h')` instead. Don't use
|
||||||
|
`expand('%...')` for the same reason.
|
||||||
|
* Don't use the `simplify()` function. It doesn't simplify paths enough. Use
|
||||||
|
`ale#path#Simplify()` instead.
|
||||||
|
* Don't use the `shellescape()` function. It doesn't escape arguments properly
|
||||||
|
on Windows. Use `ale#Escape()` instead, which will avoid escaping where it
|
||||||
|
isn't needed, and generally escape arguments better on Windows.
|
||||||
|
|
||||||
|
Apply the following guidelines when writing Vader test files.
|
||||||
|
|
||||||
|
* Use 2 spaces for Vader test files, instead of the 4 spaces for Vim files.
|
||||||
|
* If you write `Before` and `After` blocks, you should typically write them at
|
||||||
|
the top of the file, so they run for all tests. There may be some tests
|
||||||
|
where it make sense to modify the `Before` and `After` code part of the way
|
||||||
|
through the file.
|
||||||
|
* If you modify any settings or global variables, reset them in `After`
|
||||||
|
blocks. The Vader `Save` and `Restore` commands can be useful for this
|
||||||
|
purpose.
|
||||||
|
* If you load or define linters in tests, write `call ale#linter#Reset()` in
|
||||||
|
an `After` block.
|
||||||
|
* Just write `Execute` blocks for Vader tests, and don't bother writing `Then`
|
||||||
|
blocks. `Then` blocks execute after `After` blocks in older versions, and
|
||||||
|
that can be confusing.
|
||||||
|
|
||||||
|
Apply the following rules when writing Bash scripts.
|
||||||
|
|
||||||
|
* Run `shellcheck`, and do everything it says.
|
||||||
|
See: https://github.com/koalaman/shellcheck
|
||||||
|
* Try to write scripts so they will run on Linux, BSD, or Mac OSX.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
4. Testing ALE *ale-development-tests*
|
||||||
|
|
||||||
|
ALE is tested with a suite of tests executed in Travis CI and AppVeyor. ALE
|
||||||
|
runs tests with the following versions of Vim in the following environments.
|
||||||
|
|
||||||
|
1. Vim 8.0.0027 on Linux via Travis CI.
|
||||||
|
2. NeoVim 0.2.0 on Linux via Travis CI.
|
||||||
|
3. NeoVim 0.3.0 on Linux via Travis CI.
|
||||||
|
4. Vim 8 (stable builds) on Windows via AppVeyor.
|
||||||
|
|
||||||
|
If you are developing ALE code on Linux, Mac OSX, or BSD, you can run ALEs
|
||||||
|
tests by installing Docker and running the `run-tests` script. Follow the
|
||||||
|
instructions on the Docker site for installing Docker.
|
||||||
|
See: https://docs.docker.com/install/
|
||||||
|
|
||||||
|
NOTE: Don't forget to add your user to the `docker` group on Linux, or Docker
|
||||||
|
just won't work. See: https://docs.docker.com/install/linux/linux-postinstall/
|
||||||
|
|
||||||
|
If you run simply `./run-tests` from the ALE repository root directory, the
|
||||||
|
latest Docker image for tests will be downloaded if needed, and the script
|
||||||
|
will run all of the tests in Vader, Vint checks, and several Bash scripts for
|
||||||
|
finding extra issues. Run `./run-tests --help` to see all of the options the
|
||||||
|
script supports. Note that the script supports selecting particular test files.
|
||||||
|
|
||||||
|
Generally write tests for any changes you make. The following types of tests
|
||||||
|
are recommended for the following types of code.
|
||||||
|
|
||||||
|
* New/edited error handler callbacks -> Write tests in `test/handler`
|
||||||
|
* New/edited command callbacks -> Write tests in `test/command_callback`
|
||||||
|
* New/edited fixer functions -> Write tests in `test/fixers`
|
||||||
|
|
||||||
|
Look at existing tests in the codebase for examples of how to write tests.
|
||||||
|
Refer to the Vader documentation for general information on how to write Vader
|
||||||
|
tests: https://github.com/junegunn/vader.vim
|
||||||
|
|
||||||
|
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. >
|
||||||
|
|
||||||
|
========================================
|
||||||
|
diff README.md and doc/ale.txt tables
|
||||||
|
========================================
|
||||||
|
Differences follow:
|
||||||
|
|
||||||
|
--- /tmp/readme.qLjNhJdB 2018-07-01 16:29:55.590331972 +0100
|
||||||
|
+++ /tmp/doc.dAi8zfVE 2018-07-01 16:29:55.582331877 +0100
|
||||||
|
@@ -1 +1 @@
|
||||||
|
- ASM: gcc, foobar
|
||||||
|
+ ASM: gcc
|
||||||
|
<
|
||||||
|
Make sure to list documentation entries for linters and fixers in individual
|
||||||
|
help files in the table of contents, and to align help tags to the right
|
||||||
|
margin. For example, if you add a heading for an `aardvark` tool to
|
||||||
|
`ale-python.txt` with a badly aligned doc tag, you will see errors like so. >
|
||||||
|
|
||||||
|
========================================
|
||||||
|
Look for badly aligned doc tags
|
||||||
|
========================================
|
||||||
|
Badly aligned tags follow:
|
||||||
|
|
||||||
|
doc/ale-python.txt:aardvark ...
|
||||||
|
========================================
|
||||||
|
Look for table of contents issues
|
||||||
|
========================================
|
||||||
|
|
||||||
|
Check for bad ToC sorting:
|
||||||
|
|
||||||
|
Check for mismatched ToC and headings:
|
||||||
|
|
||||||
|
--- /tmp/table-of-contents.mwCFOgSI 2018-07-01 16:33:25.068811878 +0100
|
||||||
|
+++ /tmp/headings.L4WU0hsO 2018-07-01 16:33:25.076811973 +0100
|
||||||
|
@@ -168,6 +168,7 @@
|
||||||
|
pyrex (cython), ale-pyrex-options
|
||||||
|
cython, ale-pyrex-cython
|
||||||
|
python, ale-python-options
|
||||||
|
+ aardvark, ale-python-aardvark
|
||||||
|
autopep8, ale-python-autopep8
|
||||||
|
black, ale-python-black
|
||||||
|
flake8, ale-python-flake8
|
||||||
|
<
|
||||||
|
Make sure to make the table of contents match the headings, and to keep the
|
||||||
|
doc tags on the right margin.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
|
@ -71,6 +71,14 @@ g:ale_html_tidy_options *g:ale_html_tidy_options*
|
||||||
(mac), sjis (shiftjis), utf-16le, utf-16, utf-8
|
(mac), sjis (shiftjis), utf-16le, utf-16, utf-8
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_html_tidy_use_global *g:html_tidy_use_global*
|
||||||
|
|
||||||
|
Type: |Number|
|
||||||
|
Default: `get(g:, 'ale_use_global_executables', 0)`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
write-good *ale-html-write-good*
|
write-good *ale-html-write-good*
|
||||||
|
|
||||||
|
|
25
sources_non_forked/ale/doc/ale-pyrex.txt
Normal file
25
sources_non_forked/ale/doc/ale-pyrex.txt
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
===============================================================================
|
||||||
|
ALE Pyrex (Cython) Integration *ale-pyrex-options*
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
cython *ale-pyrex-cython*
|
||||||
|
|
||||||
|
g:ale_pyrex_cython_executable *g:ale_pyrex_cython_executable*
|
||||||
|
*b:ale_pyrex_cython_executable*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'cython'`
|
||||||
|
|
||||||
|
This variable can be changed to use a different executable for cython.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_pyrex_cython_options *g:ale_pyrex_cython_options*
|
||||||
|
*b:ale_pyrex_cython_options*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'--warning-extra --warning-errors'`
|
||||||
|
|
||||||
|
This variable can be changed to modify flags given to cython.
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
|
@ -363,6 +363,30 @@ g:ale_python_pyls_use_global *g:ale_python_pyls_use_global*
|
||||||
See |ale-integrations-local-executables|
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
pyre *ale-python-pyre*
|
||||||
|
|
||||||
|
`pyre` will be run from a detected project root, per |ale-python-root|.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_python_pyre_executable *g:ale_python_pyre_executable*
|
||||||
|
*b:ale_python_pyre_executable*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'pyre'`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
Set this to `'pipenv'` to invoke `'pipenv` `run` `pyre'`.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_python_pyre_use_global *g:ale_python_pyre_use_global*
|
||||||
|
*b:ale_python_pyre_use_global*
|
||||||
|
Type: |Number|
|
||||||
|
Default: `get(g:, 'ale_use_global_executables', 0)`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
yapf *ale-python-yapf*
|
yapf *ale-python-yapf*
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,15 @@ g:ale_rust_cargo_include_features *g:ale_rust_cargo_include_features*
|
||||||
When defined, ALE will set the `--features` option when invoking `cargo` to
|
When defined, ALE will set the `--features` option when invoking `cargo` to
|
||||||
perform the lint check. See |g:ale_rust_cargo_default_feature_behavior|.
|
perform the lint check. See |g:ale_rust_cargo_default_feature_behavior|.
|
||||||
|
|
||||||
|
g:ale_rust_cargo_avoid_whole_workspace *g:ale_rust_cargo_avoid_whole_workspace*
|
||||||
|
*b:ale_rust_cargo_avoid_whole_workspace*
|
||||||
|
Type: |Number|
|
||||||
|
Default: `1`
|
||||||
|
|
||||||
|
When set to 1, and ALE is used to edit a crate that is part of a Cargo
|
||||||
|
workspace, avoid building the entire entire workspace by invoking
|
||||||
|
`cargo` directly in the crate's directory. Otherwise, behave as usual.
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
rls *ale-rust-rls*
|
rls *ale-rust-rls*
|
||||||
|
|
|
@ -2,6 +2,25 @@
|
||||||
ALE Shell Integration *ale-sh-options*
|
ALE Shell Integration *ale-sh-options*
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
sh-language-server *ale-sh-language-server*
|
||||||
|
|
||||||
|
g:ale_sh_language_server_executable *g:ale_sh_language_server_executable*
|
||||||
|
*b:ale_sh_language_server_executable*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'bash-language-server'`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_sh_language_server_use_global *g:ale_sh_language_server_use_global*
|
||||||
|
*b:ale_sh_language_server_use_global*
|
||||||
|
Type: |Number|
|
||||||
|
Default: `get(g:, 'ale_use_global_executables', 0)`
|
||||||
|
|
||||||
|
See |ale-integrations-local-executables|
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
shell *ale-sh-shell*
|
shell *ale-sh-shell*
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@ CONTENTS *ale-contents*
|
||||||
foodcritic..........................|ale-chef-foodcritic|
|
foodcritic..........................|ale-chef-foodcritic|
|
||||||
clojure...............................|ale-clojure-options|
|
clojure...............................|ale-clojure-options|
|
||||||
joker...............................|ale-clojure-joker|
|
joker...............................|ale-clojure-joker|
|
||||||
|
cloudformation........................|ale-cloudformation-options|
|
||||||
|
cfn-python-lint.....................|ale-cloudformation-cfn-python-lint|
|
||||||
cmake.................................|ale-cmake-options|
|
cmake.................................|ale-cmake-options|
|
||||||
cmakelint...........................|ale-cmake-cmakelint|
|
cmakelint...........................|ale-cmake-cmakelint|
|
||||||
cpp...................................|ale-cpp-options|
|
cpp...................................|ale-cpp-options|
|
||||||
|
@ -57,6 +59,7 @@ CONTENTS *ale-contents*
|
||||||
nvcc................................|ale-cuda-nvcc|
|
nvcc................................|ale-cuda-nvcc|
|
||||||
dart..................................|ale-dart-options|
|
dart..................................|ale-dart-options|
|
||||||
dartanalyzer........................|ale-dart-dartanalyzer|
|
dartanalyzer........................|ale-dart-dartanalyzer|
|
||||||
|
dartfmt.............................|ale-dart-dartfmt|
|
||||||
dockerfile............................|ale-dockerfile-options|
|
dockerfile............................|ale-dockerfile-options|
|
||||||
hadolint............................|ale-dockerfile-hadolint|
|
hadolint............................|ale-dockerfile-hadolint|
|
||||||
elixir................................|ale-elixir-options|
|
elixir................................|ale-elixir-options|
|
||||||
|
@ -183,6 +186,8 @@ CONTENTS *ale-contents*
|
||||||
puglint.............................|ale-pug-puglint|
|
puglint.............................|ale-pug-puglint|
|
||||||
puppet................................|ale-puppet-options|
|
puppet................................|ale-puppet-options|
|
||||||
puppetlint..........................|ale-puppet-puppetlint|
|
puppetlint..........................|ale-puppet-puppetlint|
|
||||||
|
pyrex (cython)........................|ale-pyrex-options|
|
||||||
|
cython..............................|ale-pyrex-cython|
|
||||||
python................................|ale-python-options|
|
python................................|ale-python-options|
|
||||||
autopep8............................|ale-python-autopep8|
|
autopep8............................|ale-python-autopep8|
|
||||||
black...............................|ale-python-black|
|
black...............................|ale-python-black|
|
||||||
|
@ -194,6 +199,7 @@ CONTENTS *ale-contents*
|
||||||
pyflakes............................|ale-python-pyflakes|
|
pyflakes............................|ale-python-pyflakes|
|
||||||
pylint..............................|ale-python-pylint|
|
pylint..............................|ale-python-pylint|
|
||||||
pyls................................|ale-python-pyls|
|
pyls................................|ale-python-pyls|
|
||||||
|
pyre................................|ale-python-pyre|
|
||||||
yapf................................|ale-python-yapf|
|
yapf................................|ale-python-yapf|
|
||||||
qml...................................|ale-qml-options|
|
qml...................................|ale-qml-options|
|
||||||
qmlfmt..............................|ale-qml-qmlfmt|
|
qmlfmt..............................|ale-qml-qmlfmt|
|
||||||
|
@ -226,6 +232,7 @@ CONTENTS *ale-contents*
|
||||||
prettier............................|ale-scss-prettier|
|
prettier............................|ale-scss-prettier|
|
||||||
stylelint...........................|ale-scss-stylelint|
|
stylelint...........................|ale-scss-stylelint|
|
||||||
sh....................................|ale-sh-options|
|
sh....................................|ale-sh-options|
|
||||||
|
sh-language-server..................|ale-sh-language-server|
|
||||||
shell...............................|ale-sh-shell|
|
shell...............................|ale-sh-shell|
|
||||||
shellcheck..........................|ale-sh-shellcheck|
|
shellcheck..........................|ale-sh-shellcheck|
|
||||||
shfmt...............................|ale-sh-shfmt|
|
shfmt...............................|ale-sh-shfmt|
|
||||||
|
@ -302,6 +309,9 @@ control functionality used for checking for problems. Try using the
|
||||||
|ALEFixSuggest| command for browsing tools that can be used to fix problems
|
|ALEFixSuggest| command for browsing tools that can be used to fix problems
|
||||||
for the current buffer.
|
for the current buffer.
|
||||||
|
|
||||||
|
If you are interested in contributing to the development of ALE, read the
|
||||||
|
developer documentation. See |ale-development|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
2. Supported Languages & Tools *ale-support*
|
2. Supported Languages & Tools *ale-support*
|
||||||
|
|
||||||
|
@ -317,7 +327,7 @@ Notes:
|
||||||
* API Blueprint: `drafter`
|
* API Blueprint: `drafter`
|
||||||
* AsciiDoc: `alex`!!, `proselint`, `redpen`, `write-good`
|
* AsciiDoc: `alex`!!, `proselint`, `redpen`, `write-good`
|
||||||
* Awk: `gawk`
|
* Awk: `gawk`
|
||||||
* Bash: `shell` (-n flag), `shellcheck`, `shfmt`
|
* Bash: `language-server`, `shell` (-n flag), `shellcheck`, `shfmt`
|
||||||
* Bourne Shell: `shell` (-n flag), `shellcheck`, `shfmt`
|
* Bourne Shell: `shell` (-n flag), `shellcheck`, `shfmt`
|
||||||
* C: `cppcheck`, `cpplint`!!, `clang`, `clangtidy`!!, `clang-format`, `flawfinder`, `gcc`
|
* C: `cppcheck`, `cpplint`!!, `clang`, `clangtidy`!!, `clang-format`, `flawfinder`, `gcc`
|
||||||
* C++ (filetype cpp): `clang`, `clangcheck`!!, `clangtidy`!!, `clang-format`, `cppcheck`, `cpplint`!!, `cquery`, `flawfinder`, `gcc`
|
* C++ (filetype cpp): `clang`, `clangcheck`!!, `clangtidy`!!, `clang-format`, `cppcheck`, `cpplint`!!, `cquery`, `flawfinder`, `gcc`
|
||||||
|
@ -325,6 +335,7 @@ Notes:
|
||||||
* C#: `mcs`, `mcsc`!!
|
* C#: `mcs`, `mcsc`!!
|
||||||
* Chef: `foodcritic`
|
* Chef: `foodcritic`
|
||||||
* Clojure: `joker`
|
* Clojure: `joker`
|
||||||
|
* CloudFormation: `cfn-python-lint`
|
||||||
* CMake: `cmakelint`
|
* CMake: `cmakelint`
|
||||||
* CoffeeScript: `coffee`, `coffeelint`
|
* CoffeeScript: `coffee`, `coffeelint`
|
||||||
* Crystal: `crystal`!!
|
* Crystal: `crystal`!!
|
||||||
|
@ -333,9 +344,9 @@ Notes:
|
||||||
* Cython (pyrex filetype): `cython`
|
* Cython (pyrex filetype): `cython`
|
||||||
* D: `dmd`
|
* D: `dmd`
|
||||||
* Dafny: `dafny`!!
|
* Dafny: `dafny`!!
|
||||||
* Dart: `dartanalyzer`!!, `language_server`
|
* Dart: `dartanalyzer`!!, `language_server`, dartfmt!!
|
||||||
* Dockerfile: `hadolint`
|
* Dockerfile: `hadolint`
|
||||||
* Elixir: `credo`, `dialyxir`, `dogma`!!
|
* Elixir: `credo`, `dialyxir`, `dogma`, `mix`!!
|
||||||
* Elm: `elm-format, elm-make`
|
* Elm: `elm-format, elm-make`
|
||||||
* Erb: `erb`, `erubi`, `erubis`
|
* Erb: `erb`, `erubi`, `erubis`
|
||||||
* Erlang: `erlc`, `SyntaxErl`
|
* Erlang: `erlc`, `SyntaxErl`
|
||||||
|
@ -380,7 +391,7 @@ Notes:
|
||||||
* proto: `protoc-gen-lint`
|
* proto: `protoc-gen-lint`
|
||||||
* Pug: `pug-lint`
|
* Pug: `pug-lint`
|
||||||
* Puppet: `puppet`, `puppet-lint`
|
* Puppet: `puppet`, `puppet-lint`
|
||||||
* Python: `autopep8`, `black`, `flake8`, `isort`, `mypy`, `prospector`, `pycodestyle`, `pyls`, `pylint`!!, `yapf`
|
* Python: `autopep8`, `black`, `flake8`, `isort`, `mypy`, `prospector`, `pycodestyle`, `pyls`, `pyre`, `pylint`!!, `yapf`
|
||||||
* QML: `qmlfmt`, `qmllint`
|
* QML: `qmlfmt`, `qmllint`
|
||||||
* R: `lintr`
|
* R: `lintr`
|
||||||
* ReasonML: `merlin`, `ols`, `refmt`
|
* ReasonML: `merlin`, `ols`, `refmt`
|
||||||
|
@ -935,6 +946,14 @@ g:ale_fixers *g:ale_fixers*
|
||||||
`b:ale_fixers` can be set to a |List| of callbacks instead, which can be
|
`b:ale_fixers` can be set to a |List| of callbacks instead, which can be
|
||||||
more convenient.
|
more convenient.
|
||||||
|
|
||||||
|
A special `'*'` key be used as a wildcard filetype for configuring fixers
|
||||||
|
for every other type of file. For example: >
|
||||||
|
|
||||||
|
" Fix Python files with 'bar'.
|
||||||
|
" Don't fix 'html' files.
|
||||||
|
" Fix everything else with 'foo'.
|
||||||
|
let g:ale_fixers = {'python': ['bar'], 'html': [], '*': ['foo']}
|
||||||
|
<
|
||||||
|
|
||||||
g:ale_fix_on_save *g:ale_fix_on_save*
|
g:ale_fix_on_save *g:ale_fix_on_save*
|
||||||
b:ale_fix_on_save *b:ale_fix_on_save*
|
b:ale_fix_on_save *b:ale_fix_on_save*
|
||||||
|
@ -1114,6 +1133,7 @@ g:ale_linter_aliases *g:ale_linter_aliases*
|
||||||
\ 'csh': 'sh',
|
\ 'csh': 'sh',
|
||||||
\ 'plaintex': 'tex',
|
\ 'plaintex': 'tex',
|
||||||
\ 'systemverilog': 'verilog',
|
\ 'systemverilog': 'verilog',
|
||||||
|
\ 'verilog_systemverilog': ['verilog_systemverilog', 'verilog'],
|
||||||
\ 'vimwiki': 'markdown',
|
\ 'vimwiki': 'markdown',
|
||||||
\ 'zsh': 'sh',
|
\ 'zsh': 'sh',
|
||||||
\}
|
\}
|
||||||
|
@ -1219,6 +1239,32 @@ g:ale_linters_explicit *g:ale_linters_explicit*
|
||||||
as possible, unless otherwise specified.
|
as possible, unless otherwise specified.
|
||||||
|
|
||||||
|
|
||||||
|
g:ale_linters_ignore *g:ale_linters_ignore*
|
||||||
|
*b:ale_linters_ignore*
|
||||||
|
|
||||||
|
Type: |Dictionary| or |List|
|
||||||
|
Default: `{}`
|
||||||
|
|
||||||
|
Linters to ignore. Commands for ignored linters will not be run, and
|
||||||
|
diagnostics for LSP linters will be ignored. (See |ale-lsp|)
|
||||||
|
|
||||||
|
This setting can be set to a |Dictionary| mapping filetypes to linter names,
|
||||||
|
just like |g:ale_linters|, to list linters to ignore. Ignore lists will be
|
||||||
|
applied after everything else. >
|
||||||
|
|
||||||
|
" Select flake8 and pylint, and ignore pylint, so only flake8 is run.
|
||||||
|
let g:ale_linters = {'python': ['flake8', 'pylint']}
|
||||||
|
let g:ale_linters_ignore = {'python': ['pylint']}
|
||||||
|
<
|
||||||
|
This setting can be set to simply a |List| of linter names, which is
|
||||||
|
especially more convenient when using the setting in ftplugin files for
|
||||||
|
particular buffers. >
|
||||||
|
|
||||||
|
" The same as above, in a ftplugin/python.vim.
|
||||||
|
let b:ale_linters = ['flake8', 'pylint']
|
||||||
|
let b:ale_linters_ignore = ['pylint']
|
||||||
|
<
|
||||||
|
|
||||||
g:ale_list_vertical *g:ale_list_vertical*
|
g:ale_list_vertical *g:ale_list_vertical*
|
||||||
*b:ale_list_vertical*
|
*b:ale_list_vertical*
|
||||||
Type: |Number|
|
Type: |Number|
|
||||||
|
@ -1967,9 +2013,13 @@ ALEDisableBuffer *ALEDisableBuffer*
|
||||||
*:ALEDetail*
|
*:ALEDetail*
|
||||||
ALEDetail *ALEDetail*
|
ALEDetail *ALEDetail*
|
||||||
|
|
||||||
Show the full linter message for the current line in the preview window.
|
Show the full linter message for the problem nearest to the cursor on the
|
||||||
This will only have an effect on lines that contain a linter message. The
|
given line in the preview window. The preview window can be easily closed
|
||||||
preview window can be easily closed with the `q` key.
|
with the `q` key. If there is no message to show, the window will not be
|
||||||
|
opened.
|
||||||
|
|
||||||
|
If a loclist item has a `detail` key set, the message for that key will be
|
||||||
|
preferred over `text`. See |ale-loclist-format|.
|
||||||
|
|
||||||
A plug mapping `<Plug>(ale_detail)` is defined for this command.
|
A plug mapping `<Plug>(ale_detail)` is defined for this command.
|
||||||
|
|
||||||
|
@ -2153,13 +2203,16 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
||||||
|
|
||||||
This argument is required, unless the linter is an
|
This argument is required, unless the linter is an
|
||||||
LSP linter. In which case, this argument must not be
|
LSP linter. In which case, this argument must not be
|
||||||
defined, as LSP linters handle diangostics
|
defined, as LSP linters handle diagnostics
|
||||||
automatically. See |ale-lsp-linters|.
|
automatically. See |ale-lsp-linters|.
|
||||||
|
|
||||||
The keys for each item in the List will be handled in
|
The keys for each item in the List will be handled in
|
||||||
the following manner:
|
the following manner:
|
||||||
*ale-loclist-format*
|
*ale-loclist-format*
|
||||||
`text` - This error message is required.
|
`text` - This error message is required.
|
||||||
|
`detail` - An optional, more descriptive message.
|
||||||
|
This message can be displayed with the |ALEDetail|
|
||||||
|
command instead of the message for `text`, if set.
|
||||||
`lnum` - The line number is required. Any strings
|
`lnum` - The line number is required. Any strings
|
||||||
will be automatically converted to numbers by
|
will be automatically converted to numbers by
|
||||||
using `str2nr()`.
|
using `str2nr()`.
|
||||||
|
@ -2319,8 +2372,16 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
||||||
|
|
||||||
When this argument is set to `'stdio'`, then the
|
When this argument is set to `'stdio'`, then the
|
||||||
linter will be defined as an LSP linter which keeps a
|
linter will be defined as an LSP linter which keeps a
|
||||||
process for a language server runnning, and
|
process for a language server running, and
|
||||||
communicates with it directly via a |channel|.
|
communicates with it directly via a |channel|.
|
||||||
|
`executable` or `executable_callback` must be set,
|
||||||
|
and `command` or `command_callback` must be set.
|
||||||
|
|
||||||
|
When this argument is set to `'socket'`, then the
|
||||||
|
linter will be defined as an LSP linter via a TCP
|
||||||
|
socket connection. `address_callback` must be set
|
||||||
|
with a callback returning an address to connect to.
|
||||||
|
ALE will not start a server automatically.
|
||||||
|
|
||||||
When this argument is not empty, only one of either
|
When this argument is not empty, only one of either
|
||||||
`language` or `language_callback` must be defined,
|
`language` or `language_callback` must be defined,
|
||||||
|
@ -2336,6 +2397,13 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
||||||
`initialization_options_callback` may be defined to
|
`initialization_options_callback` may be defined to
|
||||||
pass initialization options to the LSP.
|
pass initialization options to the LSP.
|
||||||
|
|
||||||
|
`address_callback` A |String| or |Funcref| for a callback function
|
||||||
|
accepting a buffer number. A |String| should be
|
||||||
|
returned with an address to connect to.
|
||||||
|
|
||||||
|
This argument must only be set if the `lsp` argument
|
||||||
|
is set to `'socket'`.
|
||||||
|
|
||||||
`project_root_callback` A |String| or |Funcref| for a callback function
|
`project_root_callback` A |String| or |Funcref| for a callback function
|
||||||
accepting a buffer number. A |String| should be
|
accepting a buffer number. A |String| should be
|
||||||
returned representing the path to the project for the
|
returned representing the path to the project for the
|
||||||
|
@ -2564,5 +2632,5 @@ free to send an email to devw0rp@gmail.com.
|
||||||
Please drink responsibly, or not at all, which is ironically the preference
|
Please drink responsibly, or not at all, which is ironically the preference
|
||||||
of w0rp, who is teetotal.
|
of w0rp, who is teetotal.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||||
|
|
|
@ -32,12 +32,6 @@ if !s:has_features
|
||||||
finish
|
finish
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" remove in 2.0
|
|
||||||
if has('nvim') && !has('nvim-0.2.0') && !get(g:, 'ale_use_deprecated_neovim')
|
|
||||||
execute 'echom ''ALE support for NeoVim versions below 0.2.0 is deprecated.'''
|
|
||||||
execute 'echom ''Use `let g:ale_use_deprecated_neovim = 1` to silence this warning for now.'''
|
|
||||||
endif
|
|
||||||
|
|
||||||
" Set this flag so that other plugins can use it, like airline.
|
" Set this flag so that other plugins can use it, like airline.
|
||||||
let g:loaded_ale = 1
|
let g:loaded_ale = 1
|
||||||
|
|
||||||
|
@ -221,35 +215,13 @@ nnoremap <silent> <Plug>(ale_find_references) :ALEFindReferences<Return>
|
||||||
nnoremap <silent> <Plug>(ale_hover) :ALEHover<Return>
|
nnoremap <silent> <Plug>(ale_hover) :ALEHover<Return>
|
||||||
|
|
||||||
" Set up autocmd groups now.
|
" Set up autocmd groups now.
|
||||||
call ale#autocmd#InitAuGroups()
|
call ale#events#Init()
|
||||||
|
|
||||||
" Housekeeping
|
" Housekeeping
|
||||||
|
|
||||||
augroup ALECleanupGroup
|
augroup ALECleanupGroup
|
||||||
autocmd!
|
autocmd!
|
||||||
" Clean up buffers automatically when they are unloaded.
|
" Clean up buffers automatically when they are unloaded.
|
||||||
autocmd BufDelete * call ale#engine#Cleanup(str2nr(expand('<abuf>')))
|
autocmd BufDelete * if exists('*ale#engine#Cleanup') | call ale#engine#Cleanup(str2nr(expand('<abuf>'))) | endif
|
||||||
autocmd QuitPre * call ale#events#QuitEvent(str2nr(expand('<abuf>')))
|
autocmd QuitPre * call ale#events#QuitEvent(str2nr(expand('<abuf>')))
|
||||||
augroup END
|
augroup END
|
||||||
|
|
||||||
" Backwards Compatibility
|
|
||||||
|
|
||||||
" remove in 2.0
|
|
||||||
function! ALELint(delay) abort
|
|
||||||
if !get(g:, 'ale_deprecation_ale_lint', 0)
|
|
||||||
execute 'echom ''ALELint() is deprecated, use ale#Queue() instead.'''
|
|
||||||
let g:ale_deprecation_ale_lint = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
call ale#Queue(a:delay)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
" remove in 2.0
|
|
||||||
function! ALEGetStatusLine() abort
|
|
||||||
if !get(g:, 'ale_deprecation_ale_get_status_line', 0)
|
|
||||||
execute 'echom ''ALEGetStatusLine() is deprecated.'''
|
|
||||||
let g:ale_deprecation_ale_get_status_line = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
return ale#statusline#Status()
|
|
||||||
endfunction
|
|
||||||
|
|
|
@ -2595,6 +2595,20 @@ fu! s:ExitIfSingleCandidate()
|
||||||
return 0
|
return 0
|
||||||
endfu
|
endfu
|
||||||
|
|
||||||
|
fu! s:IsBuiltin()
|
||||||
|
let builtins = ['tag', 'dir', 'bft', 'rts', 'bkd', 'lns', 'chs', 'mix', 'udo', 'qfx']
|
||||||
|
let curtype = s:getextvar('sname')
|
||||||
|
return s:itemtype < len(s:coretypes) || index(builtins, curtype) > -1
|
||||||
|
endfu
|
||||||
|
|
||||||
|
fu! s:DetectFileType(type, ft)
|
||||||
|
if s:IsBuiltin() || empty(a:ft) || a:ft ==# 'ctrlp'
|
||||||
|
retu 'ctrlp'
|
||||||
|
el
|
||||||
|
retu 'ctrlp.' . a:ft
|
||||||
|
en
|
||||||
|
endfu
|
||||||
|
|
||||||
fu! ctrlp#init(type, ...)
|
fu! ctrlp#init(type, ...)
|
||||||
if exists('s:init') || s:iscmdwin() | retu | en
|
if exists('s:init') || s:iscmdwin() | retu | en
|
||||||
let [s:ermsg, v:errmsg] = [v:errmsg, '']
|
let [s:ermsg, v:errmsg] = [v:errmsg, '']
|
||||||
|
@ -2618,7 +2632,7 @@ fu! ctrlp#init(type, ...)
|
||||||
en
|
en
|
||||||
en
|
en
|
||||||
cal ctrlp#setlines(s:settype(type))
|
cal ctrlp#setlines(s:settype(type))
|
||||||
set ft=ctrlp
|
let &filetype = s:DetectFileType(type, &filetype)
|
||||||
cal ctrlp#syntax()
|
cal ctrlp#syntax()
|
||||||
cal s:SetDefTxt()
|
cal s:SetDefTxt()
|
||||||
let curName = s:CurTypeName()
|
let curName = s:CurTypeName()
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
" Filename: autoload/lightline.vim
|
" Filename: autoload/lightline.vim
|
||||||
" Author: itchyny
|
" Author: itchyny
|
||||||
" License: MIT License
|
" License: MIT License
|
||||||
" Last Change: 2017/12/31 15:55:00.
|
" Last Change: 2018/06/22 08:50:00.
|
||||||
" =============================================================================
|
" =============================================================================
|
||||||
|
|
||||||
let s:save_cpo = &cpo
|
let s:save_cpo = &cpo
|
||||||
|
@ -47,8 +47,10 @@ function! lightline#enable() abort
|
||||||
endif
|
endif
|
||||||
augroup lightline
|
augroup lightline
|
||||||
autocmd!
|
autocmd!
|
||||||
autocmd WinEnter,BufWinEnter,FileType,ColorScheme,SessionLoadPost * call lightline#update()
|
autocmd WinEnter,BufWinEnter,FileType,SessionLoadPost * call lightline#update()
|
||||||
autocmd ColorScheme,SessionLoadPost * call lightline#highlight()
|
autocmd SessionLoadPost * call lightline#highlight()
|
||||||
|
autocmd ColorScheme * if !has('vim_starting') || expand('<amatch>') !=# 'macvim'
|
||||||
|
\ | call lightline#update() | call lightline#highlight() | endif
|
||||||
autocmd CursorMoved,BufUnload * call lightline#update_once()
|
autocmd CursorMoved,BufUnload * call lightline#update_once()
|
||||||
augroup END
|
augroup END
|
||||||
augroup lightline-disable
|
augroup lightline-disable
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
" Filename: plugin/lightline.vim
|
" Filename: plugin/lightline.vim
|
||||||
" Author: itchyny
|
" Author: itchyny
|
||||||
" License: MIT License
|
" License: MIT License
|
||||||
" Last Change: 2016/03/14 03:31:58.
|
" Last Change: 2018/06/22 08:49:00.
|
||||||
" =============================================================================
|
" =============================================================================
|
||||||
|
|
||||||
if exists('g:loaded_lightline') || v:version < 700
|
if exists('g:loaded_lightline') || v:version < 700
|
||||||
|
@ -15,8 +15,10 @@ set cpo&vim
|
||||||
|
|
||||||
augroup lightline
|
augroup lightline
|
||||||
autocmd!
|
autocmd!
|
||||||
autocmd WinEnter,BufWinEnter,FileType,ColorScheme,SessionLoadPost * call lightline#update()
|
autocmd WinEnter,BufWinEnter,FileType,SessionLoadPost * call lightline#update()
|
||||||
autocmd ColorScheme,SessionLoadPost * call lightline#highlight()
|
autocmd SessionLoadPost * call lightline#highlight()
|
||||||
|
autocmd ColorScheme * if !has('vim_starting') || expand('<amatch>') !=# 'macvim'
|
||||||
|
\ | call lightline#update() | call lightline#highlight() | endif
|
||||||
autocmd CursorMoved,BufUnload * call lightline#update_once()
|
autocmd CursorMoved,BufUnload * call lightline#update_once()
|
||||||
augroup END
|
augroup END
|
||||||
|
|
||||||
|
|
|
@ -225,10 +225,11 @@ endfunction
|
||||||
function! NERDTreeListNode()
|
function! NERDTreeListNode()
|
||||||
let treenode = g:NERDTreeFileNode.GetSelected()
|
let treenode = g:NERDTreeFileNode.GetSelected()
|
||||||
if !empty(treenode)
|
if !empty(treenode)
|
||||||
if has("osx")
|
let s:uname = system("uname")
|
||||||
let stat_cmd = 'stat -f "%z" '
|
|
||||||
else
|
|
||||||
let stat_cmd = 'stat -c "%s" '
|
let stat_cmd = 'stat -c "%s" '
|
||||||
|
|
||||||
|
if s:uname =~? "Darwin"
|
||||||
|
let stat_cmd = 'stat -f "%z" '
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let cmd = 'size=$(' . stat_cmd . shellescape(treenode.path.str()) . ') && ' .
|
let cmd = 'size=$(' . stat_cmd . shellescape(treenode.path.str()) . ') && ' .
|
||||||
|
|
|
@ -556,6 +556,7 @@ syn keyword ngxDirective ssl_protocols nextgroup=ngxSSLProtocol,ngxSSLProtocolDe
|
||||||
syn match ngxSSLProtocol 'TLSv1' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
|
syn match ngxSSLProtocol 'TLSv1' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
|
||||||
syn match ngxSSLProtocol 'TLSv1\.1' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
|
syn match ngxSSLProtocol 'TLSv1\.1' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
|
||||||
syn match ngxSSLProtocol 'TLSv1\.2' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
|
syn match ngxSSLProtocol 'TLSv1\.2' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
|
||||||
|
syn match ngxSSLProtocol 'TLSv1\.3' contained nextgroup=ngxSSLProtocol,ngxSSLProtocolDeprecated skipwhite
|
||||||
|
|
||||||
" Do not enable highlighting of insecure protocols if sslecure is loaded
|
" Do not enable highlighting of insecure protocols if sslecure is loaded
|
||||||
if !exists('g:loaded_sslsecure')
|
if !exists('g:loaded_sslsecure')
|
||||||
|
|
|
@ -66,6 +66,14 @@ function! s:shellslash(path) abort
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:PlatformSlash(path) abort
|
||||||
|
if exists('+shellslash') && !&shellslash
|
||||||
|
return tr(a:path, '/', '\')
|
||||||
|
else
|
||||||
|
return a:path
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
let s:executables = {}
|
let s:executables = {}
|
||||||
|
|
||||||
function! s:executable(binary) abort
|
function! s:executable(binary) abort
|
||||||
|
@ -83,7 +91,7 @@ endfunction
|
||||||
|
|
||||||
function! fugitive#GitVersion(...) abort
|
function! fugitive#GitVersion(...) abort
|
||||||
if !has_key(s:git_versions, g:fugitive_git_executable)
|
if !has_key(s:git_versions, g:fugitive_git_executable)
|
||||||
let s:git_versions[g:fugitive_git_executable] = matchstr(system(g:fugitive_git_executable.' --version'), "\\S\\+\n")
|
let s:git_versions[g:fugitive_git_executable] = matchstr(system(g:fugitive_git_executable.' --version'), "\\S\\+\\ze\n")
|
||||||
endif
|
endif
|
||||||
return s:git_versions[g:fugitive_git_executable]
|
return s:git_versions[g:fugitive_git_executable]
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -107,7 +115,7 @@ function! s:recall() abort
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:map(mode, lhs, rhs, ...) abort
|
function! s:map(mode, lhs, rhs, ...) abort
|
||||||
let flags = (a:0 ? a:1 : '') . (a:rhs =~# '^<Plug>' ? '' : '<script>')
|
let flags = (a:0 ? a:1 : '') . (a:rhs =~# '<Plug>' ? '' : '<script>')
|
||||||
let head = a:lhs
|
let head = a:lhs
|
||||||
let tail = ''
|
let tail = ''
|
||||||
let keys = get(g:, a:mode.'remap', {})
|
let keys = get(g:, a:mode.'remap', {})
|
||||||
|
@ -242,10 +250,6 @@ function! s:repo_bare() dict abort
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:repo_translate(spec) dict abort
|
function! s:repo_translate(spec) dict abort
|
||||||
let refs = self.dir('refs/')
|
|
||||||
if filereadable(self.dir('commondir'))
|
|
||||||
let refs = simplify(self.dir(get(readfile(self.dir('commondir'), 1), 0, ''))) . '/refs/'
|
|
||||||
endif
|
|
||||||
if a:spec ==# '.' || a:spec ==# '/.'
|
if a:spec ==# '.' || a:spec ==# '/.'
|
||||||
return self.bare() ? self.dir() : self.tree()
|
return self.bare() ? self.dir() : self.tree()
|
||||||
elseif a:spec =~# '^/\=\.git$' && self.bare()
|
elseif a:spec =~# '^/\=\.git$' && self.bare()
|
||||||
|
@ -267,23 +271,18 @@ function! s:repo_translate(spec) dict abort
|
||||||
return 'fugitive://'.self.dir().'//'.ref
|
return 'fugitive://'.self.dir().'//'.ref
|
||||||
elseif a:spec =~# '^:'
|
elseif a:spec =~# '^:'
|
||||||
return 'fugitive://'.self.dir().'//0/'.a:spec[1:-1]
|
return 'fugitive://'.self.dir().'//0/'.a:spec[1:-1]
|
||||||
elseif a:spec ==# '@'
|
else
|
||||||
return self.dir('HEAD')
|
let refs = self.dir('refs/')
|
||||||
elseif a:spec =~# 'HEAD\|^refs/' && a:spec !~ ':' && filereadable(refs . '../' . a:spec)
|
if filereadable(self.dir('commondir'))
|
||||||
|
let refs = simplify(self.dir(get(readfile(self.dir('commondir'), 1), 0, ''))) . '/refs/'
|
||||||
|
endif
|
||||||
|
if a:spec =~# 'HEAD\|^refs/' && a:spec !~ ':' && filereadable(refs . '../' . a:spec)
|
||||||
return simplify(refs . '../' . a:spec)
|
return simplify(refs . '../' . a:spec)
|
||||||
elseif filereadable(refs.a:spec)
|
elseif filereadable(refs.a:spec)
|
||||||
return refs.a:spec
|
return refs.a:spec
|
||||||
elseif filereadable(refs.'tags/'.a:spec)
|
endif
|
||||||
return refs.'tags/'.a:spec
|
|
||||||
elseif filereadable(refs.'heads/'.a:spec)
|
|
||||||
return refs.'heads/'.a:spec
|
|
||||||
elseif filereadable(refs.'remotes/'.a:spec)
|
|
||||||
return refs.'remotes/'.a:spec
|
|
||||||
elseif filereadable(refs.'remotes/'.a:spec.'/HEAD')
|
|
||||||
return refs.'remotes/'.a:spec.'/HEAD'
|
|
||||||
else
|
|
||||||
try
|
try
|
||||||
let ref = self.rev_parse(matchstr(a:spec,'[^:]*'))
|
let ref = self.rev_parse(s:sub(matchstr(a:spec,'[^:]*'), '^\@%($|[^~])@=', 'HEAD'))
|
||||||
let path = s:sub(matchstr(a:spec,':.*'),'^:','/')
|
let path = s:sub(matchstr(a:spec,':.*'),'^:','/')
|
||||||
return 'fugitive://'.self.dir().'//'.ref.path
|
return 'fugitive://'.self.dir().'//'.ref.path
|
||||||
catch /^fugitive:/
|
catch /^fugitive:/
|
||||||
|
@ -429,6 +428,204 @@ call s:add_methods('repo',['keywordprg'])
|
||||||
|
|
||||||
" Section: Buffer
|
" Section: Buffer
|
||||||
|
|
||||||
|
function! s:DirCommitFile(path) abort
|
||||||
|
let vals = matchlist(s:shellslash(a:path), '\c^fugitive:\%(//\)\=\(.\{-\}\)\%(//\|::\)\(\w\+\)\(/.*\)\=$')
|
||||||
|
if empty(vals)
|
||||||
|
return ['', '', '']
|
||||||
|
endif
|
||||||
|
return [vals[1], (vals[2] =~# '^.$' ? ':' : '') . vals[2], vals[3]]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! fugitive#Path(url) abort
|
||||||
|
let [dir, commit, file] = s:DirCommitFile(a:url)
|
||||||
|
if len(dir)
|
||||||
|
let tree = FugitiveTreeForGitDir(dir)
|
||||||
|
return s:PlatformSlash((len(tree) ? tree : dir) . file)
|
||||||
|
elseif a:url =~# '^[\\/]\|^\a:[\\/]'
|
||||||
|
return s:PlatformSlash(a:url)
|
||||||
|
endif
|
||||||
|
return ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! fugitive#Real(url) abort
|
||||||
|
return fugitive#Path(a:url)
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
let s:trees = {}
|
||||||
|
let s:indexes = {}
|
||||||
|
function! s:TreeInfo(dir, commit) abort
|
||||||
|
let git = g:fugitive_git_executable . ' --git-dir=' . s:shellesc(a:dir)
|
||||||
|
if a:commit =~# '^:\=[0-3]$'
|
||||||
|
let index = get(s:indexes, a:dir, [])
|
||||||
|
let newftime = getftime(a:dir . '/index')
|
||||||
|
if get(index, 0, -1) < newftime
|
||||||
|
let out = system(git . ' ls-files --stage')
|
||||||
|
let s:indexes[a:dir] = [newftime, {'0': {}, '1': {}, '2': {}, '3': {}}]
|
||||||
|
if v:shell_error
|
||||||
|
return [{}, -1]
|
||||||
|
endif
|
||||||
|
for line in split(out, "\n")
|
||||||
|
let [info, filename] = split(line, "\t")
|
||||||
|
let [mode, sha, stage] = split(info, '\s\+')
|
||||||
|
let s:indexes[a:dir][1][stage][filename] = [newftime, mode, 'blob', sha, -2]
|
||||||
|
while filename =~# '/'
|
||||||
|
let filename = substitute(filename, '/[^/]*$', '', '')
|
||||||
|
let s:indexes[a:dir][1][stage][filename] = [newftime, '040000', 'tree', '', 0]
|
||||||
|
endwhile
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
return [get(s:indexes[a:dir][1], a:commit[-1:-1], {}), newftime]
|
||||||
|
elseif a:commit =~# '^\x\{40\}$'
|
||||||
|
if !has_key(s:trees, a:dir)
|
||||||
|
let ftime = +system(git . ' log -1 --pretty=format:%ct ' . a:commit)
|
||||||
|
if v:shell_error
|
||||||
|
let s:trees[a:dir] = [{}, -1]
|
||||||
|
return s:trees[a:dir]
|
||||||
|
endif
|
||||||
|
let s:trees[a:dir] = [{}, +ftime]
|
||||||
|
let out = system(git . ' ls-tree -rtl --full-name ' . a:commit)
|
||||||
|
if v:shell_error
|
||||||
|
return s:trees[a:dir]
|
||||||
|
endif
|
||||||
|
for line in split(out, "\n")
|
||||||
|
let [info, filename] = split(line, "\t")
|
||||||
|
let [mode, type, sha, size] = split(info, '\s\+')
|
||||||
|
let s:trees[a:dir][0][filename] = [ftime, mode, type, sha, +size, filename]
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
return s:trees[a:dir]
|
||||||
|
endif
|
||||||
|
return [{}, -1]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:PathInfo(url) abort
|
||||||
|
let [dir, commit, file] = s:DirCommitFile(a:url)
|
||||||
|
if empty(dir) || !get(g:, 'fugitive_file_api', 1)
|
||||||
|
return [-1, '000000', '', '', -1]
|
||||||
|
endif
|
||||||
|
let path = substitute(file[1:-1], '/*$', '', '')
|
||||||
|
let [tree, ftime] = s:TreeInfo(dir, commit)
|
||||||
|
let entry = empty(path) ? [ftime, '040000', 'tree', '', -1] : get(tree, path, [])
|
||||||
|
if empty(entry) || file =~# '/$' && entry[1] !=# 'tree'
|
||||||
|
return [-1, '000000', '', '', -1]
|
||||||
|
else
|
||||||
|
return entry
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! fugitive#simplify(url) abort
|
||||||
|
let [dir, commit, file] = s:DirCommitFile(a:url)
|
||||||
|
if empty(dir)
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
if file =~# '/\.\.\%(/\|$\)'
|
||||||
|
let tree = FugitiveTreeForGitDir(dir)
|
||||||
|
if len(tree)
|
||||||
|
let path = simplify(tree . file)
|
||||||
|
if strpart(path . '/', 0, len(tree) + 1) !=# tree . '/'
|
||||||
|
return s:PlatformSlash(path)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return s:PlatformSlash('fugitive://' . simplify(dir) . '//' . commit . simplify(file))
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! fugitive#resolve(url) abort
|
||||||
|
let url = fugitive#simplify(a:url)
|
||||||
|
if url =~? '^fugitive:'
|
||||||
|
return url
|
||||||
|
else
|
||||||
|
return resolve(url)
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! fugitive#getftime(url) abort
|
||||||
|
return s:PathInfo(a:url)[0]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! fugitive#getfsize(url) abort
|
||||||
|
let entry = s:PathInfo(a:url)
|
||||||
|
if entry[4] == -2 && entry[2] ==# 'blob' && len(entry[3])
|
||||||
|
let dir = s:DirCommitFile(a:url)[0]
|
||||||
|
let size = +system(g:fugitive_git_executable . ' ' . s:shellesc('--git-dir=' . dir) . ' cat-file -s ' . entry[3])
|
||||||
|
let entry[4] = v:shell_error ? -1 : size
|
||||||
|
endif
|
||||||
|
return entry[4]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! fugitive#getftype(url) abort
|
||||||
|
return get({'tree': 'dir', 'blob': 'file'}, s:PathInfo(a:url)[2], '')
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! fugitive#filereadable(url) abort
|
||||||
|
return s:PathInfo(a:url)[2] ==# 'blob'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! fugitive#isdirectory(url) abort
|
||||||
|
return s:PathInfo(a:url)[2] ==# 'tree'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! fugitive#readfile(url, ...) abort
|
||||||
|
let bin = a:0 && a:1 ==# 'b'
|
||||||
|
let max = a:0 > 1 ? a:2 : 'all'
|
||||||
|
let entry = s:PathInfo(a:url)
|
||||||
|
if entry[2] !=# 'blob'
|
||||||
|
return []
|
||||||
|
endif
|
||||||
|
let [dir, commit, file] = s:DirCommitFile(a:url)
|
||||||
|
let cmd = g:fugitive_git_executable . ' --git-dir=' . s:shellesc(dir) .
|
||||||
|
\ ' cat-file blob ' . s:shellesc(commit . ':' . file[1:-1])
|
||||||
|
if max > 0 && s:executable('head')
|
||||||
|
let cmd .= '|head -' . max
|
||||||
|
endif
|
||||||
|
if exists('systemlist') && !bin
|
||||||
|
let lines = systemlist(cmd)
|
||||||
|
else
|
||||||
|
let lines = split(system(cmd), "\n", 1)
|
||||||
|
if !bin && empty(lines[-1])
|
||||||
|
call remove(lines, -1)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
if v:shell_error || max is# 0
|
||||||
|
return []
|
||||||
|
elseif max > 0 && max < len(lines)
|
||||||
|
return lines[0 : max - 1]
|
||||||
|
elseif max < 0
|
||||||
|
return lines[max : -1]
|
||||||
|
else
|
||||||
|
return lines
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
let s:globsubs = {'*': '[^/]*', '**': '.*', '**/': '\%(.*/\)\=', '?': '[^/]'}
|
||||||
|
function! fugitive#glob(url, ...) abort
|
||||||
|
let [dirglob, commit, glob] = s:DirCommitFile(a:url)
|
||||||
|
let append = matchstr(glob, '/*$')
|
||||||
|
let glob = substitute(glob, '/*$', '', '')
|
||||||
|
let pattern = '^' . substitute(glob[1:-1], '\*\*/\=\|[.?*\^$]', '\=get(s:globsubs, submatch(0), "\\" . submatch(0))', 'g') . '$'
|
||||||
|
let results = []
|
||||||
|
for dir in dirglob =~# '[*?]' ? split(glob(dirglob), "\n") : [dirglob]
|
||||||
|
if empty(dir) || !get(g:, 'fugitive_file_api', 1) || !filereadable(dir . '/HEAD')
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
let files = items(s:TreeInfo(dir, commit)[0])
|
||||||
|
if len(append)
|
||||||
|
call filter(files, 'v:val[1][2] ==# "tree"')
|
||||||
|
endif
|
||||||
|
call map(files, 'v:val[0]')
|
||||||
|
call filter(files, 'v:val =~# pattern')
|
||||||
|
let prepend = 'fugitive://' . dir . '//' . substitute(commit, '^:', '', '') . '/'
|
||||||
|
call sort(files)
|
||||||
|
call map(files, 's:PlatformSlash(prepend . v:val . append)')
|
||||||
|
call extend(results, files)
|
||||||
|
endfor
|
||||||
|
if a:0 > 1 && a:2
|
||||||
|
return results
|
||||||
|
else
|
||||||
|
return join(results, "\n")
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
let s:buffer_prototype = {}
|
let s:buffer_prototype = {}
|
||||||
|
|
||||||
function! s:buffer(...) abort
|
function! s:buffer(...) abort
|
||||||
|
@ -510,7 +707,7 @@ function! s:buffer_name() dict abort
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:buffer_commit() dict abort
|
function! s:buffer_commit() dict abort
|
||||||
return matchstr(self.spec(),'^fugitive://.\{-\}//\zs\w*')
|
return matchstr(self.spec(),'^fugitive:\%(//\)\=.\{-\}\%(//\|::\)\zs\w*')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:cpath(path) abort
|
function! s:cpath(path) abort
|
||||||
|
@ -521,8 +718,8 @@ function! s:cpath(path) abort
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:buffer_path(...) dict abort
|
function! s:buffer_relative(...) dict abort
|
||||||
let rev = matchstr(self.spec(),'^fugitive://.\{-\}//\zs.*')
|
let rev = matchstr(self.spec(),'^fugitive:\%(//\)\=.\{-\}\%(//\|::\)\zs.*')
|
||||||
if rev != ''
|
if rev != ''
|
||||||
let rev = s:sub(rev,'\w*','')
|
let rev = s:sub(rev,'\w*','')
|
||||||
elseif s:cpath(self.spec()[0 : len(self.repo().dir())]) ==#
|
elseif s:cpath(self.spec()[0 : len(self.repo().dir())]) ==#
|
||||||
|
@ -536,8 +733,15 @@ function! s:buffer_path(...) dict abort
|
||||||
return s:sub(s:sub(rev,'.\zs/$',''),'^/',a:0 ? a:1 : '')
|
return s:sub(s:sub(rev,'.\zs/$',''),'^/',a:0 ? a:1 : '')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:buffer_path(...) dict abort
|
||||||
|
if a:0
|
||||||
|
return self.relative(a:1)
|
||||||
|
endif
|
||||||
|
return self.relative()
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:buffer_rev() dict abort
|
function! s:buffer_rev() dict abort
|
||||||
let rev = matchstr(self.spec(),'^fugitive://.\{-\}//\zs.*')
|
let rev = matchstr(self.spec(),'^fugitive:\%(//\)\=.\{-\}\%(//\|::\)\zs.*')
|
||||||
if rev =~ '^\x/'
|
if rev =~ '^\x/'
|
||||||
return ':'.rev[0].':'.rev[2:-1]
|
return ':'.rev[0].':'.rev[2:-1]
|
||||||
elseif rev =~ '.'
|
elseif rev =~ '.'
|
||||||
|
@ -547,12 +751,12 @@ function! s:buffer_rev() dict abort
|
||||||
elseif self.spec() =~ '\.git/refs/\|\.git/.*HEAD$'
|
elseif self.spec() =~ '\.git/refs/\|\.git/.*HEAD$'
|
||||||
return self.spec()[strlen(self.repo().dir())+1 : -1]
|
return self.spec()[strlen(self.repo().dir())+1 : -1]
|
||||||
else
|
else
|
||||||
return self.path('/')
|
return self.relative('/')
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:buffer_sha1() dict abort
|
function! s:buffer_sha1() dict abort
|
||||||
if self.spec() =~ '^fugitive://' || self.spec() =~ '\.git/refs/\|\.git/.*HEAD$'
|
if self.spec() =~? '^fugitive:' || self.spec() =~ '\.git/refs/\|\.git/.*HEAD$'
|
||||||
return self.repo().rev_parse(self.rev())
|
return self.repo().rev_parse(self.rev())
|
||||||
else
|
else
|
||||||
return ''
|
return ''
|
||||||
|
@ -561,21 +765,21 @@ endfunction
|
||||||
|
|
||||||
function! s:buffer_expand(rev) dict abort
|
function! s:buffer_expand(rev) dict abort
|
||||||
if a:rev =~# '^:[0-3]$'
|
if a:rev =~# '^:[0-3]$'
|
||||||
let file = a:rev.self.path(':')
|
let file = a:rev.self.relative(':')
|
||||||
elseif a:rev =~# '^[-:]/$'
|
elseif a:rev =~# '^[-:]/$'
|
||||||
let file = '/'.self.path()
|
let file = '/'.self.relative()
|
||||||
elseif a:rev =~# '^-'
|
elseif a:rev =~# '^-'
|
||||||
let file = 'HEAD^{}'.a:rev[1:-1].self.path(':')
|
let file = 'HEAD^{}'.a:rev[1:-1].self.relative(':')
|
||||||
elseif a:rev =~# '^@{'
|
elseif a:rev =~# '^@{'
|
||||||
let file = 'HEAD'.a:rev.self.path(':')
|
let file = 'HEAD'.a:rev.self.relative(':')
|
||||||
elseif a:rev =~# '^[~^]'
|
elseif a:rev =~# '^[~^]'
|
||||||
let commit = s:sub(self.commit(),'^\d=$','HEAD')
|
let commit = s:sub(self.commit(),'^\d=$','HEAD')
|
||||||
let file = commit.a:rev.self.path(':')
|
let file = commit.a:rev.self.relative(':')
|
||||||
else
|
else
|
||||||
let file = a:rev
|
let file = a:rev
|
||||||
endif
|
endif
|
||||||
return s:sub(substitute(file,
|
return s:sub(substitute(file,
|
||||||
\ '%$\|\\\([[:punct:]]\)','\=len(submatch(1)) ? submatch(1) : self.path()','g'),
|
\ '%$\|\\\([[:punct:]]\)','\=len(submatch(1)) ? submatch(1) : self.relative()','g'),
|
||||||
\ '\.\@<=/$','')
|
\ '\.\@<=/$','')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@ -613,7 +817,7 @@ function! s:buffer_up(...) dict abort
|
||||||
return rev
|
return rev
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
call s:add_methods('buffer',['getvar','setvar','getline','repo','type','spec','name','commit','path','rev','sha1','expand','containing_commit','up'])
|
call s:add_methods('buffer',['getvar','setvar','getline','repo','type','spec','name','commit','path','relative','rev','sha1','expand','containing_commit','up'])
|
||||||
|
|
||||||
" Section: Git
|
" Section: Git
|
||||||
|
|
||||||
|
@ -992,7 +1196,11 @@ function! s:Commit(mods, args, ...) abort
|
||||||
let outfile = tempname()
|
let outfile = tempname()
|
||||||
let errorfile = tempname()
|
let errorfile = tempname()
|
||||||
try
|
try
|
||||||
|
let guioptions = &guioptions
|
||||||
try
|
try
|
||||||
|
if &guioptions =~# '!'
|
||||||
|
setglobal guioptions-=!
|
||||||
|
endif
|
||||||
execute cd s:fnameescape(repo.tree())
|
execute cd s:fnameescape(repo.tree())
|
||||||
if s:winshell()
|
if s:winshell()
|
||||||
let command = ''
|
let command = ''
|
||||||
|
@ -1012,6 +1220,7 @@ function! s:Commit(mods, args, ...) abort
|
||||||
let error = v:shell_error
|
let error = v:shell_error
|
||||||
finally
|
finally
|
||||||
execute cd s:fnameescape(dir)
|
execute cd s:fnameescape(dir)
|
||||||
|
let &guioptions = guioptions
|
||||||
endtry
|
endtry
|
||||||
if !has('gui_running')
|
if !has('gui_running')
|
||||||
redraw!
|
redraw!
|
||||||
|
@ -1263,7 +1472,7 @@ function! s:Grep(cmd,bang,arg) abort
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:Log(cmd, line1, line2, ...) abort
|
function! s:Log(cmd, line1, line2, ...) abort
|
||||||
let path = s:buffer().path('/')
|
let path = s:buffer().relative('/')
|
||||||
if path =~# '^/\.git\%(/\|$\)' || index(a:000,'--') != -1
|
if path =~# '^/\.git\%(/\|$\)' || index(a:000,'--') != -1
|
||||||
let path = ''
|
let path = ''
|
||||||
endif
|
endif
|
||||||
|
@ -1272,11 +1481,11 @@ function! s:Log(cmd, line1, line2, ...) abort
|
||||||
if empty(filter(a:000[0 : index(a:000,'--')],'v:val !~# "^-"'))
|
if empty(filter(a:000[0 : index(a:000,'--')],'v:val !~# "^-"'))
|
||||||
if s:buffer().commit() =~# '\x\{40\}'
|
if s:buffer().commit() =~# '\x\{40\}'
|
||||||
let cmd += [s:buffer().commit()]
|
let cmd += [s:buffer().commit()]
|
||||||
elseif s:buffer().path() =~# '^\.git/refs/\|^\.git/.*HEAD$'
|
elseif s:buffer().relative() =~# '^\.git/refs/\|^\.git/.*HEAD$'
|
||||||
let cmd += [s:buffer().path()[5:-1]]
|
let cmd += [s:buffer().relative()[5:-1]]
|
||||||
endif
|
endif
|
||||||
end
|
end
|
||||||
let cmd += map(copy(a:000),'s:sub(v:val,"^\\%(%(:\\w)*)","\\=fnamemodify(s:buffer().path(),submatch(1))")')
|
let cmd += map(copy(a:000),'s:sub(v:val,"^\\%(%(:\\w)*)","\\=fnamemodify(s:buffer().relative(),submatch(1))")')
|
||||||
if path =~# '/.'
|
if path =~# '/.'
|
||||||
if a:line2
|
if a:line2
|
||||||
let cmd += ['-L', a:line1 . ',' . a:line2 . ':' . path[1:-1]]
|
let cmd += ['-L', a:line1 . ',' . a:line2 . ':' . path[1:-1]]
|
||||||
|
@ -1380,10 +1589,10 @@ function! s:Edit(cmd, bang, mods, ...) abort
|
||||||
let file = buffer.expand(join(a:000, ' '))
|
let file = buffer.expand(join(a:000, ' '))
|
||||||
elseif expand('%') ==# ''
|
elseif expand('%') ==# ''
|
||||||
let file = ':'
|
let file = ':'
|
||||||
elseif buffer.commit() ==# '' && buffer.path('/') !~# '^/.git\>'
|
elseif buffer.commit() ==# '' && buffer.relative('/') !~# '^/.git\>'
|
||||||
let file = buffer.path(':')
|
let file = buffer.relative(':')
|
||||||
else
|
else
|
||||||
let file = buffer.path('/')
|
let file = buffer.relative('/')
|
||||||
endif
|
endif
|
||||||
try
|
try
|
||||||
let file = buffer.repo().translate(file)
|
let file = buffer.repo().translate(file)
|
||||||
|
@ -1433,7 +1642,7 @@ function! s:Write(force,...) abort
|
||||||
return 'wq'
|
return 'wq'
|
||||||
elseif s:buffer().type() == 'index'
|
elseif s:buffer().type() == 'index'
|
||||||
return 'Gcommit'
|
return 'Gcommit'
|
||||||
elseif s:buffer().path() ==# '' && getline(4) =~# '^+++ '
|
elseif s:buffer().relative() ==# '' && getline(4) =~# '^+++ '
|
||||||
let filename = getline(4)[6:-1]
|
let filename = getline(4)[6:-1]
|
||||||
setlocal buftype=
|
setlocal buftype=
|
||||||
silent write
|
silent write
|
||||||
|
@ -1454,14 +1663,14 @@ function! s:Write(force,...) abort
|
||||||
endif
|
endif
|
||||||
let mytab = tabpagenr()
|
let mytab = tabpagenr()
|
||||||
let mybufnr = bufnr('')
|
let mybufnr = bufnr('')
|
||||||
let path = a:0 ? join(a:000, ' ') : s:buffer().path()
|
let path = a:0 ? join(a:000, ' ') : s:buffer().relative()
|
||||||
if empty(path)
|
if empty(path)
|
||||||
return 'echoerr '.string('fugitive: cannot determine file path')
|
return 'echoerr '.string('fugitive: cannot determine file path')
|
||||||
endif
|
endif
|
||||||
if path =~# '^:\d\>'
|
if path =~# '^:\d\>'
|
||||||
return 'write'.(a:force ? '! ' : ' ').s:fnameescape(s:repo().translate(s:buffer().expand(path)))
|
return 'write'.(a:force ? '! ' : ' ').s:fnameescape(s:repo().translate(s:buffer().expand(path)))
|
||||||
endif
|
endif
|
||||||
let always_permitted = (s:buffer().path() ==# path && s:buffer().commit() =~# '^0\=$')
|
let always_permitted = (s:buffer().relative() ==# path && s:buffer().commit() =~# '^0\=$')
|
||||||
if !always_permitted && !a:force && s:repo().git_chomp_in_tree('diff','--name-status','HEAD','--',path) . s:repo().git_chomp_in_tree('ls-files','--others','--',path) !=# ''
|
if !always_permitted && !a:force && s:repo().git_chomp_in_tree('diff','--name-status','HEAD','--',path) . s:repo().git_chomp_in_tree('ls-files','--others','--',path) !=# ''
|
||||||
let v:errmsg = 'fugitive: file has uncommitted changes (use ! to override)'
|
let v:errmsg = 'fugitive: file has uncommitted changes (use ! to override)'
|
||||||
return 'echoerr v:errmsg'
|
return 'echoerr v:errmsg'
|
||||||
|
@ -1518,7 +1727,7 @@ function! s:Write(force,...) abort
|
||||||
let v:errmsg = 'fugitive: '.error
|
let v:errmsg = 'fugitive: '.error
|
||||||
return 'echoerr v:errmsg'
|
return 'echoerr v:errmsg'
|
||||||
endif
|
endif
|
||||||
if s:buffer().path() ==# path && s:buffer().commit() =~# '^\d$'
|
if s:buffer().relative() ==# path && s:buffer().commit() =~# '^\d$'
|
||||||
set nomodified
|
set nomodified
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -1713,7 +1922,7 @@ endfunction
|
||||||
function! s:buffer_compare_age(commit) dict abort
|
function! s:buffer_compare_age(commit) dict abort
|
||||||
let scores = {':0': 1, ':1': 2, ':2': 3, ':': 4, ':3': 5}
|
let scores = {':0': 1, ':1': 2, ':2': 3, ':': 4, ':3': 5}
|
||||||
let my_score = get(scores, ':'.self.commit(), 0)
|
let my_score = get(scores, ':'.self.commit(), 0)
|
||||||
let their_score = get(scores,':'.a:commit,0)
|
let their_score = get(scores, ':'.substitute(a:commit, '^:', '', ''), 0)
|
||||||
if my_score || their_score
|
if my_score || their_score
|
||||||
return my_score < their_score ? -1 : my_score != their_score
|
return my_score < their_score ? -1 : my_score != their_score
|
||||||
elseif self.commit() ==# a:commit
|
elseif self.commit() ==# a:commit
|
||||||
|
@ -1741,7 +1950,7 @@ function! s:Diff(vert,keepfocus,...) abort
|
||||||
let vert = empty(a:vert) ? s:diff_modifier(2) : a:vert
|
let vert = empty(a:vert) ? s:diff_modifier(2) : a:vert
|
||||||
if exists(':DiffGitCached')
|
if exists(':DiffGitCached')
|
||||||
return 'DiffGitCached'
|
return 'DiffGitCached'
|
||||||
elseif (empty(args) || args[0] == ':') && s:buffer().commit() =~# '^[0-1]\=$' && s:repo().git_chomp_in_tree('ls-files', '--unmerged', '--', s:buffer().path()) !=# ''
|
elseif (empty(args) || args[0] ==# ':') && s:buffer().commit() =~# '^[0-1]\=$' && s:repo().git_chomp_in_tree('ls-files', '--unmerged', '--', s:buffer().relative()) !=# ''
|
||||||
let vert = empty(a:vert) ? s:diff_modifier(3) : a:vert
|
let vert = empty(a:vert) ? s:diff_modifier(3) : a:vert
|
||||||
let nr = bufnr('')
|
let nr = bufnr('')
|
||||||
execute 'leftabove '.vert.'split' s:fnameescape(fugitive#repo().translate(s:buffer().expand(':2')))
|
execute 'leftabove '.vert.'split' s:fnameescape(fugitive#repo().translate(s:buffer().expand(':2')))
|
||||||
|
@ -1763,12 +1972,12 @@ function! s:Diff(vert,keepfocus,...) abort
|
||||||
if arg ==# ''
|
if arg ==# ''
|
||||||
return post
|
return post
|
||||||
elseif arg ==# '/'
|
elseif arg ==# '/'
|
||||||
let file = s:buffer().path('/')
|
let file = s:buffer().relative('/')
|
||||||
elseif arg ==# ':'
|
elseif arg ==# ':'
|
||||||
let file = s:buffer().path(':0:')
|
let file = s:buffer().relative(':0:')
|
||||||
elseif arg =~# '^:/.'
|
elseif arg =~# '^:/.'
|
||||||
try
|
try
|
||||||
let file = s:repo().rev_parse(arg).s:buffer().path(':')
|
let file = s:repo().rev_parse(arg).s:buffer().relative(':')
|
||||||
catch /^fugitive:/
|
catch /^fugitive:/
|
||||||
return 'echoerr v:errmsg'
|
return 'echoerr v:errmsg'
|
||||||
endtry
|
endtry
|
||||||
|
@ -1776,20 +1985,19 @@ function! s:Diff(vert,keepfocus,...) abort
|
||||||
let file = s:buffer().expand(arg)
|
let file = s:buffer().expand(arg)
|
||||||
endif
|
endif
|
||||||
if file !~# ':' && file !~# '^/' && s:repo().git_chomp('cat-file','-t',file) =~# '^\%(tag\|commit\)$'
|
if file !~# ':' && file !~# '^/' && s:repo().git_chomp('cat-file','-t',file) =~# '^\%(tag\|commit\)$'
|
||||||
let file = file.s:buffer().path(':')
|
let file = file.s:buffer().relative(':')
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
let file = s:buffer().path(s:buffer().commit() == '' ? ':0:' : '/')
|
let file = s:buffer().relative(empty(s:buffer().commit()) ? ':0:' : '/')
|
||||||
endif
|
endif
|
||||||
try
|
try
|
||||||
let spec = s:repo().translate(file)
|
let spec = s:repo().translate(file)
|
||||||
let commit = matchstr(spec,'\C[^:/]//\zs\x\+')
|
|
||||||
let restore = s:diff_restore()
|
let restore = s:diff_restore()
|
||||||
if exists('+cursorbind')
|
if exists('+cursorbind')
|
||||||
setlocal cursorbind
|
setlocal cursorbind
|
||||||
endif
|
endif
|
||||||
let w:fugitive_diff_restore = restore
|
let w:fugitive_diff_restore = restore
|
||||||
if s:buffer().compare_age(commit) < 0
|
if s:buffer().compare_age(s:DirCommitFile(spec)[1]) < 0
|
||||||
execute 'rightbelow '.vert.'diffsplit '.s:fnameescape(spec)
|
execute 'rightbelow '.vert.'diffsplit '.s:fnameescape(spec)
|
||||||
else
|
else
|
||||||
execute 'leftabove '.vert.'diffsplit '.s:fnameescape(spec)
|
execute 'leftabove '.vert.'diffsplit '.s:fnameescape(spec)
|
||||||
|
@ -1816,7 +2024,7 @@ function! s:Move(force, rename, destination) abort
|
||||||
if a:destination =~# '^/'
|
if a:destination =~# '^/'
|
||||||
let destination = a:destination[1:-1]
|
let destination = a:destination[1:-1]
|
||||||
elseif a:rename
|
elseif a:rename
|
||||||
let destination = fnamemodify(s:buffer().path(), ':h') . '/' . a:destination
|
let destination = fnamemodify(s:buffer().relative(), ':h') . '/' . a:destination
|
||||||
else
|
else
|
||||||
let destination = s:shellslash(fnamemodify(s:sub(a:destination,'[%#]%(:\w)*','\=expand(submatch(0))'),':p'))
|
let destination = s:shellslash(fnamemodify(s:sub(a:destination,'[%#]%(:\w)*','\=expand(submatch(0))'),':p'))
|
||||||
if destination[0:strlen(s:repo().tree())] ==# s:repo().tree('')
|
if destination[0:strlen(s:repo().tree())] ==# s:repo().tree('')
|
||||||
|
@ -1827,7 +2035,7 @@ function! s:Move(force, rename, destination) abort
|
||||||
" Work around Vim parser idiosyncrasy
|
" Work around Vim parser idiosyncrasy
|
||||||
let discarded = s:buffer().setvar('&swapfile',0)
|
let discarded = s:buffer().setvar('&swapfile',0)
|
||||||
endif
|
endif
|
||||||
let message = call(s:repo().git_chomp_in_tree,['mv']+(a:force ? ['-f'] : [])+['--', s:buffer().path(), destination], s:repo())
|
let message = call(s:repo().git_chomp_in_tree,['mv']+(a:force ? ['-f'] : [])+['--', s:buffer().relative(), destination], s:repo())
|
||||||
if v:shell_error
|
if v:shell_error
|
||||||
let v:errmsg = 'fugitive: '.message
|
let v:errmsg = 'fugitive: '.message
|
||||||
return 'echoerr v:errmsg'
|
return 'echoerr v:errmsg'
|
||||||
|
@ -1862,7 +2070,7 @@ function! s:RenameComplete(A,L,P) abort
|
||||||
if a:A =~# '^/'
|
if a:A =~# '^/'
|
||||||
return s:repo().superglob(a:A)
|
return s:repo().superglob(a:A)
|
||||||
else
|
else
|
||||||
let pre = '/'. fnamemodify(s:buffer().path(), ':h') . '/'
|
let pre = '/'. fnamemodify(s:buffer().relative(), ':h') . '/'
|
||||||
return map(s:repo().superglob(pre.a:A), 'strpart(v:val, len(pre))')
|
return map(s:repo().superglob(pre.a:A), 'strpart(v:val, len(pre))')
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -1879,7 +2087,7 @@ function! s:Remove(after, force) abort
|
||||||
if a:force
|
if a:force
|
||||||
let cmd += ['--force']
|
let cmd += ['--force']
|
||||||
endif
|
endif
|
||||||
let message = call(s:repo().git_chomp_in_tree,cmd+['--',s:buffer().path()],s:repo())
|
let message = call(s:repo().git_chomp_in_tree,cmd+['--',s:buffer().relative()],s:repo())
|
||||||
if v:shell_error
|
if v:shell_error
|
||||||
let v:errmsg = 'fugitive: '.s:sub(message,'error:.*\zs\n\(.*-f.*',' (add ! to force)')
|
let v:errmsg = 'fugitive: '.s:sub(message,'error:.*\zs\n\(.*-f.*',' (add ! to force)')
|
||||||
return 'echoerr '.string(v:errmsg)
|
return 'echoerr '.string(v:errmsg)
|
||||||
|
@ -1903,7 +2111,6 @@ augroup END
|
||||||
|
|
||||||
augroup fugitive_blame
|
augroup fugitive_blame
|
||||||
autocmd!
|
autocmd!
|
||||||
autocmd BufReadPost *.fugitiveblame setfiletype fugitiveblame
|
|
||||||
autocmd FileType fugitiveblame setlocal nomodeline | if exists('b:git_dir') | let &l:keywordprg = s:repo().keywordprg() | endif
|
autocmd FileType fugitiveblame setlocal nomodeline | if exists('b:git_dir') | let &l:keywordprg = s:repo().keywordprg() | endif
|
||||||
autocmd Syntax fugitiveblame call s:BlameSyntax()
|
autocmd Syntax fugitiveblame call s:BlameSyntax()
|
||||||
autocmd User Fugitive if s:buffer().type('file', 'blob') | exe "command! -buffer -bar -bang -range=0 -nargs=* Gblame :execute s:Blame(<bang>0,<line1>,<line2>,<count>,[<f-args>])" | endif
|
autocmd User Fugitive if s:buffer().type('file', 'blob') | exe "command! -buffer -bar -bang -range=0 -nargs=* Gblame :execute s:Blame(<bang>0,<line1>,<line2>,<count>,[<f-args>])" | endif
|
||||||
|
@ -1926,7 +2133,7 @@ function! s:Blame(bang,line1,line2,count,args) abort
|
||||||
return 'bdelete'
|
return 'bdelete'
|
||||||
endif
|
endif
|
||||||
try
|
try
|
||||||
if s:buffer().path() == ''
|
if empty(s:buffer().relative())
|
||||||
call s:throw('file or blob required')
|
call s:throw('file or blob required')
|
||||||
endif
|
endif
|
||||||
if filter(copy(a:args),'v:val !~# "^\\%(--root\|--show-name\\|-\\=\\%([ltfnsew]\\|[MC]\\d*\\)\\+\\)$"') != []
|
if filter(copy(a:args),'v:val !~# "^\\%(--root\|--show-name\\|-\\=\\%([ltfnsew]\\|[MC]\\d*\\)\\+\\)$"') != []
|
||||||
|
@ -1939,7 +2146,7 @@ function! s:Blame(bang,line1,line2,count,args) abort
|
||||||
else
|
else
|
||||||
let cmd += ['--contents', '-']
|
let cmd += ['--contents', '-']
|
||||||
endif
|
endif
|
||||||
let cmd += ['--', s:buffer().path()]
|
let cmd += ['--', s:buffer().relative()]
|
||||||
let basecmd = escape(call(s:repo().git_command,cmd,s:repo()),'!%#')
|
let basecmd = escape(call(s:repo().git_command,cmd,s:repo()),'!%#')
|
||||||
try
|
try
|
||||||
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
|
let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
|
||||||
|
@ -2048,7 +2255,7 @@ function! s:BlameCommit(cmd) abort
|
||||||
let lnum = matchstr(getline('.'),' \zs\d\+\ze\s\+[([:digit:]]')
|
let lnum = matchstr(getline('.'),' \zs\d\+\ze\s\+[([:digit:]]')
|
||||||
let path = matchstr(getline('.'),'^\^\=\x\+\s\+\zs.\{-\}\ze\s*\d\+ ')
|
let path = matchstr(getline('.'),'^\^\=\x\+\s\+\zs.\{-\}\ze\s*\d\+ ')
|
||||||
if path ==# ''
|
if path ==# ''
|
||||||
let path = s:buffer(b:fugitive_blamed_bufnr).path()
|
let path = s:buffer(b:fugitive_blamed_bufnr).relative()
|
||||||
endif
|
endif
|
||||||
execute cmd
|
execute cmd
|
||||||
if search('^diff .* b/\M'.escape(path,'\').'$','W')
|
if search('^diff .* b/\M'.escape(path,'\').'$','W')
|
||||||
|
@ -2089,7 +2296,7 @@ function! s:BlameJump(suffix) abort
|
||||||
let lnum = matchstr(getline('.'),' \zs\d\+\ze\s\+[([:digit:]]')
|
let lnum = matchstr(getline('.'),' \zs\d\+\ze\s\+[([:digit:]]')
|
||||||
let path = matchstr(getline('.'),'^\^\=\x\+\s\+\zs.\{-\}\ze\s*\d\+ ')
|
let path = matchstr(getline('.'),'^\^\=\x\+\s\+\zs.\{-\}\ze\s*\d\+ ')
|
||||||
if path ==# ''
|
if path ==# ''
|
||||||
let path = s:buffer(b:fugitive_blamed_bufnr).path()
|
let path = s:buffer(b:fugitive_blamed_bufnr).relative()
|
||||||
endif
|
endif
|
||||||
let args = b:fugitive_blame_arguments
|
let args = b:fugitive_blame_arguments
|
||||||
let offset = line('.') - line('w0')
|
let offset = line('.') - line('w0')
|
||||||
|
@ -2197,15 +2404,20 @@ function! s:Browse(bang,line1,count,...) abort
|
||||||
if rev ==# ''
|
if rev ==# ''
|
||||||
let expanded = s:buffer().rev()
|
let expanded = s:buffer().rev()
|
||||||
elseif rev ==# ':'
|
elseif rev ==# ':'
|
||||||
let expanded = s:buffer().path('/')
|
let expanded = s:buffer().relative('/')
|
||||||
else
|
else
|
||||||
let expanded = s:buffer().expand(rev)
|
let expanded = s:buffer().expand(rev)
|
||||||
endif
|
endif
|
||||||
|
if filereadable(s:repo().tree('refs/tags/' . expanded))
|
||||||
|
let expanded = 'refs/tags/' . expanded
|
||||||
|
endif
|
||||||
let full = s:repo().translate(expanded)
|
let full = s:repo().translate(expanded)
|
||||||
let commit = ''
|
let commit = ''
|
||||||
if full =~# '^fugitive://'
|
if full =~? '^fugitive:'
|
||||||
let commit = matchstr(full,'://.*//\zs\w\w\+')
|
let [dir, commit, path] = s:DirCommitFile(full)
|
||||||
let path = matchstr(full,'://.*//\w\+\zs/.*')
|
if commit =~# '^:\=\d$'
|
||||||
|
let commit = ''
|
||||||
|
endif
|
||||||
if commit =~ '..'
|
if commit =~ '..'
|
||||||
let type = s:repo().git_chomp('cat-file','-t',commit.s:sub(path,'^/',':'))
|
let type = s:repo().git_chomp('cat-file','-t',commit.s:sub(path,'^/',':'))
|
||||||
let branch = matchstr(expanded, '^[^:]*')
|
let branch = matchstr(expanded, '^[^:]*')
|
||||||
|
@ -2510,15 +2722,15 @@ function! fugitive#BufReadStatus() abort
|
||||||
if &bufhidden ==# ''
|
if &bufhidden ==# ''
|
||||||
setlocal bufhidden=delete
|
setlocal bufhidden=delete
|
||||||
endif
|
endif
|
||||||
call s:JumpInit()
|
call fugitive#MapJumps()
|
||||||
nunmap <buffer> P
|
nunmap <buffer> P
|
||||||
nunmap <buffer> ~
|
nunmap <buffer> ~
|
||||||
nnoremap <buffer> <silent> <C-N> :<C-U>execute <SID>StageNext(v:count1)<CR>
|
nnoremap <buffer> <silent> <C-N> :<C-U>execute <SID>StageNext(v:count1)<CR>
|
||||||
nnoremap <buffer> <silent> <C-P> :<C-U>execute <SID>StagePrevious(v:count1)<CR>
|
nnoremap <buffer> <silent> <C-P> :<C-U>execute <SID>StagePrevious(v:count1)<CR>
|
||||||
nnoremap <buffer> <silent> - :<C-U>silent execute <SID>StageToggle(line('.'),line('.')+v:count1-1)<CR>
|
nnoremap <buffer> <silent> - :<C-U>silent execute <SID>StageToggle(line('.'),line('.')+v:count1-1)<CR>
|
||||||
xnoremap <buffer> <silent> - :<C-U>silent execute <SID>StageToggle(line("'<"),line("'>"))<CR>
|
xnoremap <buffer> <silent> - :<C-U>silent execute <SID>StageToggle(line("'<"),line("'>"))<CR>
|
||||||
nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += 1<Bar>exe <SID>BufReadIndex()<CR>
|
nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += 1<Bar>exe fugitive#BufReadIndex()<CR>
|
||||||
nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= 1<Bar>exe <SID>BufReadIndex()<CR>
|
nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= 1<Bar>exe fugitive#BufReadIndex()<CR>
|
||||||
nnoremap <buffer> <silent> C :<C-U>Gcommit<CR>:echohl WarningMsg<Bar>echo ':Gstatus C is deprecated in favor of cc'<Bar>echohl NONE<CR>
|
nnoremap <buffer> <silent> C :<C-U>Gcommit<CR>:echohl WarningMsg<Bar>echo ':Gstatus C is deprecated in favor of cc'<Bar>echohl NONE<CR>
|
||||||
nnoremap <buffer> <silent> cA :<C-U>Gcommit --amend --reuse-message=HEAD<CR>:echohl WarningMsg<Bar>echo ':Gstatus cA is deprecated in favor of ce'<CR>
|
nnoremap <buffer> <silent> cA :<C-U>Gcommit --amend --reuse-message=HEAD<CR>:echohl WarningMsg<Bar>echo ':Gstatus cA is deprecated in favor of ce'<CR>
|
||||||
nnoremap <buffer> <silent> ca :<C-U>Gcommit --amend<CR>
|
nnoremap <buffer> <silent> ca :<C-U>Gcommit --amend<CR>
|
||||||
|
@ -2550,8 +2762,9 @@ endfunction
|
||||||
|
|
||||||
function! fugitive#FileRead() abort
|
function! fugitive#FileRead() abort
|
||||||
try
|
try
|
||||||
let repo = s:repo(FugitiveExtractGitDir(expand('<amatch>')))
|
let [dir, commit, file] = s:DirCommitFile(expand('<amatch>'))
|
||||||
let path = s:sub(s:sub(matchstr(expand('<amatch>'),'fugitive://.\{-\}//\zs.*'),'/',':'),'^\d:',':&')
|
let repo = s:repo(dir)
|
||||||
|
let path = commit . substitute(file, '^/', ':', '')
|
||||||
let hash = repo.rev_parse(path)
|
let hash = repo.rev_parse(path)
|
||||||
if path =~ '^:'
|
if path =~ '^:'
|
||||||
let type = 'blob'
|
let type = 'blob'
|
||||||
|
@ -2589,15 +2802,15 @@ endfunction
|
||||||
function! fugitive#BufWriteIndex() abort
|
function! fugitive#BufWriteIndex() abort
|
||||||
let tmp = tempname()
|
let tmp = tempname()
|
||||||
try
|
try
|
||||||
let path = matchstr(expand('<amatch>'),'//\d/\zs.*')
|
let [dir, commit, file] = s:DirCommitFile(expand('<amatch>'))
|
||||||
let stage = matchstr(expand('<amatch>'),'//\zs\d')
|
let path = file[1:-1]
|
||||||
silent execute 'write !'.s:repo().git_command('hash-object','-w','--stdin').' > '.tmp
|
silent execute 'write !'.s:repo().git_command('hash-object','-w','--stdin').' > '.tmp
|
||||||
let sha1 = readfile(tmp)[0]
|
let sha1 = readfile(tmp)[0]
|
||||||
let old_mode = matchstr(s:repo().git_chomp('ls-files','--stage',path),'^\d\+')
|
let old_mode = matchstr(s:repo().git_chomp('ls-files','--stage',path),'^\d\+')
|
||||||
if old_mode == ''
|
if old_mode == ''
|
||||||
let old_mode = executable(s:repo().tree(path)) ? '100755' : '100644'
|
let old_mode = executable(s:repo().tree(path)) ? '100755' : '100644'
|
||||||
endif
|
endif
|
||||||
let info = old_mode.' '.sha1.' '.stage."\t".path
|
let info = old_mode.' '.sha1.' '.commit[-1:-1]."\t".path
|
||||||
call writefile([info],tmp)
|
call writefile([info],tmp)
|
||||||
if s:winshell()
|
if s:winshell()
|
||||||
let error = system('type '.s:gsub(tmp,'/','\\').'|'.s:repo().git_command('update-index','--index-info'))
|
let error = system('type '.s:gsub(tmp,'/','\\').'|'.s:repo().git_command('update-index','--index-info'))
|
||||||
|
@ -2688,10 +2901,10 @@ function! fugitive#BufReadObject() abort
|
||||||
endif
|
endif
|
||||||
if b:fugitive_type !=# 'blob'
|
if b:fugitive_type !=# 'blob'
|
||||||
setlocal filetype=git foldmethod=syntax
|
setlocal filetype=git foldmethod=syntax
|
||||||
nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += v:count1<Bar>exe <SID>BufReadObject()<CR>
|
nnoremap <buffer> <silent> a :<C-U>let b:fugitive_display_format += v:count1<Bar>exe fugitive#BufReadObject()<CR>
|
||||||
nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= v:count1<Bar>exe <SID>BufReadObject()<CR>
|
nnoremap <buffer> <silent> i :<C-U>let b:fugitive_display_format -= v:count1<Bar>exe fugitive#BufReadObject()<CR>
|
||||||
else
|
else
|
||||||
call s:JumpInit()
|
call fugitive#MapJumps()
|
||||||
endif
|
endif
|
||||||
endtry
|
endtry
|
||||||
|
|
||||||
|
@ -2705,14 +2918,6 @@ endfunction
|
||||||
|
|
||||||
augroup fugitive_files
|
augroup fugitive_files
|
||||||
autocmd!
|
autocmd!
|
||||||
autocmd FileType git
|
|
||||||
\ if exists('b:git_dir') |
|
|
||||||
\ call s:JumpInit() |
|
|
||||||
\ endif
|
|
||||||
autocmd FileType git,gitcommit,gitrebase
|
|
||||||
\ if exists('b:git_dir') |
|
|
||||||
\ call s:GFInit() |
|
|
||||||
\ endif
|
|
||||||
augroup END
|
augroup END
|
||||||
|
|
||||||
" Section: Temp files
|
" Section: Temp files
|
||||||
|
@ -2737,7 +2942,7 @@ augroup END
|
||||||
" Section: Go to file
|
" Section: Go to file
|
||||||
|
|
||||||
nnoremap <SID>: :<C-U><C-R>=v:count ? v:count : ''<CR>
|
nnoremap <SID>: :<C-U><C-R>=v:count ? v:count : ''<CR>
|
||||||
function! s:GFInit(...) abort
|
function! fugitive#MapCfile(...) abort
|
||||||
cnoremap <buffer> <expr> <Plug><cfile> fugitive#Cfile()
|
cnoremap <buffer> <expr> <Plug><cfile> fugitive#Cfile()
|
||||||
if !exists('g:fugitive_no_maps')
|
if !exists('g:fugitive_no_maps')
|
||||||
call s:map('n', 'gf', '<SID>:find <Plug><cfile><CR>', '<silent><unique>')
|
call s:map('n', 'gf', '<SID>:find <Plug><cfile><CR>', '<silent><unique>')
|
||||||
|
@ -2748,15 +2953,15 @@ function! s:GFInit(...) abort
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:JumpInit(...) abort
|
function! fugitive#MapJumps(...) abort
|
||||||
nnoremap <buffer> <silent> <CR> :<C-U>exe <SID>GF("edit")<CR>
|
nnoremap <buffer> <silent> <CR> :<C-U>exe <SID>GF("edit")<CR>
|
||||||
if !&modifiable
|
if !&modifiable
|
||||||
nnoremap <buffer> <silent> o :<C-U>exe <SID>GF("split")<CR>
|
nnoremap <buffer> <silent> o :<C-U>exe <SID>GF("split")<CR>
|
||||||
nnoremap <buffer> <silent> S :<C-U>exe <SID>GF("vsplit")<CR>
|
nnoremap <buffer> <silent> S :<C-U>exe <SID>GF("vsplit")<CR>
|
||||||
nnoremap <buffer> <silent> O :<C-U>exe <SID>GF("tabedit")<CR>
|
nnoremap <buffer> <silent> O :<C-U>exe <SID>GF("tabedit")<CR>
|
||||||
nnoremap <buffer> <silent> - :<C-U>exe <SID>Edit('edit',0,'',<SID>buffer().up(v:count1))<Bar> if fugitive#buffer().type('tree')<Bar>call search('^'.escape(expand('#:t'),'.*[]~\').'/\=$','wc')<Bar>endif<CR>
|
nnoremap <buffer> <silent> - :<C-U>exe <SID>Edit('edit',0,'',<SID>buffer().up(v:count1))<Bar> if fugitive#buffer().type('tree')<Bar>call search('^'.escape(expand('#:t'),'.*[]~\').'/\=$','wc')<Bar>endif<CR>
|
||||||
nnoremap <buffer> <silent> P :<C-U>exe <SID>Edit('edit',0,'',<SID>buffer().commit().'^'.v:count1.<SID>buffer().path(':'))<CR>
|
nnoremap <buffer> <silent> P :<C-U>exe <SID>Edit('edit',0,'',<SID>buffer().commit().'^'.v:count1.<SID>buffer().relative(':'))<CR>
|
||||||
nnoremap <buffer> <silent> ~ :<C-U>exe <SID>Edit('edit',0,'',<SID>buffer().commit().'~'.v:count1.<SID>buffer().path(':'))<CR>
|
nnoremap <buffer> <silent> ~ :<C-U>exe <SID>Edit('edit',0,'',<SID>buffer().commit().'~'.v:count1.<SID>buffer().relative(':'))<CR>
|
||||||
nnoremap <buffer> <silent> C :<C-U>exe <SID>Edit('edit',0,'',<SID>buffer().containing_commit())<CR>
|
nnoremap <buffer> <silent> C :<C-U>exe <SID>Edit('edit',0,'',<SID>buffer().containing_commit())<CR>
|
||||||
nnoremap <buffer> <silent> cc :<C-U>exe <SID>Edit('edit',0,'',<SID>buffer().containing_commit())<CR>
|
nnoremap <buffer> <silent> cc :<C-U>exe <SID>Edit('edit',0,'',<SID>buffer().containing_commit())<CR>
|
||||||
nnoremap <buffer> <silent> co :<C-U>exe <SID>Edit('split',0,'',<SID>buffer().containing_commit())<CR>
|
nnoremap <buffer> <silent> co :<C-U>exe <SID>Edit('split',0,'',<SID>buffer().containing_commit())<CR>
|
||||||
|
@ -2778,9 +2983,9 @@ function! s:cfile() abort
|
||||||
if buffer.type('tree')
|
if buffer.type('tree')
|
||||||
let showtree = (getline(1) =~# '^tree ' && getline(2) == "")
|
let showtree = (getline(1) =~# '^tree ' && getline(2) == "")
|
||||||
if showtree && line('.') > 2
|
if showtree && line('.') > 2
|
||||||
return [buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(getline('.'),'/$','')]
|
return [buffer.commit().':'.s:buffer().relative().(buffer.relative() =~# '^$\|/$' ? '' : '/').s:sub(getline('.'),'/$','')]
|
||||||
elseif getline('.') =~# '^\d\{6\} \l\{3,8\} \x\{40\}\t'
|
elseif getline('.') =~# '^\d\{6\} \l\{3,8\} \x\{40\}\t'
|
||||||
return [buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(matchstr(getline('.'),'\t\zs.*'),'/$','')]
|
return [buffer.commit().':'.s:buffer().relative().(buffer.relative() =~# '^$\|/$' ? '' : '/').s:sub(matchstr(getline('.'),'\t\zs.*'),'/$','')]
|
||||||
endif
|
endif
|
||||||
|
|
||||||
elseif buffer.type('blob')
|
elseif buffer.type('blob')
|
||||||
|
@ -2866,11 +3071,11 @@ function! s:cfile() abort
|
||||||
elseif getline('.') =~# '^[+-]\{3\} [abciow12]\=/'
|
elseif getline('.') =~# '^[+-]\{3\} [abciow12]\=/'
|
||||||
let ref = getline('.')[4:]
|
let ref = getline('.')[4:]
|
||||||
|
|
||||||
elseif getline('.') =~# '^[+-]' && search('^@@ -\d\+,\d\+ +\d\+,','bnW')
|
elseif getline('.') =~# '^[+-]' && search('^@@ -\d\+\%(,\d\+\)\= +\d\+','bnW')
|
||||||
let type = getline('.')[0]
|
let type = getline('.')[0]
|
||||||
let lnum = line('.') - 1
|
let lnum = line('.') - 1
|
||||||
let offset = 0
|
let offset = 0
|
||||||
while getline(lnum) !~# '^@@ -\d\+,\d\+ +\d\+,'
|
while getline(lnum) !~# '^@@ -\d\+\%(,\d\+\)\= +\d\+'
|
||||||
if getline(lnum) =~# '^[ '.type.']'
|
if getline(lnum) =~# '^[ '.type.']'
|
||||||
let offset += 1
|
let offset += 1
|
||||||
endif
|
endif
|
||||||
|
@ -2885,7 +3090,7 @@ function! s:cfile() abort
|
||||||
elseif getline('.') =~# '^rename to '
|
elseif getline('.') =~# '^rename to '
|
||||||
let ref = 'b/'.getline('.')[10:]
|
let ref = 'b/'.getline('.')[10:]
|
||||||
|
|
||||||
elseif getline('.') =~# '^@@ -\d\+,\d\+ +\d\+,'
|
elseif getline('.') =~# '^@@ -\d\+\%(,\d\+\)\= +\d\+'
|
||||||
let diff = getline(search('^diff --git \%([abciow12]/.*\|/dev/null\) \%([abciow12]/.*\|/dev/null\)', 'bcnW'))
|
let diff = getline(search('^diff --git \%([abciow12]/.*\|/dev/null\) \%([abciow12]/.*\|/dev/null\)', 'bcnW'))
|
||||||
let offset = matchstr(getline('.'), '+\zs\d\+')
|
let offset = matchstr(getline('.'), '+\zs\d\+')
|
||||||
|
|
||||||
|
|
|
@ -330,13 +330,13 @@ and the work tree file for everything else. Example revisions follow.
|
||||||
|
|
||||||
Revision Meaning ~
|
Revision Meaning ~
|
||||||
HEAD .git/HEAD
|
HEAD .git/HEAD
|
||||||
master .git/refs/heads/master
|
refs/heads/x .git/refs/heads/x
|
||||||
HEAD^{} The commit referenced by HEAD
|
@ The commit referenced by @ aka HEAD
|
||||||
HEAD^ The parent of the commit referenced by HEAD
|
master^ The parent of the commit referenced by master
|
||||||
HEAD: The tree referenced by HEAD
|
master: The tree referenced by master
|
||||||
/HEAD The file named HEAD in the work tree
|
/master The file named master in the work tree
|
||||||
Makefile The file named Makefile in the work tree
|
Makefile The file named Makefile in the work tree
|
||||||
HEAD^:Makefile The file named Makefile in the parent of HEAD
|
@^:Makefile The file named Makefile in the parent of HEAD
|
||||||
:Makefile The file named Makefile in the index (writable)
|
:Makefile The file named Makefile in the index (writable)
|
||||||
- The current file in HEAD
|
- The current file in HEAD
|
||||||
^ The current file in the previous commit
|
^ The current file in the previous commit
|
||||||
|
|
1
sources_non_forked/vim-fugitive/ftdetect/fugitive.vim
Normal file
1
sources_non_forked/vim-fugitive/ftdetect/fugitive.vim
Normal file
|
@ -0,0 +1 @@
|
||||||
|
autocmd BufReadPost *.fugitiveblame setfiletype fugitiveblame
|
|
@ -59,8 +59,8 @@ endfunction
|
||||||
|
|
||||||
function! FugitiveExtractGitDir(path) abort
|
function! FugitiveExtractGitDir(path) abort
|
||||||
let path = s:shellslash(a:path)
|
let path = s:shellslash(a:path)
|
||||||
if path =~# '^fugitive://.*//'
|
if path =~# '^fugitive:'
|
||||||
return matchstr(path, '\C^fugitive://\zs.\{-\}\ze//')
|
return matchstr(path, '\C^fugitive:\%(//\)\=\zs.\{-\}\ze\%(//\|::\|$\)')
|
||||||
elseif isdirectory(path)
|
elseif isdirectory(path)
|
||||||
let path = fnamemodify(path, ':p:s?/$??')
|
let path = fnamemodify(path, ':p:s?/$??')
|
||||||
else
|
else
|
||||||
|
@ -138,6 +138,19 @@ function! FugitiveHead(...) abort
|
||||||
return fugitive#repo().head(a:0 ? a:1 : 0)
|
return fugitive#repo().head(a:0 ? a:1 : 0)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! FugitivePath(...) abort
|
||||||
|
let file = fnamemodify(a:0 ? a:1 : @%, ':p')
|
||||||
|
if file =~? '^fugitive:'
|
||||||
|
return fugitive#Path(file)
|
||||||
|
else
|
||||||
|
return file
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! FugitiveReal(...) abort
|
||||||
|
return call('FugitivePath', a:000)
|
||||||
|
endfunction
|
||||||
|
|
||||||
augroup fugitive
|
augroup fugitive
|
||||||
autocmd!
|
autocmd!
|
||||||
|
|
||||||
|
@ -147,6 +160,15 @@ augroup fugitive
|
||||||
autocmd VimEnter * if expand('<amatch>')==''|call FugitiveDetect(getcwd())|endif
|
autocmd VimEnter * if expand('<amatch>')==''|call FugitiveDetect(getcwd())|endif
|
||||||
autocmd CmdWinEnter * call FugitiveDetect(expand('#:p'))
|
autocmd CmdWinEnter * call FugitiveDetect(expand('#:p'))
|
||||||
|
|
||||||
|
autocmd FileType git
|
||||||
|
\ if exists('b:git_dir') |
|
||||||
|
\ call fugitive#MapJumps() |
|
||||||
|
\ endif
|
||||||
|
autocmd FileType git,gitcommit,gitrebase
|
||||||
|
\ if exists('b:git_dir') |
|
||||||
|
\ call fugitive#MapCfile() |
|
||||||
|
\ endif
|
||||||
|
|
||||||
autocmd BufReadCmd index{,.lock}
|
autocmd BufReadCmd index{,.lock}
|
||||||
\ if FugitiveIsGitDir(expand('<amatch>:p:h')) |
|
\ if FugitiveIsGitDir(expand('<amatch>:p:h')) |
|
||||||
\ exe fugitive#BufReadStatus() |
|
\ exe fugitive#BufReadStatus() |
|
||||||
|
|
|
@ -146,6 +146,10 @@ endfunction
|
||||||
function! gitgutter#diff#handler(bufnr, diff) abort
|
function! gitgutter#diff#handler(bufnr, diff) abort
|
||||||
call gitgutter#debug#log(a:diff)
|
call gitgutter#debug#log(a:diff)
|
||||||
|
|
||||||
|
if !bufexists(a:bufnr)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
call gitgutter#hunk#set_hunks(a:bufnr, gitgutter#diff#parse_diff(a:diff))
|
call gitgutter#hunk#set_hunks(a:bufnr, gitgutter#diff#parse_diff(a:diff))
|
||||||
let modified_lines = gitgutter#diff#process_hunks(a:bufnr, gitgutter#hunk#hunks(a:bufnr))
|
let modified_lines = gitgutter#diff#process_hunks(a:bufnr, gitgutter#hunk#hunks(a:bufnr))
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,27 @@
|
||||||
|
|
||||||
FEATURES:
|
FEATURES:
|
||||||
|
|
||||||
|
* Add **:GoIfErr** command together with the `<Plug>(go-iferr)` plug key to
|
||||||
|
create a custom mapping. This command generates an `if err != nil { return ... }`
|
||||||
|
automatically which infer the type of return values and the numbers.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
func doSomething() (string, error) {
|
||||||
|
f, err := os.Open("file")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Becomes:
|
||||||
|
|
||||||
|
```
|
||||||
|
func doSomething() (string, error) {
|
||||||
|
f, err := os.Open("file")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
* Two new text objects has been added:
|
* Two new text objects has been added:
|
||||||
* `ic` (inner comment) selects the content of the comment, excluding the start/end markers (i.e: `//`, `/*`)
|
* `ic` (inner comment) selects the content of the comment, excluding the start/end markers (i.e: `//`, `/*`)
|
||||||
* `ac` (a comment) selects the content of the whole commment block, including markers
|
* `ac` (a comment) selects the content of the whole commment block, including markers
|
||||||
|
|
|
@ -114,10 +114,16 @@ endfunction
|
||||||
|
|
||||||
" Run runs the current file (and their dependencies if any) in a new terminal.
|
" Run runs the current file (and their dependencies if any) in a new terminal.
|
||||||
function! go#cmd#RunTerm(bang, mode, files) abort
|
function! go#cmd#RunTerm(bang, mode, files) abort
|
||||||
|
let cmd = "go run "
|
||||||
|
let tags = go#config#BuildTags()
|
||||||
|
if len(tags) > 0
|
||||||
|
let cmd .= "-tags " . go#util#Shellescape(tags) . " "
|
||||||
|
endif
|
||||||
|
|
||||||
if empty(a:files)
|
if empty(a:files)
|
||||||
let cmd = "go run ". go#util#Shelljoin(go#tool#Files())
|
let cmd .= go#util#Shelljoin(go#tool#Files())
|
||||||
else
|
else
|
||||||
let cmd = "go run ". go#util#Shelljoin(map(copy(a:files), "expand(v:val)"), 1)
|
let cmd .= go#util#Shelljoin(map(copy(a:files), "expand(v:val)"), 1)
|
||||||
endif
|
endif
|
||||||
call go#term#newmode(a:bang, cmd, a:mode)
|
call go#term#newmode(a:bang, cmd, a:mode)
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -138,8 +144,14 @@ function! go#cmd#Run(bang, ...) abort
|
||||||
" anything. Once this is implemented we're going to make :GoRun async
|
" anything. Once this is implemented we're going to make :GoRun async
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
let cmd = "go run "
|
||||||
|
let tags = go#config#BuildTags()
|
||||||
|
if len(tags) > 0
|
||||||
|
let cmd .= "-tags " . go#util#Shellescape(tags) . " "
|
||||||
|
endif
|
||||||
|
|
||||||
if go#util#IsWin()
|
if go#util#IsWin()
|
||||||
exec '!go run ' . go#util#Shelljoin(go#tool#Files())
|
exec '!' . cmd . go#util#Shelljoin(go#tool#Files())
|
||||||
if v:shell_error
|
if v:shell_error
|
||||||
redraws! | echon "vim-go: [run] " | echohl ErrorMsg | echon "FAILED"| echohl None
|
redraws! | echon "vim-go: [run] " | echohl ErrorMsg | echon "FAILED"| echohl None
|
||||||
else
|
else
|
||||||
|
@ -152,9 +164,9 @@ function! go#cmd#Run(bang, ...) abort
|
||||||
" :make expands '%' and '#' wildcards, so they must also be escaped
|
" :make expands '%' and '#' wildcards, so they must also be escaped
|
||||||
let default_makeprg = &makeprg
|
let default_makeprg = &makeprg
|
||||||
if a:0 == 0
|
if a:0 == 0
|
||||||
let &makeprg = 'go run ' . go#util#Shelljoin(go#tool#Files(), 1)
|
let &makeprg = cmd . go#util#Shelljoin(go#tool#Files(), 1)
|
||||||
else
|
else
|
||||||
let &makeprg = "go run " . go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1)
|
let &makeprg = cmd . go#util#Shelljoin(map(copy(a:000), "expand(v:val)"), 1)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:listtype = go#list#Type("GoRun")
|
let l:listtype = go#list#Type("GoRun")
|
||||||
|
|
16
sources_non_forked/vim-go/autoload/go/iferr.vim
Normal file
16
sources_non_forked/vim-go/autoload/go/iferr.vim
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
function! go#iferr#Generate()
|
||||||
|
let [l:out, l:err] = go#util#Exec(['iferr',
|
||||||
|
\ '-pos=' . go#util#OffsetCursor()], go#util#GetLines())
|
||||||
|
if len(l:out) == 1
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
if getline('.') =~ '^\s*$'
|
||||||
|
silent delete _
|
||||||
|
silent normal! k
|
||||||
|
endif
|
||||||
|
let l:pos = getcurpos()
|
||||||
|
call append(l:pos[1], split(l:out, "\n"))
|
||||||
|
silent normal! j=2j
|
||||||
|
call setpos('.', l:pos)
|
||||||
|
silent normal! 4j
|
||||||
|
endfunction
|
|
@ -36,7 +36,7 @@ function! go#tool#Files(...) abort
|
||||||
endif
|
endif
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
let [l:out, l:err] = go#tool#ExecuteInDir(['go', 'list', '-f', l:combined])
|
let [l:out, l:err] = go#tool#ExecuteInDir(['go', 'list', '-tags', go#config#BuildTags(), '-f', l:combined])
|
||||||
return split(l:out, '\n')
|
return split(l:out, '\n')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ function! go#tool#Deps() abort
|
||||||
else
|
else
|
||||||
let format = "{{range $f := .Deps}}{{$f}}\n{{end}}"
|
let format = "{{range $f := .Deps}}{{$f}}\n{{end}}"
|
||||||
endif
|
endif
|
||||||
let [l:out, l:err] = go#tool#ExecuteInDir(['go', 'list', '-f', l:format])
|
let [l:out, l:err] = go#tool#ExecuteInDir(['go', 'list', '-tags', go#config#BuildTags(), '-f', l:format])
|
||||||
return split(l:out, '\n')
|
return split(l:out, '\n')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
@ -57,14 +57,14 @@ function! go#tool#Imports() abort
|
||||||
else
|
else
|
||||||
let format = "{{range $f := .Imports}}{{$f}}{{printf \"\\n\"}}{{end}}"
|
let format = "{{range $f := .Imports}}{{$f}}{{printf \"\\n\"}}{{end}}"
|
||||||
endif
|
endif
|
||||||
let [l:out, l:err] = go#tool#ExecuteInDir(['go', 'list', '-f', l:format])
|
let [l:out, l:err] = go#tool#ExecuteInDir(['go', 'list', '-tags', go#config#BuildTags(), '-f', l:format])
|
||||||
if l:err != 0
|
if l:err != 0
|
||||||
echo out
|
echo out
|
||||||
return imports
|
return imports
|
||||||
endif
|
endif
|
||||||
|
|
||||||
for package_path in split(out, '\n')
|
for package_path in split(out, '\n')
|
||||||
let [l:out, l:err] = go#tool#ExecuteInDir(['go', 'list', '-f', '{{.Name}}', l:package_path])
|
let [l:out, l:err] = go#tool#ExecuteInDir(['go', 'list', '-tags', go#config#BuildTags(), '-f', '{{.Name}}', l:package_path])
|
||||||
if l:err != 0
|
if l:err != 0
|
||||||
echo out
|
echo out
|
||||||
return imports
|
return imports
|
||||||
|
@ -88,7 +88,7 @@ function! go#tool#Info(auto) abort
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! go#tool#PackageName() abort
|
function! go#tool#PackageName() abort
|
||||||
let [l:out, l:err] = go#tool#ExecuteInDir(['go', 'list', '-f', '{{.Name}}'])
|
let [l:out, l:err] = go#tool#ExecuteInDir(['go', 'list', '-tags', go#config#BuildTags(), '-f', '{{.Name}}'])
|
||||||
if l:err != 0
|
if l:err != 0
|
||||||
return -1
|
return -1
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -853,6 +853,27 @@ CTRL-t
|
||||||
}
|
}
|
||||||
<
|
<
|
||||||
|
|
||||||
|
*:GoIfErr*
|
||||||
|
:GoIfErr
|
||||||
|
|
||||||
|
Generate if err != nil { return ... } automatically which infer the type
|
||||||
|
of return values and the numbers.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
>
|
||||||
|
func doSomething() (string, error) {
|
||||||
|
f, err := os.Open("file")
|
||||||
|
}
|
||||||
|
<
|
||||||
|
Becomes:
|
||||||
|
>
|
||||||
|
func doSomething() (string, error) {
|
||||||
|
f, err := os.Open("file")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<
|
||||||
==============================================================================
|
==============================================================================
|
||||||
MAPPINGS *go-mappings*
|
MAPPINGS *go-mappings*
|
||||||
|
|
||||||
|
@ -1065,6 +1086,10 @@ Alternates between the implementation and test code in a new vertical split
|
||||||
|
|
||||||
Calls `:GoImport` for the current package
|
Calls `:GoImport` for the current package
|
||||||
|
|
||||||
|
*(go-iferr)*
|
||||||
|
|
||||||
|
Generate if err != nil { return ... } automatically which infer the type of
|
||||||
|
return values and the numbers.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
TEXT OBJECTS *go-text-objects*
|
TEXT OBJECTS *go-text-objects*
|
||||||
|
@ -2090,7 +2115,7 @@ Many vim-go commands use the `guru` commandline tool to get information. Some
|
||||||
a reasonable amount of performance `guru` limits this analysis to a selected
|
a reasonable amount of performance `guru` limits this analysis to a selected
|
||||||
list of packages. This is known as the "guru scope".
|
list of packages. This is known as the "guru scope".
|
||||||
|
|
||||||
The default is to use the package the curent buffer belongs to, but this may
|
The default is to use the package the current buffer belongs to, but this may
|
||||||
not always be correct. For example for the file `guthub.com/user/pkg/a/a.go`
|
not always be correct. For example for the file `guthub.com/user/pkg/a/a.go`
|
||||||
the scope will be set to `github.com/user/pkg/a`, but you probably want
|
the scope will be set to `github.com/user/pkg/a`, but you probably want
|
||||||
`github.com/user/pkg`
|
`github.com/user/pkg`
|
||||||
|
|
|
@ -109,4 +109,7 @@ endif
|
||||||
" -- issue
|
" -- issue
|
||||||
command! -nargs=0 GoReportGitHubIssue call go#issue#New()
|
command! -nargs=0 GoReportGitHubIssue call go#issue#New()
|
||||||
|
|
||||||
|
" -- iferr
|
||||||
|
command! -nargs=0 GoIfErr call go#iferr#Generate()
|
||||||
|
|
||||||
" vim: sw=2 ts=2 et
|
" vim: sw=2 ts=2 et
|
||||||
|
|
|
@ -73,4 +73,6 @@ nnoremap <silent> <Plug>(go-alternate-edit) :<C-u>call go#alternate#Switch(0, "e
|
||||||
nnoremap <silent> <Plug>(go-alternate-vertical) :<C-u>call go#alternate#Switch(0, "vsplit")<CR>
|
nnoremap <silent> <Plug>(go-alternate-vertical) :<C-u>call go#alternate#Switch(0, "vsplit")<CR>
|
||||||
nnoremap <silent> <Plug>(go-alternate-split) :<C-u>call go#alternate#Switch(0, "split")<CR>
|
nnoremap <silent> <Plug>(go-alternate-split) :<C-u>call go#alternate#Switch(0, "split")<CR>
|
||||||
|
|
||||||
|
nnoremap <silent> <Plug>(go-iferr) :<C-u>call go#iferr#Generate()<CR>
|
||||||
|
|
||||||
" vim: sw=2 ts=2 et
|
" vim: sw=2 ts=2 et
|
||||||
|
|
|
@ -47,6 +47,7 @@ let s:packages = {
|
||||||
\ 'impl': ['github.com/josharian/impl'],
|
\ 'impl': ['github.com/josharian/impl'],
|
||||||
\ 'keyify': ['github.com/dominikh/go-tools/cmd/keyify'],
|
\ 'keyify': ['github.com/dominikh/go-tools/cmd/keyify'],
|
||||||
\ 'motion': ['github.com/fatih/motion'],
|
\ 'motion': ['github.com/fatih/motion'],
|
||||||
|
\ 'iferr': ['github.com/koron/iferr'],
|
||||||
\ }
|
\ }
|
||||||
|
|
||||||
" These commands are available on any filetypes
|
" These commands are available on any filetypes
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
repeat.vim
|
# repeat.vim
|
||||||
==========
|
|
||||||
|
|
||||||
If you've ever tried using the `.` command after a plugin map, you were
|
If you've ever tried using the `.` command after a plugin map, you were
|
||||||
likely disappointed to discover it only repeated the last native command
|
likely disappointed to discover it only repeated the last native command
|
||||||
|
@ -11,9 +10,7 @@ The following plugins support repeat.vim:
|
||||||
|
|
||||||
* [surround.vim](https://github.com/tpope/vim-surround)
|
* [surround.vim](https://github.com/tpope/vim-surround)
|
||||||
* [speeddating.vim](https://github.com/tpope/vim-speeddating)
|
* [speeddating.vim](https://github.com/tpope/vim-speeddating)
|
||||||
* [abolish.vim](https://github.com/tpope/vim-abolish)
|
|
||||||
* [unimpaired.vim](https://github.com/tpope/vim-unimpaired)
|
* [unimpaired.vim](https://github.com/tpope/vim-unimpaired)
|
||||||
* [commentary.vim](https://github.com/tpope/vim-commentary)
|
|
||||||
* [vim-easyclip](https://github.com/svermeulen/vim-easyclip)
|
* [vim-easyclip](https://github.com/svermeulen/vim-easyclip)
|
||||||
|
|
||||||
Adding support to a plugin is generally as simple as the following
|
Adding support to a plugin is generally as simple as the following
|
||||||
|
@ -21,24 +18,21 @@ command at the end of your map functions.
|
||||||
|
|
||||||
silent! call repeat#set("\<Plug>MyWonderfulMap", v:count)
|
silent! call repeat#set("\<Plug>MyWonderfulMap", v:count)
|
||||||
|
|
||||||
Installation
|
## Installation
|
||||||
------------
|
|
||||||
|
|
||||||
If you don't have a preferred installation method, I recommend
|
Install using your favorite package manager, or use Vim's built-in package
|
||||||
installing [pathogen.vim](https://github.com/tpope/vim-pathogen), and
|
support:
|
||||||
then simply copy and paste:
|
|
||||||
|
|
||||||
cd ~/.vim/bundle
|
mkdir -p ~/.vim/pack/tpope/start
|
||||||
git clone git://github.com/tpope/vim-repeat.git
|
cd ~/.vim/pack/tpope/start
|
||||||
|
git clone https://tpope.io/vim/repeat.git
|
||||||
|
|
||||||
Contributing
|
## Contributing
|
||||||
------------
|
|
||||||
|
|
||||||
See the contribution guidelines for
|
See the contribution guidelines for
|
||||||
[pathogen.vim](https://github.com/tpope/vim-pathogen#readme).
|
[pathogen.vim](https://github.com/tpope/vim-pathogen#readme).
|
||||||
|
|
||||||
Self-Promotion
|
## Self-Promotion
|
||||||
--------------
|
|
||||||
|
|
||||||
Like repeat.vim? Follow the repository on
|
Like repeat.vim? Follow the repository on
|
||||||
[GitHub](https://github.com/tpope/vim-repeat) and vote for it on
|
[GitHub](https://github.com/tpope/vim-repeat) and vote for it on
|
||||||
|
@ -47,8 +41,7 @@ you're feeling especially charitable, follow [tpope](http://tpo.pe/) on
|
||||||
[Twitter](http://twitter.com/tpope) and
|
[Twitter](http://twitter.com/tpope) and
|
||||||
[GitHub](https://github.com/tpope).
|
[GitHub](https://github.com/tpope).
|
||||||
|
|
||||||
License
|
## License
|
||||||
-------
|
|
||||||
|
|
||||||
Copyright (c) Tim Pope. Distributed under the same terms as Vim itself.
|
Copyright (c) Tim Pope. Distributed under the same terms as Vim itself.
|
||||||
See `:help license`.
|
See `:help license`.
|
||||||
|
|
|
@ -48,8 +48,18 @@ snippet au augroup ... autocmd block
|
||||||
augroup end
|
augroup end
|
||||||
snippet bun Vundle.vim Plugin definition
|
snippet bun Vundle.vim Plugin definition
|
||||||
Plugin '${0}'
|
Plugin '${0}'
|
||||||
snippet plug Vundle.vim Plugin definition
|
snippet plug vim-plug Plugin definition
|
||||||
Plugin '${0}'
|
Plug '${0}'
|
||||||
|
snippet plugdo vim-plug Plugin definition with { 'do': '' }
|
||||||
|
Plug '${1}', { 'do': '${0}' }
|
||||||
|
snippet plugon vim-plug Plugin definition with { 'on': '' }
|
||||||
|
Plug '${1}', { 'on': '${0}' }
|
||||||
|
snippet plugfor vim-plug Plugin definition with { 'for': '' }
|
||||||
|
Plug '${1}', { 'for': '${0}' }
|
||||||
|
snippet plugbr vim-plug Plugin definition with { 'branch': '' }
|
||||||
|
Plug '${1}', { 'branch': '${0}' }
|
||||||
|
snippet plugtag vim-plug Plugin definition with { 'tag': '' }
|
||||||
|
Plug '${1}', { 'tag': '${0}' }
|
||||||
snippet let
|
snippet let
|
||||||
let ${1:variable} = ${0: value}
|
let ${1:variable} = ${0: value}
|
||||||
snippet se
|
snippet se
|
||||||
|
|
|
@ -573,7 +573,7 @@ nnoremap <silent> <Plug>SurroundRepeat .
|
||||||
nnoremap <silent> <Plug>Dsurround :<C-U>call <SID>dosurround(<SID>inputtarget())<CR>
|
nnoremap <silent> <Plug>Dsurround :<C-U>call <SID>dosurround(<SID>inputtarget())<CR>
|
||||||
nnoremap <silent> <Plug>Csurround :<C-U>call <SID>changesurround()<CR>
|
nnoremap <silent> <Plug>Csurround :<C-U>call <SID>changesurround()<CR>
|
||||||
nnoremap <silent> <Plug>CSurround :<C-U>call <SID>changesurround(1)<CR>
|
nnoremap <silent> <Plug>CSurround :<C-U>call <SID>changesurround(1)<CR>
|
||||||
nnoremap <expr> <Plug>Yssurround <SID>opfunc('setup').'g_'
|
nnoremap <expr> <Plug>Yssurround '^'.v:count1.<SID>opfunc('setup').'g_'
|
||||||
nnoremap <expr> <Plug>YSsurround <SID>opfunc2('setup').'_'
|
nnoremap <expr> <Plug>YSsurround <SID>opfunc2('setup').'_'
|
||||||
nnoremap <expr> <Plug>Ysurround <SID>opfunc('setup')
|
nnoremap <expr> <Plug>Ysurround <SID>opfunc('setup')
|
||||||
nnoremap <expr> <Plug>YSurround <SID>opfunc2('setup')
|
nnoremap <expr> <Plug>YSurround <SID>opfunc2('setup')
|
||||||
|
|
Loading…
Reference in a new issue