Updated plugins
This commit is contained in:
parent
44dca49794
commit
d2d303593e
105 changed files with 2141 additions and 510 deletions
|
@ -1,6 +1,12 @@
|
|||
" Author: Bjorn Neergaard <bjorn@neersighted.com>
|
||||
" Description: ansible-lint for ansible-yaml files
|
||||
|
||||
call ale#Set('ansible_ansible_lint_executable', 'ansible-lint')
|
||||
|
||||
function! ale_linters#ansible#ansible_lint#GetExecutable(buffer) abort
|
||||
return ale#Var(a:buffer, 'ansible_ansible_lint_executable')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#ansible#ansible_lint#Handle(buffer, lines) abort
|
||||
for l:line in a:lines[:10]
|
||||
if match(l:line, '^Traceback') >= 0
|
||||
|
@ -42,8 +48,9 @@ function! ale_linters#ansible#ansible_lint#Handle(buffer, lines) abort
|
|||
endfunction
|
||||
|
||||
call ale#linter#Define('ansible', {
|
||||
\ 'name': 'ansible',
|
||||
\ 'executable': 'ansible',
|
||||
\ 'command': 'ansible-lint -p %t',
|
||||
\ 'name': 'ansible_lint',
|
||||
\ 'aliases': ['ansible', 'ansible-lint'],
|
||||
\ 'executable_callback': 'ale_linters#ansible#ansible_lint#GetExecutable',
|
||||
\ 'command': '%e -p %t',
|
||||
\ 'callback': 'ale_linters#ansible#ansible_lint#Handle',
|
||||
\})
|
||||
|
|
|
@ -10,7 +10,7 @@ call ale#Set('c_clangtidy_executable', 'clang-tidy')
|
|||
" Consult the check list in clang-tidy's documentation:
|
||||
" http://clang.llvm.org/extra/clang-tidy/checks/list.html
|
||||
|
||||
call ale#Set('c_clangtidy_checks', ['*'])
|
||||
call ale#Set('c_clangtidy_checks', [])
|
||||
" Set this option to manually set some options for clang-tidy.
|
||||
" This will disable compile_commands.json detection.
|
||||
call ale#Set('c_clangtidy_options', '')
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
call ale#Set('cpp_clangtidy_executable', 'clang-tidy')
|
||||
" Set this option to check the checks clang-tidy will apply.
|
||||
call ale#Set('cpp_clangtidy_checks', ['*'])
|
||||
call ale#Set('cpp_clangtidy_checks', [])
|
||||
" Set this option to manually set some options for clang-tidy.
|
||||
" This will disable compile_commands.json detection.
|
||||
call ale#Set('cpp_clangtidy_options', '')
|
||||
|
|
22
sources_non_forked/ale/ale_linters/d/dls.vim
Normal file
22
sources_non_forked/ale/ale_linters/d/dls.vim
Normal file
|
@ -0,0 +1,22 @@
|
|||
" Author: aurieh <me@aurieh.me>
|
||||
" Description: A Language Server implementation for D
|
||||
|
||||
call ale#Set('d_dls_executable', 'dls')
|
||||
|
||||
function! ale_linters#d#dls#GetExecutable(buffer) abort
|
||||
return ale#Var(a:buffer, 'd_dls_executable')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#d#dls#FindProjectRoot(buffer) abort
|
||||
" Note: this will return . if dub config is empty
|
||||
" dls can run outside DUB projects just fine
|
||||
return fnamemodify(ale#d#FindDUBConfig(a:buffer), ':h')
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('d', {
|
||||
\ 'name': 'dls',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable_callback': 'ale_linters#d#dls#GetExecutable',
|
||||
\ 'command_callback': 'ale_linters#d#dls#GetExecutable',
|
||||
\ 'project_root_callback': 'ale_linters#d#dls#FindProjectRoot',
|
||||
\})
|
|
@ -1,20 +1,6 @@
|
|||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: "dmd for D files"
|
||||
|
||||
function! s:FindDUBConfig(buffer) abort
|
||||
" Find a DUB configuration file in ancestor paths.
|
||||
" The most DUB-specific names will be tried first.
|
||||
for l:possible_filename in ['dub.sdl', 'dub.json', 'package.json']
|
||||
let l:dub_file = ale#path#FindNearestFile(a:buffer, l:possible_filename)
|
||||
|
||||
if !empty(l:dub_file)
|
||||
return l:dub_file
|
||||
endif
|
||||
endfor
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale_linters#d#dmd#DUBCommand(buffer) abort
|
||||
" If we can't run dub, then skip this command.
|
||||
if !executable('dub')
|
||||
|
@ -22,7 +8,7 @@ function! ale_linters#d#dmd#DUBCommand(buffer) abort
|
|||
return ''
|
||||
endif
|
||||
|
||||
let l:dub_file = s:FindDUBConfig(a:buffer)
|
||||
let l:dub_file = ale#d#FindDUBConfig(a:buffer)
|
||||
|
||||
if empty(l:dub_file)
|
||||
return ''
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
" Author: Alexander Olofsson <alexander.olofsson@liu.se>
|
||||
|
||||
call ale#Set('dockerfile_dockerfile_lint_executable', 'dockerfile_lint')
|
||||
call ale#Set('dockerfile_dockerfile_lint_options', '')
|
||||
|
||||
function! ale_linters#dockerfile#dockerfile_lint#GetType(type) abort
|
||||
if a:type is? 'error'
|
||||
return 'E'
|
||||
elseif a:type is? 'warn'
|
||||
return 'W'
|
||||
endif
|
||||
|
||||
return 'I'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#dockerfile#dockerfile_lint#Handle(buffer, lines) abort
|
||||
try
|
||||
let l:data = json_decode(join(a:lines, ''))
|
||||
catch
|
||||
return []
|
||||
endtry
|
||||
|
||||
if empty(l:data)
|
||||
" Should never happen, but it's better to be on the safe side
|
||||
return []
|
||||
endif
|
||||
|
||||
let l:messages = []
|
||||
|
||||
for l:type in ['error', 'warn', 'info']
|
||||
for l:object in l:data[l:type]['data']
|
||||
let l:line = get(l:object, 'line', -1)
|
||||
let l:message = l:object['message']
|
||||
|
||||
if get(l:object, 'description', 'None') isnot# 'None'
|
||||
let l:message = l:message . '. ' . l:object['description']
|
||||
endif
|
||||
|
||||
call add(l:messages, {
|
||||
\ 'lnum': l:line,
|
||||
\ 'text': l:message,
|
||||
\ 'type': ale_linters#dockerfile#dockerfile_lint#GetType(l:type),
|
||||
\})
|
||||
endfor
|
||||
endfor
|
||||
|
||||
return l:messages
|
||||
endfunction
|
||||
|
||||
function! ale_linters#dockerfile#dockerfile_lint#GetCommand(buffer) abort
|
||||
return '%e' . ale#Pad(ale#Var(a:buffer, 'dockerfile_dockerfile_lint_options'))
|
||||
\ . ' -p -j -f'
|
||||
\ . ' %t'
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('dockerfile', {
|
||||
\ 'name': 'dockerfile_lint',
|
||||
\ 'executable_callback': ale#VarFunc('dockerfile_dockerfile_lint_executable'),
|
||||
\ 'command_callback': 'ale_linters#dockerfile#dockerfile_lint#GetCommand',
|
||||
\ 'callback': 'ale_linters#dockerfile#dockerfile_lint#Handle',
|
||||
\})
|
|
@ -11,10 +11,18 @@ function! ale_linters#elixir#credo#Handle(buffer, lines) abort
|
|||
let l:type = l:match[3]
|
||||
let l:text = l:match[4]
|
||||
|
||||
if l:type is# 'C'
|
||||
let l:type = 'E'
|
||||
elseif l:type is# 'R'
|
||||
" Refactoring opportunities
|
||||
if l:type is# 'F'
|
||||
let l:type = 'W'
|
||||
" Consistency
|
||||
elseif l:type is# 'C'
|
||||
let l:type = 'W'
|
||||
" Software Design
|
||||
elseif l:type is# 'D'
|
||||
let l:type = 'I'
|
||||
" Code Readability
|
||||
elseif l:type is# 'R'
|
||||
let l:type = 'I'
|
||||
endif
|
||||
|
||||
call add(l:output, {
|
||||
|
@ -29,9 +37,16 @@ function! ale_linters#elixir#credo#Handle(buffer, lines) abort
|
|||
return l:output
|
||||
endfunction
|
||||
|
||||
function! ale_linters#elixir#credo#GetCommand(buffer) abort
|
||||
let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
|
||||
|
||||
return ale#path#CdString(l:project_root)
|
||||
\ . ' mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s'
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('elixir', {
|
||||
\ 'name': 'credo',
|
||||
\ 'executable': 'mix',
|
||||
\ 'command': 'mix help credo && mix credo suggest --format=flycheck --read-from-stdin %s',
|
||||
\ 'command_callback': 'ale_linters#elixir#credo#GetCommand',
|
||||
\ 'callback': 'ale_linters#elixir#credo#Handle',
|
||||
\})
|
||||
|
|
|
@ -25,10 +25,17 @@ function! ale_linters#elixir#dialyxir#Handle(buffer, lines) abort
|
|||
return l:output
|
||||
endfunction
|
||||
|
||||
function! ale_linters#elixir#dialyxir#GetCommand(buffer) abort
|
||||
let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
|
||||
|
||||
return ale#path#CdString(l:project_root)
|
||||
\ . ' mix help dialyzer && mix dialyzer'
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('elixir', {
|
||||
\ 'name': 'dialyxir',
|
||||
\ 'executable': 'mix',
|
||||
\ 'command': 'mix help dialyzer && mix dialyzer',
|
||||
\ 'command_callback': 'ale_linters#elixir#dialyxir#GetCommand',
|
||||
\ 'callback': 'ale_linters#elixir#dialyxir#Handle',
|
||||
\})
|
||||
|
||||
|
|
|
@ -29,10 +29,17 @@ function! ale_linters#elixir#dogma#Handle(buffer, lines) abort
|
|||
return l:output
|
||||
endfunction
|
||||
|
||||
function! ale_linters#elixir#dogma#GetCommand(buffer) abort
|
||||
let l:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
|
||||
|
||||
return ale#path#CdString(l:project_root)
|
||||
\ . ' mix help dogma && mix dogma %s --format=flycheck'
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('elixir', {
|
||||
\ 'name': 'dogma',
|
||||
\ 'executable': 'mix',
|
||||
\ 'command': 'mix help dogma && mix dogma %s --format=flycheck',
|
||||
\ 'command_callback': 'ale_linters#elixir#dogma#GetCommand',
|
||||
\ 'lint_file': 1,
|
||||
\ 'callback': 'ale_linters#elixir#dogma#Handle',
|
||||
\})
|
||||
|
|
19
sources_non_forked/ale/ale_linters/elixir/elixir_ls.vim
Normal file
19
sources_non_forked/ale/ale_linters/elixir/elixir_ls.vim
Normal file
|
@ -0,0 +1,19 @@
|
|||
" Author: Jon Parise <jon@indelible.org>
|
||||
" Description: elixir-ls integration (https://github.com/JakeBecker/elixir-ls)
|
||||
|
||||
call ale#Set('elixir_elixir_ls_release', 'elixir-ls')
|
||||
|
||||
function! ale_linters#elixir#elixir_ls#GetExecutable(buffer) abort
|
||||
let l:dir = ale#path#Simplify(ale#Var(a:buffer, 'elixir_elixir_ls_release'))
|
||||
let l:cmd = ale#Has('win32') ? '\language_server.bat' : '/language_server.sh'
|
||||
|
||||
return l:dir . l:cmd
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('elixir', {
|
||||
\ 'name': 'elixir-ls',
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable_callback': 'ale_linters#elixir#elixir_ls#GetExecutable',
|
||||
\ 'command_callback': 'ale_linters#elixir#elixir_ls#GetExecutable',
|
||||
\ 'project_root_callback': 'ale#handlers#elixir#FindMixProjectRoot',
|
||||
\})
|
|
@ -29,18 +29,8 @@ function! ale_linters#elixir#mix#Handle(buffer, lines) abort
|
|||
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:project_root = ale#handlers#elixir#FindMixProjectRoot(a:buffer)
|
||||
|
||||
let l:temp_dir = ale#engine#CreateDirectory(a:buffer)
|
||||
|
||||
|
@ -49,8 +39,8 @@ function! ale_linters#elixir#mix#GetCommand(buffer) abort
|
|||
\ : 'MIX_BUILD_PATH=' . ale#Escape(l:temp_dir)
|
||||
|
||||
return ale#path#CdString(l:project_root)
|
||||
\ . l:mix_build_path
|
||||
\ . ' mix compile %s'
|
||||
\ . l:mix_build_path
|
||||
\ . ' mix compile %s'
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('elixir', {
|
||||
|
|
|
@ -16,7 +16,7 @@ call ale#linter#Define('haskell', {
|
|||
\ 'name': 'stack_build',
|
||||
\ 'aliases': ['stack-build'],
|
||||
\ 'output_stream': 'stderr',
|
||||
\ 'executable': 'stack',
|
||||
\ 'executable_callback': 'ale#handlers#haskell#GetStackExecutable',
|
||||
\ 'command_callback': 'ale_linters#haskell#stack_build#GetCommand',
|
||||
\ 'lint_file': 1,
|
||||
\ 'callback': 'ale#handlers#haskell#HandleGHCFormat',
|
||||
|
|
|
@ -5,7 +5,7 @@ call ale#linter#Define('haskell', {
|
|||
\ 'name': 'stack_ghc',
|
||||
\ 'aliases': ['stack-ghc'],
|
||||
\ 'output_stream': 'stderr',
|
||||
\ 'executable': 'stack',
|
||||
\ 'executable_callback': 'ale#handlers#haskell#GetStackExecutable',
|
||||
\ 'command': 'stack ghc -- -fno-code -v0 %t',
|
||||
\ 'callback': 'ale#handlers#haskell#HandleGHCFormat',
|
||||
\})
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
" Description: PMD for Java files
|
||||
|
||||
function! ale_linters#java#pmd#Handle(buffer, lines) abort
|
||||
let l:pattern = '"\(\d\+\)",".\+","\(.\+\)","\(\d\+\)","\(\d\+\)","\(.\+\)","\(.\+\)","\(.\+\)"$'
|
||||
let l:pattern = '"\(\d\+\)",".*","\(.\+\)","\(\d\+\)","\(\d\+\)","\(.\+\)","\(.\+\)","\(.\+\)"$'
|
||||
let l:output = []
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
|
|
|
@ -18,7 +18,7 @@ function! ale_linters#javascript#jshint#GetCommand(buffer) abort
|
|||
let l:command .= ' --config ' . ale#Escape(l:jshint_config)
|
||||
endif
|
||||
|
||||
let l:command .= ' -'
|
||||
let l:command .= ' --filename %s -'
|
||||
|
||||
return l:command
|
||||
endfunction
|
||||
|
|
166
sources_non_forked/ale/ale_linters/perl6/perl6.vim
Normal file
166
sources_non_forked/ale/ale_linters/perl6/perl6.vim
Normal file
|
@ -0,0 +1,166 @@
|
|||
" Author:Travis Gibson <https://github.com/Garland-g>
|
||||
" Description: This file adds support for checking perl6 syntax
|
||||
|
||||
let g:ale_perl6_perl6_executable =
|
||||
\ get(g:, 'ale_perl6_perl6_executable', 'perl6')
|
||||
|
||||
let g:ale_perl6_perl6_options =
|
||||
\ get(g:, 'ale_perl6_perl6_options', '-c -Ilib')
|
||||
|
||||
let $PERL6_EXCEPTIONS_HANDLER = 'JSON'
|
||||
|
||||
let $RAKUDO_ERROR_COLOR = 0
|
||||
|
||||
function! ale_linters#perl6#perl6#GetExecutable(buffer) abort
|
||||
return ale#Var(a:buffer, 'perl6_perl6_executable')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#perl6#perl6#GetCommand(buffer) abort
|
||||
return ale_linters#perl6#perl6#GetExecutable(a:buffer)
|
||||
\ . ' ' . ale#Var(a:buffer, 'perl6_perl6_options')
|
||||
\ . ' %t'
|
||||
endfunction
|
||||
|
||||
function! ale_linters#perl6#perl6#ExtractError(dict, item, type, buffer) abort
|
||||
let l:file = ''
|
||||
let l:line = 1
|
||||
let l:column = ''
|
||||
let l:text = ''
|
||||
let l:pre = ''
|
||||
let l:counter = 2
|
||||
let l:end_line = ''
|
||||
let l:linepatternmessage = 'at\s\+line\s\+\(\d\+\)'
|
||||
|
||||
if has_key(a:dict[a:item], 'filename') && !empty(a:dict[a:item]['filename'])
|
||||
let l:file = a:dict[a:item]['filename']
|
||||
endif
|
||||
|
||||
if has_key(a:dict[a:item], 'line') && !empty(a:dict[a:item]['line'])
|
||||
let l:line = a:dict[a:item]['line']
|
||||
let l:counter -= 1
|
||||
endif
|
||||
|
||||
if has_key(a:dict[a:item], 'column') && !empty(a:dict[a:item]['column'])
|
||||
let l:column = a:dict[a:item]['column']
|
||||
endif
|
||||
|
||||
if has_key(a:dict[a:item], 'message') && !empty(a:dict[a:item]['message'])
|
||||
let l:text = substitute(a:dict[a:item]['message'], '\s*\n\s*', ' ', 'g')
|
||||
let l:counter -= 1
|
||||
endif
|
||||
|
||||
if has_key(a:dict[a:item], 'line-real') && !empty(a:dict[a:item]['line-real'])
|
||||
let l:end_line = l:line
|
||||
let l:line = a:dict[a:item]['line-real']
|
||||
endif
|
||||
|
||||
for l:match in ale#util#GetMatches(l:text, l:linepatternmessage)
|
||||
let l:line = l:match[1]
|
||||
let l:counter -= 1
|
||||
endfor
|
||||
|
||||
" Currently, filenames and line numbers are not always given in the error output
|
||||
if l:counter < 2
|
||||
\&& ( ale#path#IsBufferPath(a:buffer, l:file) || l:file is# '' )
|
||||
return {
|
||||
\ 'lnum': '' . l:line,
|
||||
\ 'text': l:text,
|
||||
\ 'type': a:type,
|
||||
\ 'col': l:column,
|
||||
\ 'end_lnum': l:end_line,
|
||||
\ 'code': a:item,
|
||||
\}
|
||||
endif
|
||||
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
function! ale_linters#perl6#perl6#Handle(buffer, lines) abort
|
||||
let l:output = []
|
||||
|
||||
if empty(a:lines)
|
||||
return l:output
|
||||
endif
|
||||
|
||||
if a:lines[0] is# 'Syntax OK'
|
||||
return l:output
|
||||
endif
|
||||
|
||||
try
|
||||
let l:json = json_decode(join(a:lines, ''))
|
||||
catch /E474/
|
||||
call add(l:output, {
|
||||
\ 'lnum': '1',
|
||||
\ 'text': 'Received output in the default Perl6 error format. See :ALEDetail for details',
|
||||
\ 'detail': join(a:lines, "\n"),
|
||||
\ 'type': 'W',
|
||||
\ })
|
||||
|
||||
return l:output
|
||||
endtry
|
||||
|
||||
if type(l:json) is v:t_dict
|
||||
for l:key in keys(l:json)
|
||||
if has_key(l:json[l:key], 'sorrows') &&
|
||||
\ has_key(l:json[l:key], 'worries')
|
||||
if !empty(l:json[l:key]['sorrows'])
|
||||
for l:dictionary in get(l:json[l:key], 'sorrows')
|
||||
for l:item in keys(l:dictionary)
|
||||
let l:result =
|
||||
\ ale_linters#perl6#perl6#ExtractError(
|
||||
\ l:dictionary,
|
||||
\ l:item,
|
||||
\ 'E',
|
||||
\ a:buffer,
|
||||
\ )
|
||||
|
||||
if l:result isnot# ''
|
||||
call add(l:output, l:result)
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
endif
|
||||
|
||||
if !empty(l:json[l:key]['worries'])
|
||||
for l:dictionary in get(l:json[l:key], 'worries')
|
||||
for l:item in keys(l:dictionary)
|
||||
let l:result =
|
||||
\ ale_linters#perl6#perl6#ExtractError(
|
||||
\ l:dictionary,
|
||||
\ l:item,
|
||||
\ 'W',
|
||||
\ a:buffer,
|
||||
\ )
|
||||
|
||||
if l:result isnot# ''
|
||||
call add(l:output, l:result)
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
endif
|
||||
else
|
||||
let l:result = ale_linters#perl6#perl6#ExtractError(
|
||||
\ l:json,
|
||||
\ l:key,
|
||||
\ 'E',
|
||||
\ a:buffer,
|
||||
\ )
|
||||
|
||||
if l:result isnot# ''
|
||||
call add(l:output, l:result)
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('perl6', {
|
||||
\ 'name': 'perl6',
|
||||
\ 'executable_callback': 'ale_linters#perl6#perl6#GetExecutable',
|
||||
\ 'output_stream': 'both',
|
||||
\ 'command_callback': 'ale_linters#perl6#perl6#GetCommand',
|
||||
\ 'callback': 'ale_linters#perl6#perl6#Handle',
|
||||
\})
|
||||
|
|
@ -1,28 +1,21 @@
|
|||
" Author: richard marmorstein <https://github.com/twitchard>
|
||||
" Author: Matt Brown <https://github.com/muglug>
|
||||
" Description: plugin for Psalm, static analyzer for PHP
|
||||
|
||||
call ale#Set('php_psalm_executable', 'psalm')
|
||||
call ale#Set('psalm_langserver_executable', 'psalm-language-server')
|
||||
call ale#Set('psalm_langserver_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
|
||||
function! ale_linters#php#psalm#Handle(buffer, lines) abort
|
||||
" Matches patterns like the following:
|
||||
let l:pattern = '^.*:\(\d\+\):\(\d\+\):\(\w\+\) - \(.*\)$'
|
||||
let l:output = []
|
||||
function! ale_linters#php#psalm#GetProjectRoot(buffer) abort
|
||||
let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git')
|
||||
|
||||
for l:match in ale#util#GetMatches(a:lines, l:pattern)
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:match[1] + 0,
|
||||
\ 'text': l:match[4],
|
||||
\ 'type': l:match[3][:0] is# 'e' ? 'E' : 'W',
|
||||
\})
|
||||
endfor
|
||||
|
||||
return l:output
|
||||
return !empty(l:git_path) ? fnamemodify(l:git_path, ':h:h') : ''
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('php', {
|
||||
\ 'name': 'psalm',
|
||||
\ 'command': '%e --diff --output-format=emacs %s',
|
||||
\ 'executable_callback': ale#VarFunc('php_psalm_executable'),
|
||||
\ 'callback': 'ale_linters#php#psalm#Handle',
|
||||
\ 'lint_file': 1,
|
||||
\ 'lsp': 'stdio',
|
||||
\ 'executable_callback': ale#node#FindExecutableFunc('psalm_langserver', [
|
||||
\ 'vendor/bin/psalm-language-server',
|
||||
\ ]),
|
||||
\ 'command': '%e',
|
||||
\ 'project_root_callback': 'ale_linters#php#psalm#GetProjectRoot',
|
||||
\})
|
||||
|
|
100
sources_non_forked/ale/ale_linters/prolog/swipl.vim
Normal file
100
sources_non_forked/ale/ale_linters/prolog/swipl.vim
Normal file
|
@ -0,0 +1,100 @@
|
|||
" Author: Takuya Fujiwara <tyru.exe@gmail.com>
|
||||
" Description: swipl syntax / semantic check for Prolog files
|
||||
|
||||
call ale#Set('prolog_swipl_executable', 'swipl')
|
||||
call ale#Set('prolog_swipl_load', 'current_prolog_flag(argv, [File]), load_files(File, [sandboxed(true)]), halt.')
|
||||
call ale#Set('prolog_swipl_timeout', 3)
|
||||
call ale#Set('prolog_swipl_alarm', 'alarm(%t, (%h), _, [])')
|
||||
call ale#Set('prolog_swipl_alarm_handler', 'writeln(user_error, "ERROR: Exceeded %t seconds, Please change g:prolog_swipl_timeout to modify the limit."), halt(1)')
|
||||
|
||||
function! ale_linters#prolog#swipl#GetCommand(buffer) abort
|
||||
let l:goals = ale#Var(a:buffer, 'prolog_swipl_load')
|
||||
let l:goals = l:goals =~# '^\s*$' ? 'halt' : l:goals
|
||||
let l:timeout = ale#Var(a:buffer, 'prolog_swipl_timeout') + 0
|
||||
|
||||
if l:timeout > 0
|
||||
let l:goals = s:GetAlarm(a:buffer, l:timeout) . ', ' . l:goals
|
||||
endif
|
||||
|
||||
return '%e -g ' . ale#Escape(l:goals) . ' -- %s'
|
||||
endfunction
|
||||
|
||||
function! s:GetAlarm(buffer, timeout) abort
|
||||
let l:handler = ale#Var(a:buffer, 'prolog_swipl_alarm_handler')
|
||||
let l:handler = s:Subst(l:handler, {'t': a:timeout})
|
||||
let l:alarm = ale#Var(a:buffer, 'prolog_swipl_alarm')
|
||||
let l:alarm = s:Subst(l:alarm, {'t': a:timeout, 'h': l:handler})
|
||||
|
||||
return l:alarm
|
||||
endfunction
|
||||
|
||||
function! s:Subst(format, vars) abort
|
||||
let l:vars = extend(copy(a:vars), {'%': '%'})
|
||||
|
||||
return substitute(a:format, '%\(.\)', '\=get(l:vars, submatch(1), "")', 'g')
|
||||
endfunction
|
||||
|
||||
function! ale_linters#prolog#swipl#Handle(buffer, lines) abort
|
||||
let l:pattern = '\v^(ERROR|Warning)+%(:\s*[^:]+:(\d+)%(:(\d+))?)?:\s*(.*)$'
|
||||
let l:output = []
|
||||
let l:i = 0
|
||||
|
||||
while l:i < len(a:lines)
|
||||
let l:match = matchlist(a:lines[l:i], l:pattern)
|
||||
|
||||
if empty(l:match)
|
||||
let l:i += 1
|
||||
continue
|
||||
endif
|
||||
|
||||
let [l:i, l:text] = s:GetErrMsg(l:i, a:lines, l:match[4])
|
||||
let l:item = {
|
||||
\ 'lnum': (l:match[2] + 0 ? l:match[2] + 0 : 1),
|
||||
\ 'col': l:match[3] + 0,
|
||||
\ 'text': l:text,
|
||||
\ 'type': (l:match[1] is# 'ERROR' ? 'E' : 'W'),
|
||||
\}
|
||||
|
||||
if !s:Ignore(l:item)
|
||||
call add(l:output, l:item)
|
||||
endif
|
||||
endwhile
|
||||
|
||||
return l:output
|
||||
endfunction
|
||||
|
||||
" This returns [<next line number>, <error message string>]
|
||||
function! s:GetErrMsg(i, lines, text) abort
|
||||
if a:text !~# '^\s*$'
|
||||
return [a:i + 1, a:text]
|
||||
endif
|
||||
|
||||
let l:i = a:i + 1
|
||||
let l:text = []
|
||||
|
||||
while l:i < len(a:lines) && a:lines[l:i] =~# '^\s'
|
||||
call add(l:text, s:Trim(a:lines[l:i]))
|
||||
let l:i += 1
|
||||
endwhile
|
||||
|
||||
return [l:i, join(l:text, '. ')]
|
||||
endfunction
|
||||
|
||||
function! s:Trim(str) abort
|
||||
return substitute(a:str, '\v^\s+|\s+$', '', 'g')
|
||||
endfunction
|
||||
|
||||
" Skip sandbox error which is caused by directives
|
||||
" because what we want is syntactic or semantic check.
|
||||
function! s:Ignore(item) abort
|
||||
return a:item.type is# 'E' &&
|
||||
\ a:item.text =~# '\vNo permission to (call|directive|assert) sandboxed'
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('prolog', {
|
||||
\ 'name': 'swipl',
|
||||
\ 'output_stream': 'stderr',
|
||||
\ 'executable_callback': ale#VarFunc('prolog_swipl_executable'),
|
||||
\ 'command_callback': 'ale_linters#prolog#swipl#GetCommand',
|
||||
\ 'callback': 'ale_linters#prolog#swipl#Handle',
|
||||
\})
|
|
@ -30,7 +30,7 @@ function! ale_linters#ruby#reek#GetCommand(buffer, version_output) abort
|
|||
\ : ''
|
||||
|
||||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'reek')
|
||||
\ . ' -f json --no-progress --no-color'
|
||||
\ . ' -f json --no-progress --no-color --force-exclusion'
|
||||
\ . l:display_name_args
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
" Description: updated to use stdio
|
||||
|
||||
call ale#Set('ruby_solargraph_executable', 'solargraph')
|
||||
call ale#Set('ruby_solargraph_options', {})
|
||||
|
||||
function! ale_linters#ruby#solargraph#GetCommand(buffer) abort
|
||||
return '%e' . ale#Pad('stdio')
|
||||
|
@ -17,4 +18,5 @@ call ale#linter#Define('ruby', {
|
|||
\ 'executable_callback': ale#VarFunc('ruby_solargraph_executable'),
|
||||
\ 'command_callback': 'ale_linters#ruby#solargraph#GetCommand',
|
||||
\ 'project_root_callback': 'ale#ruby#FindProjectRoot',
|
||||
\ 'initialization_options_callback': ale#VarFunc('ruby_solargraph_options'),
|
||||
\})
|
||||
|
|
|
@ -9,6 +9,8 @@ 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_include_features', '')
|
||||
call ale#Set('rust_cargo_use_clippy', 0)
|
||||
call ale#Set('rust_cargo_clippy_options', '')
|
||||
|
||||
function! ale_linters#rust#cargo#GetCargoExecutable(bufnr) abort
|
||||
if ale#path#FindNearestFile(a:bufnr, 'Cargo.toml') isnot# ''
|
||||
|
@ -70,14 +72,23 @@ function! ale_linters#rust#cargo#GetCommand(buffer, version_output) abort
|
|||
let l:default_feature = ''
|
||||
endif
|
||||
|
||||
let l:subcommand = l:use_check ? 'check' : 'build'
|
||||
let l:clippy_options = ''
|
||||
|
||||
if ale#Var(a:buffer, 'rust_cargo_use_clippy')
|
||||
let l:subcommand = 'clippy'
|
||||
let l:clippy_options = ' ' . ale#Var(a:buffer, 'rust_cargo_clippy_options')
|
||||
endif
|
||||
|
||||
return l:nearest_cargo_prefix . 'cargo '
|
||||
\ . (l:use_check ? 'check' : 'build')
|
||||
\ . l:subcommand
|
||||
\ . (l:use_all_targets ? ' --all-targets' : '')
|
||||
\ . (l:use_examples ? ' --examples' : '')
|
||||
\ . (l:use_tests ? ' --tests' : '')
|
||||
\ . ' --frozen --message-format=json -q'
|
||||
\ . l:default_feature
|
||||
\ . l:include_features
|
||||
\ . l:clippy_options
|
||||
endfunction
|
||||
|
||||
call ale#linter#Define('rust', {
|
||||
|
|
|
@ -10,8 +10,7 @@ let g:ale_echo_msg_warning_str = get(g:, 'ale_echo_msg_warning_str', 'Warning')
|
|||
let g:ale_linters_ignore = get(g:, 'ale_linters_ignore', {})
|
||||
|
||||
let s:lint_timer = -1
|
||||
let s:queued_buffer_number = -1
|
||||
let s:should_lint_file_for_buffer = {}
|
||||
let s:getcmdwintype_exists = exists('*getcmdwintype')
|
||||
|
||||
" Return 1 if a file is too large for ALE to handle.
|
||||
function! ale#FileTooLarge(buffer) abort
|
||||
|
@ -20,8 +19,6 @@ function! ale#FileTooLarge(buffer) abort
|
|||
return l:max > 0 ? (line2byte(line('$') + 1) > l:max) : 0
|
||||
endfunction
|
||||
|
||||
let s:getcmdwintype_exists = exists('*getcmdwintype')
|
||||
|
||||
" A function for checking various conditions whereby ALE just shouldn't
|
||||
" attempt to do anything, say if particular buffer types are open in Vim.
|
||||
function! ale#ShouldDoNothing(buffer) abort
|
||||
|
@ -86,18 +83,44 @@ function! ale#ShouldDoNothing(buffer) abort
|
|||
return 0
|
||||
endfunction
|
||||
|
||||
function! s:Lint(buffer, should_lint_file, timer_id) abort
|
||||
" Use the filetype from the buffer
|
||||
let l:filetype = getbufvar(a:buffer, '&filetype')
|
||||
let l:linters = ale#linter#Get(l:filetype)
|
||||
|
||||
" Apply ignore lists for linters only if needed.
|
||||
let l:ignore_config = ale#Var(a:buffer, 'linters_ignore')
|
||||
let l:linters = !empty(l:ignore_config)
|
||||
\ ? ale#engine#ignore#Exclude(l:filetype, l:linters, l:ignore_config)
|
||||
\ : l:linters
|
||||
|
||||
" Tell other sources that they can start checking the buffer now.
|
||||
let g:ale_want_results_buffer = a:buffer
|
||||
silent doautocmd <nomodeline> User ALEWantResults
|
||||
unlet! g:ale_want_results_buffer
|
||||
|
||||
" Don't set up buffer data and so on if there are no linters to run.
|
||||
if !has_key(g:ale_buffer_info, a:buffer) && empty(l:linters)
|
||||
return
|
||||
endif
|
||||
|
||||
" Clear lint_file linters, or only run them if the file exists.
|
||||
let l:lint_file = empty(l:linters)
|
||||
\ || (a:should_lint_file && filereadable(expand('#' . a:buffer . ':p')))
|
||||
|
||||
call ale#engine#RunLinters(a:buffer, l:linters, l:lint_file)
|
||||
endfunction
|
||||
|
||||
" (delay, [linting_flag, buffer_number])
|
||||
function! ale#Queue(delay, ...) abort
|
||||
if a:0 > 2
|
||||
throw 'too many arguments!'
|
||||
endif
|
||||
|
||||
" Default linting_flag to ''
|
||||
let l:linting_flag = get(a:000, 0, '')
|
||||
let l:buffer = get(a:000, 1, bufnr(''))
|
||||
let l:buffer = get(a:000, 1, v:null)
|
||||
|
||||
if l:linting_flag isnot# '' && l:linting_flag isnot# 'lint_file'
|
||||
throw "linting_flag must be either '' or 'lint_file'"
|
||||
if l:buffer is v:null
|
||||
let l:buffer = bufnr('')
|
||||
endif
|
||||
|
||||
if type(l:buffer) isnot v:t_number
|
||||
|
@ -108,80 +131,24 @@ function! ale#Queue(delay, ...) abort
|
|||
return
|
||||
endif
|
||||
|
||||
" Remember that we want to check files for this buffer.
|
||||
" We will remember this until we finally run the linters, via any event.
|
||||
if l:linting_flag is# 'lint_file'
|
||||
let s:should_lint_file_for_buffer[l:buffer] = 1
|
||||
endif
|
||||
" Default linting_flag to ''
|
||||
let l:should_lint_file = get(a:000, 0) is# 'lint_file'
|
||||
|
||||
if s:lint_timer != -1
|
||||
call timer_stop(s:lint_timer)
|
||||
let s:lint_timer = -1
|
||||
endif
|
||||
|
||||
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.
|
||||
if empty(l:linters)
|
||||
" If we have some previous buffer data, then stop any jobs currently
|
||||
" running and clear everything.
|
||||
if has_key(g:ale_buffer_info, l:buffer)
|
||||
call ale#engine#RunLinters(l:buffer, [], 1)
|
||||
endif
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
if a:delay > 0
|
||||
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('s:Lint', [l:buffer, l:should_lint_file])
|
||||
\)
|
||||
else
|
||||
call ale#Lint(-1, l:buffer)
|
||||
call s:Lint(l:buffer, l:should_lint_file, 0)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#Lint(...) abort
|
||||
if a:0 > 1
|
||||
" Use the buffer number given as the optional second argument.
|
||||
let l:buffer = a:2
|
||||
elseif a:0 > 0 && a:1 == s:lint_timer
|
||||
" Use the buffer number for the buffer linting was queued for.
|
||||
let l:buffer = s:queued_buffer_number
|
||||
else
|
||||
" Use the current buffer number.
|
||||
let l:buffer = bufnr('')
|
||||
endif
|
||||
|
||||
if ale#ShouldDoNothing(l:buffer)
|
||||
return
|
||||
endif
|
||||
|
||||
" Use the filetype from the buffer
|
||||
let l:filetype = getbufvar(l:buffer, '&filetype')
|
||||
let l:linters = ale#linter#Get(l:filetype)
|
||||
let l:should_lint_file = 0
|
||||
|
||||
" Check if we previously requested checking the file.
|
||||
if has_key(s:should_lint_file_for_buffer, l:buffer)
|
||||
unlet s:should_lint_file_for_buffer[l:buffer]
|
||||
" Lint files if they exist.
|
||||
let l:should_lint_file = filereadable(expand('#' . l:buffer . ':p'))
|
||||
endif
|
||||
|
||||
" 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
|
||||
|
||||
" Reset flags indicating that files should be checked for all buffers.
|
||||
function! ale#ResetLintFileMarkers() abort
|
||||
let s:should_lint_file_for_buffer = {}
|
||||
endfunction
|
||||
|
||||
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
|
||||
|
|
|
@ -85,6 +85,14 @@ function! ale#assert#LSPOptions(expected_options) abort
|
|||
AssertEqual a:expected_options, l:initialization_options
|
||||
endfunction
|
||||
|
||||
function! ale#assert#LSPConfig(expected_config) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:linter = s:GetLinter()
|
||||
let l:config = ale#lsp_linter#GetConfig(l:buffer, l:linter)
|
||||
|
||||
AssertEqual a:expected_config, l:config
|
||||
endfunction
|
||||
|
||||
function! ale#assert#LSPLanguage(expected_language) abort
|
||||
let l:buffer = bufnr('')
|
||||
let l:linter = s:GetLinter()
|
||||
|
@ -147,6 +155,7 @@ function! ale#assert#SetUpLinterTest(filetype, name) abort
|
|||
command! -nargs=+ AssertLinter :call ale#assert#Linter(<args>)
|
||||
command! -nargs=0 AssertLinterNotExecuted :call ale#assert#LinterNotExecuted()
|
||||
command! -nargs=+ AssertLSPOptions :call ale#assert#LSPOptions(<args>)
|
||||
command! -nargs=+ AssertLSPConfig :call ale#assert#LSPConfig(<args>)
|
||||
command! -nargs=+ AssertLSPLanguage :call ale#assert#LSPLanguage(<args>)
|
||||
command! -nargs=+ AssertLSPProject :call ale#assert#LSPProject(<args>)
|
||||
command! -nargs=+ AssertLSPAddress :call ale#assert#LSPAddress(<args>)
|
||||
|
@ -172,6 +181,10 @@ function! ale#assert#TearDownLinterTest() abort
|
|||
delcommand AssertLSPOptions
|
||||
endif
|
||||
|
||||
if exists(':AssertLSPConfig')
|
||||
delcommand AssertLSPConfig
|
||||
endif
|
||||
|
||||
if exists(':AssertLSPLanguage')
|
||||
delcommand AssertLSPLanguage
|
||||
endif
|
||||
|
|
|
@ -26,7 +26,20 @@ function! ale#cursor#TruncatedEcho(original_message) abort
|
|||
|
||||
" The message is truncated and saved to the history.
|
||||
setlocal shortmess+=T
|
||||
exec "norm! :echomsg l:message\n"
|
||||
|
||||
try
|
||||
exec "norm! :echomsg l:message\n"
|
||||
catch /^Vim\%((\a\+)\)\=:E523/
|
||||
" Fallback into manual truncate (#1987)
|
||||
let l:winwidth = winwidth(0)
|
||||
|
||||
if l:winwidth < strdisplaywidth(l:message)
|
||||
" Truncate message longer than window width with trailing '...'
|
||||
let l:message = l:message[:l:winwidth - 4] . '...'
|
||||
endif
|
||||
|
||||
exec 'echomsg l:message'
|
||||
endtry
|
||||
|
||||
" Reset the cursor position if we moved off the end of the line.
|
||||
" Using :norm and :echomsg can move the cursor off the end of the
|
||||
|
|
16
sources_non_forked/ale/autoload/ale/d.vim
Normal file
16
sources_non_forked/ale/autoload/ale/d.vim
Normal file
|
@ -0,0 +1,16 @@
|
|||
" Author: Auri <me@aurieh.me>
|
||||
" Description: Functions for integrating with D linters.
|
||||
|
||||
function! ale#d#FindDUBConfig(buffer) abort
|
||||
" Find a DUB configuration file in ancestor paths.
|
||||
" The most DUB-specific names will be tried first.
|
||||
for l:possible_filename in ['dub.sdl', 'dub.json', 'package.json']
|
||||
let l:dub_file = ale#path#FindNearestFile(a:buffer, l:possible_filename)
|
||||
|
||||
if !empty(l:dub_file)
|
||||
return l:dub_file
|
||||
endif
|
||||
endfor
|
||||
|
||||
return ''
|
||||
endfunction
|
|
@ -79,6 +79,7 @@ function! ale#engine#InitBufferInfo(buffer) abort
|
|||
let g:ale_buffer_info[a:buffer] = {
|
||||
\ 'job_list': [],
|
||||
\ 'active_linter_list': [],
|
||||
\ 'active_other_sources_list': [],
|
||||
\ 'loclist': [],
|
||||
\ 'temporary_file_list': [],
|
||||
\ 'temporary_directory_list': [],
|
||||
|
@ -97,6 +98,7 @@ function! ale#engine#IsCheckingBuffer(buffer) abort
|
|||
let l:info = get(g:ale_buffer_info, a:buffer, {})
|
||||
|
||||
return !empty(get(l:info, 'active_linter_list', []))
|
||||
\ || !empty(get(l:info, 'active_other_sources_list', []))
|
||||
endfunction
|
||||
|
||||
" Register a temporary file to be managed with the ALE engine for
|
||||
|
@ -177,20 +179,27 @@ function! s:GatherOutput(job_id, line) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#engine#HandleLoclist(linter_name, buffer, loclist) abort
|
||||
function! ale#engine#HandleLoclist(linter_name, buffer, loclist, from_other_source) abort
|
||||
let l:info = get(g:ale_buffer_info, a:buffer, {})
|
||||
|
||||
if empty(l:info)
|
||||
return
|
||||
endif
|
||||
|
||||
" Remove this linter from the list of active linters.
|
||||
" This may have already been done when the job exits.
|
||||
call filter(l:info.active_linter_list, 'v:val isnot# a:linter_name')
|
||||
if !a:from_other_source
|
||||
" Remove this linter from the list of active linters.
|
||||
" This may have already been done when the job exits.
|
||||
call filter(l:info.active_linter_list, 'v:val isnot# a:linter_name')
|
||||
endif
|
||||
|
||||
" Make some adjustments to the loclists to fix common problems, and also
|
||||
" to set default values for loclist items.
|
||||
let l:linter_loclist = ale#engine#FixLocList(a:buffer, a:linter_name, a:loclist)
|
||||
let l:linter_loclist = ale#engine#FixLocList(
|
||||
\ a:buffer,
|
||||
\ a:linter_name,
|
||||
\ a:from_other_source,
|
||||
\ a:loclist,
|
||||
\)
|
||||
|
||||
" Remove previous items for this linter.
|
||||
call filter(l:info.loclist, 'v:val.linter_name isnot# a:linter_name')
|
||||
|
@ -263,7 +272,7 @@ function! s:HandleExit(job_id, exit_code) abort
|
|||
let l:loclist = []
|
||||
endtry
|
||||
|
||||
call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist)
|
||||
call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist, 0)
|
||||
endfunction
|
||||
|
||||
function! ale#engine#SetResults(buffer, loclist) abort
|
||||
|
@ -335,7 +344,7 @@ function! s:RemapItemTypes(type_map, loclist) abort
|
|||
endfor
|
||||
endfunction
|
||||
|
||||
function! ale#engine#FixLocList(buffer, linter_name, loclist) abort
|
||||
function! ale#engine#FixLocList(buffer, linter_name, from_other_source, loclist) abort
|
||||
let l:bufnr_map = {}
|
||||
let l:new_loclist = []
|
||||
|
||||
|
@ -368,6 +377,10 @@ function! ale#engine#FixLocList(buffer, linter_name, loclist) abort
|
|||
\ 'linter_name': a:linter_name,
|
||||
\}
|
||||
|
||||
if a:from_other_source
|
||||
let l:item.from_other_source = 1
|
||||
endif
|
||||
|
||||
if has_key(l:old_item, 'code')
|
||||
let l:item.code = l:old_item.code
|
||||
endif
|
||||
|
@ -691,6 +704,7 @@ endfunction
|
|||
function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort
|
||||
" Figure out which linters are still enabled, and remove
|
||||
" problems for linters which are no longer enabled.
|
||||
" Problems from other sources will be kept.
|
||||
let l:name_map = {}
|
||||
|
||||
for l:linter in a:linters
|
||||
|
@ -699,7 +713,7 @@ function! s:RemoveProblemsForDisabledLinters(buffer, linters) abort
|
|||
|
||||
call filter(
|
||||
\ get(g:ale_buffer_info[a:buffer], 'loclist', []),
|
||||
\ 'get(l:name_map, get(v:val, ''linter_name''))',
|
||||
\ 'get(v:val, ''from_other_source'') || get(l:name_map, get(v:val, ''linter_name''))',
|
||||
\)
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -250,6 +250,11 @@ let s:default_registry = {
|
|||
\ 'suggested_filetypes': ['c', 'cpp', 'cs', 'objc', 'objcpp', 'd', 'java', 'p', 'vala' ],
|
||||
\ 'description': 'Fix C, C++, C#, ObjectiveC, ObjectiveC++, D, Java, Pawn, and VALA files with uncrustify.',
|
||||
\ },
|
||||
\ 'terraform': {
|
||||
\ 'function': 'ale#fixers#terraform#Fix',
|
||||
\ 'suggested_filetypes': ['hcl', 'terraform'],
|
||||
\ 'description': 'Fix tf and hcl files with terraform fmt.',
|
||||
\ },
|
||||
\}
|
||||
|
||||
" Reset the function registry to the default entries.
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
" Author: butlerx <butlerx@notthe,cloud>
|
||||
" Description: Integration of Google-java-format with ALE.
|
||||
|
||||
call ale#Set('google_java_format_executable', 'google-java-format')
|
||||
call ale#Set('google_java_format_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('google_java_format_options', '')
|
||||
call ale#Set('java_google_java_format_executable', 'google-java-format')
|
||||
call ale#Set('java_google_java_format_use_global', get(g:, 'ale_use_global_executables', 0))
|
||||
call ale#Set('java_google_java_format_options', '')
|
||||
|
||||
function! ale#fixers#google_java_format#Fix(buffer) abort
|
||||
let l:options = ale#Var(a:buffer, 'google_java_format_options')
|
||||
let l:executable = ale#Var(a:buffer, 'google_java_format_executable')
|
||||
let l:options = ale#Var(a:buffer, 'java_google_java_format_options')
|
||||
let l:executable = ale#Var(a:buffer, 'java_google_java_format_executable')
|
||||
|
||||
if !executable(l:executable)
|
||||
return 0
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
call ale#Set('json_jq_executable', 'jq')
|
||||
call ale#Set('json_jq_options', '')
|
||||
call ale#Set('json_jq_filters', '.')
|
||||
|
||||
function! ale#fixers#jq#GetExecutable(buffer) abort
|
||||
return ale#Var(a:buffer, 'json_jq_executable')
|
||||
|
@ -7,9 +8,15 @@ endfunction
|
|||
|
||||
function! ale#fixers#jq#Fix(buffer) abort
|
||||
let l:options = ale#Var(a:buffer, 'json_jq_options')
|
||||
let l:filters = ale#Var(a:buffer, 'json_jq_filters')
|
||||
|
||||
if empty(l:filters)
|
||||
return 0
|
||||
endif
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(ale#fixers#jq#GetExecutable(a:buffer))
|
||||
\ . ' . ' . l:options,
|
||||
\ . ' ' . l:filters . ' '
|
||||
\ . l:options,
|
||||
\}
|
||||
endfunction
|
||||
|
|
|
@ -9,7 +9,7 @@ function! ale#fixers#rubocop#GetCommand(buffer) abort
|
|||
return ale#handlers#ruby#EscapeExecutable(l:executable, 'rubocop')
|
||||
\ . (!empty(l:config) ? ' --config ' . ale#Escape(l:config) : '')
|
||||
\ . (!empty(l:options) ? ' ' . l:options : '')
|
||||
\ . ' --auto-correct %t'
|
||||
\ . ' --auto-correct --force-exclusion %t'
|
||||
endfunction
|
||||
|
||||
function! ale#fixers#rubocop#Fix(buffer) abort
|
||||
|
|
17
sources_non_forked/ale/autoload/ale/fixers/terraform.vim
Normal file
17
sources_non_forked/ale/autoload/ale/fixers/terraform.vim
Normal file
|
@ -0,0 +1,17 @@
|
|||
" Author: dsifford <dereksifford@gmail.com>
|
||||
" Description: Fixer for terraform and .hcl files
|
||||
|
||||
call ale#Set('terraform_fmt_executable', 'terraform')
|
||||
call ale#Set('terraform_fmt_options', '')
|
||||
|
||||
function! ale#fixers#terraform#Fix(buffer) abort
|
||||
let l:executable = ale#Var(a:buffer, 'terraform_fmt_executable')
|
||||
let l:options = ale#Var(a:buffer, 'terraform_fmt_options')
|
||||
|
||||
return {
|
||||
\ 'command': ale#Escape(l:executable)
|
||||
\ . ' fmt'
|
||||
\ . (empty(l:options) ? '' : ' ' . l:options)
|
||||
\ . ' -'
|
||||
\}
|
||||
endfunction
|
13
sources_non_forked/ale/autoload/ale/handlers/elixir.vim
Normal file
13
sources_non_forked/ale/autoload/ale/handlers/elixir.vim
Normal file
|
@ -0,0 +1,13 @@
|
|||
" Author: Matteo Centenaro (bugant) - https://github.com/bugant
|
||||
"
|
||||
" Description: find the root directory for an elixir project that uses mix
|
||||
|
||||
function! ale#handlers#elixir#FindMixProjectRoot(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
|
|
@ -1,5 +1,15 @@
|
|||
" Author: w0rp <devw0rp@gmail.com>
|
||||
" Description: Error handling for the format GHC outputs.
|
||||
"
|
||||
function! ale#handlers#haskell#GetStackExecutable(bufnr) abort
|
||||
if ale#path#FindNearestFile(a:bufnr, 'stack.yaml') isnot# ''
|
||||
return 'stack'
|
||||
endif
|
||||
|
||||
" if there is no stack.yaml file, we don't use stack even if it exists,
|
||||
" so we return '', because executable('') apparently always fails
|
||||
return ''
|
||||
endfunction
|
||||
|
||||
" Remember the directory used for temporary files for Vim.
|
||||
let s:temp_dir = fnamemodify(ale#util#Tempname(), ':h')
|
||||
|
|
|
@ -7,6 +7,10 @@ if !exists('g:ale_rust_ignore_error_codes')
|
|||
let g:ale_rust_ignore_error_codes = []
|
||||
endif
|
||||
|
||||
if !exists('g:ale_rust_ignore_secondary_spans')
|
||||
let g:ale_rust_ignore_secondary_spans = 0
|
||||
endif
|
||||
|
||||
function! s:FindSpan(buffer, span) abort
|
||||
if ale#path#IsBufferPath(a:buffer, a:span.file_name) || a:span.file_name is# '<anon>'
|
||||
return a:span
|
||||
|
@ -47,6 +51,10 @@ function! ale#handlers#rust#HandleRustErrors(buffer, lines) abort
|
|||
for l:root_span in l:error.spans
|
||||
let l:span = s:FindSpan(a:buffer, l:root_span)
|
||||
|
||||
if ale#Var(a:buffer, 'rust_ignore_secondary_spans') && !get(l:span, 'is_primary', 1)
|
||||
continue
|
||||
endif
|
||||
|
||||
if !empty(l:span)
|
||||
call add(l:output, {
|
||||
\ 'lnum': l:span.line_start,
|
||||
|
|
|
@ -35,6 +35,7 @@ let s:default_ale_linters = {
|
|||
\ 'hack': ['hack'],
|
||||
\ 'help': [],
|
||||
\ 'perl': ['perlcritic'],
|
||||
\ 'perl6': [],
|
||||
\ 'python': ['flake8', 'mypy', 'pylint'],
|
||||
\ 'rust': ['cargo'],
|
||||
\ 'spec': [],
|
||||
|
@ -255,6 +256,24 @@ function! ale#linter#PreProcess(filetype, linter) abort
|
|||
elseif has_key(a:linter, 'initialization_options')
|
||||
let l:obj.initialization_options = a:linter.initialization_options
|
||||
endif
|
||||
|
||||
if has_key(a:linter, 'lsp_config_callback')
|
||||
if has_key(a:linter, 'lsp_config')
|
||||
throw 'Only one of `lsp_config` or `lsp_config_callback` should be set'
|
||||
endif
|
||||
|
||||
let l:obj.lsp_config_callback = a:linter.lsp_config_callback
|
||||
|
||||
if !s:IsCallback(l:obj.lsp_config_callback)
|
||||
throw '`lsp_config_callback` must be a callback if defined'
|
||||
endif
|
||||
elseif has_key(a:linter, 'lsp_config')
|
||||
if type(a:linter.lsp_config) isnot v:t_dict
|
||||
throw '`lsp_config` must be a Dictionary'
|
||||
endif
|
||||
|
||||
let l:obj.lsp_config = a:linter.lsp_config
|
||||
endif
|
||||
endif
|
||||
|
||||
let l:obj.output_stream = get(a:linter, 'output_stream', 'stdout')
|
||||
|
@ -337,8 +356,9 @@ endfunction
|
|||
function! s:GetAliasedFiletype(original_filetype) abort
|
||||
let l:buffer_aliases = get(b:, 'ale_linter_aliases', {})
|
||||
|
||||
" b:ale_linter_aliases can be set to a List.
|
||||
" b:ale_linter_aliases can be set to a List or String.
|
||||
if type(l:buffer_aliases) is v:t_list
|
||||
\|| type(l:buffer_aliases) is v:t_string
|
||||
return l:buffer_aliases
|
||||
endif
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ function! ale#lsp#Register(executable_or_address, project, init_options) abort
|
|||
" initialized: 0 if the connection is ready, 1 otherwise.
|
||||
" init_request_id: The ID for the init request.
|
||||
" init_options: Options to send to the server.
|
||||
" config: Configuration settings to send to the server.
|
||||
" callback_list: A list of callbacks for handling LSP responses.
|
||||
" message_queue: Messages queued for sending to callbacks.
|
||||
" capabilities_queue: The list of callbacks to call with capabilities.
|
||||
|
@ -32,6 +33,7 @@ function! ale#lsp#Register(executable_or_address, project, init_options) abort
|
|||
\ 'initialized': 0,
|
||||
\ 'init_request_id': 0,
|
||||
\ 'init_options': a:init_options,
|
||||
\ 'config': {},
|
||||
\ 'callback_list': [],
|
||||
\ 'message_queue': [],
|
||||
\ 'capabilities_queue': [],
|
||||
|
@ -41,6 +43,7 @@ function! ale#lsp#Register(executable_or_address, project, init_options) abort
|
|||
\ 'completion': 0,
|
||||
\ 'completion_trigger_characters': [],
|
||||
\ 'definition': 0,
|
||||
\ 'symbol_search': 0,
|
||||
\ },
|
||||
\}
|
||||
endif
|
||||
|
@ -203,8 +206,31 @@ function! s:UpdateCapabilities(conn, capabilities) abort
|
|||
if get(a:capabilities, 'definitionProvider') is v:true
|
||||
let a:conn.capabilities.definition = 1
|
||||
endif
|
||||
|
||||
if get(a:capabilities, 'workspaceSymbolProvider') is v:true
|
||||
let a:conn.capabilities.symbol_search = 1
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Update a connection's configuration dictionary and notify LSP servers
|
||||
" of any changes since the last update. Returns 1 if a configuration
|
||||
" update was sent; otherwise 0 will be returned.
|
||||
function! ale#lsp#UpdateConfig(conn_id, buffer, config) abort
|
||||
let l:conn = get(s:connections, a:conn_id, {})
|
||||
|
||||
if empty(l:conn) || a:config ==# l:conn.config " no-custom-checks
|
||||
return 0
|
||||
endif
|
||||
|
||||
let l:conn.config = a:config
|
||||
let l:message = ale#lsp#message#DidChangeConfiguration(a:buffer, a:config)
|
||||
|
||||
call ale#lsp#Send(a:conn_id, l:message)
|
||||
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
|
||||
function! ale#lsp#HandleInitResponse(conn, response) abort
|
||||
if get(a:response, 'method', '') is# 'initialize'
|
||||
let a:conn.initialized = 1
|
||||
|
@ -285,6 +311,7 @@ function! ale#lsp#MarkConnectionAsTsserver(conn_id) abort
|
|||
let l:conn.capabilities.completion = 1
|
||||
let l:conn.capabilities.completion_trigger_characters = ['.']
|
||||
let l:conn.capabilities.definition = 1
|
||||
let l:conn.capabilities.symbol_search = 1
|
||||
endfunction
|
||||
|
||||
" Start a program for LSP servers.
|
||||
|
|
|
@ -130,6 +130,12 @@ function! ale#lsp#message#References(buffer, line, column) abort
|
|||
\}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#message#Symbol(query) abort
|
||||
return [0, 'workspace/symbol', {
|
||||
\ 'query': a:query,
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#message#Hover(buffer, line, column) abort
|
||||
return [0, 'textDocument/hover', {
|
||||
\ 'textDocument': {
|
||||
|
@ -138,3 +144,9 @@ function! ale#lsp#message#Hover(buffer, line, column) abort
|
|||
\ 'position': {'line': a:line - 1, 'character': a:column},
|
||||
\}]
|
||||
endfunction
|
||||
|
||||
function! ale#lsp#message#DidChangeConfiguration(buffer, config) abort
|
||||
return [0, 'workspace/didChangeConfiguration', {
|
||||
\ 'settings': a:config,
|
||||
\}]
|
||||
endfunction
|
||||
|
|
|
@ -17,7 +17,7 @@ function! ale#lsp#reset#StopAllLSPs() abort
|
|||
|
||||
for l:linter in ale#linter#Get(getbufvar(l:buffer, '&filetype'))
|
||||
if !empty(l:linter.lsp)
|
||||
call ale#engine#HandleLoclist(l:linter.name, l:buffer, [])
|
||||
call ale#engine#HandleLoclist(l:linter.name, l:buffer, [], 0)
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
|
|
@ -38,7 +38,7 @@ function! s:HandleLSPDiagnostics(conn_id, response) abort
|
|||
|
||||
let l:loclist = ale#lsp#response#ReadDiagnostics(a:response)
|
||||
|
||||
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist)
|
||||
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0)
|
||||
endfunction
|
||||
|
||||
function! s:HandleTSServerDiagnostics(response, error_type) abort
|
||||
|
@ -81,7 +81,7 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort
|
|||
let l:loclist = get(l:info, 'semantic_loclist', [])
|
||||
\ + get(l:info, 'syntax_loclist', [])
|
||||
|
||||
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist)
|
||||
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist, 0)
|
||||
endfunction
|
||||
|
||||
function! s:HandleLSPErrorMessage(linter_name, response) abort
|
||||
|
@ -140,6 +140,18 @@ function! ale#lsp_linter#GetOptions(buffer, linter) abort
|
|||
return l:initialization_options
|
||||
endfunction
|
||||
|
||||
function! ale#lsp_linter#GetConfig(buffer, linter) abort
|
||||
let l:config = {}
|
||||
|
||||
if has_key(a:linter, 'lsp_config_callback')
|
||||
let l:config = ale#util#GetFunction(a:linter.lsp_config_callback)(a:buffer)
|
||||
elseif has_key(a:linter, 'lsp_config')
|
||||
let l:config = a:linter.lsp_config
|
||||
endif
|
||||
|
||||
return l:config
|
||||
endfunction
|
||||
|
||||
" Given a buffer, an LSP linter, start up an LSP linter and get ready to
|
||||
" receive messages for the document.
|
||||
function! ale#lsp_linter#StartLSP(buffer, linter) abort
|
||||
|
@ -188,6 +200,7 @@ function! ale#lsp_linter#StartLSP(buffer, linter) abort
|
|||
call ale#lsp#MarkConnectionAsTsserver(l:conn_id)
|
||||
endif
|
||||
|
||||
let l:config = ale#lsp_linter#GetConfig(a:buffer, a:linter)
|
||||
let l:language_id = ale#util#GetFunction(a:linter.language_callback)(a:buffer)
|
||||
|
||||
let l:details = {
|
||||
|
@ -198,6 +211,8 @@ function! ale#lsp_linter#StartLSP(buffer, linter) abort
|
|||
\ 'language_id': l:language_id,
|
||||
\}
|
||||
|
||||
call ale#lsp#UpdateConfig(l:conn_id, a:buffer, l:config)
|
||||
|
||||
if ale#lsp#OpenDocument(l:conn_id, a:buffer, l:language_id)
|
||||
if g:ale_history_enabled && !empty(l:command)
|
||||
call ale#history#Add(a:buffer, 'started', l:conn_id, l:command)
|
||||
|
|
21
sources_non_forked/ale/autoload/ale/other_source.vim
Normal file
21
sources_non_forked/ale/autoload/ale/other_source.vim
Normal file
|
@ -0,0 +1,21 @@
|
|||
" Tell ALE that another source has started checking a buffer.
|
||||
function! ale#other_source#StartChecking(buffer, linter_name) abort
|
||||
call ale#engine#InitBufferInfo(a:buffer)
|
||||
let l:list = g:ale_buffer_info[a:buffer].active_other_sources_list
|
||||
|
||||
call add(l:list, a:linter_name)
|
||||
call uniq(sort(l:list))
|
||||
endfunction
|
||||
|
||||
" Show some results, and stop checking a buffer.
|
||||
" To clear results or cancel checking a buffer, an empty List can be given.
|
||||
function! ale#other_source#ShowResults(buffer, linter_name, loclist) abort
|
||||
call ale#engine#InitBufferInfo(a:buffer)
|
||||
let l:info = g:ale_buffer_info[a:buffer]
|
||||
|
||||
" Remove this linter name from the active list.
|
||||
let l:list = l:info.active_other_sources_list
|
||||
call filter(l:list, 'v:val isnot# a:linter_name')
|
||||
|
||||
call ale#engine#HandleLoclist(a:linter_name, a:buffer, a:loclist, 1)
|
||||
endfunction
|
|
@ -65,7 +65,11 @@ endfunction
|
|||
" Output 'cd <directory> && '
|
||||
" This function can be used changing the directory for a linter command.
|
||||
function! ale#path#CdString(directory) abort
|
||||
return 'cd ' . ale#Escape(a:directory) . ' && '
|
||||
if has('win32')
|
||||
return 'cd /d ' . ale#Escape(a:directory) . ' && '
|
||||
else
|
||||
return 'cd ' . ale#Escape(a:directory) . ' && '
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" Output 'cd <buffer_filename_directory> && '
|
||||
|
|
|
@ -46,11 +46,14 @@ function! ale#preview#ShowSelection(item_list) abort
|
|||
|
||||
" Create lines to display to users.
|
||||
for l:item in a:item_list
|
||||
let l:match = get(l:item, 'match', '')
|
||||
|
||||
call add(
|
||||
\ l:lines,
|
||||
\ l:item.filename
|
||||
\ . ':' . l:item.line
|
||||
\ . ':' . l:item.column,
|
||||
\ . ':' . l:item.column
|
||||
\ . (!empty(l:match) ? ' ' . l:match : ''),
|
||||
\)
|
||||
endfor
|
||||
|
||||
|
|
109
sources_non_forked/ale/autoload/ale/symbol.vim
Normal file
109
sources_non_forked/ale/autoload/ale/symbol.vim
Normal file
|
@ -0,0 +1,109 @@
|
|||
let s:symbol_map = {}
|
||||
|
||||
" Used to get the symbol map in tests.
|
||||
function! ale#symbol#GetMap() abort
|
||||
return deepcopy(s:symbol_map)
|
||||
endfunction
|
||||
|
||||
" Used to set the symbol map in tests.
|
||||
function! ale#symbol#SetMap(map) abort
|
||||
let s:symbol_map = a:map
|
||||
endfunction
|
||||
|
||||
function! ale#symbol#ClearLSPData() abort
|
||||
let s:symbol_map = {}
|
||||
endfunction
|
||||
|
||||
function! ale#symbol#HandleLSPResponse(conn_id, response) abort
|
||||
if has_key(a:response, 'id')
|
||||
\&& has_key(s:symbol_map, a:response.id)
|
||||
let l:options = remove(s:symbol_map, a:response.id)
|
||||
|
||||
let l:result = get(a:response, 'result', v:null)
|
||||
let l:item_list = []
|
||||
|
||||
if type(l:result) is v:t_list
|
||||
" Each item looks like this:
|
||||
" {
|
||||
" 'name': 'foo',
|
||||
" 'kind': 123,
|
||||
" 'deprecated': v:false,
|
||||
" 'location': {
|
||||
" 'uri': 'file://...',
|
||||
" 'range': {
|
||||
" 'start': {'line': 0, 'character': 0},
|
||||
" 'end': {'line': 0, 'character': 0},
|
||||
" },
|
||||
" },
|
||||
" 'containerName': 'SomeContainer',
|
||||
" }
|
||||
for l:response_item in l:result
|
||||
let l:location = l:response_item.location
|
||||
|
||||
call add(l:item_list, {
|
||||
\ 'filename': ale#path#FromURI(l:location.uri),
|
||||
\ 'line': l:location.range.start.line + 1,
|
||||
\ 'column': l:location.range.start.character + 1,
|
||||
\ 'match': l:response_item.name,
|
||||
\})
|
||||
endfor
|
||||
endif
|
||||
|
||||
if empty(l:item_list)
|
||||
call ale#util#Execute('echom ''No symbols found.''')
|
||||
else
|
||||
call ale#preview#ShowSelection(l:item_list)
|
||||
endif
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:OnReady(linter, lsp_details, query, ...) abort
|
||||
let l:buffer = a:lsp_details.buffer
|
||||
|
||||
" If we already made a request, stop here.
|
||||
if getbufvar(l:buffer, 'ale_symbol_request_made', 0)
|
||||
return
|
||||
endif
|
||||
|
||||
let l:id = a:lsp_details.connection_id
|
||||
|
||||
let l:Callback = function('ale#symbol#HandleLSPResponse')
|
||||
call ale#lsp#RegisterCallback(l:id, l:Callback)
|
||||
|
||||
let l:message = ale#lsp#message#Symbol(a:query)
|
||||
let l:request_id = ale#lsp#Send(l:id, l:message)
|
||||
|
||||
call setbufvar(l:buffer, 'ale_symbol_request_made', 1)
|
||||
let s:symbol_map[l:request_id] = {
|
||||
\ 'buffer': l:buffer,
|
||||
\}
|
||||
endfunction
|
||||
|
||||
function! s:Search(linter, buffer, query) abort
|
||||
let l:lsp_details = ale#lsp_linter#StartLSP(a:buffer, a:linter)
|
||||
|
||||
if !empty(l:lsp_details)
|
||||
call ale#lsp#WaitForCapability(
|
||||
\ l:lsp_details.connection_id,
|
||||
\ 'symbol_search',
|
||||
\ function('s:OnReady', [a:linter, l:lsp_details, a:query]),
|
||||
\)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! ale#symbol#Search(query) abort
|
||||
if type(a:query) isnot v:t_string || empty(a:query)
|
||||
throw 'A non-empty string must be provided!'
|
||||
endif
|
||||
|
||||
let l:buffer = bufnr('')
|
||||
|
||||
" Set a flag so we only make one request.
|
||||
call setbufvar(l:buffer, 'ale_symbol_request_made', 0)
|
||||
|
||||
for l:linter in ale#linter#Get(getbufvar(l:buffer, '&filetype'))
|
||||
if !empty(l:linter.lsp) && l:linter.lsp isnot# 'tsserver'
|
||||
call s:Search(l:linter, l:buffer, a:query)
|
||||
endif
|
||||
endfor
|
||||
endfunction
|
16
sources_non_forked/ale/doc/ale-ansible.txt
Normal file
16
sources_non_forked/ale/doc/ale-ansible.txt
Normal file
|
@ -0,0 +1,16 @@
|
|||
===============================================================================
|
||||
ALE Ansible Integration *ale-ansible-options*
|
||||
|
||||
|
||||
===============================================================================
|
||||
ansible-lint *ale-ansible-ansible-lint*
|
||||
|
||||
g:ale_ansible_ansible_lint_executable *g:ale_ansible_ansible_lint_executable*
|
||||
*b:ale_ansible_ansible_lint_executable*
|
||||
Type: |String|
|
||||
Default: `'ansible-lint'`
|
||||
|
||||
This variable can be changed to modify the executable used for ansible-lint.
|
||||
|
||||
===============================================================================
|
||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
|
@ -130,7 +130,7 @@ overrides |g:ale_c_build_dir_names|.
|
|||
g:ale_c_clangtidy_checks *g:ale_c_clangtidy_checks*
|
||||
*b:ale_c_clangtidy_checks*
|
||||
Type: |List|
|
||||
Default: `['*']`
|
||||
Default: `[]`
|
||||
|
||||
The checks to enable for clang-tidy with the `-checks` argument.
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ overrides |g:ale_c_build_dir_names|.
|
|||
g:ale_cpp_clangtidy_checks *g:ale_cpp_clangtidy_checks*
|
||||
*b:ale_cpp_clangtidy_checks*
|
||||
Type: |List|
|
||||
Default: `['*']`
|
||||
Default: `[]`
|
||||
|
||||
The checks to enable for clang-tidy with the `-checks` argument.
|
||||
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
ALE C# Integration *ale-cs-options*
|
||||
|
||||
|
||||
In addition to the linters that are provided with ALE, C# code can be checked
|
||||
with the OmniSharp plugin. See here: https://github.com/OmniSharp/omnisharp-vim
|
||||
|
||||
|
||||
===============================================================================
|
||||
mcs *ale-cs-mcs*
|
||||
|
||||
|
|
|
@ -2,6 +2,17 @@
|
|||
ALE D Integration *ale-d-options*
|
||||
|
||||
|
||||
===============================================================================
|
||||
dls *ale-d-dls*
|
||||
|
||||
g:ale_d_dls_executable *g:ale_d_dls_executable*
|
||||
*b:ale_d_dls_executable*
|
||||
Type: |String|
|
||||
Default: `dls`
|
||||
|
||||
See |ale-integrations-local-executables|
|
||||
|
||||
|
||||
===============================================================================
|
||||
uncrustify *ale-d-uncrustify*
|
||||
|
||||
|
|
|
@ -306,6 +306,7 @@ given the above setup are as follows.
|
|||
`AssertLinterNotExecuted` - Check that linters will not be executed.
|
||||
`AssertLSPLanguage language` - Check the language given to an LSP server.
|
||||
`AssertLSPOptions options_dict` - Check the options given to an LSP server.
|
||||
`AssertLSPConfig config_dict` - Check the config given to an LSP server.
|
||||
`AssertLSPProject project_root` - Check the root given to an LSP server.
|
||||
`AssertLSPAddress address` - Check the address to an LSP server.
|
||||
|
||||
|
|
|
@ -2,6 +2,29 @@
|
|||
ALE Dockerfile Integration *ale-dockerfile-options*
|
||||
|
||||
|
||||
===============================================================================
|
||||
dockerfile_lint *ale-dockerfile-dockerfile_lint*
|
||||
|
||||
g:ale_dockerfile_dockerfile_lint_executable
|
||||
*g:ale_dockerfile_dockerfile_lint_executable*
|
||||
*b:ale_dockerfile_dockerfile_lint_executable*
|
||||
Type: |String|
|
||||
Default: `'dockerfile_lint'`
|
||||
|
||||
This variable can be changed to specify the executable used to run
|
||||
dockerfile_lint.
|
||||
|
||||
|
||||
g:ale_dockerfile_dockerfile_lint_options
|
||||
*g:ale_dockerfile_dockerfile_lint_options*
|
||||
*b:ale_dockerfile_dockerfile_lint_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
This variable can be changed to add additional command-line arguments to
|
||||
the dockerfile lint invocation - like custom rule file definitions.
|
||||
|
||||
|
||||
===============================================================================
|
||||
hadolint *ale-dockerfile-hadolint*
|
||||
|
||||
|
|
|
@ -40,5 +40,18 @@ configured on your project's `mix.exs`.
|
|||
See https://github.com/jeremyjh/dialyxir#with-explaining-stuff for more
|
||||
information.
|
||||
|
||||
===============================================================================
|
||||
elixir-ls *ale-elixir-elixir-ls*
|
||||
|
||||
Elixir Language Server (https://github.com/JakeBecker/elixir-ls)
|
||||
|
||||
g:ale_elixir_elixir_ls_release *g:ale_elixir_elixir_ls_release*
|
||||
*b:ale_elixir_elixir_ls_release*
|
||||
Type: |String|
|
||||
Default: `'elixir-ls'`
|
||||
|
||||
Location of the elixir-ls release directory. This directory must contain
|
||||
the language server scripts (language_server.sh and language_server.bat).
|
||||
|
||||
===============================================================================
|
||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
||||
|
|
11
sources_non_forked/ale/doc/ale-hcl.txt
Normal file
11
sources_non_forked/ale/doc/ale-hcl.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
===============================================================================
|
||||
ALE HCL Integration *ale-hcl-options*
|
||||
|
||||
|
||||
===============================================================================
|
||||
terraform-fmt *ale-hcl-terraform-fmt*
|
||||
|
||||
See |ale-terraform-fmt| for information about the available options.
|
||||
|
||||
===============================================================================
|
||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
|
@ -73,6 +73,13 @@ g:ale_json_jq_options *g:ale_json_jq_options*
|
|||
|
||||
This option can be changed to pass extra options to `jq`.
|
||||
|
||||
g:ale_json_jq_filters *g:ale_json_jq_filters*
|
||||
*b:ale_json_jq_filters*
|
||||
Type: |String|
|
||||
Default: `'.'`
|
||||
|
||||
This option can be changed to pass custom filters to `jq`.
|
||||
|
||||
|
||||
===============================================================================
|
||||
prettier *ale-json-prettier*
|
||||
|
|
43
sources_non_forked/ale/doc/ale-perl6.txt
Normal file
43
sources_non_forked/ale/doc/ale-perl6.txt
Normal file
|
@ -0,0 +1,43 @@
|
|||
===============================================================================
|
||||
ALE Perl6 Integration *ale-perl6-options*
|
||||
|
||||
Checking code with `perl6` is disabled by default, as `perl6` code cannot be
|
||||
checked without executing it. Specifically, we use the `-c` flag to see if
|
||||
`perl6` code compiles. This does not execute all of the code in a file, but it
|
||||
does run `BEGIN` and `CHECK` blocks. See `perl6 --help`
|
||||
|
||||
Full support requires a perl6 implementation that supports the
|
||||
PERL6_EXCEPTIONS_HANDLER environment variable and JSON error output,
|
||||
which was specified in 6.d. Rakudo version 2018.08 is the first rakudo release
|
||||
that supports this. See `perl6 --version` and
|
||||
https://docs.perl6.org/programs/03-environment-variables.
|
||||
|
||||
Without this variable, errors and warnings will appear at line 1, and can be
|
||||
viewed with ALEDetail. This also serves as a fallback for errors and warnings
|
||||
that do not trigger JSON output.
|
||||
|
||||
See |g:ale_linters|.
|
||||
|
||||
|
||||
===============================================================================
|
||||
perl6 *ale-perl6-perl6*
|
||||
|
||||
g:ale_perl6_perl6_executable *g:ale_perl6_perl6_executable*
|
||||
*b:ale_perl6_perl6_executable*
|
||||
Type: |String|
|
||||
Default: `'perl6'`
|
||||
|
||||
This variable can be changed to modify the executable used for linting
|
||||
perl6.
|
||||
|
||||
|
||||
g:ale_perl6_perl6_options *g:ale_perl6_perl6_options*
|
||||
*b:ale_perl6_perl6_options*
|
||||
Type: |String|
|
||||
Default: `'-c -Ilib'`
|
||||
|
||||
This variable can be changed to alter the command-line arguments to the
|
||||
perl6 invocation.
|
||||
|
||||
===============================================================================
|
||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
56
sources_non_forked/ale/doc/ale-prolog.txt
Normal file
56
sources_non_forked/ale/doc/ale-prolog.txt
Normal file
|
@ -0,0 +1,56 @@
|
|||
===============================================================================
|
||||
ALE Prolog Integration *ale-prolog-options*
|
||||
|
||||
|
||||
===============================================================================
|
||||
swipl *ale-prolog-swipl*
|
||||
|
||||
g:ale_prolog_swipl_executable *g:ale_prolog_swipl_executable*
|
||||
*b:ale_prolog_swipl_executable*
|
||||
Type: |String|
|
||||
Default: `'swipl'`
|
||||
|
||||
The executable that will be run for the `swipl` linter.
|
||||
|
||||
g:ale_prolog_swipl_load *g:ale_prolog_swipl_load*
|
||||
*b:ale_prolog_swipl_load*
|
||||
Type: |String|
|
||||
Default: `'current_prolog_flag(argv, [File]), load_files(File, [sandboxed(true)]), halt.'`
|
||||
|
||||
The prolog goals that will be passed to |g:ale_prolog_swipl_executable| with `-g` option.
|
||||
|
||||
It does:
|
||||
1. Takes the first command argument (current file path)
|
||||
2. Checks (syntactic / semantic) problems and output to stderr
|
||||
|
||||
NOTE: `sandboxed(true)` prohibits executing some directives such as 'initialization main'.
|
||||
|
||||
g:ale_prolog_swipl_timeout *g:ale_prolog_swipl_timeout*
|
||||
*b:ale_prolog_swipl_timeout*
|
||||
Type: |Number|
|
||||
Default: `3`
|
||||
|
||||
Timeout seconds to detect long-running linter.
|
||||
It is done by setting SIGALRM.
|
||||
See |g:ale_prolog_swipl_alarm| and |g:ale_prolog_swipl_alarm_handler|.
|
||||
|
||||
g:ale_prolog_swipl_alarm *g:ale_prolog_swipl_alarm*
|
||||
*b:ale_prolog_swipl_alarm*
|
||||
Type: |String|
|
||||
Default: `'alarm(%t, (%h), _, [])'`
|
||||
|
||||
The prolog goals to be expected to set SIGALRM.
|
||||
`%t` is replaced by |g:ale_prolog_swipl_timeout|.
|
||||
`%h` is replaced by |g:ale_prolog_swipl_alarm_handler|.
|
||||
|
||||
g:ale_prolog_swipl_alarm_handler *g:ale_prolog_swipl_alarm_handler*
|
||||
*b:ale_prolog_swipl_alarm_handler*
|
||||
Type: |String|
|
||||
Default: `'writeln(user_error, "ERROR: Exceeded %t seconds, Please change g:prolog_swipl_timeout to modify the limit."), halt(1)'`
|
||||
|
||||
The prolog goals to be expected that will be run on SIGALRM.
|
||||
`%t` is replaced by |g:ale_prolog_swipl_timeout|.
|
||||
|
||||
|
||||
===============================================================================
|
||||
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:
|
|
@ -109,6 +109,7 @@ g:ale_rust_cargo_include_features *g:ale_rust_cargo_include_features*
|
|||
When defined, ALE will set the `--features` option when invoking `cargo` to
|
||||
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|
|
||||
|
@ -119,6 +120,36 @@ g:ale_rust_cargo_avoid_whole_workspace *g:ale_rust_cargo_avoid_whole_workspace*
|
|||
in the crate's directory. Otherwise, behave as usual.
|
||||
|
||||
|
||||
g:ale_rust_cargo_use_clippy
|
||||
*g:ale_rust_cargo_use_clippy*
|
||||
*b:ale_rust_cargo_use_clippy*
|
||||
Type: |Number|
|
||||
Default: `0`
|
||||
|
||||
When set to 1, `cargo clippy` will be used instead of `cargo check` or
|
||||
`cargo build` as linter.
|
||||
For details of `cargo clippy`, please visit the following link:
|
||||
|
||||
https://github.com/rust-lang-nursery/rust-clippy
|
||||
|
||||
Since `cargo clippy` is optional toolchain, it's safer to check whether
|
||||
`cargo-clippy` is executable as follows:
|
||||
>
|
||||
let g:ale_rust_cargo_use_clippy = executable('cargo-clippy')
|
||||
<
|
||||
|
||||
g:ale_rust_cargo_clippy_options
|
||||
*g:ale_rust_cargo_clippy_options*
|
||||
*b:ale_rust_cargo_clippy_options*
|
||||
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
When `cargo clippy` is used, this value will be added to a command line to run
|
||||
it. This variable is useful when you want to add some extra options which
|
||||
only `cargo clippy` supports (e.g. `--deny`).
|
||||
|
||||
|
||||
===============================================================================
|
||||
rls *ale-rust-rls*
|
||||
|
||||
|
@ -167,6 +198,22 @@ g:ale_rust_ignore_error_codes *g:ale_rust_ignore_error_codes*
|
|||
>
|
||||
let g:ale_rust_ignore_error_codes = ['E0432', 'E0433']
|
||||
|
||||
g:ale_rust_ignore_secondary_spans *g:ale_rust_ignore_secondary_spans*
|
||||
*b:ale_rust_ignore_secondary_spans*
|
||||
Type: Number
|
||||
Default: 0
|
||||
|
||||
When set to 1, instructs the Rust error repporting to ignore secondary
|
||||
spans. The problem with secondary spans is that they sometimes appear in
|
||||
error messages before the main cause of the error, for example: >
|
||||
|
||||
1 src/main.rs|98 col 5 error| this function takes 4 parameters but 5
|
||||
parameters were supplied: defined here
|
||||
2 src/main.rs|430 col 32 error| this function takes 4 parameters but 5
|
||||
parameters were supplied: expected 4 parameters
|
||||
<
|
||||
This is due to the sorting by line numbers. With this option set to 1,
|
||||
the 'defined here' span will not be presented.
|
||||
|
||||
===============================================================================
|
||||
rustfmt *ale-rust-rustfmt*
|
||||
|
|
|
@ -2,6 +2,24 @@
|
|||
ALE Terraform Integration *ale-terraform-options*
|
||||
|
||||
|
||||
===============================================================================
|
||||
fmt *ale-terraform-fmt*
|
||||
|
||||
g:ale_terraform_fmt_executable *g:ale_terraform_fmt_executable*
|
||||
*b:ale_terraform_fmt_executable*
|
||||
|
||||
Type: |String|
|
||||
Default: `'terraform'`
|
||||
|
||||
This variable can be changed to use a different executable for terraform.
|
||||
|
||||
|
||||
g:ale_terraform_fmt_options *g:ale_terraform_fmt_options*
|
||||
*b:ale_terraform_fmt_options*
|
||||
Type: |String|
|
||||
Default: `''`
|
||||
|
||||
|
||||
===============================================================================
|
||||
tflint *ale-terraform-tflint*
|
||||
|
||||
|
|
|
@ -9,15 +9,20 @@ CONTENTS *ale-contents*
|
|||
1. Introduction.........................|ale-introduction|
|
||||
2. Supported Languages & Tools..........|ale-support|
|
||||
3. Linting..............................|ale-lint|
|
||||
3.1 Other Sources.....................|ale-lint-other-sources|
|
||||
4. Fixing Problems......................|ale-fix|
|
||||
5. Language Server Protocol Support.....|ale-lsp|
|
||||
5.1 Completion........................|ale-completion|
|
||||
5.2 Go To Definition..................|ale-go-to-definition|
|
||||
5.3 Find References...................|ale-find-references|
|
||||
5.4 Hovering..........................|ale-hover|
|
||||
5.5 Symbol Search.....................|ale-symbol-search|
|
||||
6. Global Options.......................|ale-options|
|
||||
6.1 Highlights........................|ale-highlights|
|
||||
6.2 Options for write-good Linter.....|ale-write-good-options|
|
||||
7. Integration Documentation............|ale-integrations|
|
||||
ansible...............................|ale-ansible-options|
|
||||
ansible-lint........................|ale-ansible-ansible-lint|
|
||||
asciidoc..............................|ale-asciidoc-options|
|
||||
write-good..........................|ale-asciidoc-write-good|
|
||||
asm...................................|ale-asm-options|
|
||||
|
@ -67,16 +72,19 @@ CONTENTS *ale-contents*
|
|||
cuda..................................|ale-cuda-options|
|
||||
nvcc................................|ale-cuda-nvcc|
|
||||
d.....................................|ale-d-options|
|
||||
dls.................................|ale-d-dls|
|
||||
uncrustify..........................|ale-d-uncrustify|
|
||||
dart..................................|ale-dart-options|
|
||||
dartanalyzer........................|ale-dart-dartanalyzer|
|
||||
dartfmt.............................|ale-dart-dartfmt|
|
||||
dockerfile............................|ale-dockerfile-options|
|
||||
dockerfile_lint.....................|ale-dockerfile-dockerfile_lint|
|
||||
hadolint............................|ale-dockerfile-hadolint|
|
||||
elixir................................|ale-elixir-options|
|
||||
mix.................................|ale-elixir-mix|
|
||||
mix_format..........................|ale-elixir-mix-format|
|
||||
dialyxir............................|ale-elixir-dialyxir|
|
||||
elixir-ls...........................|ale-elixir-elixir-ls|
|
||||
elm...................................|ale-elm-options|
|
||||
elm-format..........................|ale-elm-elm-format|
|
||||
elm-make............................|ale-elm-elm-make|
|
||||
|
@ -125,6 +133,8 @@ CONTENTS *ale-contents*
|
|||
stack-build.........................|ale-haskell-stack-build|
|
||||
stylish-haskell.....................|ale-haskell-stylish-haskell|
|
||||
hie.................................|ale-haskell-hie|
|
||||
hcl...................................|ale-hcl-options|
|
||||
terraform-fmt.......................|ale-hcl-terraform-fmt|
|
||||
html..................................|ale-html-options|
|
||||
htmlhint............................|ale-html-htmlhint|
|
||||
tidy................................|ale-html-tidy|
|
||||
|
@ -203,6 +213,8 @@ CONTENTS *ale-contents*
|
|||
perl................................|ale-perl-perl|
|
||||
perlcritic..........................|ale-perl-perlcritic|
|
||||
perltidy............................|ale-perl-perltidy|
|
||||
perl6.................................|ale-perl6-options|
|
||||
perl6...............................|ale-perl6-perl6|
|
||||
php...................................|ale-php-options|
|
||||
langserver..........................|ale-php-langserver|
|
||||
phan................................|ale-php-phan|
|
||||
|
@ -218,6 +230,8 @@ CONTENTS *ale-contents*
|
|||
write-good..........................|ale-pod-write-good|
|
||||
pony..................................|ale-pony-options|
|
||||
ponyc...............................|ale-pony-ponyc|
|
||||
prolog................................|ale-prolog-options|
|
||||
swipl...............................|ale-prolog-swipl|
|
||||
proto.................................|ale-proto-options|
|
||||
protoc-gen-lint.....................|ale-proto-protoc-gen-lint|
|
||||
pug...................................|ale-pug-options|
|
||||
|
@ -293,6 +307,7 @@ CONTENTS *ale-contents*
|
|||
tcl...................................|ale-tcl-options|
|
||||
nagelfar............................|ale-tcl-nagelfar|
|
||||
terraform.............................|ale-terraform-options|
|
||||
fmt.................................|ale-terraform-fmt|
|
||||
tflint..............................|ale-terraform-tflint|
|
||||
tex...................................|ale-tex-options|
|
||||
chktex..............................|ale-tex-chktex|
|
||||
|
@ -393,11 +408,11 @@ Notes:
|
|||
* CSS: `csslint`, `prettier`, `stylelint`
|
||||
* Cucumber: `cucumber`
|
||||
* Cython (pyrex filetype): `cython`
|
||||
* D: `dmd`, `uncrustify`
|
||||
* D: `dls`, `dmd`, `uncrustify`
|
||||
* Dafny: `dafny`!!
|
||||
* Dart: `dartanalyzer`!!, `language_server`, dartfmt!!
|
||||
* Dockerfile: `hadolint`
|
||||
* Elixir: `credo`, `dialyxir`, `dogma`, `mix`!!
|
||||
* Dockerfile: `dockerfile_lint`, `hadolint`
|
||||
* Elixir: `credo`, `dialyxir`, `dogma`, `mix`!!, `elixir-ls`
|
||||
* Elm: `elm-format, elm-make`
|
||||
* Erb: `erb`, `erubi`, `erubis`
|
||||
* Erlang: `erlc`, `SyntaxErl`
|
||||
|
@ -413,6 +428,7 @@ Notes:
|
|||
* Haml: `haml-lint`
|
||||
* Handlebars: `ember-template-lint`
|
||||
* Haskell: `brittany`, `ghc`, `cabal-ghc`, `stylish-haskell`, `stack-ghc`, `stack-build`!!, `ghc-mod`, `hlint`, `hdevtools`, `hfmt`, `hie`
|
||||
* HCL: `terraform-fmt`
|
||||
* HTML: `alex`!!, `HTMLHint`, `proselint`, `tidy`, `write-good`
|
||||
* Idris: `idris`
|
||||
* Java: `checkstyle`, `javac`, `google-java-format`, `PMD`, `javalsp`, `uncrustify`
|
||||
|
@ -438,10 +454,12 @@ Notes:
|
|||
* OCaml: `merlin` (see |ale-ocaml-merlin|), `ols`, `ocamlformat`
|
||||
* Pawn: `uncrustify`
|
||||
* Perl: `perl -c`, `perl-critic`, `perltidy`
|
||||
* Perl6: `perl6 -c`
|
||||
* PHP: `langserver`, `phan`, `php -l`, `phpcs`, `phpmd`, `phpstan`, `phpcbf`, `php-cs-fixer`, `psalm`!!
|
||||
* PO: `alex`!!, `msgfmt`, `proselint`, `write-good`
|
||||
* Pod: `alex`!!, `proselint`, `write-good`
|
||||
* Pony: `ponyc`
|
||||
* Prolog: `swipl`
|
||||
* proto: `protoc-gen-lint`
|
||||
* Pug: `pug-lint`
|
||||
* Puppet: `languageserver`, `puppet`, `puppet-lint`
|
||||
|
@ -464,7 +482,7 @@ Notes:
|
|||
* SQL: `sqlint`, `sqlfmt`
|
||||
* Swift: `swiftlint`, `swiftformat`
|
||||
* Tcl: `nagelfar`!!
|
||||
* Terraform: `tflint`
|
||||
* Terraform: `fmt`, `tflint`
|
||||
* Texinfo: `alex`!!, `proselint`, `write-good`
|
||||
* Text^: `alex`!!, `proselint`, `redpen`, `textlint`, `vale`, `write-good`
|
||||
* Thrift: `thrift`
|
||||
|
@ -559,6 +577,68 @@ ALE offers several options for controlling which linters are run.
|
|||
* Only running linters you asked for. - |g:ale_linters_explicit|
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
3.1 Other Sources *ale-lint-other-sources*
|
||||
|
||||
Problems for a buffer can be taken from other sources and rendered by ALE.
|
||||
This allows ALE to be used in combination with other plugins which also want
|
||||
to display any problems they might find with a buffer. ALE's API includes the
|
||||
following components for making this possible.
|
||||
|
||||
* |ale#other_source#StartChecking()| - Tell ALE that a buffer is being checked.
|
||||
* |ale#other_source#ShowResults()| - Show results from another source.
|
||||
* |ALEWantResults| - A signal for when ALE wants results.
|
||||
|
||||
Other resources can provide results for ALE to display at any time, following
|
||||
ALE's loclist format. (See |ale-loclist-format|) For example: >
|
||||
|
||||
" Tell ALE to show some results.
|
||||
" This function can be called at any time.
|
||||
call ale#other_source#ShowResults(bufnr(''), 'some-linter-name', [
|
||||
\ {'text': 'Something went wrong', 'lnum': 13},
|
||||
\])
|
||||
<
|
||||
|
||||
Other sources should use a unique name for identifying themselves. A single
|
||||
linter name can be used for all problems from another source, or a series of
|
||||
unique linter names can be used. Results can be cleared for that source by
|
||||
providing an empty List.
|
||||
|
||||
|ale#other_source#StartChecking()| should be called whenever another source
|
||||
starts checking a buffer, so other tools can know that a buffer is being
|
||||
checked by some plugin. The |ALEWantResults| autocmd event can be used to
|
||||
start checking a buffer for problems every time that ALE does. When
|
||||
|ALEWantResults| is signaled, |g:ale_want_results_buffer| will be set to the
|
||||
number of the buffer that ALE wants to check.
|
||||
|ale#other_source#StartChecking()| should be called synchronously, and other
|
||||
sources should perform their checks on a buffer in the background
|
||||
asynchronously, so they don't interrupt editing.
|
||||
|
||||
A plugin might integrate its own checks with ALE like so: >
|
||||
|
||||
augroup SomeGroupName
|
||||
autocmd!
|
||||
autocmd User ALEWantResults call Hook(g:ale_want_results_buffer)
|
||||
augroup END
|
||||
|
||||
function! DoBackgroundWork(buffer) abort
|
||||
" Start some work in the background here.
|
||||
" ...
|
||||
" Then call WorkDone(a:buffer, results)
|
||||
endfunction
|
||||
|
||||
function! Hook(buffer) abort
|
||||
" Tell ALE we're going to check this buffer.
|
||||
call ale#other_source#StartChecking(a:buffer, 'some-name')
|
||||
call DoBackgroundWork(a:buffer)
|
||||
endfunction
|
||||
|
||||
function! WorkDone(buffer, results) abort
|
||||
" Send results to ALE after they have been collected.
|
||||
call ale#other_source#ShowResults(buffer, 'some-name', a:results)
|
||||
endfunction
|
||||
<
|
||||
|
||||
===============================================================================
|
||||
4. Fixing Problems *ale-fix*
|
||||
|
||||
|
@ -709,10 +789,11 @@ Completion is only supported while at least one LSP linter is enabled. ALE
|
|||
will only suggest symbols provided by the LSP servers.
|
||||
|
||||
Suggestions will be made while you type after completion is enabled.
|
||||
Completion can be enabled by setting |g:ale_completion_enabled| to `1`. The
|
||||
delay for completion can be configured with |g:ale_completion_delay|. ALE will
|
||||
only suggest so many possible matches for completion. The maximum number of
|
||||
items can be controlled with |g:ale_completion_max_suggestions|.
|
||||
Completion can be enabled by setting |g:ale_completion_enabled| to `1`. This
|
||||
setting must be set to `1` before ALE is loaded. The delay for completion can
|
||||
be configured with |g:ale_completion_delay|. ALE will only suggest so many
|
||||
possible matches for completion. The maximum number of items can be controlled
|
||||
with |g:ale_completion_max_suggestions|.
|
||||
|
||||
If you don't like some of the suggestions you see, you can filter them out
|
||||
with |g:ale_completion_excluded_words| or |b:ale_completion_excluded_words|.
|
||||
|
@ -758,12 +839,34 @@ at the cursor taken from LSP linters. The following commands are supported:
|
|||
|
||||
|ALEHover| - Print information about the symbol at the cursor.
|
||||
|
||||
If |b:ale_set_balloons| is set to `1` and your version of Vim supports the
|
||||
If |g:ale_set_balloons| is set to `1` and your version of Vim supports the
|
||||
|balloon_show()| function, then "hover" information also show up when you move
|
||||
the mouse over a symbol in a buffer. Diagnostic information will take priority
|
||||
over hover information for balloons. If a line contains a problem, that
|
||||
problem will be displayed in a balloon instead of hover information.
|
||||
|
||||
For Vim 8.1+ terminals, mouse hovering is disabled by default. Enabling
|
||||
|balloonexpr| commands in terminals can cause scrolling issues in terminals,
|
||||
so ALE will not attempt to show balloons unless |g:ale_set_balloons| is set to
|
||||
`1` before ALE is loaded.
|
||||
|
||||
For enabling mouse support in terminals, you may have to change your mouse
|
||||
settings. For example: >
|
||||
|
||||
" Example mouse settings.
|
||||
" You will need to try different settings, depending on your terminal.
|
||||
set mouse=a
|
||||
set ttymouse=xterm
|
||||
<
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
5.5 Symbol Search *ale-symbol-search*
|
||||
|
||||
ALE supports searching for workspace symbols via LSP linters. The following
|
||||
commands are supported:
|
||||
|
||||
|ALESymbolSearch| - Search for symbols in the workspace.
|
||||
|
||||
|
||||
===============================================================================
|
||||
6. Global Options *ale-options*
|
||||
|
@ -876,6 +979,9 @@ g:ale_completion_enabled *g:ale_completion_enabled*
|
|||
|
||||
When this option is set to `1`, completion support will be enabled.
|
||||
|
||||
This setting must be set to `1` before ALE is loaded for this behavior
|
||||
to be enabled.
|
||||
|
||||
See |ale-completion|
|
||||
|
||||
|
||||
|
@ -1282,10 +1388,12 @@ g:ale_linter_aliases *g:ale_linter_aliases*
|
|||
ALE will first look for aliases for filetypes in the `b:ale_linter_aliases`
|
||||
variable, then `g:ale_linter_aliases`, and then a default Dictionary.
|
||||
|
||||
`b:ale_linter_aliases` can be set to a |List|, to tell ALE to load the
|
||||
linters for specific filetypes for a given buffer. >
|
||||
`b:ale_linter_aliases` can be set to a |List| or a |String|, to tell ALE to
|
||||
load the linters for specific filetypes for a given buffer. >
|
||||
|
||||
let b:ale_linter_aliases = ['html', 'javascript', 'css']
|
||||
" OR, Alias a filetype to only a single filetype with a String.
|
||||
let b:ale_linter_aliases = 'javascript'
|
||||
<
|
||||
No linters will be loaded when the buffer's filetype is empty.
|
||||
|
||||
|
@ -1306,6 +1414,7 @@ g:ale_linters *g:ale_linters*
|
|||
\ 'hack': ['hack'],
|
||||
\ 'help': [],
|
||||
\ 'perl': ['perlcritic'],
|
||||
\ 'perl6': [],
|
||||
\ 'python': ['flake8', 'mypy', 'pylint'],
|
||||
\ 'rust': ['cargo'],
|
||||
\ 'spec': [],
|
||||
|
@ -2049,6 +2158,14 @@ ALEHover *ALEHover*
|
|||
|
||||
A plug mapping `<Plug>(ale_hover)` is defined for this command.
|
||||
|
||||
|
||||
ALESymbolSearch `<query>` *ALESymbolSearch*
|
||||
|
||||
Search for symbols in the workspace, taken from any available LSP linters.
|
||||
|
||||
The arguments provided to this command will be used as a search query for
|
||||
finding symbols in the workspace, such as functions, types, etc.
|
||||
|
||||
*:ALELint*
|
||||
ALELint *ALELint*
|
||||
|
||||
|
@ -2568,6 +2685,9 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
|||
`initialization_options_callback` may be defined to
|
||||
pass initialization options to the LSP.
|
||||
|
||||
An optional `lsp_config` or `lsp_config_callback` may
|
||||
be defined to pass configuration settings 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.
|
||||
|
@ -2628,6 +2748,16 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
|||
This can be used in place of `initialization_options`
|
||||
when more complicated processing is needed.
|
||||
|
||||
`lsp_config` A |Dictionary| of configuration settings for LSPs.
|
||||
This will be fed (as JSON) to the LSP in the
|
||||
workspace/didChangeConfiguration command.
|
||||
|
||||
`lsp_config_callback` A |String| or |Funcref| for a callback function
|
||||
accepting a buffer number. A |Dictionary| should be
|
||||
returned for configuration settings to pass the LSP.
|
||||
This can be used in place of `lsp_config` when more
|
||||
complicated processing is needed.
|
||||
|
||||
Only one of `command`, `command_callback`, or `command_chain` should be
|
||||
specified. `command_callback` is generally recommended when a command string
|
||||
needs to be generated dynamically, or any global options are used.
|
||||
|
@ -2728,6 +2858,25 @@ ale#linter#PreventLoading(filetype) *ale#linter#PreventLoading()*
|
|||
|runtimepath| for that filetype. This function can be called from vimrc or
|
||||
similar to prevent ALE from loading linters.
|
||||
|
||||
ale#other_source#ShowResults(buffer, linter_name, loclist)
|
||||
*ale#other_source#ShowResults()*
|
||||
|
||||
Show results from another source of information.
|
||||
|
||||
`buffer` must be a valid buffer number, and `linter_name` must be a unique
|
||||
name for identifying another source of information. The `loclist` given
|
||||
where the problems in a buffer are, and should be provided in the format ALE
|
||||
uses for regular linter results. See |ale-loclist-format|.
|
||||
|
||||
|
||||
ale#other_source#StartChecking(buffer, linter_name)
|
||||
*ale#other_source#StartChecking()*
|
||||
|
||||
Tell ALE that another source of information has started checking a buffer.
|
||||
|
||||
`buffer` must be a valid buffer number, and `linter_name` must be a unique
|
||||
name for identifying another source of information.
|
||||
|
||||
|
||||
ale#statusline#Count(buffer) *ale#statusline#Count()*
|
||||
|
||||
|
@ -2756,10 +2905,21 @@ b:ale_linted *b:ale_linted*
|
|||
echo getbufvar(bufnr(''), 'ale_linted', 0) > 0 ? 'checked' : 'not checked'
|
||||
<
|
||||
|
||||
g:ale_want_results_buffer *g:ale_want_results_buffer*
|
||||
|
||||
`g:ale_want_results_buffer` is set to the number of the buffer being checked
|
||||
when the |ALEWantResults| event is signaled. This variable should be read to
|
||||
figure out which buffer other sources should lint.
|
||||
|
||||
|
||||
ALELintPre *ALELintPre-autocmd*
|
||||
*ALELintPre*
|
||||
ALELintPost *ALELintPost-autocmd*
|
||||
*ALELintPost*
|
||||
ALEFixPre *ALEFixPre-autocmd*
|
||||
*ALEFixPre*
|
||||
ALEFixPost *ALEFixPost-autocmd*
|
||||
*ALEFixPost*
|
||||
|
||||
These |User| autocommands are triggered before and after every lint or fix
|
||||
cycle. They can be used to update statuslines, send notifications, etc.
|
||||
|
@ -2773,7 +2933,7 @@ ALEFixPost *ALEFixPost-autocmd*
|
|||
autocmd!
|
||||
autocmd User ALELintPre hi Statusline ctermfg=darkgrey
|
||||
autocmd User ALELintPost hi Statusline ctermfg=NONE
|
||||
augroup end
|
||||
augroup END
|
||||
<
|
||||
Or to display the progress in the statusline:
|
||||
>
|
||||
|
@ -2783,10 +2943,11 @@ ALEFixPost *ALEFixPost-autocmd*
|
|||
autocmd!
|
||||
autocmd User ALELintPre let s:ale_running = 1 | redrawstatus
|
||||
autocmd User ALELintPost let s:ale_running = 0 | redrawstatus
|
||||
augroup end
|
||||
augroup END
|
||||
|
||||
<
|
||||
ALEJobStarted *ALEJobStarted-autocmd*
|
||||
*ALEJobStarted*
|
||||
|
||||
This |User| autocommand is triggered immediately after a job is successfully
|
||||
run. This provides better accuracy for checking linter status with
|
||||
|
@ -2794,6 +2955,22 @@ ALEJobStarted *ALEJobStarted-autocmd*
|
|||
triggered before any linters are executed.
|
||||
|
||||
|
||||
ALEWantResults *ALEWantResults-autocmd*
|
||||
*ALEWantResults*
|
||||
|
||||
This |User| autocommand is triggered before ALE begins a lint cycle. Another
|
||||
source can respond by calling |ale#other_source#StartChecking()|, and
|
||||
|ALELintPre| will be signaled thereafter, to allow other plugins to know
|
||||
that another source is checking the buffer.
|
||||
|
||||
|g:ale_want_results_buffer| will be set to the number for a buffer being
|
||||
checked when the event is signaled, and deleted after the event is done.
|
||||
This variable should be read to know which buffer to check.
|
||||
|
||||
Other plugins can use this event to start checking buffers when ALE events
|
||||
for checking buffers are triggered.
|
||||
|
||||
|
||||
===============================================================================
|
||||
10. Special Thanks *ale-special-thanks*
|
||||
|
||||
|
|
|
@ -194,6 +194,9 @@ command! -bar ALEFindReferences :call ale#references#Find()
|
|||
command! -bar ALEHover :call ale#hover#Show(bufnr(''), getcurpos()[1],
|
||||
\ getcurpos()[2], {})
|
||||
|
||||
" Search for appearances of a symbol, such as a type name or function name.
|
||||
command! -nargs=1 ALESymbolSearch :call ale#symbol#Search(<q-args>)
|
||||
|
||||
" <Plug> mappings for commands
|
||||
nnoremap <silent> <Plug>(ale_previous) :ALEPrevious<Return>
|
||||
nnoremap <silent> <Plug>(ale_previous_wrap) :ALEPreviousWrap<Return>
|
||||
|
|
|
@ -2015,7 +2015,7 @@ fu! s:bufnrfilpath(line)
|
|||
let filpath = s:dyncwd.s:lash().a:line
|
||||
en
|
||||
let filpath = fnamemodify(filpath, ':p')
|
||||
let bufnr = bufnr('^'.filpath.'$')
|
||||
let bufnr = bufnr('^'.fnameescape(filpath).'$')
|
||||
if (!filereadable(filpath) && bufnr < 1)
|
||||
if (a:line =~ '[\/]\?\[\d\+\*No Name\]$')
|
||||
let bufnr = str2nr(matchstr(a:line, '[\/]\?\[\zs\d\+\ze\*No Name\]$'))
|
||||
|
|
|
@ -255,6 +255,7 @@ function! s:findAndRevealPath(pathStr)
|
|||
endif
|
||||
|
||||
try
|
||||
let l:pathStr = g:NERDTreePath.Resolve(l:pathStr)
|
||||
let l:pathObj = g:NERDTreePath.New(l:pathStr)
|
||||
catch /^NERDTree.InvalidArgumentsError/
|
||||
call nerdtree#echoWarning('invalid path')
|
||||
|
@ -524,10 +525,17 @@ endfunction
|
|||
" Reloads the current root. All nodes below this will be lost and the root dir
|
||||
" will be reloaded.
|
||||
function! s:refreshRoot()
|
||||
if !g:NERDTree.IsOpen()
|
||||
return
|
||||
endif
|
||||
call nerdtree#echo("Refreshing the root node. This could take a while...")
|
||||
|
||||
let l:curWin = winnr()
|
||||
call nerdtree#exec(g:NERDTree.GetWinNum() . "wincmd w")
|
||||
call b:NERDTree.root.refresh()
|
||||
call b:NERDTree.render()
|
||||
redraw
|
||||
call nerdtree#exec(l:curWin . "wincmd w")
|
||||
call nerdtree#echo("Refreshing the root node. This could take a while... DONE")
|
||||
endfunction
|
||||
|
||||
|
@ -554,6 +562,7 @@ function! nerdtree#ui_glue#setupCommands()
|
|||
command! -n=1 -complete=customlist,nerdtree#completeBookmarks -bar NERDTreeFromBookmark call g:NERDTreeCreator.CreateTabTree('<args>')
|
||||
command! -n=0 -bar NERDTreeMirror call g:NERDTreeCreator.CreateMirror()
|
||||
command! -n=? -complete=file -bar NERDTreeFind call s:findAndRevealPath('<args>')
|
||||
command! -n=0 -bar NERDTreeRefreshRoot call s:refreshRoot()
|
||||
command! -n=0 -bar NERDTreeFocus call NERDTreeFocus()
|
||||
command! -n=0 -bar NERDTreeCWD call NERDTreeCWD()
|
||||
endfunction
|
||||
|
|
|
@ -145,6 +145,9 @@ The following features and functionality are provided by the NERD tree:
|
|||
Change the NERDTree root to the current working directory. If no
|
||||
NERDTree exists for this tab, a new one is opened.
|
||||
|
||||
:NERDTreeRefreshRoot *:NERDTreeRefreshRoot*
|
||||
Refreshes the NERD tree root node.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
2.2. Bookmarks *NERDTreeBookmarks*
|
||||
|
||||
|
@ -992,17 +995,33 @@ appended to the array.
|
|||
|
||||
The regex '\/$' should be used to match directory nodes.
|
||||
|
||||
A special flag can be used to sort by the modification timestamps of files and
|
||||
directories. It is either '[[timestamp]]' for ascending, or '[[-timestamp]]'
|
||||
for descending. If placed at the beginning of the list, files and directories
|
||||
are sorted by timestamp, and then by the remaining items in the sort order
|
||||
list. If this flag is in any other position of the list, timestamp sorting is
|
||||
done secondarily. See examples 4, 5, and 6 below.
|
||||
|
||||
After this sorting is done, the files in each group are sorted alphabetically.
|
||||
|
||||
Other examples: >
|
||||
(1) ['*', '\/$']
|
||||
(2) []
|
||||
(3) ['\/$', '\.rb$', '\.php$', '*', '\.swp$', '\.bak$', '\~$']
|
||||
(4) ['[[timestamp]]']
|
||||
(5) ['\/$', '*', '[[-timestamp]]']
|
||||
(6) ['\.md$', '\.c$', '[[-timestamp]]', '*']
|
||||
<
|
||||
1. Directories will appear last, everything else will appear above.
|
||||
2. Everything will simply appear in alphabetical order.
|
||||
3. Dirs will appear first, then ruby and php. Swap files, bak files and vim
|
||||
backup files will appear last with everything else preceding them.
|
||||
4. All files and directories are sorted by timestamp, oldest first. If any
|
||||
files have identical timestamps, they are sorted alphabetically.
|
||||
5. Directories are first, newest to oldest, then everything else, newest to
|
||||
oldest.
|
||||
6. Markdown files first, followed by C source files, then everything else.
|
||||
Each group is shown newest to oldest.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
*'NERDTreeStatusline'*
|
||||
|
@ -1014,7 +1033,7 @@ Defines the value for the |'statusline'| setting in NERDTree windows.
|
|||
Note: The setting is actually applied using |:let-&|, not |:set|, so
|
||||
escaping spaces is not necessary.
|
||||
|
||||
Setting this option to -1 will will deactivate it so that your global
|
||||
Setting this option to -1 will deactivate it so that your global
|
||||
|'statusline'| setting is used.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
|
|
@ -39,10 +39,10 @@ endfunction
|
|||
|
||||
" FUNCTION: Path.cacheDisplayString() {{{1
|
||||
function! s:Path.cacheDisplayString() abort
|
||||
let self.cachedDisplayString = self.getLastPathComponent(1)
|
||||
let self.cachedDisplayString = g:NERDTreeNodeDelimiter . self.getLastPathComponent(1)
|
||||
|
||||
if self.isExecutable
|
||||
let self.cachedDisplayString = self.cachedDisplayString . '*'
|
||||
let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . '*'
|
||||
endif
|
||||
|
||||
let self._bookmarkNames = []
|
||||
|
@ -52,15 +52,24 @@ function! s:Path.cacheDisplayString() abort
|
|||
endif
|
||||
endfor
|
||||
if !empty(self._bookmarkNames) && g:NERDTreeMarkBookmarks == 1
|
||||
let self.cachedDisplayString .= ' {' . join(self._bookmarkNames) . '}'
|
||||
let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . ' {' . join(self._bookmarkNames) . '}'
|
||||
endif
|
||||
|
||||
if self.isSymLink
|
||||
let self.cachedDisplayString .= ' -> ' . self.symLinkDest
|
||||
let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . ' -> ' . self.symLinkDest
|
||||
endif
|
||||
|
||||
if self.isReadOnly
|
||||
let self.cachedDisplayString .= ' ['.g:NERDTreeGlyphReadOnly.']'
|
||||
let self.cachedDisplayString = self.addDelimiter(self.cachedDisplayString) . ' ['.g:NERDTreeGlyphReadOnly.']'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" FUNCTION: Path.addDelimiter() {{{1
|
||||
function! s:Path.addDelimiter(line)
|
||||
if a:line =~# '\(.*' . g:NERDTreeNodeDelimiter . '\)\{2}'
|
||||
return a:line
|
||||
else
|
||||
return a:line . g:NERDTreeNodeDelimiter
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
@ -392,7 +401,17 @@ endfunction
|
|||
" FUNCTION: Path.getSortKey() {{{1
|
||||
" returns a key used in compare function for sorting
|
||||
function! s:Path.getSortKey()
|
||||
if !exists("self._sortKey") || g:NERDTreeSortOrder !=# g:NERDTreeOldSortOrder
|
||||
let l:ascending = index(g:NERDTreeSortOrder,'[[timestamp]]')
|
||||
let l:descending = index(g:NERDTreeSortOrder,'[[-timestamp]]')
|
||||
if !exists("self._sortKey") || g:NERDTreeSortOrder !=# g:NERDTreeOldSortOrder || l:ascending >= 0 || l:descending >= 0
|
||||
let self._sortKey = [self.getSortOrderIndex()]
|
||||
|
||||
if l:descending >= 0
|
||||
call insert(self._sortKey, -getftime(self.str()), l:descending == 0 ? 0 : len(self._sortKey))
|
||||
elseif l:ascending >= 0
|
||||
call insert(self._sortKey, getftime(self.str()), l:ascending == 0 ? 0 : len(self._sortKey))
|
||||
endif
|
||||
|
||||
let path = self.getLastPathComponent(1)
|
||||
if !g:NERDTreeSortHiddenFirst
|
||||
let path = substitute(path, '^[._]', '', '')
|
||||
|
@ -400,13 +419,9 @@ function! s:Path.getSortKey()
|
|||
if !g:NERDTreeCaseSensitiveSort
|
||||
let path = tolower(path)
|
||||
endif
|
||||
if !g:NERDTreeNaturalSort
|
||||
let self._sortKey = [self.getSortOrderIndex(), path]
|
||||
else
|
||||
let self._sortKey = [self.getSortOrderIndex()] + self._splitChunks(path)
|
||||
endif
|
||||
endif
|
||||
|
||||
call extend(self._sortKey, (g:NERDTreeNaturalSort ? self._splitChunks(path) : [path]))
|
||||
endif
|
||||
return self._sortKey
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -99,7 +99,8 @@ function! s:TreeDirNode.displayString()
|
|||
let l:label = ''
|
||||
let l:cascade = self.getCascade()
|
||||
for l:dirNode in l:cascade
|
||||
let l:label .= l:dirNode.path.displayString()
|
||||
let l:next = l:dirNode.path.displayString()
|
||||
let l:label .= l:label == '' ? l:next : substitute(l:next,'^.','','')
|
||||
endfor
|
||||
|
||||
" Select the appropriate open/closed status indicator symbol.
|
||||
|
@ -304,9 +305,11 @@ function! s:TreeDirNode._glob(pattern, all)
|
|||
for l:file in l:globList
|
||||
let l:tail = fnamemodify(l:file, ':t')
|
||||
|
||||
" Double the modifier if only a separator was stripped.
|
||||
" If l:file has a trailing slash, then its :tail will be ''. Use
|
||||
" :h to drop the slash and the empty string after it; then use :t
|
||||
" to get the directory name.
|
||||
if l:tail == ''
|
||||
let l:tail = fnamemodify(l:file, ':t:t')
|
||||
let l:tail = fnamemodify(l:file, ':h:t')
|
||||
endif
|
||||
|
||||
if l:tail == '.' || l:tail == '..'
|
||||
|
|
|
@ -180,7 +180,7 @@ function! s:TreeFileNode.GetSelected()
|
|||
endif
|
||||
|
||||
return b:NERDTree.root.findNode(l:path)
|
||||
catch /^NERDTree/
|
||||
catch
|
||||
return {}
|
||||
endtry
|
||||
endfunction
|
||||
|
@ -242,7 +242,7 @@ endfunction
|
|||
|
||||
" FUNCTION: TreeFileNode.openInNewTab(options) {{{1
|
||||
function! s:TreeFileNode.openInNewTab(options)
|
||||
echomsg 'TreeFileNode.openInNewTab is deprecated'
|
||||
call nerdtree#deprecated('TreeFileNode.openinNewTab', 'is deprecated, use .open() instead.')
|
||||
call self.open(extend({'where': 't'}, a:options))
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -300,7 +300,7 @@ endfunction
|
|||
|
||||
" FUNCTION: s:UI.MarkupReg() {{{1
|
||||
function! s:UI.MarkupReg()
|
||||
return '^\(['.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.'] \| \+['.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.'] \| \+\)'
|
||||
return '^ *['.g:NERDTreeDirArrowExpandable.g:NERDTreeDirArrowCollapsible.']\? '
|
||||
endfunction
|
||||
|
||||
" FUNCTION: s:UI._renderBookmarks {{{1
|
||||
|
@ -363,30 +363,13 @@ function! s:UI.setShowHidden(val)
|
|||
endfunction
|
||||
|
||||
" FUNCTION: s:UI._stripMarkup(line){{{1
|
||||
" returns the given line with all the tree parts stripped off
|
||||
" find the filename in the given line, and return it.
|
||||
"
|
||||
" Args:
|
||||
" line: the subject line
|
||||
function! s:UI._stripMarkup(line)
|
||||
let line = a:line
|
||||
" remove the tree parts and the leading space
|
||||
let line = substitute (line, g:NERDTreeUI.MarkupReg(),"","")
|
||||
|
||||
" strip off any read only flag
|
||||
let line = substitute (line, ' \['.g:NERDTreeGlyphReadOnly.'\]', "","")
|
||||
|
||||
" strip off any bookmark flags
|
||||
let line = substitute (line, ' {[^}]*}', "","")
|
||||
|
||||
" strip off any executable flags
|
||||
let line = substitute (line, '*\ze\($\| \)', "","")
|
||||
|
||||
" strip off any generic flags
|
||||
let line = substitute (line, '\[[^]]*\]', "","")
|
||||
|
||||
let line = substitute (line,' -> .*',"","") " remove link to
|
||||
|
||||
return line
|
||||
let l:line = substitute(a:line, '^.\{-}' . g:NERDTreeNodeDelimiter, '', '')
|
||||
return substitute(l:line, g:NERDTreeNodeDelimiter.'.*$', '', '')
|
||||
endfunction
|
||||
|
||||
" FUNCTION: s:UI.render() {{{1
|
||||
|
|
|
@ -83,31 +83,32 @@ function! s:promptToDelBuffer(bufnum, msg)
|
|||
endif
|
||||
endfunction
|
||||
|
||||
"FUNCTION: s:promptToRenameBuffer(bufnum, msg){{{1
|
||||
"prints out the given msg and, if the user responds by pushing 'y' then the
|
||||
"buffer with the given bufnum is replaced with a new one
|
||||
"FUNCTION: s:renameBuffer(bufNum, newNodeName, isDirectory){{{1
|
||||
"The buffer with the given bufNum is replaced with a new one
|
||||
"
|
||||
"Args:
|
||||
"bufnum: the buffer that may be deleted
|
||||
"msg: a message that will be echoed to the user asking them if they wish to
|
||||
" del the buffer
|
||||
function! s:promptToRenameBuffer(bufnum, msg, newFileName)
|
||||
echo a:msg
|
||||
if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y'
|
||||
let quotedFileName = fnameescape(a:newFileName)
|
||||
" 1. ensure that a new buffer is loaded
|
||||
exec "badd " . quotedFileName
|
||||
" 2. ensure that all windows which display the just deleted filename
|
||||
" display a buffer for a new filename.
|
||||
let s:originalTabNumber = tabpagenr()
|
||||
let s:originalWindowNumber = winnr()
|
||||
let editStr = g:NERDTreePath.New(a:newFileName).str({'format': 'Edit'})
|
||||
exec "tabdo windo if winbufnr(0) == " . a:bufnum . " | exec ':e! " . editStr . "' | endif"
|
||||
exec "tabnext " . s:originalTabNumber
|
||||
exec s:originalWindowNumber . "wincmd w"
|
||||
" 3. We don't need a previous buffer anymore
|
||||
exec "bwipeout! " . a:bufnum
|
||||
"bufNum: the buffer that may be deleted
|
||||
"newNodeName: the name given to the renamed node
|
||||
"isDirectory: determines how to do the create the new filenames
|
||||
function! s:renameBuffer(bufNum, newNodeName, isDirectory)
|
||||
if a:isDirectory
|
||||
let quotedFileName = fnameescape(a:newNodeName . '/' . fnamemodify(bufname(a:bufNum),':t'))
|
||||
let editStr = g:NERDTreePath.New(a:newNodeName . '/' . fnamemodify(bufname(a:bufNum),':t')).str({'format': 'Edit'})
|
||||
else
|
||||
let quotedFileName = fnameescape(a:newNodeName)
|
||||
let editStr = g:NERDTreePath.New(a:newNodeName).str({'format': 'Edit'})
|
||||
endif
|
||||
" 1. ensure that a new buffer is loaded
|
||||
exec "badd " . quotedFileName
|
||||
" 2. ensure that all windows which display the just deleted filename
|
||||
" display a buffer for a new filename.
|
||||
let s:originalTabNumber = tabpagenr()
|
||||
let s:originalWindowNumber = winnr()
|
||||
exec "tabdo windo if winbufnr(0) == " . a:bufNum . " | exec ':e! " . editStr . "' | endif"
|
||||
exec "tabnext " . s:originalTabNumber
|
||||
exec s:originalWindowNumber . "wincmd w"
|
||||
" 3. We don't need a previous buffer anymore
|
||||
exec "bwipeout! " . a:bufNum
|
||||
endfunction
|
||||
"FUNCTION: NERDTreeAddNode(){{{1
|
||||
function! NERDTreeAddNode()
|
||||
|
@ -128,6 +129,9 @@ function! NERDTreeAddNode()
|
|||
let parentNode = b:NERDTree.root.findNode(newPath.getParent())
|
||||
|
||||
let newTreeNode = g:NERDTreeFileNode.New(newPath, b:NERDTree)
|
||||
" Emptying g:NERDTreeOldSortOrder forces the sort to
|
||||
" recalculate the cached sortKey so nodes sort correctly.
|
||||
let g:NERDTreeOldSortOrder = []
|
||||
if empty(parentNode)
|
||||
call b:NERDTree.root.refresh()
|
||||
call b:NERDTree.render()
|
||||
|
@ -155,17 +159,33 @@ function! NERDTreeMoveNode()
|
|||
endif
|
||||
|
||||
try
|
||||
let bufnum = bufnr("^".curNode.path.str()."$")
|
||||
if curNode.path.isDirectory
|
||||
let l:openBuffers = filter(range(1,bufnr("$")),'bufexists(v:val) && fnamemodify(bufname(v:val),":p") =~# curNode.path.str() . "/.*"')
|
||||
else
|
||||
let l:openBuffers = filter(range(1,bufnr("$")),'bufexists(v:val) && fnamemodify(bufname(v:val),":p") ==# curNode.path.str()')
|
||||
endif
|
||||
|
||||
call curNode.rename(newNodePath)
|
||||
" Emptying g:NERDTreeOldSortOrder forces the sort to
|
||||
" recalculate the cached sortKey so nodes sort correctly.
|
||||
let g:NERDTreeOldSortOrder = []
|
||||
call b:NERDTree.root.refresh()
|
||||
call NERDTreeRender()
|
||||
|
||||
"if the node is open in a buffer, ask the user if they want to
|
||||
"close that buffer
|
||||
if bufnum != -1
|
||||
let prompt = "\nNode renamed.\n\nThe old file is open in buffer ". bufnum . (bufwinnr(bufnum) ==# -1 ? " (hidden)" : "") .". Replace this buffer with the new file? (yN)"
|
||||
call s:promptToRenameBuffer(bufnum, prompt, newNodePath)
|
||||
" If the file node is open, or files under the directory node are
|
||||
" open, ask the user if they want to replace the file(s) with the
|
||||
" renamed files.
|
||||
if !empty(l:openBuffers)
|
||||
if curNode.path.isDirectory
|
||||
echo "\nDirectory renamed.\n\nFiles with the old directory name are open in buffers " . join(l:openBuffers, ', ') . ". Replace these buffers with the new files? (yN)"
|
||||
else
|
||||
echo "\nFile renamed.\n\nThe old file is open in buffer " . l:openBuffers[0] . ". Replace this buffer with the new file? (yN)"
|
||||
endif
|
||||
if g:NERDTreeAutoDeleteBuffer || nr2char(getchar()) ==# 'y'
|
||||
for bufNum in l:openBuffers
|
||||
call s:renameBuffer(bufNum, newNodePath, curNode.path.isDirectory)
|
||||
endfor
|
||||
endif
|
||||
endif
|
||||
|
||||
call curNode.putCursorHere(1, 0)
|
||||
|
@ -226,9 +246,9 @@ function! NERDTreeListNode()
|
|||
let treenode = g:NERDTreeFileNode.GetSelected()
|
||||
if !empty(treenode)
|
||||
let s:uname = system("uname")
|
||||
let stat_cmd = 'stat -c "%s" '
|
||||
|
||||
if s:uname =~? "Darwin"
|
||||
let stat_cmd = 'stat -c "%s" '
|
||||
|
||||
if s:uname =~? "Darwin"
|
||||
let stat_cmd = 'stat -f "%z" '
|
||||
endif
|
||||
|
||||
|
@ -248,33 +268,13 @@ function! NERDTreeListNodeWin32()
|
|||
let l:node = g:NERDTreeFileNode.GetSelected()
|
||||
|
||||
if !empty(l:node)
|
||||
|
||||
let l:save_shell = &shell
|
||||
set shell&
|
||||
|
||||
if exists('+shellslash')
|
||||
let l:save_shellslash = &shellslash
|
||||
set noshellslash
|
||||
endif
|
||||
|
||||
let l:command = 'DIR /Q '
|
||||
\ . shellescape(l:node.path.str())
|
||||
\ . ' | FINDSTR "^[012][0-9]/[0-3][0-9]/[12][0-9][0-9][0-9]"'
|
||||
|
||||
let l:metadata = split(system(l:command), "\n")
|
||||
|
||||
if v:shell_error == 0
|
||||
call nerdtree#echo(l:metadata[0])
|
||||
else
|
||||
call nerdtree#echoError('shell command failed')
|
||||
endif
|
||||
|
||||
let &shell = l:save_shell
|
||||
|
||||
if exists('l:save_shellslash')
|
||||
let &shellslash = l:save_shellslash
|
||||
endif
|
||||
|
||||
let l:path = l:node.path.str()
|
||||
call nerdtree#echo(printf("%s:%s MOD:%s BYTES:%d PERMISSIONS:%s",
|
||||
\ toupper(getftype(l:path)),
|
||||
\ fnamemodify(l:path, ':t'),
|
||||
\ strftime("%c", getftime(l:path)),
|
||||
\ getfsize(l:path),
|
||||
\ getfperm(l:path)))
|
||||
return
|
||||
endif
|
||||
|
||||
|
@ -303,6 +303,9 @@ function! NERDTreeCopyNode()
|
|||
if confirmed
|
||||
try
|
||||
let newNode = currentNode.copy(newNodePath)
|
||||
" Emptying g:NERDTreeOldSortOrder forces the sort to
|
||||
" recalculate the cached sortKey so nodes sort correctly.
|
||||
let g:NERDTreeOldSortOrder = []
|
||||
if empty(newNode)
|
||||
call b:NERDTree.root.refresh()
|
||||
call b:NERDTree.render()
|
||||
|
|
|
@ -86,6 +86,9 @@ let g:NERDTreeOldSortOrder = []
|
|||
|
||||
call s:initVariable("g:NERDTreeGlyphReadOnly", "RO")
|
||||
|
||||
" ASCII 160: non-breaking space used to delimit items in the tree's nodes.
|
||||
call s:initVariable("g:NERDTreeNodeDelimiter", "\u00a0")
|
||||
|
||||
if !exists('g:NERDTreeStatusline')
|
||||
|
||||
"the exists() crap here is a hack to stop vim spazzing out when
|
||||
|
|
|
@ -36,6 +36,15 @@ exec 'syn match NERDTreeRO # *\zs.*\ze \['.g:NERDTreeGlyphReadOnly.'\]# contains
|
|||
syn match NERDTreeFlags #^ *\zs\[.\]# containedin=NERDTreeFile,NERDTreeExecFile
|
||||
syn match NERDTreeFlags #\[.\]# containedin=NERDTreeDir
|
||||
|
||||
"highlighing to conceal the delimiter around the file/dir name
|
||||
if has("conceal")
|
||||
exec 'syn match NERDTreeNodeDelimiters #' . g:NERDTreeNodeDelimiter . '# conceal containedin=NERDTreeFile,NERDTreeLinkFile,NERDTreeExecFile,NERDTreeRO,NERDTreeDir'
|
||||
setlocal conceallevel=3 concealcursor=nvic
|
||||
else
|
||||
exec 'syn match NERDTreeNodeDelimiters #' . g:NERDTreeNodeDelimiter . '# containedin=NERDTreeFile,NERDTreeLinkFile,NERDTreeExecFile,NERDTreeRO,NERDTreeDir'
|
||||
hi! link NERDTreeNodeDelimiters Ignore
|
||||
endif
|
||||
|
||||
syn match NERDTreeCWD #^[</].*$#
|
||||
|
||||
"highlighting for bookmarks
|
||||
|
|
|
@ -76,8 +76,12 @@ It also has auto-completion for location and server blocks with `location<tab>`
|
|||
|
||||
## Installation
|
||||
|
||||
Just plug it into your favorite Vim package manager:
|
||||
### Pathogen
|
||||
```bash
|
||||
git clone https://github.com/chr4/nginx.vim ~/.vim/bundle/nginx.vim
|
||||
```
|
||||
|
||||
### Other (Plug, Dein.vim, Vundle)
|
||||
```vim
|
||||
" Plug
|
||||
Plug 'chr4/nginx.vim'
|
||||
|
|
|
@ -29,9 +29,9 @@ endfunction
|
|||
|
||||
function! s:send(self,func,...)
|
||||
if type(a:func) == type('') || type(a:func) == type(0)
|
||||
let Func = get(a:self,a:func,'')
|
||||
let l:Func = get(a:self,a:func,'')
|
||||
else
|
||||
let Func = a:func
|
||||
let l:Func = a:func
|
||||
endif
|
||||
let s = type(a:self) == type({}) ? a:self : {}
|
||||
if type(Func) == type(function('tr'))
|
||||
|
@ -578,45 +578,54 @@ call extend(Abolish.Coercions, {
|
|||
\ "function missing": s:function("s:unknown_coercion")
|
||||
\}, "keep")
|
||||
|
||||
function! s:coerce(transformation)
|
||||
function! s:coerce(type) abort
|
||||
if a:type !~# '^\%(line\|char\|block\)'
|
||||
let s:transformation = a:type
|
||||
let &opfunc = matchstr(expand('<sfile>'), '<SNR>\w*')
|
||||
return 'g@'
|
||||
endif
|
||||
let selection = &selection
|
||||
let clipboard = &clipboard
|
||||
try
|
||||
set clipboard=
|
||||
set selection=inclusive clipboard-=unnamed clipboard-=unnamedplus
|
||||
let regbody = getreg('"')
|
||||
let regtype = getregtype('"')
|
||||
let c = v:count1
|
||||
while c > 0
|
||||
let c -= 1
|
||||
norm! yiw
|
||||
if a:type ==# 'line'
|
||||
let move = "'[V']"
|
||||
elseif a:type ==# 'block'
|
||||
let move = "`[\<C-V>`]"
|
||||
else
|
||||
let move = "`[v`]"
|
||||
endif
|
||||
silent exe 'normal!' move.'y'
|
||||
let word = @@
|
||||
let @@ = s:send(g:Abolish.Coercions,a:transformation,word)
|
||||
let @@ = s:send(g:Abolish.Coercions,s:transformation,word)
|
||||
if !exists('begin')
|
||||
let begin = getpos("'[")
|
||||
endif
|
||||
if word !=# @@
|
||||
let changed = 1
|
||||
norm! viwpw
|
||||
else
|
||||
norm! w
|
||||
exe 'normal!' move.'p'
|
||||
endif
|
||||
endwhile
|
||||
call setreg('"',regbody,regtype)
|
||||
call setpos("'[",begin)
|
||||
call setpos(".",begin)
|
||||
if exists("changed")
|
||||
silent! call repeat#set("\<Plug>Coerce".a:transformation)
|
||||
endif
|
||||
finally
|
||||
let &selection = selection
|
||||
let &clipboard = clipboard
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
nnoremap <silent> <Plug>Coerce :<C-U>call <SID>coerce(nr2char(getchar()))<CR>
|
||||
nnoremap <expr> <Plug>(abolish-coerce) <SID>coerce(nr2char(getchar())).'iw'
|
||||
|
||||
" }}}1
|
||||
|
||||
if !exists("g:abolish_no_mappings") || ! g:abolish_no_mappings
|
||||
nmap cr <Plug>Coerce
|
||||
nmap cr <Plug>(abolish-coerce)
|
||||
endif
|
||||
|
||||
command! -nargs=+ -bang -bar -range=0 -complete=custom,s:Complete Abolish
|
||||
|
|
|
@ -376,7 +376,7 @@ function! fugitive#repo(...) abort
|
|||
endif
|
||||
return extend(repo, s:repo_prototype, 'keep')
|
||||
endif
|
||||
call s:throw('not a git repository: '.expand('%:p'))
|
||||
call s:throw('not a Git repository: ' . string(dir))
|
||||
endfunction
|
||||
|
||||
function! s:repo_dir(...) dict abort
|
||||
|
@ -400,19 +400,19 @@ function! s:repo_bare() dict abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! s:repo_route(object) dict abort
|
||||
return fugitive#Route(a:object, self.git_dir)
|
||||
function! s:repo_find(object) dict abort
|
||||
return fugitive#Find(a:object, self.git_dir)
|
||||
endfunction
|
||||
|
||||
function! s:repo_translate(rev) dict abort
|
||||
return s:Slash(fugitive#Route(substitute(a:rev, '^/', ':(top)', ''), self.git_dir))
|
||||
return s:Slash(fugitive#Find(substitute(a:rev, '^/', ':(top)', ''), self.git_dir))
|
||||
endfunction
|
||||
|
||||
function! s:repo_head(...) dict abort
|
||||
return fugitive#Head(a:0 ? a:1 : 0, self.git_dir)
|
||||
endfunction
|
||||
|
||||
call s:add_methods('repo',['dir','tree','bare','route','translate','head'])
|
||||
call s:add_methods('repo',['dir','tree','bare','find','translate','head'])
|
||||
|
||||
function! s:repo_prepare(...) dict abort
|
||||
return call('fugitive#Prepare', [self.git_dir] + a:000)
|
||||
|
@ -485,8 +485,24 @@ function! s:Owner(path, ...) abort
|
|||
return ''
|
||||
endif
|
||||
let [pdir, commit, file] = s:DirCommitFile(a:path)
|
||||
if s:cpath(dir, pdir) && commit =~# '^\x\{40\}$'
|
||||
return commit
|
||||
if s:cpath(dir, pdir)
|
||||
if commit =~# '^\x\{40\}$'
|
||||
return commit
|
||||
elseif commit ==# '2'
|
||||
return 'HEAD^{}'
|
||||
endif
|
||||
if filereadable(dir . '/MERGE_HEAD')
|
||||
let merge_head = 'MERGE_HEAD'
|
||||
elseif filereadable(dir . '/REBASE_HEAD')
|
||||
let merge_head = 'REBASE_HEAD'
|
||||
else
|
||||
return ''
|
||||
endif
|
||||
if commit ==# '3'
|
||||
return merge_head . '^{}'
|
||||
elseif commit ==# '1'
|
||||
return s:TreeChomp('merge-base', 'HEAD', merge_head, '--')
|
||||
endif
|
||||
endif
|
||||
let path = fnamemodify(a:path, ':p')
|
||||
if s:cpath(dir . '/', path[0 : len(dir)]) && a:path =~# 'HEAD$'
|
||||
|
@ -565,7 +581,7 @@ function! s:Relative(...) abort
|
|||
return fugitive#Path(@%, a:0 ? a:1 : ':(top)')
|
||||
endfunction
|
||||
|
||||
function! fugitive#Route(object, ...) abort
|
||||
function! fugitive#Find(object, ...) abort
|
||||
if type(a:object) == type(0)
|
||||
let name = bufname(a:object)
|
||||
return s:PlatformSlash(name =~# '^$\|^/\|^\a\+:' ? name : getcwd() . '/' . name)
|
||||
|
@ -622,7 +638,7 @@ function! fugitive#Route(object, ...) abort
|
|||
else
|
||||
let altdir = FugitiveExtractGitDir(f)
|
||||
if len(altdir) && !s:cpath(dir, altdir)
|
||||
return fugitive#Route(a:object, altdir)
|
||||
return fugitive#Find(a:object, altdir)
|
||||
endif
|
||||
endif
|
||||
elseif rev =~# '^:[0-3]:'
|
||||
|
@ -654,7 +670,7 @@ function! fugitive#Route(object, ...) abort
|
|||
else
|
||||
let altdir = FugitiveExtractGitDir(file)
|
||||
if len(altdir) && !s:cpath(dir, altdir)
|
||||
return fugitive#Route(a:object, altdir)
|
||||
return fugitive#Find(a:object, altdir)
|
||||
endif
|
||||
return file
|
||||
endif
|
||||
|
@ -682,7 +698,7 @@ function! s:Generate(rev, ...) abort
|
|||
elseif a:rev =~# '^/' && len(tree) && getftime(tree . a:rev) >= 0 && getftime(a:rev) < 0
|
||||
let object = ':(top)' . a:rev[1:-1]
|
||||
endif
|
||||
return fugitive#Route(object, dir)
|
||||
return fugitive#Find(object, dir)
|
||||
endfunction
|
||||
|
||||
function! s:DotRelative(path) abort
|
||||
|
@ -1082,7 +1098,7 @@ function! fugitive#buffer(...) abort
|
|||
if buffer.getvar('git_dir') !=# ''
|
||||
return buffer
|
||||
endif
|
||||
call s:throw('not a git repository: '.bufname(buffer['#']))
|
||||
call s:throw('not a Fugitive buffer: ' . string(bufname(buffer['#'])))
|
||||
endfunction
|
||||
|
||||
function! s:buffer_getvar(var) dict abort
|
||||
|
@ -1500,7 +1516,7 @@ function! fugitive#BufReadCmd(...) abort
|
|||
if lnum
|
||||
silent keepjumps delete_
|
||||
end
|
||||
silent exe (exists(':keeppatterns') ? 'keeppatterns' : '') 'keepjumps 1,/^diff --git\|\%$/g/\r$/s///'
|
||||
silent exe (exists(':keeppatterns') ? 'keeppatterns' : '') 'keepjumps 1,/^diff --git\|\%$/s/\r$//e'
|
||||
keepjumps 1
|
||||
endif
|
||||
elseif b:fugitive_type ==# 'stage'
|
||||
|
|
|
@ -43,8 +43,8 @@ function! FugitiveReal(...) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! FugitiveRoute(...) abort
|
||||
return fugitive#Route(a:0 ? a:1 : bufnr(''), FugitiveGitDir(a:0 > 1 ? a:2 : -1))
|
||||
function! FugitiveFind(...) abort
|
||||
return fugitive#Find(a:0 ? a:1 : bufnr(''), FugitiveGitDir(a:0 > 1 ? a:2 : -1))
|
||||
endfunction
|
||||
|
||||
function! FugitivePath(...) abort
|
||||
|
@ -104,6 +104,8 @@ function! FugitiveTreeForGitDir(path) abort
|
|||
let dir = a:path
|
||||
if dir =~# '/\.git$'
|
||||
return len(dir) ==# 5 ? '/' : dir[0:-6]
|
||||
elseif dir ==# ''
|
||||
return ''
|
||||
endif
|
||||
if !has_key(s:worktree_for_dir, dir)
|
||||
let s:worktree_for_dir[dir] = ''
|
||||
|
@ -203,12 +205,12 @@ function! FugitiveDetect(path) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! FugitiveFind(...) abort
|
||||
return call('FugitiveRoute', a:000)
|
||||
function! FugitiveRoute(...) abort
|
||||
return call('FugitiveFind', a:000)
|
||||
endfunction
|
||||
|
||||
function! FugitiveGenerate(...) abort
|
||||
return call('FugitiveRoute', a:000)
|
||||
throw 'Use FugitiveFind() instead'
|
||||
endfunction
|
||||
|
||||
function! s:Slash(path) abort
|
||||
|
@ -258,7 +260,7 @@ augroup fugitive
|
|||
autocmd FileType gitrebase
|
||||
\ let &l:include = '^\%(pick\|squash\|edit\|reword\|fixup\|drop\|[pserfd]\)\>' |
|
||||
\ if exists('b:git_dir') |
|
||||
\ let &l:includeexpr = 'v:fname =~# ''^\x\{4,40\}$'' ? FugitiveRoute(v:fname) : ' .
|
||||
\ let &l:includeexpr = 'v:fname =~# ''^\x\{4,40\}$'' ? FugitiveFind(v:fname) : ' .
|
||||
\ (len(&l:includeexpr) ? &l:includeexpr : 'v:fname') |
|
||||
\ endif |
|
||||
\ let b:undo_ftplugin = get(b:, 'undo_ftplugin', 'exe') . '|setl inex= inc='
|
||||
|
|
|
@ -41,7 +41,7 @@ function! gitgutter#process_buffer(bufnr, force) abort
|
|||
|
||||
let diff = ''
|
||||
try
|
||||
let diff = gitgutter#diff#run_diff(a:bufnr, 0)
|
||||
let diff = gitgutter#diff#run_diff(a:bufnr, 'index', 0)
|
||||
catch /gitgutter not tracked/
|
||||
call gitgutter#debug#log('Not tracked: '.gitgutter#utility#file(a:bufnr))
|
||||
catch /gitgutter diff failed/
|
||||
|
|
|
@ -11,10 +11,16 @@ endfunction
|
|||
let s:c_flag = s:git_supports_command_line_config_override()
|
||||
|
||||
|
||||
let s:temp_index = tempname()
|
||||
let s:temp_from = tempname()
|
||||
let s:temp_buffer = tempname()
|
||||
|
||||
" Returns a diff of the buffer.
|
||||
" Returns a diff of the buffer against the index or the working tree.
|
||||
"
|
||||
" After running the diff we pass it through grep where available to reduce
|
||||
" subsequent processing by the plugin. If grep is not available the plugin
|
||||
" does the filtering instead.
|
||||
"
|
||||
" When diffing against the index:
|
||||
"
|
||||
" The buffer contents is not the same as the file on disk so we need to pass
|
||||
" two instances of the file to git-diff:
|
||||
|
@ -27,11 +33,6 @@ let s:temp_buffer = tempname()
|
|||
"
|
||||
" and myfileB is the buffer contents.
|
||||
"
|
||||
" After running the diff we pass it through grep where available to reduce
|
||||
" subsequent processing by the plugin. If grep is not available the plugin
|
||||
" does the filtering instead.
|
||||
"
|
||||
"
|
||||
" Regarding line endings:
|
||||
"
|
||||
" git-show does not convert line endings.
|
||||
|
@ -57,7 +58,15 @@ let s:temp_buffer = tempname()
|
|||
" When writing the temporary files we preserve the original file's extension
|
||||
" so that repos using .gitattributes to control EOL conversion continue to
|
||||
" convert correctly.
|
||||
function! gitgutter#diff#run_diff(bufnr, preserve_full_diff) abort
|
||||
"
|
||||
" Arguments:
|
||||
"
|
||||
" bufnr - the number of the buffer to be diffed
|
||||
" from - 'index' or 'working_tree'; what the buffer is diffed against
|
||||
" preserve_full_diff - truthy to return the full diff or falsey to return only
|
||||
" the hunk headers (@@ -x,y +m,n @@); only possible if
|
||||
" grep is available.
|
||||
function! gitgutter#diff#run_diff(bufnr, from, preserve_full_diff) abort
|
||||
while gitgutter#utility#repo_path(a:bufnr, 0) == -1
|
||||
sleep 5m
|
||||
endwhile
|
||||
|
@ -66,18 +75,13 @@ function! gitgutter#diff#run_diff(bufnr, preserve_full_diff) abort
|
|||
throw 'gitgutter not tracked'
|
||||
endif
|
||||
|
||||
|
||||
" Wrap compound commands in parentheses to make Windows happy.
|
||||
" bash doesn't mind the parentheses.
|
||||
let cmd = '('
|
||||
|
||||
" Append buffer number to avoid race conditions between writing and reading
|
||||
" the files when asynchronously processing multiple buffers.
|
||||
"
|
||||
" Without the buffer number, index_file would have a race in the shell
|
||||
" between the second process writing it (with git-show) and the first
|
||||
" reading it (with git-diff).
|
||||
let index_file = s:temp_index.'.'.a:bufnr
|
||||
" Append buffer number to temp filenames to avoid race conditions between
|
||||
" writing and reading the files when asynchronously processing multiple
|
||||
" buffers.
|
||||
|
||||
" Without the buffer number, buff_file would have a race between the
|
||||
" second gitgutter#process_buffer() writing the file (synchronously, below)
|
||||
|
@ -87,26 +91,39 @@ function! gitgutter#diff#run_diff(bufnr, preserve_full_diff) abort
|
|||
|
||||
let extension = gitgutter#utility#extension(a:bufnr)
|
||||
if !empty(extension)
|
||||
let index_file .= '.'.extension
|
||||
let buff_file .= '.'.extension
|
||||
endif
|
||||
|
||||
" Write file from index to temporary file.
|
||||
let index_name = g:gitgutter_diff_base.':'.gitgutter#utility#repo_path(a:bufnr, 1)
|
||||
let cmd .= g:gitgutter_git_executable.' --no-pager show '.index_name.' > '.index_file.' && '
|
||||
|
||||
" Write buffer to temporary file.
|
||||
" Note: this is synchronous.
|
||||
call s:write_buffer(a:bufnr, buff_file)
|
||||
|
||||
" Call git-diff with the temporary files.
|
||||
if a:from ==# 'index'
|
||||
" Without the buffer number, from_file would have a race in the shell
|
||||
" between the second process writing it (with git-show) and the first
|
||||
" reading it (with git-diff).
|
||||
let from_file = s:temp_from.'.'.a:bufnr
|
||||
|
||||
if !empty(extension)
|
||||
let from_file .= '.'.extension
|
||||
endif
|
||||
|
||||
" Write file from index to temporary file.
|
||||
let index_name = g:gitgutter_diff_base.':'.gitgutter#utility#repo_path(a:bufnr, 1)
|
||||
let cmd .= g:gitgutter_git_executable.' --no-pager show '.index_name.' > '.from_file.' && '
|
||||
|
||||
elseif a:from ==# 'working_tree'
|
||||
let from_file = gitgutter#utility#repo_path(a:bufnr, 1)
|
||||
endif
|
||||
|
||||
" Call git-diff.
|
||||
let cmd .= g:gitgutter_git_executable.' --no-pager '.g:gitgutter_git_args
|
||||
if s:c_flag
|
||||
let cmd .= ' -c "diff.autorefreshindex=0"'
|
||||
let cmd .= ' -c "diff.noprefix=false"'
|
||||
let cmd .= ' -c "core.safecrlf=false"'
|
||||
endif
|
||||
let cmd .= ' diff --no-ext-diff --no-color -U0 '.g:gitgutter_diff_args.' -- '.index_file.' '.buff_file
|
||||
let cmd .= ' diff --no-ext-diff --no-color -U0 '.g:gitgutter_diff_args.' -- '.from_file.' '.buff_file
|
||||
|
||||
" Pipe git-diff output into grep.
|
||||
if !a:preserve_full_diff && !empty(g:gitgutter_grep)
|
||||
|
@ -315,8 +332,14 @@ endfunction
|
|||
|
||||
|
||||
" Returns a diff for the current hunk.
|
||||
function! gitgutter#diff#hunk_diff(bufnr, full_diff)
|
||||
" Assumes there is only 1 current hunk unless the optional argument is given,
|
||||
" in which case the cursor is in two hunks and the argument specifies the one
|
||||
" to choose.
|
||||
"
|
||||
" Optional argument: 0 (to use the first hunk) or 1 (to use the second).
|
||||
function! gitgutter#diff#hunk_diff(bufnr, full_diff, ...)
|
||||
let modified_diff = []
|
||||
let hunk_index = 0
|
||||
let keep_line = 1
|
||||
" Don't keepempty when splitting because the diff we want may not be the
|
||||
" final one. Instead add trailing NL at end of function.
|
||||
|
@ -324,6 +347,12 @@ function! gitgutter#diff#hunk_diff(bufnr, full_diff)
|
|||
let hunk_info = gitgutter#diff#parse_hunk(line)
|
||||
if len(hunk_info) == 4 " start of new hunk
|
||||
let keep_line = gitgutter#hunk#cursor_in_hunk(hunk_info)
|
||||
|
||||
if a:0 && hunk_index != a:1
|
||||
let keep_line = 0
|
||||
endif
|
||||
|
||||
let hunk_index += 1
|
||||
endif
|
||||
if keep_line
|
||||
call add(modified_diff, line)
|
||||
|
|
|
@ -73,6 +73,7 @@ function! gitgutter#highlight#define_signs() abort
|
|||
sign define GitGutterLineModified
|
||||
sign define GitGutterLineRemoved
|
||||
sign define GitGutterLineRemovedFirstLine
|
||||
sign define GitGutterLineRemovedAboveAndBelow
|
||||
sign define GitGutterLineModifiedRemoved
|
||||
sign define GitGutterDummy
|
||||
|
||||
|
@ -82,11 +83,12 @@ function! gitgutter#highlight#define_signs() abort
|
|||
endfunction
|
||||
|
||||
function! s:define_sign_text() abort
|
||||
execute "sign define GitGutterLineAdded text=" . g:gitgutter_sign_added
|
||||
execute "sign define GitGutterLineModified text=" . g:gitgutter_sign_modified
|
||||
execute "sign define GitGutterLineRemoved text=" . g:gitgutter_sign_removed
|
||||
execute "sign define GitGutterLineRemovedFirstLine text=" . g:gitgutter_sign_removed_first_line
|
||||
execute "sign define GitGutterLineModifiedRemoved text=" . g:gitgutter_sign_modified_removed
|
||||
execute "sign define GitGutterLineAdded text=" . g:gitgutter_sign_added
|
||||
execute "sign define GitGutterLineModified text=" . g:gitgutter_sign_modified
|
||||
execute "sign define GitGutterLineRemoved text=" . g:gitgutter_sign_removed
|
||||
execute "sign define GitGutterLineRemovedFirstLine text=" . g:gitgutter_sign_removed_first_line
|
||||
execute "sign define GitGutterLineRemovedAboveAndBelow text=" . g:gitgutter_sign_removed_above_and_below
|
||||
execute "sign define GitGutterLineModifiedRemoved text=" . g:gitgutter_sign_modified_removed
|
||||
endfunction
|
||||
|
||||
function! gitgutter#highlight#define_sign_text_highlights() abort
|
||||
|
@ -95,33 +97,37 @@ function! gitgutter#highlight#define_sign_text_highlights() abort
|
|||
" off or disabling) we make them invisible by setting their foreground colours
|
||||
" to the background's.
|
||||
if g:gitgutter_signs
|
||||
sign define GitGutterLineAdded texthl=GitGutterAdd
|
||||
sign define GitGutterLineModified texthl=GitGutterChange
|
||||
sign define GitGutterLineRemoved texthl=GitGutterDelete
|
||||
sign define GitGutterLineRemovedFirstLine texthl=GitGutterDelete
|
||||
sign define GitGutterLineModifiedRemoved texthl=GitGutterChangeDelete
|
||||
sign define GitGutterLineAdded texthl=GitGutterAdd
|
||||
sign define GitGutterLineModified texthl=GitGutterChange
|
||||
sign define GitGutterLineRemoved texthl=GitGutterDelete
|
||||
sign define GitGutterLineRemovedFirstLine texthl=GitGutterDelete
|
||||
sign define GitGutterLineRemovedAboveAndBelow texthl=GitGutterDelete
|
||||
sign define GitGutterLineModifiedRemoved texthl=GitGutterChangeDelete
|
||||
else
|
||||
sign define GitGutterLineAdded texthl=GitGutterAddInvisible
|
||||
sign define GitGutterLineModified texthl=GitGutterChangeInvisible
|
||||
sign define GitGutterLineRemoved texthl=GitGutterDeleteInvisible
|
||||
sign define GitGutterLineRemovedFirstLine texthl=GitGutterDeleteInvisible
|
||||
sign define GitGutterLineModifiedRemoved texthl=GitGutterChangeDeleteInvisible
|
||||
sign define GitGutterLineAdded texthl=GitGutterAddInvisible
|
||||
sign define GitGutterLineModified texthl=GitGutterChangeInvisible
|
||||
sign define GitGutterLineRemoved texthl=GitGutterDeleteInvisible
|
||||
sign define GitGutterLineRemovedFirstLine texthl=GitGutterDeleteInvisible
|
||||
sign define GitGutterLineRemovedAboveAndBelow texthl=GitGutterDeleteInvisible
|
||||
sign define GitGutterLineModifiedRemoved texthl=GitGutterChangeDeleteInvisible
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:define_sign_line_highlights() abort
|
||||
if g:gitgutter_highlight_lines
|
||||
sign define GitGutterLineAdded linehl=GitGutterAddLine
|
||||
sign define GitGutterLineModified linehl=GitGutterChangeLine
|
||||
sign define GitGutterLineRemoved linehl=GitGutterDeleteLine
|
||||
sign define GitGutterLineRemovedFirstLine linehl=GitGutterDeleteLine
|
||||
sign define GitGutterLineModifiedRemoved linehl=GitGutterChangeDeleteLine
|
||||
sign define GitGutterLineAdded linehl=GitGutterAddLine
|
||||
sign define GitGutterLineModified linehl=GitGutterChangeLine
|
||||
sign define GitGutterLineRemoved linehl=GitGutterDeleteLine
|
||||
sign define GitGutterLineRemovedFirstLine linehl=GitGutterDeleteLine
|
||||
sign define GitGutterLineRemovedAboveAndBelow linehl=GitGutterDeleteLine
|
||||
sign define GitGutterLineModifiedRemoved linehl=GitGutterChangeDeleteLine
|
||||
else
|
||||
sign define GitGutterLineAdded linehl=
|
||||
sign define GitGutterLineModified linehl=
|
||||
sign define GitGutterLineRemoved linehl=
|
||||
sign define GitGutterLineRemovedFirstLine linehl=
|
||||
sign define GitGutterLineModifiedRemoved linehl=
|
||||
sign define GitGutterLineAdded linehl=
|
||||
sign define GitGutterLineModified linehl=
|
||||
sign define GitGutterLineRemoved linehl=
|
||||
sign define GitGutterLineRemovedFirstLine linehl=
|
||||
sign define GitGutterLineRemovedAboveAndBelow linehl=
|
||||
sign define GitGutterLineModifiedRemoved linehl=
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -93,6 +93,22 @@ function! s:current_hunk() abort
|
|||
return current_hunk
|
||||
endfunction
|
||||
|
||||
" Returns truthy if the cursor is in two hunks (which can only happen if the
|
||||
" cursor is on the first line and lines above have been deleted and lines
|
||||
" immediately below have been deleted) or falsey otherwise.
|
||||
function! s:cursor_in_two_hunks()
|
||||
let hunks = gitgutter#hunk#hunks(bufnr(''))
|
||||
|
||||
if line('.') == 1 && len(hunks) > 1 && hunks[0][2:3] == [0, 0] && hunks[1][2:3] == [1, 0]
|
||||
return 1
|
||||
endif
|
||||
|
||||
return 0
|
||||
endfunction
|
||||
|
||||
" A line can be in 0 or 1 hunks, with the following exception: when the first
|
||||
" line(s) of a file has been deleted, and the new second line (and
|
||||
" optionally below) has been deleted, the new first line is in two hunks.
|
||||
function! gitgutter#hunk#cursor_in_hunk(hunk) abort
|
||||
let current_line = line('.')
|
||||
|
||||
|
@ -151,13 +167,24 @@ function! s:hunk_op(op)
|
|||
if gitgutter#utility#is_active(bufnr)
|
||||
" Get a (synchronous) diff.
|
||||
let [async, g:gitgutter_async] = [g:gitgutter_async, 0]
|
||||
let diff = gitgutter#diff#run_diff(bufnr, 1)
|
||||
let diff = gitgutter#diff#run_diff(bufnr, 'index', 1)
|
||||
let g:gitgutter_async = async
|
||||
|
||||
call gitgutter#hunk#set_hunks(bufnr, gitgutter#diff#parse_diff(diff))
|
||||
|
||||
if empty(s:current_hunk())
|
||||
call gitgutter#utility#warn('cursor is not in a hunk')
|
||||
elseif s:cursor_in_two_hunks()
|
||||
let choice = input('Choose hunk: upper or lower (u/l)? ')
|
||||
" Clear input
|
||||
normal! :<ESC>
|
||||
if choice =~ 'u'
|
||||
call a:op(gitgutter#diff#hunk_diff(bufnr, diff, 0))
|
||||
elseif choice =~ 'l'
|
||||
call a:op(gitgutter#diff#hunk_diff(bufnr, diff, 1))
|
||||
else
|
||||
call gitgutter#utility#warn('did not recognise your choice')
|
||||
endif
|
||||
else
|
||||
call a:op(gitgutter#diff#hunk_diff(bufnr, diff))
|
||||
endif
|
||||
|
|
|
@ -170,7 +170,16 @@ function! s:upsert_new_gitgutter_signs(bufnr, modified_lines) abort
|
|||
let other_signs = gitgutter#utility#getbufvar(a:bufnr, 'other_signs')
|
||||
let old_gitgutter_signs = gitgutter#utility#getbufvar(a:bufnr, 'gitgutter_signs')
|
||||
|
||||
for line in a:modified_lines
|
||||
" Handle special case where the first line is the site of two hunks:
|
||||
" lines deleted above at the start of the file, and lines deleted
|
||||
" immediately below.
|
||||
if a:modified_lines[0:1] == [[1, 'removed_first_line'], [1, 'removed']]
|
||||
let modified_lines = [[1, 'removed_above_and_below']] + a:modified_lines[2:]
|
||||
else
|
||||
let modified_lines = a:modified_lines
|
||||
endif
|
||||
|
||||
for line in modified_lines
|
||||
let line_number = line[0] " <number>
|
||||
if index(other_signs, line_number) == -1 " don't clobber others' signs
|
||||
let name = s:highlight_name_for_change(line[1])
|
||||
|
@ -213,6 +222,8 @@ function! s:highlight_name_for_change(text) abort
|
|||
return 'GitGutterLineModified'
|
||||
elseif a:text ==# 'modified_removed'
|
||||
return 'GitGutterLineModifiedRemoved'
|
||||
elseif a:text ==# 'removed_above_and_below'
|
||||
return 'GitGutterLineRemovedAboveAndBelow'
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -7,11 +7,12 @@ function! gitgutter#utility#supports_overscore_sign()
|
|||
endfunction
|
||||
|
||||
function! gitgutter#utility#setbufvar(buffer, varname, val)
|
||||
let dict = get(getbufvar(a:buffer, ''), 'gitgutter', {})
|
||||
let buffer = +a:buffer
|
||||
let dict = get(getbufvar(buffer, '', {}), 'gitgutter', {})
|
||||
let needs_setting = empty(dict)
|
||||
let dict[a:varname] = a:val
|
||||
if needs_setting
|
||||
call setbufvar(+a:buffer, 'gitgutter', dict)
|
||||
call setbufvar(buffer, 'gitgutter', dict)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -34,9 +34,9 @@ if g:gitgutter_sign_column_always && exists('&signcolumn')
|
|||
call gitgutter#utility#warn('please replace "let g:gitgutter_sign_column_always=1" with "set signcolumn=yes"')
|
||||
endif
|
||||
call s:set('g:gitgutter_override_sign_column_highlight', 1)
|
||||
call s:set('g:gitgutter_sign_added', '+')
|
||||
call s:set('g:gitgutter_sign_modified', '~')
|
||||
call s:set('g:gitgutter_sign_removed', '_')
|
||||
call s:set('g:gitgutter_sign_added', '+')
|
||||
call s:set('g:gitgutter_sign_modified', '~')
|
||||
call s:set('g:gitgutter_sign_removed', '_')
|
||||
|
||||
if gitgutter#utility#supports_overscore_sign()
|
||||
call s:set('g:gitgutter_sign_removed_first_line', '‾')
|
||||
|
@ -44,14 +44,15 @@ else
|
|||
call s:set('g:gitgutter_sign_removed_first_line', '_^')
|
||||
endif
|
||||
|
||||
call s:set('g:gitgutter_sign_modified_removed', '~_')
|
||||
call s:set('g:gitgutter_git_args', '')
|
||||
call s:set('g:gitgutter_diff_args', '')
|
||||
call s:set('g:gitgutter_diff_base', '')
|
||||
call s:set('g:gitgutter_map_keys', 1)
|
||||
call s:set('g:gitgutter_terminal_reports_focus', 1)
|
||||
call s:set('g:gitgutter_async', 1)
|
||||
call s:set('g:gitgutter_log', 0)
|
||||
call s:set('g:gitgutter_sign_removed_above_and_below', '[')
|
||||
call s:set('g:gitgutter_sign_modified_removed', '~_')
|
||||
call s:set('g:gitgutter_git_args', '')
|
||||
call s:set('g:gitgutter_diff_args', '')
|
||||
call s:set('g:gitgutter_diff_base', '')
|
||||
call s:set('g:gitgutter_map_keys', 1)
|
||||
call s:set('g:gitgutter_terminal_reports_focus', 1)
|
||||
call s:set('g:gitgutter_async', 1)
|
||||
call s:set('g:gitgutter_log', 0)
|
||||
|
||||
call s:set('g:gitgutter_git_executable', 'git')
|
||||
if !executable(g:gitgutter_git_executable)
|
||||
|
|
|
@ -117,6 +117,16 @@ function Test_remove_first_lines()
|
|||
endfunction
|
||||
|
||||
|
||||
function Test_overlapping_hunks()
|
||||
execute '3d'
|
||||
execute '1d'
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = ["line=1 id=3000 name=GitGutterLineRemovedAboveAndBelow"]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
endfunction
|
||||
|
||||
|
||||
function Test_edit_file_with_same_name_as_a_branch()
|
||||
normal 5Gi*
|
||||
call system('git checkout -b fixture.txt')
|
||||
|
@ -445,6 +455,42 @@ function Test_undo_nearby_hunk()
|
|||
endfunction
|
||||
|
||||
|
||||
function Test_overlapping_hunk_op()
|
||||
func Answer(char)
|
||||
call feedkeys(a:char."\<CR>")
|
||||
endfunc
|
||||
|
||||
" Undo upper
|
||||
|
||||
execute '3d'
|
||||
execute '1d'
|
||||
call s:trigger_gitgutter()
|
||||
normal gg
|
||||
call timer_start(100, {-> Answer('u')} )
|
||||
GitGutterUndoHunk
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = [
|
||||
\ 'line=2 id=3000 name=GitGutterLineRemoved',
|
||||
\ ]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
|
||||
" Undo lower
|
||||
|
||||
execute '1d'
|
||||
call s:trigger_gitgutter()
|
||||
normal gg
|
||||
call timer_start(100, {-> Answer('l')} )
|
||||
GitGutterUndoHunk
|
||||
call s:trigger_gitgutter()
|
||||
|
||||
let expected = [
|
||||
\ 'line=1 id=3000 name=GitGutterLineRemovedFirstLine',
|
||||
\ ]
|
||||
call assert_equal(expected, s:signs('fixture.txt'))
|
||||
endfunction
|
||||
|
||||
|
||||
function Test_write_option()
|
||||
set nowrite
|
||||
|
||||
|
|
|
@ -55,7 +55,15 @@ IMPROVEMENTS:
|
|||
[[GH-1978]](https://github.com/fatih/vim-go/pull/1978)
|
||||
* Internal: install tools by their custom names
|
||||
[[GH-1984]](https://github.com/fatih/vim-go/pull/1984)
|
||||
|
||||
* Support the go-debugger features in Neovim.
|
||||
[[GH-2007]](https://github.com/fatih/vim-go/pull/2007)
|
||||
* color the statusline for termguicolors and Neovim.
|
||||
[[GH-2014]](https://github.com/fatih/vim-go/pull/2014)
|
||||
* add an option to disable highlighting of breakpoints and the current line
|
||||
when debugging.
|
||||
[[GH-2025]](https://github.com/fatih/vim-go/pull/2025)
|
||||
* Update autocompletion to work with Go modules.
|
||||
[[GH-1988]](https://github.com/fatih/vim-go/pull/1988)
|
||||
|
||||
BUG FIXES:
|
||||
* Fix `:GoRun %` on Windows.
|
||||
|
@ -70,6 +78,14 @@ BUG FIXES:
|
|||
[[GH-1794]](https://github.com/fatih/vim-go/pull/1794)
|
||||
* Fix `:GoImport` when adding to an empty import block (i.e`import ()`)
|
||||
[[GH-1938]](https://github.com/fatih/vim-go/pull/1938)
|
||||
* Run shell commands with shellcmdflag set to `-c`.
|
||||
[[GH-2006]](https://github.com/fatih/vim-go/pull/2006)
|
||||
* Use the correct log output option for delve.
|
||||
[[GH-1992]](https://github.com/fatih/vim-go/pull/1992)
|
||||
* Pass empty arguments correctly in async jobs on Windows.
|
||||
[[GH-2011]](https://github.com/fatih/vim-go/pull/2011)
|
||||
* Don't close godoc scratch window when using arrow keys.
|
||||
[[GH-2021]](https://github.com/fatih/vim-go/pull/2021)
|
||||
|
||||
BACKWARDS INCOMPATIBILITIES:
|
||||
* Bump minimum required version of Vim to 7.4.2009.
|
||||
|
@ -153,8 +169,7 @@ BUG FIXES:
|
|||
* The `gohtmltmpl` filetype will now highlight `{{ .. }}` syntax HTML attributes
|
||||
and some other locations.
|
||||
[[GH-1790]](https://github.com/fatih/vim-go/pull/1790)
|
||||
* Update using the correct logging flag option that was caused with the recent
|
||||
delve changes
|
||||
* Use the correct logging flag argument for delve.
|
||||
[[GH-1809]](https://github.com/fatih/vim-go/pull/1809)
|
||||
* Fix gocode option string values that would cause gocode settings not to set
|
||||
correctly
|
||||
|
|
|
@ -1,5 +1,20 @@
|
|||
function! s:gocodeCommand(cmd, args) abort
|
||||
let bin_path = go#path#CheckBinPath("gocode")
|
||||
let l:gocode_bin = "gocode"
|
||||
let l:gomod = go#util#gomod()
|
||||
if filereadable(l:gomod)
|
||||
" Save the file when in module mode so that go list can read the
|
||||
" imports. If the user doesn't have autowrite or autorwriteall enabled,
|
||||
" they'll need to write the file manually to get reliable results.
|
||||
" See https://github.com/fatih/vim-go/pull/1988#issuecomment-428576989.
|
||||
"
|
||||
" TODO(bc): don't save the file when in module mode once
|
||||
" golang.org/x/tools/go/packages has support for an overlay and it's used
|
||||
" by gocode.
|
||||
call go#cmd#autowrite()
|
||||
let l:gocode_bin = "gocode-gomod"
|
||||
endif
|
||||
|
||||
let bin_path = go#path#CheckBinPath(l:gocode_bin)
|
||||
if empty(bin_path)
|
||||
return []
|
||||
endif
|
||||
|
@ -18,6 +33,10 @@ function! s:gocodeCommand(cmd, args) abort
|
|||
let cmd = extend(cmd, ['-source'])
|
||||
endif
|
||||
|
||||
if go#config#GocodeUnimportedPackages()
|
||||
let cmd = extend(cmd, ['-unimported-packages'])
|
||||
endif
|
||||
|
||||
let cmd = extend(cmd, [a:cmd])
|
||||
let cmd = extend(cmd, a:args)
|
||||
|
||||
|
|
|
@ -135,6 +135,10 @@ function! go#config#SetGuruScope(scope) abort
|
|||
endif
|
||||
endfunction
|
||||
|
||||
function! go#config#GocodeUnimportedPackages() abort
|
||||
return get(g:, 'go_gocode_unimported_packages', 0)
|
||||
endfunction
|
||||
|
||||
let s:sock_type = (has('win32') || has('win64')) ? 'tcp' : 'unix'
|
||||
function! go#config#GocodeSocketType() abort
|
||||
return get(g:, 'go_gocode_socket_type', s:sock_type)
|
||||
|
@ -420,6 +424,10 @@ function! go#config#HighlightVariableDeclarations() abort
|
|||
return get(g:, 'go_highlight_variable_declarations', 0)
|
||||
endfunction
|
||||
|
||||
function! go#config#HighlightDebug() abort
|
||||
return get(g:, 'go_highlight_debug', 1)
|
||||
endfunction
|
||||
|
||||
function! go#config#FoldEnable(...) abort
|
||||
if a:0 > 0
|
||||
return index(go#config#FoldEnable(), a:1) > -1
|
||||
|
|
|
@ -29,6 +29,11 @@ function! s:complete(job, exit_status, data) abort
|
|||
if has_key(s:state, 'job')
|
||||
call remove(s:state, 'job')
|
||||
endif
|
||||
|
||||
if has_key(s:state, 'ready')
|
||||
call remove(s:state, 'ready')
|
||||
endif
|
||||
|
||||
call s:clearState()
|
||||
if a:exit_status > 0
|
||||
call go#util#EchoError(s:state['message'])
|
||||
|
@ -66,7 +71,6 @@ function! s:call_jsonrpc(method, ...) abort
|
|||
let Cb = a:000[0]
|
||||
let args = a:000[1:]
|
||||
else
|
||||
let Cb = v:none
|
||||
let args = a:000
|
||||
endif
|
||||
let s:state['rpcid'] += 1
|
||||
|
@ -78,9 +82,26 @@ function! s:call_jsonrpc(method, ...) abort
|
|||
|
||||
try
|
||||
" Use callback
|
||||
if type(Cb) == v:t_func
|
||||
let s:ch = ch_open('127.0.0.1:8181', {'mode': 'nl', 'callback': Cb})
|
||||
call ch_sendraw(s:ch, req_json)
|
||||
if exists('l:Cb')
|
||||
if has('nvim')
|
||||
let state = {'callback': Cb}
|
||||
function! state.on_data(ch, msg, event) abort
|
||||
call self.state.callback(a:ch, a:msg)
|
||||
endfunction
|
||||
let l:ch = sockconnect('tcp', go#config#DebugAddress(), {'on_data': state.on_data, 'state': state})
|
||||
call chansend(l:ch, req_json)
|
||||
|
||||
if go#util#HasDebug('debugger-commands')
|
||||
let g:go_debug_commands = add(g:go_debug_commands, {
|
||||
\ 'request': req_json,
|
||||
\ 'response': Cb,
|
||||
\ })
|
||||
endif
|
||||
return
|
||||
endif
|
||||
|
||||
let l:ch = ch_open(go#config#DebugAddress(), {'mode': 'nl', 'callback': Cb})
|
||||
call ch_sendraw(l:ch, req_json)
|
||||
|
||||
if go#util#HasDebug('debugger-commands')
|
||||
let g:go_debug_commands = add(g:go_debug_commands, {
|
||||
|
@ -91,9 +112,23 @@ function! s:call_jsonrpc(method, ...) abort
|
|||
return
|
||||
endif
|
||||
|
||||
let ch = ch_open('127.0.0.1:8181', {'mode': 'nl', 'timeout': 20000})
|
||||
call ch_sendraw(ch, req_json)
|
||||
let resp_json = ch_readraw(ch)
|
||||
if has('nvim')
|
||||
let state = {'done': 0}
|
||||
function! state.on_data(ch, msg, event) abort
|
||||
let self.state.resp = a:msg
|
||||
let self.state.done = 1
|
||||
endfunction
|
||||
let l:ch = sockconnect('tcp', go#config#DebugAddress(), {'on_data': state.on_data, 'state': state})
|
||||
call chansend(l:ch, req_json)
|
||||
while state.done == 0
|
||||
sleep 50m
|
||||
endwhile
|
||||
let resp_json = state.resp
|
||||
else
|
||||
let ch = ch_open(go#config#DebugAddress(), {'mode': 'raw', 'timeout': 20000})
|
||||
call ch_sendraw(ch, req_json)
|
||||
let resp_json = ch_readraw(ch)
|
||||
endif
|
||||
|
||||
if go#util#HasDebug('debugger-commands')
|
||||
let g:go_debug_commands = add(g:go_debug_commands, {
|
||||
|
@ -115,7 +150,7 @@ endfunction
|
|||
" Update the location of the current breakpoint or line we're halted on based on
|
||||
" response from dlv.
|
||||
function! s:update_breakpoint(res) abort
|
||||
if type(a:res) ==# v:t_none
|
||||
if type(a:res) ==# type(v:null)
|
||||
return
|
||||
endif
|
||||
|
||||
|
@ -216,11 +251,17 @@ function! s:clearState() abort
|
|||
endfunction
|
||||
|
||||
function! s:stop() abort
|
||||
" TODO(bc): call Detach
|
||||
call go#job#Stop(s:state['job'])
|
||||
|
||||
call s:clearState()
|
||||
if has_key(s:state, 'job')
|
||||
call job_stop(s:state['job'])
|
||||
call remove(s:state, 'job')
|
||||
endif
|
||||
|
||||
if has_key(s:state, 'ready')
|
||||
call remove(s:state, 'ready')
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! go#debug#Stop() abort
|
||||
|
@ -257,8 +298,10 @@ function! go#debug#Stop() abort
|
|||
silent! exe bufwinnr(bufnr('__GODEBUG_VARIABLES__')) 'wincmd c'
|
||||
silent! exe bufwinnr(bufnr('__GODEBUG_OUTPUT__')) 'wincmd c'
|
||||
|
||||
set noballooneval
|
||||
set balloonexpr=
|
||||
if has('balloon_eval')
|
||||
set noballooneval
|
||||
set balloonexpr=
|
||||
endif
|
||||
|
||||
augroup vim-go-debug
|
||||
autocmd!
|
||||
|
@ -453,8 +496,10 @@ function! s:start_cb(ch, json) abort
|
|||
nnoremap <silent> <Plug>(go-debug-stop) :<C-u>call go#debug#Stop()<CR>
|
||||
nnoremap <silent> <Plug>(go-debug-print) :<C-u>call go#debug#Print(expand('<cword>'))<CR>
|
||||
|
||||
set balloonexpr=go#debug#BalloonExpr()
|
||||
set ballooneval
|
||||
if has('balloon_eval')
|
||||
set balloonexpr=go#debug#BalloonExpr()
|
||||
set ballooneval
|
||||
endif
|
||||
|
||||
exe bufwinnr(oldbuf) 'wincmd w'
|
||||
|
||||
|
@ -470,20 +515,29 @@ function! s:start_cb(ch, json) abort
|
|||
endfunction
|
||||
|
||||
function! s:err_cb(ch, msg) abort
|
||||
if get(s:state, 'ready', 0) != 0
|
||||
call call('s:logger', ['ERR: ', a:ch, a:msg])
|
||||
return
|
||||
endif
|
||||
|
||||
call go#util#EchoError(a:msg)
|
||||
let s:state['message'] += [a:msg]
|
||||
endfunction
|
||||
|
||||
function! s:out_cb(ch, msg) abort
|
||||
if get(s:state, 'ready', 0) != 0
|
||||
call call('s:logger', ['OUT: ', a:ch, a:msg])
|
||||
return
|
||||
endif
|
||||
|
||||
call go#util#EchoProgress(a:msg)
|
||||
let s:state['message'] += [a:msg]
|
||||
|
||||
" TODO: why do this in this callback?
|
||||
if stridx(a:msg, go#config#DebugAddress()) != -1
|
||||
call ch_setoptions(a:ch, {
|
||||
\ 'out_cb': function('s:logger', ['OUT: ']),
|
||||
\ 'err_cb': function('s:logger', ['ERR: ']),
|
||||
\})
|
||||
" After this block executes, Delve will be running with all the
|
||||
" breakpoints setup, so this callback doesn't have to run again; just log
|
||||
" future messages.
|
||||
let s:state['ready'] = 1
|
||||
|
||||
" Tell dlv about the breakpoints that the user added before delve started.
|
||||
let l:breaks = copy(s:state.breakpoint)
|
||||
|
@ -501,17 +555,13 @@ endfunction
|
|||
function! go#debug#Start(is_test, ...) abort
|
||||
call go#cmd#autowrite()
|
||||
|
||||
if has('nvim')
|
||||
call go#util#EchoError('This feature only works in Vim for now; Neovim is not (yet) supported. Sorry :-(')
|
||||
return
|
||||
endif
|
||||
if !go#util#has_job()
|
||||
call go#util#EchoError('This feature requires Vim 8.0.0087 or newer with +job.')
|
||||
call go#util#EchoError('This feature requires either Vim 8.0.0087 or newer with +job or Neovim.')
|
||||
return
|
||||
endif
|
||||
|
||||
" It's already running.
|
||||
if has_key(s:state, 'job') && job_status(s:state['job']) == 'run'
|
||||
if has_key(s:state, 'job')
|
||||
return
|
||||
endif
|
||||
|
||||
|
@ -556,7 +606,7 @@ function! go#debug#Start(is_test, ...) abort
|
|||
\ '--output', tempname(),
|
||||
\ '--headless',
|
||||
\ '--api-version', '2',
|
||||
\ '--log', 'debugger',
|
||||
\ '--log', '--log-output', 'debugger,rpc',
|
||||
\ '--listen', go#config#DebugAddress(),
|
||||
\ '--accept-multiclient',
|
||||
\]
|
||||
|
@ -807,10 +857,7 @@ function! go#debug#Restart() abort
|
|||
call go#cmd#autowrite()
|
||||
|
||||
try
|
||||
call job_stop(s:state['job'])
|
||||
while has_key(s:state, 'job') && job_status(s:state['job']) is# 'run'
|
||||
sleep 50m
|
||||
endwhile
|
||||
call go#job#Stop(s:state['job'])
|
||||
|
||||
let l:breaks = s:state['breakpoint']
|
||||
let s:state = {
|
||||
|
@ -857,7 +904,7 @@ function! go#debug#Breakpoint(...) abort
|
|||
|
||||
try
|
||||
" Check if we already have a breakpoint for this line.
|
||||
let found = v:none
|
||||
let found = {}
|
||||
for k in keys(s:state.breakpoint)
|
||||
let bt = s:state.breakpoint[k]
|
||||
if bt.file == l:filename && bt.line == linenr
|
||||
|
@ -867,7 +914,7 @@ function! go#debug#Breakpoint(...) abort
|
|||
endfor
|
||||
|
||||
" Remove breakpoint.
|
||||
if type(found) == v:t_dict
|
||||
if type(found) == v:t_dict && !empty(found)
|
||||
call remove(s:state['breakpoint'], bt.id)
|
||||
exe 'sign unplace '. found.id .' file=' . found.file
|
||||
if s:isActive()
|
||||
|
|
|
@ -122,9 +122,12 @@ function! s:GodocView(newposition, position, content) abort
|
|||
setlocal nomodifiable
|
||||
sil normal! gg
|
||||
|
||||
" close easily with <esc> or enter
|
||||
" close easily with enter
|
||||
noremap <buffer> <silent> <CR> :<C-U>close<CR>
|
||||
noremap <buffer> <silent> <Esc> :<C-U>close<CR>
|
||||
" make sure any key that sends an escape as a prefix (e.g. the arrow keys)
|
||||
" don't cause the window to close.
|
||||
nnoremap <buffer> <silent> <Esc>[ <Esc>[
|
||||
endfunction
|
||||
|
||||
function! s:gogetdoc(json) abort
|
||||
|
|
95
sources_non_forked/vim-go/autoload/go/highlight_test.vim
Normal file
95
sources_non_forked/vim-go/autoload/go/highlight_test.vim
Normal file
|
@ -0,0 +1,95 @@
|
|||
function! Test_gomodVersion_highlight() abort
|
||||
try
|
||||
syntax on
|
||||
|
||||
let l:dir= gotest#write_file('gomodtest/go.mod', [
|
||||
\ 'module github.com/fatih/vim-go',
|
||||
\ '',
|
||||
\ '\x1frequire (',
|
||||
\ '\tversion/simple v1.0.0',
|
||||
\ '\tversion/pseudo/premajor v1.0.0-20060102150405-0123456789abcdef',
|
||||
\ '\tversion/pseudo/prerelease v1.0.0-prerelease.0.20060102150405-0123456789abcdef',
|
||||
\ '\tversion/pseudo/prepatch v1.0.1-0.20060102150405-0123456789abcdef',
|
||||
\ '\tversion/simple/incompatible v2.0.0+incompatible',
|
||||
\ '\tversion/pseudo/premajor/incompatible v2.0.0-20060102150405-0123456789abcdef+incompatible',
|
||||
\ '\tversion/pseudo/prerelease/incompatible v2.0.0-prerelease.0.20060102150405-0123456789abcdef+incompatible',
|
||||
\ '\tversion/pseudo/prepatch/incompatible v2.0.1-0.20060102150405-0123456789abcdef+incompatible',
|
||||
\ ')'])
|
||||
|
||||
let l:lineno = 4
|
||||
let l:lineclose = line('$')
|
||||
while l:lineno < l:lineclose
|
||||
let l:line = getline(l:lineno)
|
||||
let l:col = col([l:lineno, '$']) - 1
|
||||
let l:idx = len(l:line) - 1
|
||||
let l:from = stridx(l:line, ' ') + 1
|
||||
|
||||
while l:idx >= l:from
|
||||
call cursor(l:lineno, l:col)
|
||||
let l:synname = synIDattr(synID(l:lineno, l:col, 1), 'name')
|
||||
let l:errlen = len(v:errors)
|
||||
|
||||
call assert_equal('gomodVersion', l:synname, 'version on line ' . l:lineno)
|
||||
|
||||
" continue at the next line if there was an error at this column;
|
||||
" there's no need to test each column once an error is detected.
|
||||
if l:errlen < len(v:errors)
|
||||
break
|
||||
endif
|
||||
|
||||
let l:col -= 1
|
||||
let l:idx -= 1
|
||||
endwhile
|
||||
let l:lineno += 1
|
||||
endwhile
|
||||
finally
|
||||
call delete(l:dir, 'rf')
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
function! Test_gomodVersion_incompatible_highlight() abort
|
||||
try
|
||||
syntax on
|
||||
|
||||
let l:dir= gotest#write_file('gomodtest/go.mod', [
|
||||
\ 'module github.com/fatih/vim-go',
|
||||
\ '',
|
||||
\ '\x1frequire (',
|
||||
\ '\tversion/invalid/incompatible v1.0.0+incompatible',
|
||||
\ '\tversion/invalid/premajor/incompatible v1.0.0-20060102150405-0123456789abcdef+incompatible',
|
||||
\ '\tversion/invalid/prerelease/incompatible v1.0.0-prerelease.0.20060102150405-0123456789abcdef+incompatible',
|
||||
\ '\tversion/invalid/prepatch/incompatible v1.0.1-0.20060102150405-0123456789abcdef+incompatible',
|
||||
\ ')'])
|
||||
|
||||
let l:lineno = 4
|
||||
let l:lineclose = line('$')
|
||||
while l:lineno < l:lineclose
|
||||
let l:line = getline(l:lineno)
|
||||
let l:col = col([l:lineno, '$']) - 1
|
||||
let l:idx = len(l:line) - 1
|
||||
let l:from = stridx(l:line, '+')
|
||||
|
||||
while l:idx >= l:from
|
||||
call cursor(l:lineno, l:col)
|
||||
let l:synname = synIDattr(synID(l:lineno, l:col, 1), 'name')
|
||||
let l:errlen = len(v:errors)
|
||||
|
||||
call assert_notequal('gomodVersion', l:synname, 'version on line ' . l:lineno)
|
||||
|
||||
" continue at the next line if there was an error at this column;
|
||||
" there's no need to test each column once an error is detected.
|
||||
if l:errlen < len(v:errors)
|
||||
break
|
||||
endif
|
||||
|
||||
let l:col -= 1
|
||||
let l:idx -= 1
|
||||
endwhile
|
||||
let l:lineno += 1
|
||||
endwhile
|
||||
finally
|
||||
call delete(l:dir, 'rf')
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
" vim: sw=2 ts=2 et
|
|
@ -1,4 +1,7 @@
|
|||
func! Test_indent_raw_string() abort
|
||||
" The goRawString discovery requires that syntax be enabled.
|
||||
syntax on
|
||||
|
||||
try
|
||||
let l:dir= gotest#write_file('indent/indent.go', [
|
||||
\ 'package main',
|
||||
|
@ -17,6 +20,43 @@ func! Test_indent_raw_string() abort
|
|||
finally
|
||||
call delete(l:dir, 'rf')
|
||||
endtry
|
||||
endfunc
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
try
|
||||
let l:dir= gotest#write_file('indent/indent.go', [
|
||||
\ 'package main',
|
||||
\ '',
|
||||
\ 'import "fmt"',
|
||||
\ '',
|
||||
\ 'func main() {',
|
||||
\ "\t\x1fmsg := `",
|
||||
\ '`',
|
||||
\ '\tfmt.Println(msg)',
|
||||
\ '}'])
|
||||
|
||||
silent execute "normal o" . "not indented\<Esc>"
|
||||
let l:indent = indent(line('.'))
|
||||
call assert_equal(0, l:indent)
|
||||
finally
|
||||
call delete(l:dir, 'rf')
|
||||
endtry
|
||||
|
||||
try
|
||||
let l:dir= gotest#write_file('indent/indent.go', [
|
||||
\ 'package main',
|
||||
\ '',
|
||||
\ 'import "fmt"',
|
||||
\ '',
|
||||
\ 'func main() {',
|
||||
\ "\tconst msg = `",
|
||||
\ "\t\x1findented",
|
||||
\ '`',
|
||||
\ '\tfmt.Println(msg)',
|
||||
\ '}'])
|
||||
|
||||
silent execute "normal o" . "indented\<Esc>"
|
||||
let l:indent = indent(line('.'))
|
||||
call assert_equal(shiftwidth(), l:indent)
|
||||
finally
|
||||
call delete(l:dir, 'rf')
|
||||
endtry
|
||||
endfunc
|
||||
|
|
|
@ -293,6 +293,10 @@ function! go#job#Start(cmd, options)
|
|||
unlet l:options._start
|
||||
endif
|
||||
|
||||
if go#util#HasDebug('shell-commands')
|
||||
call go#util#EchoInfo('job command: ' . string(a:cmd))
|
||||
endif
|
||||
|
||||
if has('nvim')
|
||||
let l:input = []
|
||||
if has_key(a:options, 'in_io') && a:options.in_io ==# 'file' && !empty(a:options.in_name)
|
||||
|
@ -307,7 +311,12 @@ function! go#job#Start(cmd, options)
|
|||
call chanclose(job, 'stdin')
|
||||
endif
|
||||
else
|
||||
let job = job_start(a:cmd, l:options)
|
||||
let l:cmd = a:cmd
|
||||
if go#util#IsWin()
|
||||
let l:cmd = join(map(copy(a:cmd), function('s:winjobarg')), " ")
|
||||
endif
|
||||
|
||||
let job = job_start(l:cmd, l:options)
|
||||
endif
|
||||
|
||||
if !has_key(l:options, 'cwd')
|
||||
|
@ -501,4 +510,33 @@ function! s:neooptions(options)
|
|||
return l:options
|
||||
endfunction
|
||||
|
||||
function! go#job#Stop(job) abort
|
||||
if has('nvim')
|
||||
call jobstop(a:job)
|
||||
return
|
||||
endif
|
||||
|
||||
call job_stop(a:job)
|
||||
call go#job#Wait(a:job)
|
||||
return
|
||||
endfunction
|
||||
|
||||
function! go#job#Wait(job) abort
|
||||
if has('nvim')
|
||||
call jobwait(a:job)
|
||||
return
|
||||
endif
|
||||
|
||||
while job_status(a:job) is# 'run'
|
||||
sleep 50m
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
function! s:winjobarg(idx, val) abort
|
||||
if empty(a:val)
|
||||
return '""'
|
||||
endif
|
||||
return a:val
|
||||
endfunction
|
||||
|
||||
" vim: sw=2 ts=2 et
|
||||
|
|
|
@ -3,7 +3,7 @@ let s:go_major_version = ""
|
|||
function! go#mod#Format() abort
|
||||
" go mod only exists in `v1.11`
|
||||
if empty(s:go_major_version)
|
||||
let tokens = matchlist(go#util#System("go version"), '\d\+.\(\d\+\) ')
|
||||
let tokens = matchlist(go#util#System("go version"), '\d\+.\(\d\+\)\(\.\d\+\)\? ')
|
||||
let s:go_major_version = str2nr(tokens[1])
|
||||
endif
|
||||
|
||||
|
|
|
@ -54,11 +54,11 @@ function! go#statusline#Show() abort
|
|||
" only update highlight if status has changed.
|
||||
if status_text != s:last_status
|
||||
if status.state =~ "success" || status.state =~ "finished" || status.state =~ "pass"
|
||||
hi goStatusLineColor cterm=bold ctermbg=76 ctermfg=22
|
||||
hi goStatusLineColor cterm=bold ctermbg=76 ctermfg=22 guibg=#5fd700 guifg=#005f00
|
||||
elseif status.state =~ "started" || status.state =~ "analysing" || status.state =~ "compiling"
|
||||
hi goStatusLineColor cterm=bold ctermbg=208 ctermfg=88
|
||||
hi goStatusLineColor cterm=bold ctermbg=208 ctermfg=88 guibg=#ff8700 guifg=#870000
|
||||
elseif status.state =~ "failed"
|
||||
hi goStatusLineColor cterm=bold ctermbg=196 ctermfg=52
|
||||
hi goStatusLineColor cterm=bold ctermbg=196 ctermfg=52 guibg=#ff0000 guifg=#5f0000
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
@ -127,6 +127,13 @@ function! go#util#gopath() abort
|
|||
return substitute(s:exec(['go', 'env', 'GOPATH'])[0], '\n', '', 'g')
|
||||
endfunction
|
||||
|
||||
" gomod returns 'go env GOMOD'. gomod changes depending on the folder. Don't
|
||||
" use go#util#env as it caches the value.
|
||||
function! go#util#gomod() abort
|
||||
return substitute(s:exec(['go', 'env', 'GOMOD'])[0], '\n', '', 'g')
|
||||
endfunction
|
||||
|
||||
|
||||
function! go#util#osarch() abort
|
||||
return go#util#env("goos") . '_' . go#util#env("goarch")
|
||||
endfunction
|
||||
|
@ -137,12 +144,13 @@ endfunction
|
|||
" so that we always use a standard POSIX-compatible Bourne shell (and not e.g.
|
||||
" csh, fish, etc.) See #988 and #1276.
|
||||
function! s:system(cmd, ...) abort
|
||||
" Preserve original shell and shellredir values
|
||||
" Preserve original shell, shellredir and shellcmdflag values
|
||||
let l:shell = &shell
|
||||
let l:shellredir = &shellredir
|
||||
let l:shellcmdflag = &shellcmdflag
|
||||
|
||||
if !go#util#IsWin() && executable('/bin/sh')
|
||||
set shell=/bin/sh shellredir=>%s\ 2>&1
|
||||
set shell=/bin/sh shellredir=>%s\ 2>&1 shellcmdflag=-c
|
||||
endif
|
||||
|
||||
try
|
||||
|
@ -151,6 +159,7 @@ function! s:system(cmd, ...) abort
|
|||
" Restore original values
|
||||
let &shell = l:shell
|
||||
let &shellredir = l:shellredir
|
||||
let &shellcmdflag = l:shellcmdflag
|
||||
endtry
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -148,9 +148,6 @@ The following plugins are supported for use with vim-go:
|
|||
https://github.com/SirVer/ultisnips or
|
||||
https://github.com/joereynolds/vim-minisnip
|
||||
|
||||
* For a better documentation viewer check out:
|
||||
https://github.com/garyburd/go-explorer
|
||||
|
||||
* Integration with `delve` (Neovim only):
|
||||
https://github.com/jodosha/vim-godebug
|
||||
|
||||
|
@ -1614,6 +1611,14 @@ package and packages that have been installed will proposed.
|
|||
>
|
||||
let g:go_gocode_propose_source = 1
|
||||
<
|
||||
*'g:go_gocode_unimported_packages'*
|
||||
|
||||
Specifies whether `gocode` should include suggestions from unimported
|
||||
packages. By default it is disabled.
|
||||
>
|
||||
let g:go_gocode_unimported_packages = 0
|
||||
<
|
||||
|
||||
*'g:go_gocode_socket_type'*
|
||||
|
||||
Specifies whether `gocode` should use a different socket type. By default
|
||||
|
@ -1902,7 +1907,7 @@ The `gohtmltmpl` filetype is automatically set for `*.tmpl` files; the
|
|||
*gomod* *ft-gomod-syntax*
|
||||
go.mod file syntax~
|
||||
|
||||
The `gomod` 'filetype' provides syntax highlighting for Go's module file
|
||||
The `gomod` 'filetype' provides syntax highlighting for Go's module file
|
||||
`go.mod`
|
||||
|
||||
|
||||
|
@ -1924,10 +1929,10 @@ features:
|
|||
* Toggle breakpoint.
|
||||
* Stack operation continue/next/step out.
|
||||
|
||||
This feature requires Vim 8.0.0087 or newer with the |+job| feature. Neovim
|
||||
does _not_ work (yet).
|
||||
This requires Delve 1.0.0 or newer, and it is recommended to use Go 1.10 or
|
||||
newer, as its new caching will speed up recompiles.
|
||||
This feature requires either Vim 8.0.0087 or newer with the |+job| feature or
|
||||
Neovim. This features also requires Delve 1.0.0 or newer, and it is
|
||||
recommended to use Go 1.10 or newer, as its new caching will speed up
|
||||
recompiles.
|
||||
|
||||
*go-debug-intro*
|
||||
GETTING STARTED WITH THE DEBUGGER~
|
||||
|
@ -2112,6 +2117,14 @@ Defaults to `127.0.0.1:8181`:
|
|||
let g:go_debug_address = '127.0.0.1:8181'
|
||||
<
|
||||
|
||||
*'g:go_highlight_debug'*
|
||||
|
||||
Highlight the current line and breakpoints in the debugger.
|
||||
|
||||
>
|
||||
let g:go_highlight_debug = 1
|
||||
<
|
||||
|
||||
==============================================================================
|
||||
FAQ TROUBLESHOOTING *go-troubleshooting*
|
||||
|
||||
|
|
|
@ -31,6 +31,11 @@ au BufReadPost *.s call s:gofiletype_post()
|
|||
|
||||
au BufRead,BufNewFile *.tmpl set filetype=gohtmltmpl
|
||||
|
||||
" remove the autocommands for modsim3, and lprolog files so that their
|
||||
" highlight groups, syntax, etc. will not be loaded. *.MOD is included, so
|
||||
" that on case insensitive file systems the module2 autocmds will not be
|
||||
" executed.
|
||||
au! BufNewFile,BufRead *.mod,*.MOD
|
||||
" Set the filetype if the first non-comment and non-blank line starts with
|
||||
" 'module <path>'.
|
||||
au BufNewFile,BufRead go.mod call s:gomod()
|
||||
|
|
|
@ -24,7 +24,7 @@ if exists("*GoIndent")
|
|||
finish
|
||||
endif
|
||||
|
||||
function! GoIndent(lnum)
|
||||
function! GoIndent(lnum) abort
|
||||
let prevlnum = prevnonblank(a:lnum-1)
|
||||
if prevlnum == 0
|
||||
" top of file
|
||||
|
@ -38,10 +38,17 @@ function! GoIndent(lnum)
|
|||
|
||||
let ind = previ
|
||||
|
||||
if prevl =~ ' = `[^`]*$'
|
||||
" previous line started a multi-line raw string
|
||||
return 0
|
||||
endif
|
||||
for synid in synstack(a:lnum, 1)
|
||||
if synIDattr(synid, 'name') == 'goRawString'
|
||||
if prevl =~ '\%(\%(:\?=\)\|(\|,\)\s*`[^`]*$'
|
||||
" previous line started a multi-line raw string
|
||||
return 0
|
||||
endif
|
||||
" return -1 to keep the current indent.
|
||||
return -1
|
||||
endif
|
||||
endfor
|
||||
|
||||
if prevl =~ '[({]\s*$'
|
||||
" previous line opened a block
|
||||
let ind += shiftwidth()
|
||||
|
|
|
@ -47,10 +47,11 @@ let s:packages = {
|
|||
\ 'errcheck': ['github.com/kisielk/errcheck'],
|
||||
\ 'fillstruct': ['github.com/davidrjenni/reftools/cmd/fillstruct'],
|
||||
\ 'gocode': ['github.com/mdempsky/gocode', {'windows': ['-ldflags', '-H=windowsgui']}],
|
||||
\ 'gocode-gomod': ['github.com/stamblerre/gocode'],
|
||||
\ 'godef': ['github.com/rogpeppe/godef'],
|
||||
\ 'gogetdoc': ['github.com/zmb3/gogetdoc'],
|
||||
\ 'goimports': ['golang.org/x/tools/cmd/goimports'],
|
||||
\ 'golint': ['github.com/golang/lint/golint'],
|
||||
\ 'golint': ['golang.org/x/lint/golint'],
|
||||
\ 'gometalinter': ['github.com/alecthomas/gometalinter'],
|
||||
\ 'gomodifytags': ['github.com/fatih/gomodifytags'],
|
||||
\ 'gorename': ['golang.org/x/tools/cmd/gorename'],
|
||||
|
|
|
@ -374,8 +374,10 @@ function! s:hi()
|
|||
hi def goCoverageUncover ctermfg=red guifg=#F92672
|
||||
|
||||
" :GoDebug commands
|
||||
hi GoDebugBreakpoint term=standout ctermbg=117 ctermfg=0 guibg=#BAD4F5 guifg=Black
|
||||
hi GoDebugCurrent term=reverse ctermbg=12 ctermfg=7 guibg=DarkBlue guifg=White
|
||||
if go#config#HighlightDebug()
|
||||
hi GoDebugBreakpoint term=standout ctermbg=117 ctermfg=0 guibg=#BAD4F5 guifg=Black
|
||||
hi GoDebugCurrent term=reverse ctermbg=12 ctermfg=7 guibg=DarkBlue guifg=White
|
||||
endif
|
||||
endfunction
|
||||
|
||||
augroup vim-go-hi
|
||||
|
|
|
@ -37,10 +37,26 @@ syntax match gomodReplaceOperator "\v\=\>"
|
|||
highlight default link gomodReplaceOperator Operator
|
||||
|
||||
|
||||
" highlight semver, note that this is very simple. But it works for now
|
||||
syntax match gomodVersion "v\d\+\.\d\+\.\d\+"
|
||||
syntax match gomodVersion "v\d\+\.\d\+\.\d\+-\S*"
|
||||
syntax match gomodVersion "v\d\+\.\d\+\.\d\++incompatible"
|
||||
" highlight versions:
|
||||
" * vX.Y.Z
|
||||
" * vX.0.0-yyyyymmddhhmmss-abcdefabcdef
|
||||
" * vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef
|
||||
" * vX.Y.(Z+1)-0.yyyymmddhhss-abcdefabcdef
|
||||
" * +incompatible suffix when X > 1
|
||||
" match vX.Y.Z and their prereleases
|
||||
syntax match gomodVersion "v\d\+\.\d\+\.\d\+\%(-\%(\w\+\.\)\+0\.\d\{14}-\x\+\)\?"
|
||||
" match target when most recent version before the target is X.Y.Z
|
||||
syntax match gomodVersion "v\d\+\.\d\+\.[1-9]\{1}\d*\%(-0\.\%(\d\{14}-\x\+\)\)\?"
|
||||
" match target without a major version before the commit (e.g. vX.0.0-yyyymmddhhmmss-abcdefabcdef)
|
||||
syntax match gomodVersion "v\d\+\.0\.0-\d\{14\}-\x\+"
|
||||
|
||||
" match vX.Y.Z and their prereleases for X>1
|
||||
syntax match gomodVersion "v[2-9]\{1}\d\?\.\d\+\.\d\+\%(-\%(\w\+\.\)\+0\.\d\{14\}-\x\+\)\?\%(+incompatible\>\)\?"
|
||||
" match target when most recent version before the target is X.Y.Z for X>1
|
||||
syntax match gomodVersion "v[2-9]\{1}\d\?\.\d\+\.[1-9]\{1}\d*\%(-0\.\%(\d\{14\}-\x\+\)\)\?\%(+incompatible\>\)\?"
|
||||
" match target without a major version before the commit (e.g. vX.0.0-yyyymmddhhmmss-abcdefabcdef) for X>1
|
||||
syntax match gomodVersion "v[2-9]\{1}\d\?\.0\.0-\d\{14\}-\x\+\%(+incompatible\>\)\?"
|
||||
|
||||
highlight default link gomodVersion Identifier
|
||||
|
||||
let b:current_syntax = "gomod"
|
||||
|
|
|
@ -115,7 +115,7 @@ syn match mkdRule /^\s*_\s\{0,1}_\s\{0,1}_\(_\|\s\)*$/
|
|||
" YAML frontmatter
|
||||
if get(g:, 'vim_markdown_frontmatter', 0)
|
||||
syn include @yamlTop syntax/yaml.vim
|
||||
syn region Comment matchgroup=mkdDelimiter start="\%^---$" end="^\(---\|...\)$" contains=@yamlTop keepend
|
||||
syn region Comment matchgroup=mkdDelimiter start="\%^---$" end="^\(---\|\.\.\.\)$" contains=@yamlTop keepend
|
||||
unlet! b:current_syntax
|
||||
endif
|
||||
|
||||
|
|
|
@ -189,6 +189,14 @@ g:multi_cursor_select_all_key
|
|||
#### **Q** <kbd>CTRL</kbd>+<kbd>n</kbd> doesn't seem to work in gVIM?
|
||||
**A** Try setting `set selection=inclusive` in your `~/.gvimrc`
|
||||
|
||||
**A** Alternatively, you can just temporarily disable _exclusive_ selection whenever the plugin is active:
|
||||
```VimL
|
||||
augroup MultipleCursorsSelectionFix
|
||||
autocmd User MultipleCursorsPre if &selection ==# 'exclusive' | let g:multi_cursor_save_selection = &selection | set selection=inclusive | endif
|
||||
autocmd User MultipleCursorsPost if exists('g:multi_cursor_save_selection') | let &selection = g:multi_cursor_save_selection | unlet g:multi_cursor_save_selection | endif
|
||||
augroup END
|
||||
```
|
||||
|
||||
#### **Q** is it also working on Mac?
|
||||
**A** On Mac OS, [MacVim](https://code.google.com/p/macvim/) is known to work.
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue