mirror of
1
0
Fork 0

Updated plugins

This commit is contained in:
Amir 2021-07-30 22:52:54 +02:00
parent a8f0b6f678
commit 65de68fa88
66 changed files with 1368 additions and 404 deletions

View File

@ -73,8 +73,8 @@ endfunction
function! ale_linters#ansible#ansible_lint#GetCommand(buffer, version) abort function! ale_linters#ansible#ansible_lint#GetCommand(buffer, version) abort
let l:commands = { let l:commands = {
\ '>=5.0.0': '%e --parseable-severity -x yaml', \ '>=5.0.0': '%e --nocolor --parseable-severity -x yaml -',
\ '<5.0.0': '%e -p %t' \ '<5.0.0': '%e --nocolor -p %t'
\} \}
let l:command = ale#semver#GTE(a:version, [5, 0]) ? l:commands['>=5.0.0'] : l:commands['<5.0.0'] let l:command = ale#semver#GTE(a:version, [5, 0]) ? l:commands['>=5.0.0'] : l:commands['<5.0.0']

View File

@ -1,6 +1,18 @@
" Author: Masashi Iizuka <liquidz.uo@gmail.com> " Author: Masashi Iizuka <liquidz.uo@gmail.com>
" Description: linter for clojure using clj-kondo https://github.com/borkdude/clj-kondo " Description: linter for clojure using clj-kondo https://github.com/borkdude/clj-kondo
call ale#Set('clojure_clj_kondo_options', '--cache')
function! ale_linters#clojure#clj_kondo#GetCommand(buffer) abort
let l:options = ale#Var(a:buffer, 'clojure_clj_kondo_options')
let l:command = 'clj-kondo'
\ . ale#Pad(l:options)
\ . ' --lint %t'
return l:command
endfunction
function! ale_linters#clojure#clj_kondo#HandleCljKondoFormat(buffer, lines) abort function! ale_linters#clojure#clj_kondo#HandleCljKondoFormat(buffer, lines) abort
" output format " output format
" <filename>:<line>:<column>: <issue type>: <message> " <filename>:<line>:<column>: <issue type>: <message>
@ -29,6 +41,6 @@ call ale#linter#Define('clojure', {
\ 'name': 'clj-kondo', \ 'name': 'clj-kondo',
\ 'output_stream': 'stdout', \ 'output_stream': 'stdout',
\ 'executable': 'clj-kondo', \ 'executable': 'clj-kondo',
\ 'command': 'clj-kondo --cache --lint %t', \ 'command': function('ale_linters#clojure#clj_kondo#GetCommand'),
\ 'callback': 'ale_linters#clojure#clj_kondo#HandleCljKondoFormat', \ 'callback': 'ale_linters#clojure#clj_kondo#HandleCljKondoFormat',
\}) \})

View File

@ -0,0 +1,28 @@
" Author: ghsang <gwonhyuksang@gmail.com>
" Description: Check Dart files with dart analyze
call ale#Set('dart_analyze_executable', 'dart')
function! ale_linters#dart#dart_analyze#Handle(buffer, lines) abort
let l:pattern = '\v^ ([a-z]+) - (.+):(\d+):(\d+) - (.+) - (.+)$'
let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern)
call add(l:output, {
\ 'type': l:match[1] is# 'error' ? 'E' : 'W',
\ 'text': l:match[6] . ': ' . l:match[5],
\ 'lnum': str2nr(l:match[3]),
\ 'col': str2nr(l:match[4]),
\})
endfor
return l:output
endfunction
call ale#linter#Define('dart', {
\ 'name': 'dart_analyze',
\ 'executable': {b -> ale#Var(b, 'dart_analyze_executable')},
\ 'command': '%e analyze %s',
\ 'callback': 'ale_linters#dart#dart_analyze#Handle',
\ 'lint_file': 1,
\})

View File

@ -7,7 +7,7 @@ call ale#Set('dockerfile_hadolint_docker_image', 'hadolint/hadolint')
function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort
" Matches patterns line the following: " Matches patterns line the following:
" "
" /dev/stdin:19 DL3001 Pipe chain should start with a raw value. " -:19 DL3001 warning: Pipe chain should start with a raw value.
" /dev/stdin:19:3 unexpected thing " /dev/stdin:19:3 unexpected thing
let l:pattern = '\v^%(/dev/stdin|-):(\d+):?(\d+)? ((DL|SC)(\d+) )?((.+)?: )?(.+)$' let l:pattern = '\v^%(/dev/stdin|-):(\d+):?(\d+)? ((DL|SC)(\d+) )?((.+)?: )?(.+)$'
let l:output = [] let l:output = []
@ -38,6 +38,8 @@ function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort
let l:text = l:match[8] let l:text = l:match[8]
let l:detail = l:match[8] let l:detail = l:match[8]
let l:domain = 'https://github.com/hadolint/hadolint/wiki/' let l:domain = 'https://github.com/hadolint/hadolint/wiki/'
let l:code = ''
let l:link = ''
if l:match[4] is# 'SC' if l:match[4] is# 'SC'
let l:domain = 'https://github.com/koalaman/shellcheck/wiki/' let l:domain = 'https://github.com/koalaman/shellcheck/wiki/'
@ -46,9 +48,11 @@ function! ale_linters#dockerfile#hadolint#Handle(buffer, lines) abort
if l:match[5] isnot# '' if l:match[5] isnot# ''
let l:code = l:match[4] . l:match[5] let l:code = l:match[4] . l:match[5]
let l:link = ' ( ' . l:domain . l:code . ' )' let l:link = ' ( ' . l:domain . l:code . ' )'
let l:text = l:code . ': ' . l:detail
let l:detail = l:code . l:link . "\n\n" . l:detail let l:detail = l:code . l:link . "\n\n" . l:detail
else else
let l:type = 'E' let l:type = 'E'
let l:detail = 'hadolint could not parse the file because of a syntax error.'
endif endif
call add(l:output, { call add(l:output, {

View File

@ -25,7 +25,7 @@ function! ale_linters#erlang#erlc#Handle(buffer, lines) abort
" error.erl:4: variable 'B' is unbound " error.erl:4: variable 'B' is unbound
" error.erl:3: Warning: function main/0 is unused " error.erl:3: Warning: function main/0 is unused
" error.erl:4: Warning: variable 'A' is unused " error.erl:4: Warning: variable 'A' is unused
let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+): (Warning: )?(.+)$' let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+:)? (Warning: )?(.+)$'
" parse_transforms are a special case. The error message does not indicate a location: " parse_transforms are a special case. The error message does not indicate a location:
" error.erl: undefined parse transform 'some_parse_transform' " error.erl: undefined parse transform 'some_parse_transform'
@ -65,8 +65,8 @@ function! ale_linters#erlang#erlc#Handle(buffer, lines) abort
endif endif
let l:line = l:match[2] let l:line = l:match[2]
let l:warning_or_text = l:match[3] let l:warning_or_text = l:match[4]
let l:text = l:match[4] let l:text = l:match[5]
" If this file is a header .hrl, ignore the following expected messages: " If this file is a header .hrl, ignore the following expected messages:
" - 'no module definition' " - 'no module definition'

View File

@ -6,6 +6,7 @@ let g:ale_php_phpstan_executable = get(g:, 'ale_php_phpstan_executable', 'phpsta
let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '') let g:ale_php_phpstan_level = get(g:, 'ale_php_phpstan_level', '')
let g:ale_php_phpstan_configuration = get(g:, 'ale_php_phpstan_configuration', '') let g:ale_php_phpstan_configuration = get(g:, 'ale_php_phpstan_configuration', '')
let g:ale_php_phpstan_autoload = get(g:, 'ale_php_phpstan_autoload', '') let g:ale_php_phpstan_autoload = get(g:, 'ale_php_phpstan_autoload', '')
call ale#Set('php_phpstan_use_global', get(g:, 'ale_use_global_executables', 0))
function! ale_linters#php#phpstan#GetCommand(buffer, version) abort function! ale_linters#php#phpstan#GetCommand(buffer, version) abort
let l:configuration = ale#Var(a:buffer, 'php_phpstan_configuration') let l:configuration = ale#Var(a:buffer, 'php_phpstan_configuration')
@ -32,8 +33,8 @@ function! ale_linters#php#phpstan#GetCommand(buffer, version) abort
\ : '' \ : ''
let l:error_format = ale#semver#GTE(a:version, [0, 10, 3]) let l:error_format = ale#semver#GTE(a:version, [0, 10, 3])
\ ? ' --error-format raw' \ ? ' --error-format json'
\ : ' --errorFormat raw' \ : ' --errorFormat json'
return '%e analyze --no-progress' return '%e analyze --no-progress'
\ . l:error_format \ . l:error_format
@ -44,17 +45,17 @@ function! ale_linters#php#phpstan#GetCommand(buffer, version) abort
endfunction endfunction
function! ale_linters#php#phpstan#Handle(buffer, lines) abort function! ale_linters#php#phpstan#Handle(buffer, lines) abort
" Matches against lines like the following: let l:res = ale#util#FuzzyJSONDecode(a:lines, {'files': []})
"
" filename.php:15:message
" C:\folder\filename.php:15:message
let l:pattern = '^\([a-zA-Z]:\)\?[^:]\+:\(\d\+\):\(.*\)$'
let l:output = [] let l:output = []
for l:match in ale#util#GetMatches(a:lines, l:pattern) if type(l:res.files) is v:t_list
return l:output
endif
for l:err in l:res.files[expand('#' . a:buffer .':p')].messages
call add(l:output, { call add(l:output, {
\ 'lnum': l:match[2] + 0, \ 'lnum': l:err.line,
\ 'text': l:match[3], \ 'text': l:err.message,
\ 'type': 'E', \ 'type': 'E',
\}) \})
endfor endfor
@ -64,10 +65,16 @@ endfunction
call ale#linter#Define('php', { call ale#linter#Define('php', {
\ 'name': 'phpstan', \ 'name': 'phpstan',
\ 'executable': {b -> ale#Var(b, 'php_phpstan_executable')}, \ 'executable': {buffer -> ale#path#FindExecutable(buffer, 'php_phpstan', [
\ 'vendor/bin/phpstan',
\ 'phpstan'
\ ])},
\ 'command': {buffer -> ale#semver#RunWithVersionCheck( \ 'command': {buffer -> ale#semver#RunWithVersionCheck(
\ buffer, \ buffer,
\ ale#Var(buffer, 'php_phpstan_executable'), \ ale#path#FindExecutable(buffer, 'php_phpstan', [
\ 'vendor/bin/phpstan',
\ 'phpstan'
\ ]),
\ '%e --version', \ '%e --version',
\ function('ale_linters#php#phpstan#GetCommand'), \ function('ale_linters#php#phpstan#GetCommand'),
\ )}, \ )},

View File

@ -6,6 +6,7 @@ call ale#Set('python_bandit_options', '')
call ale#Set('python_bandit_use_config', 1) call ale#Set('python_bandit_use_config', 1)
call ale#Set('python_bandit_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_bandit_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_bandit_auto_pipenv', 0) call ale#Set('python_bandit_auto_pipenv', 0)
call ale#Set('python_bandit_auto_poetry', 0)
function! ale_linters#python#bandit#GetExecutable(buffer) abort function! ale_linters#python#bandit#GetExecutable(buffer) abort
if ( if (
@ -15,6 +16,13 @@ function! ale_linters#python#bandit#GetExecutable(buffer) abort
return 'pipenv' return 'pipenv'
endif endif
if (
\ ale#Var(a:buffer, 'python_auto_poetry')
\ || ale#Var(a:buffer, 'python_bandit_auto_poetry')
\) && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
return ale#python#FindExecutable(a:buffer, 'python_bandit', ['bandit']) return ale#python#FindExecutable(a:buffer, 'python_bandit', ['bandit'])
endfunction endfunction
@ -31,7 +39,7 @@ function! ale_linters#python#bandit#GetCommand(buffer) abort
endif endif
endif endif
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv\|poetry$'
\ ? ' run bandit' \ ? ' run bandit'
\ : '' \ : ''

View File

@ -6,6 +6,7 @@ call ale#Set('python_flake8_options', '')
call ale#Set('python_flake8_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_flake8_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_flake8_change_directory', 'project') call ale#Set('python_flake8_change_directory', 'project')
call ale#Set('python_flake8_auto_pipenv', 0) call ale#Set('python_flake8_auto_pipenv', 0)
call ale#Set('python_flake8_auto_poetry', 0)
function! s:UsingModule(buffer) abort function! s:UsingModule(buffer) abort
return ale#Var(a:buffer, 'python_flake8_options') =~# ' *-m flake8' return ale#Var(a:buffer, 'python_flake8_options') =~# ' *-m flake8'
@ -17,6 +18,11 @@ function! ale_linters#python#flake8#GetExecutable(buffer) abort
return 'pipenv' return 'pipenv'
endif endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_flake8_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
if !s:UsingModule(a:buffer) if !s:UsingModule(a:buffer)
return ale#python#FindExecutable(a:buffer, 'python_flake8', ['flake8']) return ale#python#FindExecutable(a:buffer, 'python_flake8', ['flake8'])
endif endif
@ -62,7 +68,7 @@ endfunction
function! ale_linters#python#flake8#GetCommand(buffer, version) abort function! ale_linters#python#flake8#GetCommand(buffer, version) abort
let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer) let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv\|poetry$'
\ ? ' run flake8' \ ? ' run flake8'
\ : '' \ : ''

View File

@ -7,6 +7,7 @@ call ale#Set('python_mypy_show_notes', 1)
call ale#Set('python_mypy_options', '') call ale#Set('python_mypy_options', '')
call ale#Set('python_mypy_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_mypy_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_mypy_auto_pipenv', 0) call ale#Set('python_mypy_auto_pipenv', 0)
call ale#Set('python_mypy_auto_poetry', 0)
function! ale_linters#python#mypy#GetExecutable(buffer) abort function! ale_linters#python#mypy#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_mypy_auto_pipenv')) if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_mypy_auto_pipenv'))
@ -14,6 +15,11 @@ function! ale_linters#python#mypy#GetExecutable(buffer) abort
return 'pipenv' return 'pipenv'
endif endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_mypy_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
return ale#python#FindExecutable(a:buffer, 'python_mypy', ['mypy']) return ale#python#FindExecutable(a:buffer, 'python_mypy', ['mypy'])
endfunction endfunction
@ -37,7 +43,7 @@ endfunction
function! ale_linters#python#mypy#GetCommand(buffer) abort function! ale_linters#python#mypy#GetCommand(buffer) abort
let l:executable = ale_linters#python#mypy#GetExecutable(a:buffer) let l:executable = ale_linters#python#mypy#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv\|poetry$'
\ ? ' run mypy' \ ? ' run mypy'
\ : '' \ : ''

View File

@ -2,6 +2,7 @@
" Description: prospector linter python files " Description: prospector linter python files
call ale#Set('python_prospector_auto_pipenv', 0) call ale#Set('python_prospector_auto_pipenv', 0)
call ale#Set('python_prospector_auto_poetry', 0)
let g:ale_python_prospector_executable = let g:ale_python_prospector_executable =
\ get(g:, 'ale_python_prospector_executable', 'prospector') \ get(g:, 'ale_python_prospector_executable', 'prospector')
@ -17,13 +18,18 @@ function! ale_linters#python#prospector#GetExecutable(buffer) abort
return 'pipenv' return 'pipenv'
endif endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_prospector_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
return ale#python#FindExecutable(a:buffer, 'python_prospector', ['prospector']) return ale#python#FindExecutable(a:buffer, 'python_prospector', ['prospector'])
endfunction endfunction
function! ale_linters#python#prospector#GetCommand(buffer) abort function! ale_linters#python#prospector#GetCommand(buffer) abort
let l:executable = ale_linters#python#prospector#GetExecutable(a:buffer) let l:executable = ale_linters#python#prospector#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv\|poetry$'
\ ? ' run prospector' \ ? ' run prospector'
\ : '' \ : ''

View File

@ -5,6 +5,7 @@ call ale#Set('python_pycodestyle_executable', 'pycodestyle')
call ale#Set('python_pycodestyle_options', '') call ale#Set('python_pycodestyle_options', '')
call ale#Set('python_pycodestyle_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_pycodestyle_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pycodestyle_auto_pipenv', 0) call ale#Set('python_pycodestyle_auto_pipenv', 0)
call ale#Set('python_pycodestyle_auto_poetry', 0)
function! ale_linters#python#pycodestyle#GetExecutable(buffer) abort function! ale_linters#python#pycodestyle#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pycodestyle_auto_pipenv')) if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pycodestyle_auto_pipenv'))
@ -12,13 +13,18 @@ function! ale_linters#python#pycodestyle#GetExecutable(buffer) abort
return 'pipenv' return 'pipenv'
endif endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pycodestyle_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
return ale#python#FindExecutable(a:buffer, 'python_pycodestyle', ['pycodestyle']) return ale#python#FindExecutable(a:buffer, 'python_pycodestyle', ['pycodestyle'])
endfunction endfunction
function! ale_linters#python#pycodestyle#GetCommand(buffer) abort function! ale_linters#python#pycodestyle#GetCommand(buffer) abort
let l:executable = ale_linters#python#pycodestyle#GetExecutable(a:buffer) let l:executable = ale_linters#python#pycodestyle#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv\|poetry$'
\ ? ' run pycodestyle' \ ? ' run pycodestyle'
\ : '' \ : ''

View File

@ -5,6 +5,7 @@ call ale#Set('python_pydocstyle_executable', 'pydocstyle')
call ale#Set('python_pydocstyle_options', '') call ale#Set('python_pydocstyle_options', '')
call ale#Set('python_pydocstyle_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_pydocstyle_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pydocstyle_auto_pipenv', 0) call ale#Set('python_pydocstyle_auto_pipenv', 0)
call ale#Set('python_pydocstyle_auto_poetry', 0)
function! ale_linters#python#pydocstyle#GetExecutable(buffer) abort function! ale_linters#python#pydocstyle#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pydocstyle_auto_pipenv')) if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pydocstyle_auto_pipenv'))
@ -12,12 +13,17 @@ function! ale_linters#python#pydocstyle#GetExecutable(buffer) abort
return 'pipenv' return 'pipenv'
endif endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pydocstyle_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
return ale#python#FindExecutable(a:buffer, 'python_pydocstyle', ['pydocstyle']) return ale#python#FindExecutable(a:buffer, 'python_pydocstyle', ['pydocstyle'])
endfunction endfunction
function! ale_linters#python#pydocstyle#GetCommand(buffer) abort function! ale_linters#python#pydocstyle#GetCommand(buffer) abort
let l:executable = ale_linters#python#pydocstyle#GetExecutable(a:buffer) let l:executable = ale_linters#python#pydocstyle#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv\|poetry$'
\ ? ' run pydocstyle' \ ? ' run pydocstyle'
\ : '' \ : ''

View File

@ -4,6 +4,7 @@
call ale#Set('python_pyflakes_executable', 'pyflakes') call ale#Set('python_pyflakes_executable', 'pyflakes')
call ale#Set('python_pyflakes_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_pyflakes_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pyflakes_auto_pipenv', 0) call ale#Set('python_pyflakes_auto_pipenv', 0)
call ale#Set('python_pyflakes_auto_poetry', 0)
function! ale_linters#python#pyflakes#GetExecutable(buffer) abort function! ale_linters#python#pyflakes#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pyflakes_auto_pipenv')) if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pyflakes_auto_pipenv'))
@ -11,13 +12,18 @@ function! ale_linters#python#pyflakes#GetExecutable(buffer) abort
return 'pipenv' return 'pipenv'
endif endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pyflakes_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
return ale#python#FindExecutable(a:buffer, 'python_pyflakes', ['pyflakes']) return ale#python#FindExecutable(a:buffer, 'python_pyflakes', ['pyflakes'])
endfunction endfunction
function! ale_linters#python#pyflakes#GetCommand(buffer) abort function! ale_linters#python#pyflakes#GetCommand(buffer) abort
let l:executable = ale_linters#python#pyflakes#GetExecutable(a:buffer) let l:executable = ale_linters#python#pyflakes#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv\|poetry$'
\ ? ' run pyflakes' \ ? ' run pyflakes'
\ : '' \ : ''

View File

@ -5,6 +5,7 @@ call ale#Set('python_pylama_executable', 'pylama')
call ale#Set('python_pylama_options', '') call ale#Set('python_pylama_options', '')
call ale#Set('python_pylama_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_pylama_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pylama_auto_pipenv', 0) call ale#Set('python_pylama_auto_pipenv', 0)
call ale#Set('python_pylama_auto_poetry', 0)
call ale#Set('python_pylama_change_directory', 1) call ale#Set('python_pylama_change_directory', 1)
function! ale_linters#python#pylama#GetExecutable(buffer) abort function! ale_linters#python#pylama#GetExecutable(buffer) abort
@ -13,6 +14,11 @@ function! ale_linters#python#pylama#GetExecutable(buffer) abort
return 'pipenv' return 'pipenv'
endif endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pylama_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
return ale#python#FindExecutable(a:buffer, 'python_pylama', ['pylama']) return ale#python#FindExecutable(a:buffer, 'python_pylama', ['pylama'])
endfunction endfunction
@ -31,7 +37,7 @@ endfunction
function! ale_linters#python#pylama#GetCommand(buffer) abort function! ale_linters#python#pylama#GetCommand(buffer) abort
let l:executable = ale_linters#python#pylama#GetExecutable(a:buffer) let l:executable = ale_linters#python#pylama#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv\|poetry$'
\ ? ' run pylama' \ ? ' run pylama'
\ : '' \ : ''

View File

@ -6,6 +6,7 @@ call ale#Set('python_pylint_options', '')
call ale#Set('python_pylint_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_pylint_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pylint_change_directory', 1) call ale#Set('python_pylint_change_directory', 1)
call ale#Set('python_pylint_auto_pipenv', 0) call ale#Set('python_pylint_auto_pipenv', 0)
call ale#Set('python_pylint_auto_poetry', 0)
call ale#Set('python_pylint_use_msg_id', 0) call ale#Set('python_pylint_use_msg_id', 0)
function! ale_linters#python#pylint#GetExecutable(buffer) abort function! ale_linters#python#pylint#GetExecutable(buffer) abort
@ -14,6 +15,11 @@ function! ale_linters#python#pylint#GetExecutable(buffer) abort
return 'pipenv' return 'pipenv'
endif endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pylint_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
return ale#python#FindExecutable(a:buffer, 'python_pylint', ['pylint']) return ale#python#FindExecutable(a:buffer, 'python_pylint', ['pylint'])
endfunction endfunction
@ -32,7 +38,7 @@ endfunction
function! ale_linters#python#pylint#GetCommand(buffer, version) abort function! ale_linters#python#pylint#GetCommand(buffer, version) abort
let l:executable = ale_linters#python#pylint#GetExecutable(a:buffer) let l:executable = ale_linters#python#pylint#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv\|poetry$'
\ ? ' run pylint' \ ? ' run pylint'
\ : '' \ : ''

View File

@ -1,37 +0,0 @@
" Author: aurieh <me@aurieh.me>
" Description: A language server for Python
call ale#Set('python_pyls_executable', 'pyls')
call ale#Set('python_pyls_options', '')
call ale#Set('python_pyls_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pyls_auto_pipenv', 0)
call ale#Set('python_pyls_config', {})
function! ale_linters#python#pyls#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pyls_auto_pipenv'))
\ && ale#python#PipenvPresent(a:buffer)
return 'pipenv'
endif
return ale#python#FindExecutable(a:buffer, 'python_pyls', ['pyls'])
endfunction
function! ale_linters#python#pyls#GetCommand(buffer) abort
let l:executable = ale_linters#python#pyls#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$'
\ ? ' run pyls'
\ : ''
return ale#Escape(l:executable) . l:exec_args . ale#Pad(ale#Var(a:buffer, 'python_pyls_options'))
endfunction
call ale#linter#Define('python', {
\ 'name': 'pyls',
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#python#pyls#GetExecutable'),
\ 'command': function('ale_linters#python#pyls#GetCommand'),
\ 'project_root': function('ale#python#FindProjectRoot'),
\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
\ 'lsp_config': {b -> ale#Var(b, 'python_pyls_config')},
\})

View File

@ -0,0 +1,43 @@
" Author: aurieh <me@aurieh.me>
" Description: A language server for Python
call ale#Set('python_pylsp_executable', 'pylsp')
call ale#Set('python_pylsp_options', '')
call ale#Set('python_pylsp_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pylsp_auto_pipenv', 0)
call ale#Set('python_pylsp_auto_poetry', 0)
call ale#Set('python_pylsp_config', {})
function! ale_linters#python#pylsp#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pylsp_auto_pipenv'))
\ && ale#python#PipenvPresent(a:buffer)
return 'pipenv'
endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pylsp_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
return ale#python#FindExecutable(a:buffer, 'python_pylsp', ['pylsp'])
endfunction
function! ale_linters#python#pylsp#GetCommand(buffer) abort
let l:executable = ale_linters#python#pylsp#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv\|poetry$'
\ ? ' run pylsp'
\ : ''
return ale#Escape(l:executable) . l:exec_args . ale#Pad(ale#Var(a:buffer, 'python_pylsp_options'))
endfunction
call ale#linter#Define('python', {
\ 'name': 'pylsp',
\ 'lsp': 'stdio',
\ 'executable': function('ale_linters#python#pylsp#GetExecutable'),
\ 'command': function('ale_linters#python#pylsp#GetCommand'),
\ 'project_root': function('ale#python#FindProjectRoot'),
\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
\ 'lsp_config': {b -> ale#Var(b, 'python_pylsp_config')},
\})

View File

@ -4,6 +4,7 @@
call ale#Set('python_pyre_executable', 'pyre') call ale#Set('python_pyre_executable', 'pyre')
call ale#Set('python_pyre_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_pyre_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_pyre_auto_pipenv', 0) call ale#Set('python_pyre_auto_pipenv', 0)
call ale#Set('python_pyre_auto_poetry', 0)
function! ale_linters#python#pyre#GetExecutable(buffer) abort function! ale_linters#python#pyre#GetExecutable(buffer) abort
if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pyre_auto_pipenv')) if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pyre_auto_pipenv'))
@ -11,13 +12,18 @@ function! ale_linters#python#pyre#GetExecutable(buffer) abort
return 'pipenv' return 'pipenv'
endif endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pyre_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
return ale#python#FindExecutable(a:buffer, 'python_pyre', ['pyre']) return ale#python#FindExecutable(a:buffer, 'python_pyre', ['pyre'])
endfunction endfunction
function! ale_linters#python#pyre#GetCommand(buffer) abort function! ale_linters#python#pyre#GetCommand(buffer) abort
let l:executable = ale_linters#python#pyre#GetExecutable(a:buffer) let l:executable = ale_linters#python#pyre#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv\|poetry$'
\ ? ' run pyre persistent' \ ? ' run pyre persistent'
\ : ' persistent' \ : ' persistent'

View File

@ -29,7 +29,7 @@ endfunction
function! ale_linters#python#vulture#GetCommand(buffer) abort function! ale_linters#python#vulture#GetCommand(buffer) abort
let l:executable = ale_linters#python#vulture#GetExecutable(a:buffer) let l:executable = ale_linters#python#vulture#GetExecutable(a:buffer)
let l:exec_args = l:executable =~? 'pipenv$' let l:exec_args = l:executable =~? 'pipenv\|poetry$'
\ ? ' run vulture' \ ? ' run vulture'
\ : '' \ : ''
let l:lint_dest = ale#Var(a:buffer, 'python_vulture_change_directory') let l:lint_dest = ale#Var(a:buffer, 'python_vulture_change_directory')

View File

@ -0,0 +1,7 @@
call ale#linter#Define('racket', {
\ 'name': 'racket_langserver',
\ 'lsp': 'stdio',
\ 'executable': 'racket',
\ 'command': '%e -l racket-langserver',
\ 'project_root': function('ale#racket#FindProjectRoot'),
\})

View File

@ -1,4 +1,5 @@
" Author: Mohammed Chelouti - https://github.com/motato1 " Author: Mohammed Chelouti - https://github.com/motato1
" Arnold Chand <creativenull@outlook.com>
" Description: Deno lsp linter for TypeScript files. " Description: Deno lsp linter for TypeScript files.
call ale#linter#Define('typescript', { call ale#linter#Define('typescript', {
@ -7,19 +8,5 @@ call ale#linter#Define('typescript', {
\ 'executable': function('ale#handlers#deno#GetExecutable'), \ 'executable': function('ale#handlers#deno#GetExecutable'),
\ 'command': '%e lsp', \ 'command': '%e lsp',
\ 'project_root': function('ale#handlers#deno#GetProjectRoot'), \ 'project_root': function('ale#handlers#deno#GetProjectRoot'),
\ 'initialization_options': function('ale_linters#typescript#deno#GetInitializationOptions'), \ 'initialization_options': function('ale#handlers#deno#GetInitializationOptions'),
\}) \})
function! ale_linters#typescript#deno#GetInitializationOptions(buffer) abort
let l:options = {
\ 'enable': v:true,
\ 'lint': v:true,
\ 'unstable': v:false,
\ }
if ale#Var(a:buffer, 'deno_unstable')
let l:options.unstable = v:true
endif
return l:options
endfunction

View File

@ -0,0 +1,42 @@
" Author: Nathan Sharp <nwsharp+eda@live.com>
" Description: Yosys for Verilog files
call ale#Set('verilog_yosys_executable', 'yosys')
call ale#Set('verilog_yosys_options', '-Q -T -p ''read_verilog %s''')
function! ale_linters#verilog#yosys#GetCommand(buffer) abort
return '%e ' . ale#Var(a:buffer, 'verilog_yosys_options') . ' 2>&1'
endfunction
function! ale_linters#verilog#yosys#Handle(buffer, lines) abort
let l:output = []
let l:path = fnamemodify(bufname(a:buffer), ':p')
for l:match in ale#util#GetMatches(a:lines, '^\([^:]\+\):\(\d\+\): \(WARNING\|ERROR\): \(.\+\)$')
call add(l:output, {
\ 'lnum': str2nr(l:match[2]),
\ 'text': l:match[4],
\ 'type': l:match[3][0],
\ 'filename': l:match[1],
\})
endfor
for l:match in ale#util#GetMatches(a:lines, '^\(Warning\|ERROR\): \(.\+\)$')
call add(l:output, {
\ 'lnum': 1,
\ 'text': l:match[2],
\ 'type': l:match[1][0],
\})
endfor
return l:output
endfunction
call ale#linter#Define('verilog', {
\ 'name': 'yosys',
\ 'output_stream': 'stdout',
\ 'executable': {b -> ale#Var(b, 'verilog_yosys_executable')},
\ 'command': function('ale_linters#verilog#yosys#GetCommand'),
\ 'callback': 'ale_linters#verilog#yosys#Handle',
\ 'lint_file': 1,
\})

View File

@ -1002,7 +1002,7 @@ endfunction
function! ale#completion#HandleUserData(completed_item) abort function! ale#completion#HandleUserData(completed_item) abort
let l:user_data_json = get(a:completed_item, 'user_data', '') let l:user_data_json = get(a:completed_item, 'user_data', '')
let l:user_data = !empty(l:user_data_json) let l:user_data = !empty(l:user_data_json)
\ ? json_decode(l:user_data_json) \ ? ale#util#FuzzyJSONDecode(l:user_data_json, v:null)
\ : v:null \ : v:null
if type(l:user_data) isnot v:t_dict if type(l:user_data) isnot v:t_dict

View File

@ -17,6 +17,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['python'], \ 'suggested_filetypes': ['python'],
\ 'description': 'Fix import issues with autoimport.', \ 'description': 'Fix import issues with autoimport.',
\ }, \ },
\ 'autoflake': {
\ 'function': 'ale#fixers#autoflake#Fix',
\ 'suggested_filetypes': ['python'],
\ 'description': 'Fix flake issues with autoflake.',
\ },
\ 'autopep8': { \ 'autopep8': {
\ 'function': 'ale#fixers#autopep8#Fix', \ 'function': 'ale#fixers#autopep8#Fix',
\ 'suggested_filetypes': ['python'], \ 'suggested_filetypes': ['python'],
@ -376,6 +381,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['dart'], \ 'suggested_filetypes': ['dart'],
\ 'description': 'Fix Dart files with dartfmt.', \ 'description': 'Fix Dart files with dartfmt.',
\ }, \ },
\ 'dart-format': {
\ 'function': 'ale#fixers#dart_format#Fix',
\ 'suggested_filetypes': ['dart'],
\ 'description': 'Fix Dart files with dart format.',
\ },
\ 'xmllint': { \ 'xmllint': {
\ 'function': 'ale#fixers#xmllint#Fix', \ 'function': 'ale#fixers#xmllint#Fix',
\ 'suggested_filetypes': ['xml'], \ 'suggested_filetypes': ['xml'],
@ -441,6 +451,11 @@ let s:default_registry = {
\ 'suggested_filetypes': ['html', 'htmldjango'], \ 'suggested_filetypes': ['html', 'htmldjango'],
\ 'description': 'Fix HTML files with html-beautify.', \ 'description': 'Fix HTML files with html-beautify.',
\ }, \ },
\ 'lua-format': {
\ 'function': 'ale#fixers#lua_format#Fix',
\ 'suggested_filetypes': ['lua'],
\ 'description': 'Fix Lua files with lua-format.',
\ },
\ 'luafmt': { \ 'luafmt': {
\ 'function': 'ale#fixers#luafmt#Fix', \ 'function': 'ale#fixers#luafmt#Fix',
\ 'suggested_filetypes': ['lua'], \ 'suggested_filetypes': ['lua'],

View File

@ -0,0 +1,28 @@
" Author: circld <circld1@gmail.com>
" Description: Fixing files with autoflake.
call ale#Set('python_autoflake_executable', 'autoflake')
call ale#Set('python_autoflake_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_autoflake_options', '')
function! ale#fixers#autoflake#Fix(buffer) abort
let l:executable = ale#python#FindExecutable(
\ a:buffer,
\ 'python_autoflake',
\ ['autoflake'],
\)
if !executable(l:executable)
return 0
endif
let l:options = ale#Var(a:buffer, 'python_autoflake_options')
return {
\ 'command': ale#Escape(l:executable)
\ . (!empty(l:options) ? ' ' . l:options : '')
\ . ' --in-place '
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

@ -5,6 +5,7 @@ call ale#Set('python_black_executable', 'black')
call ale#Set('python_black_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_black_use_global', get(g:, 'ale_use_global_executables', 0))
call ale#Set('python_black_options', '') call ale#Set('python_black_options', '')
call ale#Set('python_black_auto_pipenv', 0) call ale#Set('python_black_auto_pipenv', 0)
call ale#Set('python_black_auto_poetry', 0)
call ale#Set('python_black_change_directory', 1) call ale#Set('python_black_change_directory', 1)
function! ale#fixers#black#GetExecutable(buffer) abort function! ale#fixers#black#GetExecutable(buffer) abort
@ -13,6 +14,11 @@ function! ale#fixers#black#GetExecutable(buffer) abort
return 'pipenv' return 'pipenv'
endif endif
if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_black_auto_poetry'))
\ && ale#python#PoetryPresent(a:buffer)
return 'poetry'
endif
return ale#python#FindExecutable(a:buffer, 'python_black', ['black']) return ale#python#FindExecutable(a:buffer, 'python_black', ['black'])
endfunction endfunction
@ -20,7 +26,7 @@ function! ale#fixers#black#Fix(buffer) abort
let l:executable = ale#fixers#black#GetExecutable(a:buffer) let l:executable = ale#fixers#black#GetExecutable(a:buffer)
let l:cmd = [ale#Escape(l:executable)] let l:cmd = [ale#Escape(l:executable)]
if l:executable =~? 'pipenv$' if l:executable =~? 'pipenv\|poetry$'
call extend(l:cmd, ['run', 'black']) call extend(l:cmd, ['run', 'black'])
endif endif

View File

@ -0,0 +1,18 @@
" Author: ghsang <gwonhyuksang@gmail.com>
" Description: Integration of dart format with ALE.
call ale#Set('dart_format_executable', 'dart')
call ale#Set('dart_format_options', '')
function! ale#fixers#dart_format#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'dart_format_executable')
let l:options = ale#Var(a:buffer, 'dart_format_options')
return {
\ 'command': ale#Escape(l:executable)
\ . ' format'
\ . (empty(l:options) ? '' : ' ' . l:options)
\ . ' %t',
\ 'read_temporary_file': 1,
\}
endfunction

View File

@ -29,6 +29,7 @@ function! ale#fixers#isort#Fix(buffer) abort
return { return {
\ 'cwd': '%s:h', \ 'cwd': '%s:h',
\ 'command': ale#Escape(l:executable) . l:exec_args \ 'command': ale#Escape(l:executable) . l:exec_args
\ . ale#Pad('--filename %s')
\ . (!empty(l:options) ? ' ' . l:options : '') . ' -', \ . (!empty(l:options) ? ' ' . l:options : '') . ' -',
\} \}
endfunction endfunction

View File

@ -0,0 +1,16 @@
" Author: Mathias Jean Johansen <mathias@mjj.io>
" Description: Integration of LuaFormatter with ALE.
call ale#Set('lua_lua_format_executable', 'lua-format')
call ale#Set('lua_lua_format_options', '')
function! ale#fixers#lua_format#Fix(buffer) abort
let l:executable = ale#Var(a:buffer, 'lua_lua_format_executable')
let l:options = ale#Var(a:buffer, 'lua_lua_format_options')
return {
\ 'command': ale#Escape(l:executable)
\ . ale#Pad(l:options)
\ . ' -i',
\}
endfunction

View File

@ -1,26 +1,35 @@
" Author: Jan-Grimo Sobez <jan-grimo.sobez@phys.chem.ethz.ch> " Author: Jan-Grimo Sobez <jan-grimo.sobez@phys.chem.ethz.ch>
" Author: Kevin Clark <kevin.clark@gmail.com> " Author: Kevin Clark <kevin.clark@gmail.com>
" Author: D. Ben Knoble <ben.knoble+github@gmail.com>
" Description: Floating preview window for showing whatever information in. " Description: Floating preview window for showing whatever information in.
" Precondition: exists('*nvim_open_win') " Precondition: exists('*nvim_open_win') || has('popupwin')
function! ale#floating_preview#Show(lines, ...) abort function! ale#floating_preview#Show(lines, ...) abort
if !exists('*nvim_open_win') if !exists('*nvim_open_win') && !has('popupwin')
execute 'echom ''Floating windows not supported in this vim instance.''' execute 'echom ''Floating windows not supported in this vim instance.'''
return return
endif endif
let l:options = get(a:000, 0, {})
if has('nvim')
call s:NvimShow(a:lines, l:options)
else
call s:VimShow(a:lines, l:options)
endif
endfunction
function! s:NvimShow(lines, options) abort
" Remove the close autocmd so it doesn't happen mid update " Remove the close autocmd so it doesn't happen mid update
augroup ale_floating_preview_window augroup ale_floating_preview_window
autocmd! autocmd!
augroup END augroup END
let l:options = get(a:000, 0, {})
" Only create a new window if we need it " Only create a new window if we need it
if !exists('w:preview') || index(nvim_list_wins(), w:preview['id']) is# -1 if !exists('w:preview') || index(nvim_list_wins(), w:preview['id']) is# -1
call s:Create(l:options) call s:NvimCreate(a:options)
else else
call nvim_buf_set_option(w:preview['buffer'], 'modifiable', v:true) call nvim_buf_set_option(w:preview['buffer'], 'modifiable', v:true)
endif endif
@ -30,7 +39,7 @@ function! ale#floating_preview#Show(lines, ...) abort
call nvim_set_current_win(w:preview['id']) call nvim_set_current_win(w:preview['id'])
for l:command in get(l:options, 'commands', []) for l:command in get(a:options, 'commands', [])
call execute(l:command) call execute(l:command)
endfor endfor
@ -41,13 +50,13 @@ function! ale#floating_preview#Show(lines, ...) abort
autocmd! autocmd!
if g:ale_close_preview_on_insert if g:ale_close_preview_on_insert
autocmd CursorMoved,TabLeave,WinLeave,InsertEnter <buffer> ++once call s:Close() autocmd CursorMoved,TabLeave,WinLeave,InsertEnter <buffer> ++once call s:NvimClose()
else else
autocmd CursorMoved,TabLeave,WinLeave <buffer> ++once call s:Close() autocmd CursorMoved,TabLeave,WinLeave <buffer> ++once call s:NvimClose()
endif endif
augroup END augroup END
let [l:lines, l:width, l:height] = s:PrepareWindowContent(a:lines) let [l:lines, l:width, l:height] = s:NvimPrepareWindowContent(a:lines)
call nvim_win_set_width(w:preview['id'], l:width) call nvim_win_set_width(w:preview['id'], l:width)
call nvim_win_set_height(w:preview['id'], l:height) call nvim_win_set_height(w:preview['id'], l:height)
@ -56,7 +65,33 @@ function! ale#floating_preview#Show(lines, ...) abort
call nvim_buf_set_option(w:preview['buffer'], 'modifiable', v:false) call nvim_buf_set_option(w:preview['buffer'], 'modifiable', v:false)
endfunction endfunction
function! s:PrepareWindowContent(lines) abort function! s:VimShow(lines, options) abort
if g:ale_close_preview_on_insert
" Remove the close autocmd so it doesn't happen mid update
silent! autocmd! ale_floating_preview_window
endif
" Only create a new window if we need it
if !exists('w:preview') || index(popup_list(), w:preview['id']) is# -1
call s:VimCreate(a:options)
endif
" Execute commands in window context
for l:command in get(a:options, 'commands', [])
call win_execute(w:preview['id'], l:command)
endfor
call popup_settext(w:preview['id'], a:lines)
if g:ale_close_preview_on_insert
augroup ale_floating_preview_window
autocmd!
autocmd InsertEnter * ++once call s:VimClose()
augroup END
endif
endfunction
function! s:NvimPrepareWindowContent(lines) abort
let l:max_height = 10 let l:max_height = 10
let l:width = max(map(copy(a:lines), 'strdisplaywidth(v:val)')) let l:width = max(map(copy(a:lines), 'strdisplaywidth(v:val)'))
@ -94,7 +129,7 @@ function! s:PrepareWindowContent(lines) abort
return [l:lines, l:width, l:height] return [l:lines, l:width, l:height]
endfunction endfunction
function! s:Create(options) abort function! s:NvimCreate(options) abort
let l:buffer = nvim_create_buf(v:false, v:false) let l:buffer = nvim_create_buf(v:false, v:false)
let l:winid = nvim_open_win(l:buffer, v:false, { let l:winid = nvim_open_win(l:buffer, v:false, {
\ 'relative': 'cursor', \ 'relative': 'cursor',
@ -112,7 +147,32 @@ function! s:Create(options) abort
let w:preview = {'id': l:winid, 'buffer': l:buffer} let w:preview = {'id': l:winid, 'buffer': l:buffer}
endfunction endfunction
function! s:Close() abort function! s:VimCreate(options) abort
let l:popup_id = popup_create([], {
\ 'line': 'cursor+1',
\ 'col': 'cursor',
\ 'drag': v:true,
\ 'resize': v:true,
\ 'close': 'button',
\ 'padding': [0, 1, 0, 1],
\ 'border': [],
\ 'borderchars': empty(g:ale_floating_window_border) ? [' '] : [
\ g:ale_floating_window_border[1],
\ g:ale_floating_window_border[0],
\ g:ale_floating_window_border[1],
\ g:ale_floating_window_border[0],
\ g:ale_floating_window_border[2],
\ g:ale_floating_window_border[3],
\ g:ale_floating_window_border[4],
\ g:ale_floating_window_border[5],
\ ],
\ 'moved': 'any',
\ })
call setbufvar(winbufnr(l:popup_id), '&filetype', get(a:options, 'filetype', 'ale-preview'))
let w:preview = {'id': l:popup_id}
endfunction
function! s:NvimClose() abort
let l:mode = mode() let l:mode = mode()
let l:restore_visual = l:mode is# 'v' || l:mode is# 'V' || l:mode is# "\<C-V>" let l:restore_visual = l:mode is# 'v' || l:mode is# 'V' || l:mode is# "\<C-V>"
@ -132,3 +192,12 @@ function! s:Close() abort
normal! gv normal! gv
endif endif
endfunction endfunction
function! s:VimClose() abort
if !exists('w:preview')
return
endif
call popup_close(w:preview['id'])
unlet w:preview
endfunction

View File

@ -1,8 +1,10 @@
" Author: Mohammed Chelouti - https://github.com/motato1 " Author: Mohammed Chelouti - https://github.com/motato1
" Arnold Chand <creativenull@outlook.com>
" Description: Handler functions for Deno. " Description: Handler functions for Deno.
call ale#Set('deno_executable', 'deno') call ale#Set('deno_executable', 'deno')
call ale#Set('deno_unstable', 0) call ale#Set('deno_unstable', 0)
call ale#Set('deno_importMap', 'import_map.json')
call ale#Set('deno_lsp_project_root', '') call ale#Set('deno_lsp_project_root', '')
function! ale#handlers#deno#GetExecutable(buffer) abort function! ale#handlers#deno#GetExecutable(buffer) abort
@ -50,3 +52,23 @@ function! ale#handlers#deno#GetProjectRoot(buffer) abort
return '' return ''
endfunction endfunction
" Initialization Options for deno, for javascript and typescript
function! ale#handlers#deno#GetInitializationOptions(buffer) abort
let l:options = {
\ 'enable': v:true,
\ 'lint': v:true,
\ 'unstable': v:false,
\ 'importMap': ale#path#FindNearestFile(a:buffer, 'import_map.json'),
\ }
if ale#Var(a:buffer, 'deno_unstable')
let l:options.unstable = v:true
endif
if ale#Var(a:buffer, 'deno_importMap') isnot# ''
let l:options.importMap = ale#path#FindNearestFile(a:buffer, ale#Var(a:buffer, 'deno_importMap'))
endif
return l:options
endfunction

View File

@ -2,6 +2,7 @@
" Description: Functions for integrating with Python linters. " Description: Functions for integrating with Python linters.
call ale#Set('python_auto_pipenv', '0') call ale#Set('python_auto_pipenv', '0')
call ale#Set('python_auto_poetry', '0')
let s:sep = has('win32') ? '\' : '/' let s:sep = has('win32') ? '\' : '/'
" bin is used for Unix virtualenv directories, and Scripts is for Windows. " bin is used for Unix virtualenv directories, and Scripts is for Windows.
@ -34,6 +35,7 @@ function! ale#python#FindProjectRootIni(buffer) abort
\|| filereadable(l:path . '/Pipfile.lock') \|| filereadable(l:path . '/Pipfile.lock')
\|| filereadable(l:path . '/poetry.lock') \|| filereadable(l:path . '/poetry.lock')
\|| filereadable(l:path . '/pyproject.toml') \|| filereadable(l:path . '/pyproject.toml')
\|| filereadable(l:path . '/.tool-versions')
return l:path return l:path
endif endif
endfor endfor
@ -157,3 +159,8 @@ endfunction
function! ale#python#PipenvPresent(buffer) abort function! ale#python#PipenvPresent(buffer) abort
return findfile('Pipfile.lock', expand('#' . a:buffer . ':p:h') . ';') isnot# '' return findfile('Pipfile.lock', expand('#' . a:buffer . ':p:h') . ';') isnot# ''
endfunction endfunction
" Detects whether a poetry environment is present.
function! ale#python#PoetryPresent(buffer) abort
return findfile('poetry.lock', expand('#' . a:buffer . ':p:h') . ';') isnot# ''
endfunction

View File

@ -0,0 +1,12 @@
function! ale#racket#FindProjectRoot(buffer) abort
let l:cwd = expand('#' . a:buffer . ':p:h')
let l:highest_init = l:cwd
for l:path in ale#path#Upwards(l:cwd)
if filereadable(l:path.'/init.rkt')
let l:highest_init = l:path
endif
endfor
return l:highest_init
endfunction

View File

@ -85,7 +85,7 @@ execute 'sign define ALEStyleWarningSign text=' . s:EscapeSignText(g:ale_sign_st
\ . ' texthl=ALEStyleWarningSign linehl=ALEWarningLine' \ . ' texthl=ALEStyleWarningSign linehl=ALEWarningLine'
execute 'sign define ALEInfoSign text=' . s:EscapeSignText(g:ale_sign_info) execute 'sign define ALEInfoSign text=' . s:EscapeSignText(g:ale_sign_info)
\ . ' texthl=ALEInfoSign linehl=ALEInfoLine' \ . ' texthl=ALEInfoSign linehl=ALEInfoLine'
sign define ALEDummySign sign define ALEDummySign text=\ texthl=SignColumn
if g:ale_sign_highlight_linenrs && has('nvim-0.3.2') if g:ale_sign_highlight_linenrs && has('nvim-0.3.2')
if !hlexists('ALEErrorSignLineNr') if !hlexists('ALEErrorSignLineNr')

View File

@ -9,6 +9,14 @@ A minimal and opinionated linter for code that sparks joy.
https://github.com/borkdude/clj-kondo https://github.com/borkdude/clj-kondo
g:ale_clojure_clj_kondo_options *g:ale_clojure_clj_kondo_options*
*b:ale_clojure_clj_kondo_options*
Type: |String|
Default: `'--cache'`
This variable can be changed to modify options passed to clj-kondo.
=============================================================================== ===============================================================================
joker *ale-clojure-joker* joker *ale-clojure-joker*

View File

@ -27,6 +27,67 @@ g:ale_dart_analysis_server_executable *g:ale_dart_analysis_server_executable*
This variable can be set to change the path of dart. This variable can be set to change the path of dart.
===============================================================================
dart-analyze *ale-dart-analyze*
Installation
-------------------------------------------------------------------------------
Installing Dart should probably ensure that `dart` is in your `$PATH`.
In case it is not, try to set the executable option to its absolute path. : >
" Set the executable path for dart to the absolute path to it.
let g:ale_dart_format_executable = '/usr/lib/dart/bin/dart'
>
Install Dart via whatever means. `dart analyze` will be included in the SDK.
Options
-------------------------------------------------------------------------------
g:ale_dart_analyze_executable *g:ale_dart_analyze_executable*
*b:ale_dart_analyze_executable*
Type: |String|
Default: `'dart'`
This variable can be set to specify an absolute path to the
format executable (or to specify an alternate executable).
===============================================================================
dart-format *ale-dart-format*
Installation
-------------------------------------------------------------------------------
Installing Dart should probably ensure that `dart` is in your `$PATH`.
In case it is not, try to set the executable option to its absolute path. : >
" Set the executable path for dart to the absolute path to it.
let g:ale_dart_format_executable = '/usr/lib/dart/bin/dart'
>
Options
-------------------------------------------------------------------------------
g:ale_dart_format_executable *g:ale_dart_format_executable*
*b:ale_dart_format_executable*
Type: |String|
Default: `'dart'`
This variable can be set to specify an absolute path to the
format executable (or to specify an alternate executable).
g:ale_dart_format_options *g:ale_dart_format_options*
*b:ale_dart_format_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to the dart format fixer.
=============================================================================== ===============================================================================
dartanalyzer *ale-dart-dartanalyzer* dartanalyzer *ale-dart-dartanalyzer*

View File

@ -193,13 +193,13 @@ The Java language server will look for the dependencies you specify in
=============================================================================== ===============================================================================
eclipselsp *ale-java-eclipselsp* eclipselsp *ale-java-eclipselsp*
To enable Eclipse LSP linter you need to clone and build the eclipse.jdt.ls To enable Eclipse JDT LSP linter you need to clone and build the eclipse.jdt.ls
language server from https://github.com/eclipse/eclipse.jdt.ls. Simply language server from https://github.com/eclipse/eclipse.jdt.ls. Simply
clone the source code repo and then build the plugin: clone the source code repo and then build the plugin:
./mvnw clean verify ./mvnw clean verify
Note: currently, the build can only run when launched with JDK 8. JDK 9 or more Note: currently, the build can only run when launched with JDK 11. More
recent versions can be used to run the server though. recent versions can be used to run the server though.
After build completes the files required to run the language server will be After build completes the files required to run the language server will be

View File

@ -1,6 +1,24 @@
=============================================================================== ===============================================================================
ALE Lua Integration *ale-lua-options* ALE Lua Integration *ale-lua-options*
===============================================================================
lua-format *ale-lua-lua-format*
g:ale_lua_lua_format_executable *g:ale_lua_lua_format_executable*
*b:ale_lua_lua_format_executable*
Type: |String|
Default: `'lua-format'`
This variable can be changed to change the path to lua-format.
g:ale_lua_lua_format_options *g:ale_lua_lua_format_options*
*b:ale_lua_lua_format_options*
Type: |String|
Default: `''`
This variable can be set to pass additional options to lua-format.
=============================================================================== ===============================================================================
luac *ale-lua-luac* luac *ale-lua-luac*

View File

@ -26,7 +26,7 @@ g:ale_purescript_ls_config g:ale_purescript_ls_config
\ 'purescript': { \ 'purescript': {
\ 'addSpagoSources': v:true, \ 'addSpagoSources': v:true,
\ 'addNpmPath': v:true, \ 'addNpmPath': v:true,
\ 'buildCommand': 'spago build -- --json-errors' \ 'buildCommand': 'spago --quiet build --purs-args --json-errors'
\ } \ }
\} \}
=============================================================================== ===============================================================================

View File

@ -10,6 +10,14 @@ g:ale_python_auto_pipenv *g:ale_python_auto_pipenv*
Detect whether the file is inside a pipenv, and set the executable to `pipenv` Detect whether the file is inside a pipenv, and set the executable to `pipenv`
if true. This is overridden by a manually-set executable. if true. This is overridden by a manually-set executable.
g:ale_python_auto_poetry *g:ale_python_auto_poetry*
*b:ale_python_auto_poetry*
Type: |Number|
Default: `0`
Detect whether the file is inside a poetry, and set the executable to `poetry`
if true. This is overridden by a manually-set executable.
=============================================================================== ===============================================================================
ALE Python Project Root Behavior *ale-python-root* ALE Python Project Root Behavior *ale-python-root*
@ -36,13 +44,41 @@ ALE will look for configuration files with the following filenames. >
.pylintrc .pylintrc
Pipfile Pipfile
Pipfile.lock Pipfile.lock
poetry.lock poetry.lock
pyproject.toml pyproject.toml
.tool-versions
< <
The first directory containing any of the files named above will be used. The first directory containing any of the files named above will be used.
===============================================================================
autoflake *ale-python-autoflake*
g:ale_python_autoflake_executable *g:ale_python_autoflake_executable*
*b:ale_python_autoflake_executable*
Type: |String|
Default: `'autoflake'`
See |ale-integrations-local-executables|
g:ale_python_autoflake_options *g:ale_python_autoflake_options*
*b:ale_python_autoflake_options*
Type: |String|
Default: `''`
This variable can be set to pass extra options to autoflake.
g:ale_python_autoflake_use_global *g:ale_python_autoflake_use_global*
*b:ale_python_autoflake_use_global*
Type: |Number|
Default: `get(g:, 'ale_use_global_executables', 0)`
See |ale-integrations-local-executables|
=============================================================================== ===============================================================================
autoimport *ale-python-autoimport* autoimport *ale-python-autoimport*
@ -69,6 +105,7 @@ g:ale_python_autoimport_use_global *g:ale_python_autoimport_use_glob
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
=============================================================================== ===============================================================================
autopep8 *ale-python-autopep8* autopep8 *ale-python-autopep8*
@ -107,6 +144,7 @@ g:ale_python_bandit_executable *g:ale_python_bandit_executable*
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
Set this to `'pipenv'` to invoke `'pipenv` `run` `bandit'`. Set this to `'pipenv'` to invoke `'pipenv` `run` `bandit'`.
Set this to `'poetry'` to invoke `'poetry` `run` `bandit'`.
g:ale_python_bandit_options *g:ale_python_bandit_options* g:ale_python_bandit_options *g:ale_python_bandit_options*
@ -146,6 +184,15 @@ g:ale_python_bandit_auto_pipenv *g:ale_python_bandit_auto_pipenv*
if true. This is overridden by a manually-set executable. if true. This is overridden by a manually-set executable.
g:ale_python_bandit_auto_poetry *g:ale_python_bandit_auto_poetry*
*b:ale_python_bandit_auto_poetry*
Type: |Number|
Default: `0`
Detect whether the file is inside a poetry, and set the executable to `poetry`
if true. This is overridden by a manually-set executable.
=============================================================================== ===============================================================================
black *ale-python-black* black *ale-python-black*
@ -181,6 +228,14 @@ g:ale_python_black_auto_pipenv *g:ale_python_black_auto_pipenv*
Detect whether the file is inside a pipenv, and set the executable to `pipenv` Detect whether the file is inside a pipenv, and set the executable to `pipenv`
if true. This is overridden by a manually-set executable. if true. This is overridden by a manually-set executable.
g:ale_python_black_auto_poetry *g:ale_python_black_auto_poetry*
*b:ale_python_black_auto_poetry*
Type: |Number|
Default: `0`
Detect whether the file is inside a poetry, and set the executable to `poetry`
if true. This is overridden by a manually-set executable.
g:ale_python_black_change_directory *g:ale_python_black_change_directory* g:ale_python_black_change_directory *g:ale_python_black_change_directory*
*b:ale_python_black_change_directory* *b:ale_python_black_change_directory*
Type: |Number| Type: |Number|
@ -213,7 +268,8 @@ g:ale_python_flake8_executable *g:ale_python_flake8_executable*
Default: `'flake8'` Default: `'flake8'`
This variable can be changed to modify the executable used for flake8. Set This variable can be changed to modify the executable used for flake8. Set
this to `'pipenv'` to invoke `'pipenv` `run` `flake8'`. this to `'pipenv'` to invoke `'pipenv` `run` `flake8'`. Set this to
`'poetry'` to invoke `'poetry` `run` `flake8'`.
g:ale_python_flake8_options *g:ale_python_flake8_options* g:ale_python_flake8_options *g:ale_python_flake8_options*
@ -255,6 +311,15 @@ g:ale_python_flake8_auto_pipenv *g:ale_python_flake8_auto_pipenv*
if true. This is overridden by a manually-set executable. if true. This is overridden by a manually-set executable.
g:ale_python_flake8_auto_poetry *g:ale_python_flake8_auto_poetry*
*b:ale_python_flake8_auto_poetry*
Type: |Number|
Default: `0`
Detect whether the file is inside a poetry, and set the executable to `poetry`
if true. This is overridden by a manually-set executable.
=============================================================================== ===============================================================================
isort *ale-python-isort* isort *ale-python-isort*
@ -310,6 +375,15 @@ g:ale_python_mypy_auto_pipenv *g:ale_python_mypy_auto_pipenv*
if true. This is overridden by a manually-set executable. if true. This is overridden by a manually-set executable.
g:ale_python_mypy_auto_poetry *g:ale_python_mypy_auto_poetry*
*b:ale_python_mypy_auto_poetry*
Type: |Number|
Default: `0`
Detect whether the file is inside a poetry, and set the executable to `poetry`
if true. This is overridden by a manually-set executable.
g:ale_python_mypy_executable *g:ale_python_mypy_executable* g:ale_python_mypy_executable *g:ale_python_mypy_executable*
*b:ale_python_mypy_executable* *b:ale_python_mypy_executable*
Type: |String| Type: |String|
@ -318,6 +392,7 @@ g:ale_python_mypy_executable *g:ale_python_mypy_executable*
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
Set this to `'pipenv'` to invoke `'pipenv` `run` `mypy'`. Set this to `'pipenv'` to invoke `'pipenv` `run` `mypy'`.
Set this to `'poetry'` to invoke `'poetry` `run` `mypy'`.
g:ale_python_mypy_ignore_invalid_syntax g:ale_python_mypy_ignore_invalid_syntax
@ -368,6 +443,7 @@ g:ale_python_prospector_executable *g:ale_python_prospector_executable*
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
Set this to `'pipenv'` to invoke `'pipenv` `run` `prospector'`. Set this to `'pipenv'` to invoke `'pipenv` `run` `prospector'`.
Set this to `'poetry'` to invoke `'poetry` `run` `prospector'`.
g:ale_python_prospector_options *g:ale_python_prospector_options* g:ale_python_prospector_options *g:ale_python_prospector_options*
@ -408,6 +484,15 @@ g:ale_python_prospector_auto_pipenv *g:ale_python_prospector_auto_pipenv*
if true. This is overridden by a manually-set executable. if true. This is overridden by a manually-set executable.
g:ale_python_prospector_auto_poetry *g:ale_python_prospector_auto_poetry*
*b:ale_python_prospector_auto_poetry*
Type: |Number|
Default: `0`
Detect whether the file is inside a poetry, and set the executable to `poetry`
if true. This is overridden by a manually-set executable.
=============================================================================== ===============================================================================
pycodestyle *ale-python-pycodestyle* pycodestyle *ale-python-pycodestyle*
@ -420,6 +505,7 @@ g:ale_python_pycodestyle_executable *g:ale_python_pycodestyle_executable*
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
Set this to `'pipenv'` to invoke `'pipenv` `run` `pycodestyle'`. Set this to `'pipenv'` to invoke `'pipenv` `run` `pycodestyle'`.
Set this to `'poetry'` to invoke `'poetry` `run` `pycodestyle'`.
g:ale_python_pycodestyle_options *g:ale_python_pycodestyle_options* g:ale_python_pycodestyle_options *g:ale_python_pycodestyle_options*
@ -448,6 +534,15 @@ g:ale_python_pycodestyle_auto_pipenv *g:ale_python_pycodestyle_auto_pipenv*
if true. This is overridden by a manually-set executable. if true. This is overridden by a manually-set executable.
g:ale_python_pycodestyle_auto_poetry *g:ale_python_pycodestyle_auto_poetry*
*b:ale_python_pycodestyle_auto_poetry*
Type: |Number|
Default: `0`
Detect whether the file is inside a poetry, and set the executable to `poetry`
if true. This is overridden by a manually-set executable.
=============================================================================== ===============================================================================
pydocstyle *ale-python-pydocstyle* pydocstyle *ale-python-pydocstyle*
@ -460,6 +555,7 @@ g:ale_python_pydocstyle_executable *g:ale_python_pydocstyle_executable*
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
Set this to `'pipenv'` to invoke `'pipenv` `run` `pydocstyle'`. Set this to `'pipenv'` to invoke `'pipenv` `run` `pydocstyle'`.
Set this to `'poetry'` to invoke `'poetry` `run` `pydocstyle'`.
g:ale_python_pydocstyle_options *g:ale_python_pydocstyle_options* g:ale_python_pydocstyle_options *g:ale_python_pydocstyle_options*
@ -488,6 +584,15 @@ g:ale_python_pydocstyle_auto_pipenv *g:ale_python_pydocstyle_auto_pipenv*
if true. This is overridden by a manually-set executable. if true. This is overridden by a manually-set executable.
g:ale_python_pydocstyle_auto_poetry *g:ale_python_pydocstyle_auto_poetry*
*b:ale_python_pydocstyle_auto_poetry*
Type: |Number|
Default: `0`
Detect whether the file is inside a poetry, and set the executable to `poetry`
if true. This is overridden by a manually-set executable.
=============================================================================== ===============================================================================
pyflakes *ale-python-pyflakes* pyflakes *ale-python-pyflakes*
@ -500,6 +605,7 @@ g:ale_python_pyflakes_executable *g:ale_python_pyflakes_executable*
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
Set this to `'pipenv'` to invoke `'pipenv` `run` `pyflakes'`. Set this to `'pipenv'` to invoke `'pipenv` `run` `pyflakes'`.
Set this to `'poetry'` to invoke `'poetry` `run` `pyflakes'`.
g:ale_python_pyflakes_auto_pipenv *g:ale_python_pyflakes_auto_pipenv* g:ale_python_pyflakes_auto_pipenv *g:ale_python_pyflakes_auto_pipenv*
@ -511,6 +617,15 @@ g:ale_python_pyflakes_auto_pipenv *g:ale_python_pyflakes_auto_pipenv*
if true. This is overridden by a manually-set executable. if true. This is overridden by a manually-set executable.
g:ale_python_pyflakes_auto_poetry *g:ale_python_pyflakes_auto_poetry*
*b:ale_python_pyflakes_auto_poetry*
Type: |Number|
Default: `0`
Detect whether the file is inside a poetry, and set the executable to `poetry`
if true. This is overridden by a manually-set executable.
=============================================================================== ===============================================================================
pylama *ale-python-pylama* pylama *ale-python-pylama*
@ -532,7 +647,8 @@ g:ale_python_pylama_executable *g:ale_python_pylama_executable*
Default: `'pylama'` Default: `'pylama'`
This variable can be changed to modify the executable used for pylama. Set This variable can be changed to modify the executable used for pylama. Set
this to `'pipenv'` to invoke `'pipenv` `run` `pylama'`. this to `'pipenv'` to invoke `'pipenv` `run` `pylama'`. Set this to
`'poetry'` to invoke `'poetry` `run` `pylama'`.
g:ale_python_pylama_options *g:ale_python_pylama_options* g:ale_python_pylama_options *g:ale_python_pylama_options*
@ -565,6 +681,15 @@ g:ale_python_pylama_auto_pipenv *g:ale_python_pylama_auto_pipenv*
if true. This is overridden by a manually-set executable. if true. This is overridden by a manually-set executable.
g:ale_python_pylama_auto_poetry *g:ale_python_pylama_auto_poetry*
*b:ale_python_pylama_auto_poetry*
Type: |Number|
Default: `0`
Detect whether the file is inside a poetry, and set the executable to `poetry`
if true. This is overridden by a manually-set executable.
=============================================================================== ===============================================================================
pylint *ale-python-pylint* pylint *ale-python-pylint*
@ -589,6 +714,7 @@ g:ale_python_pylint_executable *g:ale_python_pylint_executable*
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
Set this to `'pipenv'` to invoke `'pipenv` `run` `pylint'`. Set this to `'pipenv'` to invoke `'pipenv` `run` `pylint'`.
Set this to `'poetry'` to invoke `'poetry` `run` `pylint'`.
g:ale_python_pylint_options *g:ale_python_pylint_options* g:ale_python_pylint_options *g:ale_python_pylint_options*
@ -628,6 +754,15 @@ g:ale_python_pylint_auto_pipenv *g:ale_python_pylint_auto_pipenv*
if true. This is overridden by a manually-set executable. if true. This is overridden by a manually-set executable.
g:ale_python_pylint_auto_poetry *g:ale_python_pylint_auto_poetry*
*b:ale_python_pylint_auto_poetry*
Type: |Number|
Default: `0`
Detect whether the file is inside a poetry, and set the executable to `poetry`
if true. This is overridden by a manually-set executable.
g:ale_python_pylint_use_msg_id *g:ale_python_pylint_use_msg_id* g:ale_python_pylint_use_msg_id *g:ale_python_pylint_use_msg_id*
*b:ale_python_pylint_use_msg_id* *b:ale_python_pylint_use_msg_id*
Type: |Number| Type: |Number|
@ -638,31 +773,32 @@ g:ale_python_pylint_use_msg_id *g:ale_python_pylint_use_msg_id*
=============================================================================== ===============================================================================
pyls *ale-python-pyls* pylsp *ale-python-pylsp*
`pyls` will be run from a detected project root, per |ale-python-root|. `pylsp` will be run from a detected project root, per |ale-python-root|.
g:ale_python_pyls_executable *g:ale_python_pyls_executable* g:ale_python_pylsp_executable *g:ale_python_pylsp_executable*
*b:ale_python_pyls_executable* *b:ale_python_pylsp_executable*
Type: |String| Type: |String|
Default: `'pyls'` Default: `'pylsp'`
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
Set this to `'pipenv'` to invoke `'pipenv` `run` `pyls'`. Set this to `'pipenv'` to invoke `'pipenv` `run` `pylsp'`.
Set this to `'poetry'` to invoke `'poetry` `run` `pyls'`.
g:ale_python_pyls_use_global *g:ale_python_pyls_use_global* g:ale_python_pylsp_use_global *g:ale_python_pylsp_use_global*
*b:ale_python_pyls_use_global* *b:ale_python_pylsp_use_global*
Type: |Number| Type: |Number|
Default: `get(g:, 'ale_use_global_executables', 0)` Default: `get(g:, 'ale_use_global_executables', 0)`
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
g:ale_python_pyls_auto_pipenv *g:ale_python_pyls_auto_pipenv* g:ale_python_pylsp_auto_pipenv *g:ale_python_pylsp_auto_pipenv*
*b:ale_python_pyls_auto_pipenv* *b:ale_python_pylsp_auto_pipenv*
Type: |Number| Type: |Number|
Default: `0` Default: `0`
@ -670,15 +806,24 @@ g:ale_python_pyls_auto_pipenv *g:ale_python_pyls_auto_pipenv*
if true. This is overridden by a manually-set executable. if true. This is overridden by a manually-set executable.
g:ale_python_pyls_config *g:ale_python_pyls_config* g:ale_python_pylsp_auto_poetry *g:ale_python_pylsp_auto_poetry*
*b:ale_python_pyls_config* *b:ale_python_pylsp_auto_poetry*
Type: |Number|
Default: `0`
Detect whether the file is inside a poetry, and set the executable to `poetry`
if true. This is overridden by a manually-set executable.
g:ale_python_pylsp_config *g:ale_python_pylsp_config*
*b:ale_python_pylsp_config*
Type: |Dictionary| Type: |Dictionary|
Default: `{}` Default: `{}`
Dictionary with configuration settings for pyls. For example, to disable Dictionary with configuration settings for pylsp. For example, to disable
the pycodestyle linter: > the pycodestyle linter: >
{ {
\ 'pyls': { \ 'pylsp': {
\ 'plugins': { \ 'plugins': {
\ 'pycodestyle': { \ 'pycodestyle': {
\ 'enabled': v:false \ 'enabled': v:false
@ -688,24 +833,24 @@ g:ale_python_pyls_config *g:ale_python_pyls_config*
\ } \ }
< <
g:ale_python_pyls_options *g:ale_python_pyls_options* g:ale_python_pylsp_options *g:ale_python_pylsp_options*
*b:ale_python_pyls_options* *b:ale_python_pylsp_options*
Type: |String| Type: |String|
Default: `''` Default: `''`
This variable can be changed to add command-line arguments to the pyls This variable can be changed to add command-line arguments to the pylsp
invocation. Note that this is not the same thing as ale_python_pyls_config, invocation. Note that this is not the same thing as ale_python_pylsp_config,
which allows configuration of how pyls functions; this is intended to which allows configuration of how pylsp functions; this is intended to
provide flexibility in how the pyls command is invoked. provide flexibility in how the pylsp command is invoked.
For example, if you had installed `pyls` but your `pyls` executable was not For example, if you had installed `pylsp` but your `pylsp` executable was not
on your `PATH` for some reason, an alternative way to run the pyls server on your `PATH` for some reason, an alternative way to run the pylsp server
would be: would be:
let g:ale_python_pyls_executable = 'python3' let g:ale_python_pylsp_executable = 'python3'
let g:ale_python_pyls_options = '-m pyls' let g:ale_python_pylsp_options = '-m pylsp'
An example stragety for installing `pyls`: An example stragety for installing `pylsp`:
`python3 -m pip install --user pyls` `python3 -m pip install --user pylsp`
=============================================================================== ===============================================================================
pyre *ale-python-pyre* pyre *ale-python-pyre*
@ -721,6 +866,7 @@ g:ale_python_pyre_executable *g:ale_python_pyre_executable*
See |ale-integrations-local-executables| See |ale-integrations-local-executables|
Set this to `'pipenv'` to invoke `'pipenv` `run` `pyre'`. Set this to `'pipenv'` to invoke `'pipenv` `run` `pyre'`.
Set this to `'poetry'` to invoke `'poetry` `run` `pyre'`.
g:ale_python_pyre_use_global *g:ale_python_pyre_use_global* g:ale_python_pyre_use_global *g:ale_python_pyre_use_global*
@ -740,6 +886,15 @@ g:ale_python_pyre_auto_pipenv *g:ale_python_pyre_auto_pipenv*
if true. This is overridden by a manually-set executable. if true. This is overridden by a manually-set executable.
g:ale_python_pyre_auto_poetry *g:ale_python_pyre_auto_poetry*
*b:ale_python_pyre_auto_poetry*
Type: |Number|
Default: `0`
Detect whether the file is inside a poetry, and set the executable to `poetry`
if true. This is overridden by a manually-set executable.
=============================================================================== ===============================================================================
pyright *ale-python-pyright* pyright *ale-python-pyright*

View File

@ -124,6 +124,8 @@ Notes:
* `dafny`!! * `dafny`!!
* Dart * Dart
* `analysis_server` * `analysis_server`
* `dart-analyze`!!
* `dart-format`!!
* `dartanalyzer`!! * `dartanalyzer`!!
* `dartfmt`!! * `dartfmt`!!
* `language_server` * `language_server`
@ -285,6 +287,7 @@ Notes:
* LLVM * LLVM
* `llc` * `llc`
* Lua * Lua
* `lua-format`
* `luac` * `luac`
* `luacheck` * `luacheck`
* `luafmt` * `luafmt`
@ -398,6 +401,7 @@ Notes:
* `purescript-language-server` * `purescript-language-server`
* `purty` * `purty`
* Python * Python
* `autoflake`!!
* `autoimport` * `autoimport`
* `autopep8` * `autopep8`
* `bandit` * `bandit`
@ -411,7 +415,7 @@ Notes:
* `pyflakes` * `pyflakes`
* `pylama`!! * `pylama`!!
* `pylint`!! * `pylint`!!
* `pyls` * `pylsp`
* `pyre` * `pyre`
* `pyright` * `pyright`
* `reorder-python-imports` * `reorder-python-imports`
@ -425,6 +429,7 @@ Notes:
* `lintr` * `lintr`
* `styler` * `styler`
* Racket * Racket
* `racket-langserver`
* `raco` * `raco`
* Re:VIEW * Re:VIEW
* `redpen` * `redpen`
@ -549,6 +554,7 @@ Notes:
* `verilator` * `verilator`
* `vlog` * `vlog`
* `xvlog` * `xvlog`
* `yosys`
* VHDL * VHDL
* `ghdl` * `ghdl`
* `vcom` * `vcom`

View File

@ -34,6 +34,12 @@ g:ale_deno_unstable *g:ale_deno_unstable*
Enable or disable unstable Deno features and APIs. Enable or disable unstable Deno features and APIs.
g:ale_deno_importMap *g:ale_deno_importMap*
*b:ale_deno_importMap*
Type: |String|
Default: `'import_map.json'`
Specify the import map filename to load url maps in a deno project.
=============================================================================== ===============================================================================
eslint *ale-typescript-eslint* eslint *ale-typescript-eslint*

View File

@ -3,7 +3,7 @@ ALE Verilog/SystemVerilog Integration *ale-verilog-options*
=============================================================================== ===============================================================================
ALE can use five different linters for Verilog HDL: ALE can use six different linters for Verilog HDL:
HDL Checker HDL Checker
Using `hdl_checker --lsp` Using `hdl_checker --lsp`
@ -20,6 +20,9 @@ ALE can use five different linters for Verilog HDL:
Vivado Vivado
Using `xvlog` Using `xvlog`
Yosys
Using `ysoys -Q -T -p 'read_verilog'`
By default, both 'verilog' and 'systemverilog' filetypes are checked. By default, both 'verilog' and 'systemverilog' filetypes are checked.
You can limit 'systemverilog' files to be checked using only 'verilator' by You can limit 'systemverilog' files to be checked using only 'verilator' by
@ -114,5 +117,26 @@ g:ale_verilog_xvlog_options *g:ale_verilog_xvlog_options*
This variable can be changed to modify the flags/options passed to 'xvlog'. This variable can be changed to modify the flags/options passed to 'xvlog'.
===============================================================================
yosys *ale-verilog-yosys*
g:ale_verilog_yosys_executable *g:ale_verilog_yosys_executable*
*b:ale_verilog_yosys_executable*
Type: |String|
Default: `'yosys'`
This variable can be changed to the path to the 'yosys' executable.
g:ale_verilog_yosys_options *g:ale_verilog_yosys_options*
*b:ale_verilog_yosys_options*
Type: |String|
Default: `'-Q -T -p ''read_verilog %s'''`
This variable can be changed to modify the flags/options passed to 'yosys'.
By default, Yosys is an interative program. To obtain linting functionality,
the `'read_verilog'` command is used.
=============================================================================== ===============================================================================
vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl:

View File

@ -651,9 +651,9 @@ problem will be displayed in a balloon instead of hover information.
Hover information can be displayed in the preview window instead by setting Hover information can be displayed in the preview window instead by setting
|g:ale_hover_to_preview| to `1`. |g:ale_hover_to_preview| to `1`.
When using Neovim, if |g:ale_hover_to_floating_preview| or |g:ale_floating_preview| When using Neovim or Vim with |popupwin|, if |g:ale_hover_to_floating_preview|
is set to 1, the hover information will show in a floating window. And or |g:ale_floating_preview| is set to 1, the hover information will show in a
|g:ale_floating_window_border| for the border setting. floating window. And |g:ale_floating_window_border| for the border setting.
For Vim 8.1+ terminals, mouse hovering is disabled by default. Enabling For Vim 8.1+ terminals, mouse hovering is disabled by default. Enabling
|balloonexpr| commands in terminals can cause scrolling issues in terminals, |balloonexpr| commands in terminals can cause scrolling issues in terminals,
@ -968,8 +968,8 @@ g:ale_detail_to_floating_preview *g:ale_detail_to_floating_preview*
Type: |Number| Type: |Number|
Default: `0` Default: `0`
When this option is set to `1`, Neovim will use a floating window for When this option is set to `1`, Neovim or Vim with |popupwin| will use a
ALEDetail output. floating window for ALEDetail output.
g:ale_disable_lsp *g:ale_disable_lsp* g:ale_disable_lsp *g:ale_disable_lsp*
@ -1200,7 +1200,8 @@ g:ale_floating_preview *g:ale_floating_preview*
Type: |Number| Type: |Number|
Default: `0` Default: `0`
When set to `1`, Neovim will use a floating window for ale's preview window. When set to `1`, Neovim or Vim with |popupwin| will use a floating window
for ale's preview window.
This is equivalent to setting |g:ale_hover_to_floating_preview| and This is equivalent to setting |g:ale_hover_to_floating_preview| and
|g:ale_detail_to_floating_preview| to `1`. |g:ale_detail_to_floating_preview| to `1`.
@ -1281,7 +1282,8 @@ g:ale_hover_to_floating_preview *g:ale_hover_to_floating_preview*
Type: |Number| Type: |Number|
Default: `0` Default: `0`
If set to `1`, Neovim will use floating windows for hover messages. If set to `1`, Neovim or Vim with |popupwin| will use floating windows for
hover messages.
g:ale_keep_list_window_open *g:ale_keep_list_window_open* g:ale_keep_list_window_open *g:ale_keep_list_window_open*
@ -2698,6 +2700,8 @@ documented in additional help files.
dafny.................................|ale-dafny-dafny| dafny.................................|ale-dafny-dafny|
dart....................................|ale-dart-options| dart....................................|ale-dart-options|
analysis_server.......................|ale-dart-analysis_server| analysis_server.......................|ale-dart-analysis_server|
dart-analyze..........................|ale-dart-analyze|
dart-format...........................|ale-dart-format|
dartanalyzer..........................|ale-dart-dartanalyzer| dartanalyzer..........................|ale-dart-dartanalyzer|
dartfmt...............................|ale-dart-dartfmt| dartfmt...............................|ale-dart-dartfmt|
desktop.................................|ale-desktop-options| desktop.................................|ale-desktop-options|
@ -2840,6 +2844,7 @@ documented in additional help files.
llvm....................................|ale-llvm-options| llvm....................................|ale-llvm-options|
llc...................................|ale-llvm-llc| llc...................................|ale-llvm-llc|
lua.....................................|ale-lua-options| lua.....................................|ale-lua-options|
lua-format............................|ale-lua-lua-format|
luac..................................|ale-lua-luac| luac..................................|ale-lua-luac|
luacheck..............................|ale-lua-luacheck| luacheck..............................|ale-lua-luacheck|
luafmt................................|ale-lua-luafmt| luafmt................................|ale-lua-luafmt|
@ -2932,6 +2937,7 @@ documented in additional help files.
pyrex (cython)..........................|ale-pyrex-options| pyrex (cython)..........................|ale-pyrex-options|
cython................................|ale-pyrex-cython| cython................................|ale-pyrex-cython|
python..................................|ale-python-options| python..................................|ale-python-options|
autoflake.............................|ale-python-autoflake|
autoimport............................|ale-python-autoimport| autoimport............................|ale-python-autoimport|
autopep8..............................|ale-python-autopep8| autopep8..............................|ale-python-autopep8|
bandit................................|ale-python-bandit| bandit................................|ale-python-bandit|
@ -2945,7 +2951,7 @@ documented in additional help files.
pyflakes..............................|ale-python-pyflakes| pyflakes..............................|ale-python-pyflakes|
pylama................................|ale-python-pylama| pylama................................|ale-python-pylama|
pylint................................|ale-python-pylint| pylint................................|ale-python-pylint|
pyls..................................|ale-python-pyls| pylsp.................................|ale-python-pylsp|
pyre..................................|ale-python-pyre| pyre..................................|ale-python-pyre|
pyright...............................|ale-python-pyright| pyright...............................|ale-python-pyright|
reorder-python-imports................|ale-python-reorder_python_imports| reorder-python-imports................|ale-python-reorder_python_imports|
@ -3066,6 +3072,7 @@ documented in additional help files.
verilator.............................|ale-verilog-verilator| verilator.............................|ale-verilog-verilator|
vlog..................................|ale-verilog-vlog| vlog..................................|ale-verilog-vlog|
xvlog.................................|ale-verilog-xvlog| xvlog.................................|ale-verilog-xvlog|
yosys.................................|ale-verilog-yosys|
vhdl....................................|ale-vhdl-options| vhdl....................................|ale-vhdl-options|
ghdl..................................|ale-vhdl-ghdl| ghdl..................................|ale-vhdl-ghdl|
hdl-checker...........................|ale-vhdl-hdl-checker| hdl-checker...........................|ale-vhdl-hdl-checker|
@ -3104,7 +3111,7 @@ ALEComplete *ALEComplete*
Manually trigger LSP autocomplete and show the menu. Works only when called Manually trigger LSP autocomplete and show the menu. Works only when called
from insert mode. > from insert mode. >
inoremap <silent> <C-Space> <C-\><C-O>:AleComplete<CR> inoremap <silent> <C-Space> <C-\><C-O>:ALEComplete<CR>
< <
A plug mapping `<Plug>(ale_complete)` is defined for this command. > A plug mapping `<Plug>(ale_complete)` is defined for this command. >

View File

@ -172,9 +172,15 @@ let g:ale_completion_enabled = get(g:, 'ale_completion_enabled', 0)
" Enable automatic detection of pipenv for Python linters. " Enable automatic detection of pipenv for Python linters.
let g:ale_python_auto_pipenv = get(g:, 'ale_python_auto_pipenv', 0) let g:ale_python_auto_pipenv = get(g:, 'ale_python_auto_pipenv', 0)
" Enable automatic detection of poetry for Python linters.
let g:ale_python_auto_poetry = get(g:, 'ale_python_auto_poetry', 0)
" This variable can be overridden to set the GO111MODULE environment variable. " This variable can be overridden to set the GO111MODULE environment variable.
let g:ale_go_go111module = get(g:, 'ale_go_go111module', '') let g:ale_go_go111module = get(g:, 'ale_go_go111module', '')
" Default executable for deno, needed set before plugin start
let g:ale_deno_executable = get(g:, 'ale_deno_executable', 'deno')
" If 1, enable a popup menu for commands. " If 1, enable a popup menu for commands.
let g:ale_popup_menu_enabled = get(g:, 'ale_popup_menu_enabled', has('gui_running')) let g:ale_popup_menu_enabled = get(g:, 'ale_popup_menu_enabled', has('gui_running'))

View File

@ -133,6 +133,8 @@ formatting.
* [dafny](https://rise4fun.com/Dafny) :floppy_disk: * [dafny](https://rise4fun.com/Dafny) :floppy_disk:
* Dart * Dart
* [analysis_server](https://github.com/dart-lang/sdk/tree/master/pkg/analysis_server) * [analysis_server](https://github.com/dart-lang/sdk/tree/master/pkg/analysis_server)
* [dart-analyze](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) :floppy_disk:
* [dart-format](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt)
* [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) :floppy_disk: * [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) :floppy_disk:
* [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) * [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt)
* [language_server](https://github.com/natebosch/dart_language_server) * [language_server](https://github.com/natebosch/dart_language_server)
@ -294,6 +296,7 @@ formatting.
* LLVM * LLVM
* [llc](https://llvm.org/docs/CommandGuide/llc.html) * [llc](https://llvm.org/docs/CommandGuide/llc.html)
* Lua * Lua
* [lua-format](https://github.com/Koihik/LuaFormatter)
* [luac](https://www.lua.org/manual/5.1/luac.html) * [luac](https://www.lua.org/manual/5.1/luac.html)
* [luacheck](https://github.com/mpeterv/luacheck) * [luacheck](https://github.com/mpeterv/luacheck)
* [luafmt](https://github.com/trixnz/lua-fmt) * [luafmt](https://github.com/trixnz/lua-fmt)
@ -407,6 +410,7 @@ formatting.
* [purescript-language-server](https://github.com/nwolverson/purescript-language-server) * [purescript-language-server](https://github.com/nwolverson/purescript-language-server)
* [purty](https://gitlab.com/joneshf/purty) * [purty](https://gitlab.com/joneshf/purty)
* Python * Python
* [autoflake](https://github.com/myint/autoflake)
* [autoimport](https://lyz-code.github.io/autoimport/) * [autoimport](https://lyz-code.github.io/autoimport/)
* [autopep8](https://github.com/hhatto/autopep8) * [autopep8](https://github.com/hhatto/autopep8)
* [bandit](https://github.com/PyCQA/bandit) :warning: * [bandit](https://github.com/PyCQA/bandit) :warning:
@ -420,7 +424,7 @@ formatting.
* [pyflakes](https://github.com/PyCQA/pyflakes) * [pyflakes](https://github.com/PyCQA/pyflakes)
* [pylama](https://github.com/klen/pylama) :floppy_disk: * [pylama](https://github.com/klen/pylama) :floppy_disk:
* [pylint](https://www.pylint.org/) :floppy_disk: * [pylint](https://www.pylint.org/) :floppy_disk:
* [pyls](https://github.com/palantir/python-language-server) :warning: * [pylsp](https://github.com/python-lsp/python-lsp-server) :warning:
* [pyre](https://github.com/facebook/pyre-check) :warning: * [pyre](https://github.com/facebook/pyre-check) :warning:
* [pyright](https://github.com/microsoft/pyright) * [pyright](https://github.com/microsoft/pyright)
* [reorder-python-imports](https://github.com/asottile/reorder_python_imports) * [reorder-python-imports](https://github.com/asottile/reorder_python_imports)
@ -434,6 +438,7 @@ formatting.
* [lintr](https://github.com/jimhester/lintr) * [lintr](https://github.com/jimhester/lintr)
* [styler](https://github.com/r-lib/styler) * [styler](https://github.com/r-lib/styler)
* Racket * Racket
* [racket-langserver](https://github.com/jeapostrophe/racket-langserver/tree/master)
* [raco](https://docs.racket-lang.org/raco/) * [raco](https://docs.racket-lang.org/raco/)
* Re:VIEW * Re:VIEW
* [redpen](http://redpen.cc/) * [redpen](http://redpen.cc/)
@ -558,6 +563,7 @@ formatting.
* [verilator](http://www.veripool.org/projects/verilator/wiki/Intro) * [verilator](http://www.veripool.org/projects/verilator/wiki/Intro)
* [vlog](https://www.mentor.com/products/fv/questa/) * [vlog](https://www.mentor.com/products/fv/questa/)
* [xvlog](https://www.xilinx.com/products/design-tools/vivado.html) * [xvlog](https://www.xilinx.com/products/design-tools/vivado.html)
* [yosys](http://www.clifford.at/yosys/)
* VHDL * VHDL
* [ghdl](https://github.com/ghdl/ghdl) * [ghdl](https://github.com/ghdl/ghdl)
* [vcom](https://www.mentor.com/products/fv/questa/) * [vcom](https://www.mentor.com/products/fv/questa/)

View File

@ -24,12 +24,8 @@
" POSSIBILITY OF SUCH DAMAGE. " POSSIBILITY OF SUCH DAMAGE.
" "
if v:version < 700 " check for Vim versions and duplicate script loading.
finish if v:version < 700 || exists("g:loaded_EditorConfig")
endif
" check whether this script is already loaded
if exists("g:loaded_EditorConfig")
finish finish
endif endif
let g:loaded_EditorConfig = 1 let g:loaded_EditorConfig = 1
@ -507,7 +503,7 @@ function! s:TrimTrailingWhitespace() " {{{1
" don't lose user position when trimming trailing whitespace " don't lose user position when trimming trailing whitespace
let s:view = winsaveview() let s:view = winsaveview()
try try
silent! keeppatterns %s/\s\+$//e silent! keeppatterns keepjumps %s/\s\+$//e
finally finally
call winrestview(s:view) call winrestview(s:view)
endtry endtry

View File

@ -5,41 +5,42 @@ labels: bug
--- ---
<!-- Attention! Please Read! <!-- Attention! Please Read!
Please fill out ALL the information below so that the issue can be fully Please fill out ALL the information below so that the issue can be fully understood. Omitting
understood. Omitting information will delay the resolution of your issue. It information will delay the resolution of your issue. It will be labeled "Needs More Info", and
will be labeled "Needs More Info", and may be closed until there is enough may be closed until there is enough information.
information.
Keep in mind that others may have the same question in the future. The better Keep in mind that others may have the same question in the future. The better your information,
your information, the more likely they'll be able to help themselves. --> the more likely they'll be able to help themselves.
-->
#### Self-Diagnosis #### Self-Diagnosis
<!-- Check the boxes after creating the issue, or use [x]. --> Before creating an issue, take some time to search these resources for an answer. It's possible that someone else has already seen and solved your issue.
- [ ] I have searched the [issues](https://github.com/scrooloose/nerdtree/issues) for an answer to my question. - [old NERDTree issues](https://github.com/preservim/nerdtree/issues?q=is%3Aissue)
- [ ] I have reviewed the NERDTree documentation. `:h NERDTree` - NERDTree documentation - `:h NERDTree`
- [ ] I have reviewed the [Wiki](https://github.com/scrooloose/nerdtree/wiki). - [NERDTree Wiki](https://github.com/preservim/nerdtree/wiki)
- [ ] I have searched the web for an answer to my question. - Other resources: <https://stackoverflow.com>, <https://vi.stackexchange.com>, etc.
#### Environment (for bug reports) #### Environment
- [ ] Operating System: - Operating System:
- [ ] Vim/Neovim version `:echo v:version`: - Vim/Neovim version `:version`:
- [ ] NERDTree version, found on 1st line in NERDTree quickhelp `?`: - NERDTree version, found on first line of quickhelp `?`:
- [ ] vimrc settings - Are you using any of these NERDTree-dependent plugins? <!-- Check the boxes after creating the issue. -->
- [ ] NERDTree variables - [ ] [Xuyuanp/nerdtree-git-plugin](https://github.com/Xuyuanp/nerdtree-git-plugin)
```vim - [ ] [ryanoasis/vim-devicons](https://github.com/ryanoasis/vim-devicons)
``` - [ ] [tiagofumo/vim-nerdtree-syntax-highlight](https://github.com/tiagofumo/vim-nerdtree-syntax-highlight)
- Other NERDTree-dependent Plugins - [ ] [scrooloose/nerdtree-project-plugin](https://github.com/scrooloose/nerdtree-project-plugin)
- [ ] jistr/vim-nerdtree-tabs - [ ] [PhilRunninger/nerdtree-buffer-ops](https://github.com/PhilRunninger/nerdtree-buffer-ops)
- [ ] ryanoasis/vim-devicons - [ ] [PhilRunninger/nerdtree-visual-selection](https://github.com/PhilRunninger/nerdtree-visual-selection)
- [ ] tiagofumo/vim-nerdtree-syntax-highlight - [ ] [jistr/vim-nerdtree-tabs](https://github.com/jistr/vim-nerdtree-tabs)
- [ ] Xuyuanp/nerdtree-git-plugin - [ ] Others (specify):
- [ ] Others (specify): - Provide a minimal **.vimrc** file that will reproduce the issue.
- [ ] I've verified the issue occurs with only NERDTree installed. ```vim
```
#### Steps to Reproduce the Issue #### Steps to Reproduce the Issue
1. 1.
#### Current Result (Include screenshots where appropriate.) #### Current Behavior (Include screenshots where appropriate.)
#### Expected Result #### Expected Result

View File

@ -3,22 +3,11 @@ name: "General Question"
about: "Having trouble setting up NERDTree? Need clarification on a setting? Ask your question here." about: "Having trouble setting up NERDTree? Need clarification on a setting? Ask your question here."
labels: "general question" labels: "general question"
--- ---
<!-- Attention! Please Read! Before creating an issue, take some time to search these resources. It's possible that someone else has already asked your question and gotten an answer.
- [old NERDTree issues](https://github.com/preservim/nerdtree/issues?q=is%3Aissue)
Please fill out ALL the information below so that the issue can be fully - NERDTree documentation - `:h NERDTree`
understood. Omitting information will delay the resolution of your issue. It - [NERDTree Wiki](https://github.com/preservim/nerdtree/wiki)
will be labeled "Needs More Info", and may be closed until there is enough - Other resource: <https://stackoverflow.com>, <https://vi.stackexchange.com>, etc.
information.
Keep in mind that others may have the same question in the future. The better
your information, the more likely they'll be able to help themselves. -->
#### Self-Diagnosis
<!-- Check the boxes after creating the issue, or use [x]. -->
- [ ] I have searched the [issues](https://github.com/scrooloose/nerdtree/issues) for an answer to my question.
- [ ] I have reviewed the NERDTree documentation. `:h NERDTree`
- [ ] I have reviewed the [Wiki](https://github.com/scrooloose/nerdtree/wiki).
- [ ] I have searched the web for an answer to my question.
#### State Your Question #### State Your Question

View File

@ -5,10 +5,11 @@
- **.PATCH**: Pull Request Title (PR Author) [PR Number](Link to PR) - **.PATCH**: Pull Request Title (PR Author) [PR Number](Link to PR)
--> -->
#### 6.10 #### 6.10
- **.10**: Improve F.A.Q. Answers and Issue Templates (PhilRunninger) [#1249](https://github.com/preservim/nerdtree/pull/1249)
- **.9**: `go` on a bookmark directory will NERDTreeFind it. (PhilRunninger) [#1236](https://github.com/preservim/nerdtree/pull/1236) - **.9**: `go` on a bookmark directory will NERDTreeFind it. (PhilRunninger) [#1236](https://github.com/preservim/nerdtree/pull/1236)
- **.8**: Put `Callback` function variables in local scope. (PhilRunninger) [#1230](https://github.com/preservim/nerdtree/pull/1230) - **.8**: Put `Callback` function variables in local scope. (PhilRunninger) [#1230](https://github.com/preservim/nerdtree/pull/1230)
- **.7**: Fix mouse-clicking a file to open it. (PhilRunninger) [#1225](https://github.com/preservim/nerdtree/pull/1225) - **.7**: Fix mouse-clicking a file to open it. (PhilRunninger) [#1225](https://github.com/preservim/nerdtree/pull/1225)
- **.6**: Restore the default behavior of the <CR> key. (PhilRunninger) [#1221](https://github.com/preservim/nerdtree/pull/1221) - **.6**: Restore the default behavior of the `<CR>` key. (PhilRunninger) [#1221](https://github.com/preservim/nerdtree/pull/1221)
- **.5**: Fix `{'keepopen':0}` in NERDTreeCustomOpenArgs (PhilRunninger) [#1217](https://github.com/preservim/nerdtree/pull/1217) - **.5**: Fix `{'keepopen':0}` in NERDTreeCustomOpenArgs (PhilRunninger) [#1217](https://github.com/preservim/nerdtree/pull/1217)
- **.4**: Removed directory separator from sort key (Daniel E) [#1219](https://github.com/preservim/nerdtree/pull/1219) - **.4**: Removed directory separator from sort key (Daniel E) [#1219](https://github.com/preservim/nerdtree/pull/1219)
- **.3**: Add new FAQ and answer: How to prevent buffers replacing NERDTree. (PhilRunninger) [#1215](https://github.com/preservim/nerdtree/pull/1215) - **.3**: Add new FAQ and answer: How to prevent buffers replacing NERDTree. (PhilRunninger) [#1215](https://github.com/preservim/nerdtree/pull/1215)

View File

@ -148,12 +148,16 @@ autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists('s:std_in
\ execute 'NERDTree' argv()[0] | wincmd p | enew | execute 'cd '.argv()[0] | endif \ execute 'NERDTree' argv()[0] | wincmd p | enew | execute 'cd '.argv()[0] | endif
``` ```
### How can I close Vim automatically when NERDTree is the last window? ### How can I close Vim or a tab automatically when NERDTree is the last window?
```vim ```vim
" Exit Vim if NERDTree is the only window left. " Exit Vim if NERDTree is the only window remaining in the only tab.
autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif
\ quit | endif ```
---
```vim
" Close the tab if NERDTree is the only window remaining in it.
autocmd BufEnter * if winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif
``` ```
### How can I prevent other buffers replacing NERDTree in its window? ### How can I prevent other buffers replacing NERDTree in its window?
@ -168,7 +172,7 @@ autocmd BufEnter * if bufname('#') =~ 'NERD_tree_\d\+' && bufname('%') !~ 'NERD_
```vim ```vim
" Open the existing NERDTree on each new tab. " Open the existing NERDTree on each new tab.
autocmd BufWinEnter * silent NERDTreeMirror autocmd BufWinEnter * if getcmdwintype() == '' | silent NERDTreeMirror | endif
``` ```
or change your NERDTree-launching shortcut key like so: or change your NERDTree-launching shortcut key like so:
```vim ```vim

View File

@ -146,7 +146,7 @@ function! s:Flake8() " {{{
set t_te= set t_te=
" perform the grep itself " perform the grep itself
let &grepformat="%f:%l:%c: %m\,%f:%l: %m" let &grepformat="%f:%l:%c: %m\,%f:%l: %m,%-G%\\d"
let &grepprg=s:flake8_cmd let &grepprg=s:flake8_cmd
silent! grep! "%" silent! grep! "%"
" close any existing cwindows, " close any existing cwindows,

View File

@ -1,6 +1,9 @@
" Location: autoload/fugitive.vim " Location: autoload/fugitive.vim
" Maintainer: Tim Pope <http://tpo.pe/> " Maintainer: Tim Pope <http://tpo.pe/>
" The functions contained within this file are for internal use only. For the
" official API, see the commented functions in plugin/fugitive.vim.
if exists('g:autoloaded_fugitive') if exists('g:autoloaded_fugitive')
finish finish
endif endif
@ -88,11 +91,16 @@ function! s:VersionCheck() abort
endif endif
endfunction endfunction
let s:worktree_error = "core.worktree is required when using an external Git dir"
function! s:DirCheck(...) abort function! s:DirCheck(...) abort
let vcheck = s:VersionCheck() let vcheck = s:VersionCheck()
if !empty(vcheck) if !empty(vcheck)
return vcheck return vcheck
elseif !empty(a:0 ? s:Dir(a:1) : s:Dir()) endif
let dir = a:0 ? s:Dir(a:1) : s:Dir()
if !empty(dir) && FugitiveWorkTree(dir, 1) is# 0
return 'return ' . string('echoerr "fugitive: ' . s:worktree_error . '"')
elseif !empty(dir)
return '' return ''
elseif empty(bufname('')) elseif empty(bufname(''))
return 'return ' . string('echoerr "fugitive: working directory does not belong to a Git repository"') return 'return ' . string('echoerr "fugitive: working directory does not belong to a Git repository"')
@ -225,6 +233,12 @@ function! fugitive#Autowrite() abort
return '' return ''
endfunction endfunction
function! s:add_methods(namespace, method_names) abort
for name in a:method_names
let s:{a:namespace}_prototype[name] = s:function('s:'.a:namespace.'_'.name)
endfor
endfunction
" Section: Git " Section: Git
function! s:GitCmd() abort function! s:GitCmd() abort
@ -237,7 +251,7 @@ function! s:GitCmd() abort
let string = g:fugitive_git_executable let string = g:fugitive_git_executable
let list = [] let list = []
if string =~# '^\w\+=' if string =~# '^\w\+='
call add(list, 'env') call add(list, '/usr/bin/env')
endif endif
while string =~# '\S' while string =~# '\S'
let arg = matchstr(string, '^\s*\%(' . dquote . '''[^'']*''\|\\.\|[^[:space:] |]\)\+') let arg = matchstr(string, '^\s*\%(' . dquote . '''[^'']*''\|\\.\|[^[:space:] |]\)\+')
@ -307,7 +321,7 @@ let s:git_versions = {}
function! fugitive#GitVersion(...) abort function! fugitive#GitVersion(...) abort
let git = s:GitShellCmd() let git = s:GitShellCmd()
if !has_key(s:git_versions, git) if !has_key(s:git_versions, git)
let s:git_versions[git] = matchstr(s:SystemError(git.' --version')[0], '\d[^[:space:]]\+') let s:git_versions[git] = matchstr(s:SystemError(s:GitCmd() + ['--version'])[0], '\d[^[:space:]]\+')
endif endif
if !a:0 if !a:0
return s:git_versions[git] return s:git_versions[git]
@ -460,12 +474,12 @@ function! s:BuildEnvPrefix(env) abort
let env = items(a:env) let env = items(a:env)
if empty(env) if empty(env)
return '' return ''
elseif &shellcmdflag =~# '-Command' elseif &shell =~? '\%(powershell\|pwsh\)\%(\.exe\)\=$'
return join(map(env, '"$Env:" . v:val[0] . " = ''" . substitute(v:val[1], "''", "''''", "g") . "''; "'), '') return join(map(env, '"$Env:" . v:val[0] . " = ''" . substitute(v:val[1], "''", "''''", "g") . "''; "'), '')
elseif s:winshell() elseif s:winshell()
return join(map(env, '"set " . substitute(join(v:val, "="), "[&|<>^]", "^^^&", "g") . "& "'), '') return join(map(env, '"set " . substitute(join(v:val, "="), "[&|<>^]", "^^^&", "g") . "& "'), '')
else else
return 'env ' . s:shellesc(map(env, 'join(v:val, "=")')) . ' ' return '/usr/bin/env ' . s:shellesc(map(env, 'join(v:val, "=")')) . ' '
endif endif
endfunction endfunction
@ -477,7 +491,7 @@ function! s:JobOpts(cmd, env) abort
endif endif
let envlist = map(items(a:env), 'join(v:val, "=")') let envlist = map(items(a:env), 'join(v:val, "=")')
if !has('win32') if !has('win32')
return [['env'] + envlist + a:cmd, {}] return [['/usr/bin/env'] + envlist + a:cmd, {}]
else else
let pre = join(map(envlist, '"set " . substitute(v:val, "[&|<>^]", "^^^&", "g") . "& "'), '') let pre = join(map(envlist, '"set " . substitute(v:val, "[&|<>^]", "^^^&", "g") . "& "'), '')
if len(a:cmd) == 3 && a:cmd[0] ==# 'cmd.exe' && a:cmd[1] ==# '/c' if len(a:cmd) == 3 && a:cmd[0] ==# 'cmd.exe' && a:cmd[1] ==# '/c'
@ -519,7 +533,7 @@ function! s:SystemError(cmd, ...) abort
let guioptions = &guioptions let guioptions = &guioptions
set guioptions-=! set guioptions-=!
endif endif
let out = call('system', [type(a:cmd) ==# type([]) ? fugitive#Prepare(a:cmd) : a:cmd] + a:000) let out = call('system', [type(a:cmd) == type([]) ? s:shellesc(a:cmd) : a:cmd] + a:000)
return [out, v:shell_error] return [out, v:shell_error]
catch /^Vim\%((\a\+)\)\=:E484:/ catch /^Vim\%((\a\+)\)\=:E484:/
let opts = ['shell', 'shellcmdflag', 'shellredir', 'shellquote', 'shellxquote', 'shellxescape', 'shellslash'] let opts = ['shell', 'shellcmdflag', 'shellredir', 'shellquote', 'shellxquote', 'shellxescape', 'shellslash']
@ -554,7 +568,7 @@ endfunction
function! s:NullError(...) abort function! s:NullError(...) abort
let [out, exec_error] = s:SystemError(call('fugitive#Prepare', a:000)) let [out, exec_error] = s:SystemError(call('fugitive#Prepare', a:000))
if exec_error if exec_error
return [[], substitute(out, "\n$", "", "") : '', exec_error] return [[], substitute(out, "\n$", "", ""), exec_error]
else else
let list = split(out, "\1", 1) let list = split(out, "\1", 1)
call remove(list, -1) call remove(list, -1)
@ -625,13 +639,14 @@ function! s:ConfigTimestamps(dir, dict) abort
return join(map(files, 'getftime(expand(v:val))'), ',') return join(map(files, 'getftime(expand(v:val))'), ',')
endfunction endfunction
let s:config_prototype = {}
let s:config = {} let s:config = {}
function! fugitive#Config(...) abort function! fugitive#Config(...) abort
let name = '' let name = ''
let default = get(a:, 3, '') let default = get(a:, 3, '')
if a:0 >= 2 && type(a:2) == type({}) && !has_key(a:2, 'git_dir') if a:0 >= 2 && type(a:2) == type({}) && has_key(a:2, 'GetAll')
let name = substitute(a:1, '^[^.]\+\|[^.]\+$', '\L&', 'g') return fugitive#ConfigGetAll(a:1, a:2)
return len(a:1) ? get(get(a:2, name, []), 0, default) : a:2
elseif a:0 >= 2 elseif a:0 >= 2
let dir = s:Dir(a:2) let dir = s:Dir(a:2)
let name = a:1 let name = a:1
@ -650,7 +665,8 @@ function! fugitive#Config(...) abort
if has_key(s:config, dir_key) && s:config[dir_key][0] ==# s:ConfigTimestamps(dir, s:config[dir_key][1]) if has_key(s:config, dir_key) && s:config[dir_key][0] ==# s:ConfigTimestamps(dir, s:config[dir_key][1])
let dict = s:config[dir_key][1] let dict = s:config[dir_key][1]
else else
let dict = {} let dict = copy(s:config_prototype)
let dict.git_dir = dir
let [lines, message, exec_error] = s:NullError([dir, 'config', '--list', '-z']) let [lines, message, exec_error] = s:NullError([dir, 'config', '--list', '-z'])
if exec_error if exec_error
return {} return {}
@ -694,6 +710,25 @@ function! fugitive#ConfigGetRegexp(pattern, ...) abort
return transformed return transformed
endfunction endfunction
function! s:config_GetAll(name) dict abort
let name = substitute(a:name, '^[^.]\+\|[^.]\+$', '\L&', 'g')
if name =~# '\.'
return get(self, name, [])
else
return []
endif
endfunction
function! s:config_Get(name, ...) dict abort
return get(self.GetAll(a:name), 0, a:0 ? a:1 : '')
endfunction
function! s:config_GetRegexp(pattern) dict abort
return fugitive#ConfigGetRegexp(self, a:pattern)
endfunction
call s:add_methods('config', ['GetAll', 'Get', 'GetRegexp'])
function! s:Remote(dir) abort function! s:Remote(dir) abort
let head = FugitiveHead(0, a:dir) let head = FugitiveHead(0, a:dir)
let remote = len(head) ? FugitiveConfigGet('branch.' . head . '.remote', a:dir) : '' let remote = len(head) ? FugitiveConfigGet('branch.' . head . '.remote', a:dir) : ''
@ -706,32 +741,83 @@ function! s:Remote(dir) abort
return remote =~# '^\.\=$' ? 'origin' : remote return remote =~# '^\.\=$' ? 'origin' : remote
endfunction endfunction
unlet! s:ssh_aliases function! s:SshParseHost(value) abort
function! fugitive#SshHostAlias(...) abort let patterns = []
if !exists('s:ssh_aliases') let negates = []
let s:ssh_aliases = {} for host in split(a:value, '\s\+')
if filereadable(expand('~/.ssh/config')) let pattern = substitute(host, '[\\^$.*~?]', '\=submatch(0) == "*" ? ".*" : submatch(0) == "?" ? "." : "\\" . submatch(0)', 'g')
let hosts = [] if pattern[0] ==# '!'
for line in readfile(expand('~/.ssh/config')) call add(negates, '\&\%(^' . pattern[1 : -1] . '$\)\@!')
let key = matchstr(line, '^\s*\zs\w\+\ze\s') else
let value = matchstr(line, '^\s*\w\+\s\+\zs.*\S') call add(patterns, pattern)
if key ==? 'host'
let hosts = split(value, '\s\+')
elseif key ==? 'hostname'
for host in hosts
if !has_key(s:ssh_aliases, host)
let s:ssh_aliases[host] = tolower(value)
endif
endfor
endif
endfor
endif endif
endfor
return '^\%(' . join(patterns, '\|') . '\)$' . join(negates, '')
endfunction
function! s:SshParseConfig(into, root, file, ...) abort
if !filereadable(a:file)
return a:into
endif endif
if a:0 let host = a:0 ? a:1 : '^\%(.*\)$'
return get(s:ssh_aliases, a:1, a:1) for line in readfile(a:file)
else let key = tolower(matchstr(line, '^\s*\zs\w\+\ze\s'))
return s:ssh_aliases let value = matchstr(line, '^\s*\w\+\s\+\zs.*\S')
if key ==# 'match'
let host = value ==# 'all' ? '^\%(.*\)$' : ''
elseif key ==# 'host'
let host = s:SshParseHost(value)
elseif key ==# 'include'
call s:SshParseInclude(a:into, a:root, host, value)
elseif len(key) && len(host)
call extend(a:into, {key: []}, 'keep')
call add(a:into[key], [host, value])
endif
endfor
return a:into
endfunction
function! s:SshParseInclude(into, root, host, value) abort
for glob in split(a:value)
if glob !~# '^/'
let glob = a:root . glob
endif
for file in split(glob(glob), "\n")
call s:SshParseConfig(a:into, a:root, file, a:host)
endfor
endfor
endfunction
unlet! s:ssh_config
function! fugitive#SshConfig(host, ...) abort
if !exists('s:ssh_config')
let s:ssh_config = {}
for file in [expand("~/.ssh/config"), "/etc/ssh/ssh_config"]
call s:SshParseConfig(s:ssh_config, substitute(file, '\w*$', '', ''), file)
endfor
endif endif
let host_config = {}
for key in a:0 ? a:1 : keys(s:ssh_config)
for [host_pattern, value] in get(s:ssh_config, key, [])
if a:host =~# host_pattern
let host_config[key] = value
break
endif
endfor
endfor
return host_config
endfunction
function! fugitive#SshHostAlias(authority) abort
let [_, user, host, port; __] = matchlist(a:authority, '^\%(\([^/@]\+\)@\)\=\(.\{-\}\)\%(:\(\d\+\)\)\=$')
let c = fugitive#SshConfig(host, ['user', 'hostname', 'port'])
if empty(user)
let user = get(c, 'user', '')
endif
if empty(port)
let port = get(c, 'port', '')
endif
return (len(user) ? user . '@' : '') . get(c, 'hostname', host) . (port =~# '^\%(22\)\=$' ? '' : ':' . port)
endfunction endfunction
let s:redirects = {} let s:redirects = {}
@ -740,28 +826,55 @@ function! fugitive#ResolveRemote(remote) abort
if a:remote =~# '^https\=://' && s:executable('curl') if a:remote =~# '^https\=://' && s:executable('curl')
if !has_key(s:redirects, a:remote) if !has_key(s:redirects, a:remote)
let s:redirects[a:remote] = matchstr(s:SystemError( let s:redirects[a:remote] = matchstr(s:SystemError(
\ 'curl --disable --silent --max-time 5 -I ' . \ ['curl', '--disable', '--silent', '--max-time', '5', '-I',
\ s:shellesc(a:remote . '/info/refs?service=git-upload-pack'))[0], \ a:remote . '/info/refs?service=git-upload-pack'])[0],
\ 'Location: \zs\S\+\ze/info/refs?') \ 'Location: \zs\S\+\ze/info/refs?')
endif endif
if len(s:redirects[a:remote]) if len(s:redirects[a:remote])
return s:redirects[a:remote] return s:redirects[a:remote]
endif endif
elseif a:remote =~# '^ssh://'
let authority = matchstr(a:remote, '[^/?#]*', 6)
return 'ssh://' . fugitive#SshHostAlias(authority) . strpart(a:remote, 6 + len(authority))
endif endif
return substitute(a:remote, let scp_authority = matchstr(a:remote, '^[^:/]\+\ze:\%(//\)\@!')
\ '^ssh://\%([^@:/]\+@\)\=\zs[^/:]\+\|^\%([^@:/]\+@\)\=\zs[^/:]\+\ze:/\@!', if empty(scp_authority)
\ '\=fugitive#SshHostAlias(submatch(0))', '') return a:remote
endif
let path = strpart(a:remote, len(scp_authority) + 1)
let alias = fugitive#SshHostAlias(scp_authority)
if alias !~# ':'
return alias . ':' . path
elseif path =~# '^/'
return 'ssh://' . alias . path
else
return a:remote
endif
endfunction
function! s:ConfigLengthSort(i1, i2) abort
return len(a:i2[0]) - len(a:i1[0])
endfunction endfunction
function! fugitive#RemoteUrl(...) abort function! fugitive#RemoteUrl(...) abort
let dir = a:0 > 1 ? a:2 : s:Dir() let dir = a:0 > 1 ? s:Dir(a:2) : s:Dir()
let url = !a:0 || a:1 =~# '^\.\=$' ? s:Remote(dir) : a:1 let url = !a:0 || a:1 =~# '^\.\=$' ? s:Remote(dir) : a:1
if url !~# ':\|^/\|^\.\.\=/' if url !~# ':\|^/\|^\.\.\=/'
if !fugitive#GitVersion(2, 7) let config = fugitive#Config(a:0 > 1 ? a:2 : s:Dir())
let url = FugitiveConfigGet('remote.' . url . '.url') let url = FugitiveConfigGet('remote.' . url . '.url', config)
else let instead_of = []
let url = s:ChompDefault('', [dir, 'remote', 'get-url', url, '--']) for [k, vs] in items(fugitive#ConfigGetRegexp('^url\.\zs.\{-\}\ze\.insteadof$', config))
endif for v in vs
call add(instead_of, [v, k])
endfor
endfor
call sort(instead_of, 's:ConfigLengthSort')
for [orig, replacement] in instead_of
if strpart(url, 0, len(orig)) ==# orig
let url = replacement . strpart(url, len(orig))
break
endif
endfor
endif endif
if !get(a:, 3, 0) if !get(a:, 3, 0)
let url = fugitive#ResolveRemote(url) let url = fugitive#ResolveRemote(url)
@ -796,6 +909,7 @@ function! s:QuickfixCreate(nr, opts) abort
endfunction endfunction
function! s:QuickfixStream(nr, event, title, cmd, first, mods, callback, ...) abort function! s:QuickfixStream(nr, event, title, cmd, first, mods, callback, ...) abort
call s:BlurStatus()
let mods = s:Mods(a:mods) let mods = s:Mods(a:mods)
let opts = {'title': a:title, 'context': {'items': []}} let opts = {'title': a:title, 'context': {'items': []}}
call s:QuickfixCreate(a:nr, opts) call s:QuickfixCreate(a:nr, opts)
@ -808,7 +922,7 @@ function! s:QuickfixStream(nr, event, title, cmd, first, mods, callback, ...) ab
endif endif
let buffer = [] let buffer = []
let lines = split(s:SystemError(s:shellesc(a:cmd))[0], "\n") let lines = split(s:SystemError(a:cmd)[0], "\n")
for line in lines for line in lines
call extend(buffer, call(a:callback, a:000 + [line])) call extend(buffer, call(a:callback, a:000 + [line]))
if len(buffer) >= 20 if len(buffer) >= 20
@ -829,7 +943,6 @@ function! s:QuickfixStream(nr, event, title, cmd, first, mods, callback, ...) ab
silent exe s:DoAutocmd('QuickFixCmdPost ' . event) silent exe s:DoAutocmd('QuickFixCmdPost ' . event)
if a:first && len(s:QuickfixGet(a:nr)) if a:first && len(s:QuickfixGet(a:nr))
call s:BlurStatus()
return mods . (a:nr < 0 ? 'cfirst' : 'lfirst') return mods . (a:nr < 0 ? 'cfirst' : 'lfirst')
else else
return 'exe' return 'exe'
@ -849,12 +962,6 @@ endfunction
" Section: Repository Object " Section: Repository Object
function! s:add_methods(namespace, method_names) abort
for name in a:method_names
let s:{a:namespace}_prototype[name] = s:function('s:'.a:namespace.'_'.name)
endfor
endfunction
let s:repo_prototype = {} let s:repo_prototype = {}
let s:repos = {} let s:repos = {}
@ -1109,19 +1216,20 @@ function! fugitive#Find(object, ...) abort
if rev ==# '.git' if rev ==# '.git'
let f = len(tree) ? tree . '/.git' : dir let f = len(tree) ? tree . '/.git' : dir
elseif rev =~# '^\.git/' elseif rev =~# '^\.git/'
let f = substitute(rev, '^\.git', '', '') let f = strpart(rev, 5)
let cdir = fugitive#CommonDir(dir) let fdir = dir . '/'
if f =~# '^/\.\./\.\.\%(/\|$\)' let cdir = fugitive#CommonDir(dir) . '/'
let f = simplify(len(tree) ? tree . f[3:-1] : dir . f) if f =~# '^\.\./\.\.\%(/\|$\)'
elseif f =~# '^/\.\.\%(/\|$\)' let f = simplify(len(tree) ? tree . f[2:-1] : fdir . f)
let f = base . f[3:-1] elseif f =~# '^\.\.\%(/\|$\)'
elseif cdir !=# dir && ( let f = base . f[2:-1]
\ f =~# '^/\%(config\|hooks\|info\|logs/refs\|objects\|refs\|worktrees\)\%(/\|$\)' || elseif cdir !=# fdir && (
\ f !~# '^/\%(index$\|index\.lock$\|\w*MSG$\|\w*HEAD$\|logs/\w*HEAD$\|logs$\|rebase-\w\+\)\%(/\|$\)' && \ f =~# '^\%(config\|hooks\|info\|logs/refs\|objects\|refs\|worktrees\)\%(/\|$\)' ||
\ getftime(FugitiveVimPath(dir . f)) < 0 && getftime(FugitiveVimPath(cdir . f)) >= 0) \ f !~# '^\%(index$\|index\.lock$\|\w*MSG$\|\w*HEAD$\|logs/\w*HEAD$\|logs$\|rebase-\w\+\)\%(/\|$\)' &&
\ getftime(FugitiveVimPath(fdir . f)) < 0 && getftime(FugitiveVimPath(cdir . f)) >= 0)
let f = simplify(cdir . f) let f = simplify(cdir . f)
else else
let f = simplify(dir . f) let f = simplify(fdir . f)
endif endif
elseif rev ==# ':/' elseif rev ==# ':/'
let f = tree let f = tree
@ -1146,10 +1254,9 @@ function! fugitive#Find(object, ...) abort
elseif rev =~# '^:[0-3]:' elseif rev =~# '^:[0-3]:'
let f = 'fugitive://' . dir . '//' . rev[1] . '/' . rev[3:-1] let f = 'fugitive://' . dir . '//' . rev[1] . '/' . rev[3:-1]
elseif rev ==# ':' elseif rev ==# ':'
if $GIT_INDEX_FILE =~# '/[^/]*index[^/]*\.lock$' && s:cpath(fnamemodify($GIT_INDEX_FILE,':p')[0:strlen(dir)]) ==# s:cpath(dir . '/') && filereadable($GIT_INDEX_FILE) let f = FugitiveFind('.git/index', dir)
if $GIT_INDEX_FILE =~# '/[^/]*index[^/]*\.lock$' && s:cpath(fnamemodify($GIT_INDEX_FILE,':p')[0:strlen(f)-6], s:cpath(f[0 : -6])) && filereadable($GIT_INDEX_FILE)
let f = fnamemodify($GIT_INDEX_FILE, ':p') let f = fnamemodify($GIT_INDEX_FILE, ':p')
else
let f = fugitive#Find('.git/index', dir)
endif endif
elseif rev =~# '^:(\%(top\|top,literal\|literal,top\|literal\))' elseif rev =~# '^:(\%(top\|top,literal\|literal,top\|literal\))'
let f = matchstr(rev, ')\zs.*') let f = matchstr(rev, ')\zs.*')
@ -1278,44 +1385,50 @@ function! s:ExpandVar(other, var, flags, esc, ...) abort
let owner = s:Owner(buffer) let owner = s:Owner(buffer)
return len(owner) ? owner : '@' return len(owner) ? owner : '@'
elseif a:var ==# '<cfile>' elseif a:var ==# '<cfile>'
let bufname = expand('<cfile>') let bufnames = [expand('<cfile>')]
if v:version >= 704 && get(maparg('<Plug><cfile>', 'c', 0, 1), 'expr') if v:version >= 704 && get(maparg('<Plug><cfile>', 'c', 0, 1), 'expr')
try try
let bufname = eval(maparg('<Plug><cfile>', 'c')) let bufnames = [eval(maparg('<Plug><cfile>', 'c'))]
if bufname ==# "\<C-R>\<C-F>" if bufnames[0] ==# "\<C-R>\<C-F>"
let bufname = expand('<cfile>') let bufnames = [expand('<cfile>')]
endif endif
catch catch
endtry endtry
endif endif
elseif a:var =~# '^<' elseif a:var =~# '^<'
let bufname = s:BufName(a:var) let bufnames = [s:BufName(a:var)]
elseif a:var ==# '##'
let bufnames = map(argv(), 'fugitive#Real(v:val)')
else else
let bufname = fugitive#Real(s:BufName(a:var)) let bufnames = [fugitive#Real(s:BufName(a:var))]
endif endif
let flags = a:flags let files = []
let file = s:DotRelative(bufname, cwd) for bufname in bufnames
while len(flags) let flags = a:flags
let flag = matchstr(flags, s:flag) let file = s:DotRelative(bufname, cwd)
let flags = strpart(flags, len(flag)) while len(flags)
if flag ==# ':.' let flag = matchstr(flags, s:flag)
let file = s:DotRelative(fugitive#Real(file), cwd) let flags = strpart(flags, len(flag))
else if flag ==# ':.'
let file = fnamemodify(file, flag) let file = s:DotRelative(fugitive#Real(file), cwd)
else
let file = fnamemodify(file, flag)
endif
endwhile
let file = s:Slash(file)
if file =~# '^fugitive://'
let [dir, commit, file_candidate] = s:DirCommitFile(file)
let tree = s:Tree(dir)
if len(tree) && len(file_candidate)
let file = (commit =~# '^.$' ? ':' : '') . commit . ':' .
\ s:DotRelative(tree . file_candidate)
elseif empty(file_candidate) && commit !~# '^.$'
let file = commit
endif
endif endif
endwhile call add(files, len(a:esc) ? shellescape(file) : file)
let file = s:Slash(file) endfor
if file =~# '^fugitive://' return join(files, "\1")
let [dir, commit, file_candidate] = s:DirCommitFile(file)
let tree = s:Tree(dir)
if len(tree) && len(file_candidate)
let file = (commit =~# '^.$' ? ':' : '') . commit . ':' .
\ s:DotRelative(tree . file_candidate)
elseif empty(file_candidate) && commit !~# '^.$'
let file = commit
endif
endif
return (len(a:esc) ? shellescape(file) : file)
endfunction endfunction
function! s:Expand(rev, ...) abort function! s:Expand(rev, ...) abort
@ -1332,13 +1445,13 @@ function! s:Expand(rev, ...) abort
endif endif
return substitute(file, return substitute(file,
\ '\(\\[' . s:fnameescape . ']\|^\\[>+-]\|!\d*\)\|' . s:expand, \ '\(\\[' . s:fnameescape . ']\|^\\[>+-]\|!\d*\)\|' . s:expand,
\ '\=s:ExpandVar(submatch(1),submatch(2),submatch(3),"", a:0 ? a:1 : getcwd())', 'g') \ '\=tr(s:ExpandVar(submatch(1),submatch(2),submatch(3),"", a:0 ? a:1 : getcwd()), "\1", " ")', 'g')
endfunction endfunction
function! fugitive#Expand(object) abort function! fugitive#Expand(object) abort
return substitute(a:object, return substitute(a:object,
\ '\(\\[' . s:fnameescape . ']\|^\\[>+-]\|!\d*\)\|' . s:expand, \ '\(\\[' . s:fnameescape . ']\|^\\[>+-]\|!\d*\)\|' . s:expand,
\ '\=s:ExpandVar(submatch(1),submatch(2),submatch(3),submatch(5))', 'g') \ '\=tr(s:ExpandVar(submatch(1),submatch(2),submatch(3),submatch(5)), "\1", " ")', 'g')
endfunction endfunction
function! s:SplitExpandChain(string, ...) abort function! s:SplitExpandChain(string, ...) abort
@ -1360,7 +1473,7 @@ function! s:SplitExpandChain(string, ...) abort
let arg = substitute(arg, let arg = substitute(arg,
\ '\(' . dquote . '''\%(''''\|[^'']\)*''\|\\[' . s:fnameescape . ']\|^\\[>+-]\|!\d*\)\|' . s:expand, \ '\(' . dquote . '''\%(''''\|[^'']\)*''\|\\[' . s:fnameescape . ']\|^\\[>+-]\|!\d*\)\|' . s:expand,
\ '\=s:ExpandVar(submatch(1),submatch(2),submatch(3),submatch(5), cwd)', 'g') \ '\=s:ExpandVar(submatch(1),submatch(2),submatch(3),submatch(5), cwd)', 'g')
call add(list, arg) call extend(list, split(arg, "\1", 1))
if arg ==# '--' if arg ==# '--'
let seen_separator = 1 let seen_separator = 1
endif endif
@ -1512,8 +1625,8 @@ endfunction
function! s:UpdateIndex(dir, info) abort function! s:UpdateIndex(dir, info) abort
let info = join(a:info[0:-2]) . "\t" . a:info[-1] . "\n" let info = join(a:info[0:-2]) . "\t" . a:info[-1] . "\n"
let [error, exec_error] = s:SystemError([a:dir, 'update-index', '--index-info'], info) let [error, exec_error] = s:SystemError(fugitive#Prepare([a:dir, 'update-index', '--index-info']), info)
return !exec_error ? '' : len(error) ? error : 'fugitive: unknown update-index error' return !exec_error ? '' : len(error) ? error : 'unknown update-index error'
endfunction endfunction
function! fugitive#setfperm(url, perm) abort function! fugitive#setfperm(url, perm) abort
@ -1532,9 +1645,11 @@ function! s:TempCmd(out, cmd) abort
try try
let cmd = (type(a:cmd) == type([]) ? fugitive#Prepare(a:cmd) : a:cmd) let cmd = (type(a:cmd) == type([]) ? fugitive#Prepare(a:cmd) : a:cmd)
let redir = ' > ' . a:out let redir = ' > ' . a:out
if (s:winshell() || &shellcmdflag ==# '-Command') && !has('nvim') if s:winshell() && !has('nvim')
let cmd_escape_char = &shellxquote == '(' ? '^' : '^^^' let cmd_escape_char = &shellxquote == '(' ? '^' : '^^^'
return s:SystemError('cmd /c "' . s:gsub(cmd, '[<>%]', cmd_escape_char . '&') . redir . '"') return s:SystemError('cmd /c "' . s:gsub(cmd, '[<>%]', cmd_escape_char . '&') . redir . '"')
elseif &shell =~? '\%(powershell\|pwsh\)\%(\.exe\)\=$'
return s:SystemError(&shell . ' ' . &shellcmdflag . ' ' . s:shellesc(cmd . redir))
elseif &shell =~# 'fish' elseif &shell =~# 'fish'
return s:SystemError(' begin;' . cmd . redir . ';end ') return s:SystemError(' begin;' . cmd . redir . ';end ')
else else
@ -1714,12 +1829,13 @@ function! fugitive#CompletePath(base, ...) abort
let stripped = matchstr(a:base, '^\%(:(literal)\|:\)') let stripped = matchstr(a:base, '^\%(:(literal)\|:\)')
let base = strpart(a:base, len(stripped)) let base = strpart(a:base, len(stripped))
endif endif
if base =~# '^\.git/' if base =~# '^\.git/' && len(dir)
let pattern = s:gsub(base[5:-1], '/', '*&').'*' let pattern = s:gsub(base[5:-1], '/', '*&').'*'
let matches = s:GlobComplete(dir . '/', pattern) let fdir = fugitive#Find(dir . '/')
let cdir = fugitive#CommonDir(dir) let matches = s:GlobComplete(fdir, pattern)
if len(cdir) && s:cpath(dir) !=# s:cpath(cdir) let cdir = fugitive#Find('.git/refs', dir)[0 : -5]
call extend(matches, s:GlobComplete(cdir . '/', pattern)) if len(cdir) && s:cpath(fdir) !=# s:cpath(cdir)
call extend(matches, s:GlobComplete(cdir, pattern))
endif endif
call s:Uniq(matches) call s:Uniq(matches)
call map(matches, "'.git/' . v:val") call map(matches, "'.git/' . v:val")
@ -1761,7 +1877,8 @@ function! fugitive#CompleteObject(base, ...) abort
if a:base =~# '^\.\=/\|^:(' || a:base !~# ':' if a:base =~# '^\.\=/\|^:(' || a:base !~# ':'
let results = [] let results = []
if a:base =~# '^refs/' if a:base =~# '^refs/'
let results += map(s:GlobComplete(fugitive#CommonDir(dir) . '/', a:base . '*'), 's:Slash(v:val)') let cdir = fugitive#Find('.git/refs', dir)[0 : -5]
let results += map(s:GlobComplete(cdir, a:base . '*'), 's:Slash(v:val)')
call map(results, 's:fnameescape(v:val)') call map(results, 's:fnameescape(v:val)')
elseif a:base !~# '^\.\=/\|^:(' elseif a:base !~# '^\.\=/\|^:('
let heads = s:CompleteHeads(dir) let heads = s:CompleteHeads(dir)
@ -1954,7 +2071,7 @@ function! fugitive#BufReadStatus() abort
if len(prop) if len(prop)
let props[prop[1]] = prop[2] let props[prop[1]] = prop[2]
elseif line[0] ==# '?' elseif line[0] ==# '?'
call add(untracked, {'type': 'File', 'status': line[0], 'filename': line[2:-1]}) call add(untracked, {'type': 'File', 'status': line[0], 'filename': line[2:-1], 'relative': [line[2:-1]]})
elseif line[0] !=# '#' elseif line[0] !=# '#'
if line[0] ==# 'u' if line[0] ==# 'u'
let file = matchstr(line, '^.\{37\} \x\{40,\} \x\{40,\} \x\{40,\} \zs.*$') let file = matchstr(line, '^.\{37\} \x\{40,\} \x\{40,\} \x\{40,\} \zs.*$')
@ -1964,17 +2081,18 @@ function! fugitive#BufReadStatus() abort
if line[0] ==# '2' if line[0] ==# '2'
let i += 1 let i += 1
let file = matchstr(file, ' \zs.*') let file = matchstr(file, ' \zs.*')
let files = output[i] . ' -> ' . file let relative = [file, output[i]]
else else
let files = file let relative = [file]
endif endif
let filename = join(reverse(copy(relative)), ' -> ')
let sub = matchstr(line, '^[12u] .. \zs....') let sub = matchstr(line, '^[12u] .. \zs....')
if line[2] !=# '.' if line[2] !=# '.'
call add(staged, {'type': 'File', 'status': line[2], 'filename': files, 'submodule': sub}) call add(staged, {'type': 'File', 'status': line[2], 'filename': filename, 'relative': relative, 'submodule': sub})
endif endif
if line[3] !=# '.' if line[3] !=# '.'
let sub = matchstr(line, '^[12u] .. \zs....') let sub = matchstr(line, '^[12u] .. \zs....')
call add(unstaged, {'type': 'File', 'status': get({'C':'M','M':'?','U':'?'}, matchstr(sub, 'S\.*\zs[CMU]'), line[3]), 'filename': file, 'submodule': sub}) call add(unstaged, {'type': 'File', 'status': get({'C':'M','M':'?','U':'?'}, matchstr(sub, 'S\.*\zs[CMU]'), line[3]), 'filename': file, 'relative': [file], 'submodule': sub})
endif endif
endif endif
let i += 1 let i += 1
@ -2013,22 +2131,24 @@ function! fugitive#BufReadStatus() abort
while i < len(output) while i < len(output)
let line = output[i] let line = output[i]
let file = line[3:-1] let file = line[3:-1]
let files = file
let i += 1 let i += 1
if line[2] !=# ' ' if line[2] !=# ' '
continue continue
endif endif
if line[0:1] =~# '[RC]' if line[0:1] =~# '[RC]'
let files = output[i] . ' -> ' . file let relative = [file, output[i]]
let i += 1 let i += 1
else
let relative = [file]
endif endif
let filename = join(reverse(copy(relative)), ' -> ')
if line[0] !~# '[ ?!#]' if line[0] !~# '[ ?!#]'
call add(staged, {'type': 'File', 'status': line[0], 'filename': files, 'submodule': ''}) call add(staged, {'type': 'File', 'status': line[0], 'filename': filename, 'relative': relative, 'submodule': ''})
endif endif
if line[0:1] ==# '??' if line[0:1] ==# '??'
call add(untracked, {'type': 'File', 'status': line[1], 'filename': files}) call add(untracked, {'type': 'File', 'status': line[1], 'filename': filename, 'relative': relative})
elseif line[1] !~# '[ !#]' elseif line[1] !~# '[ !#]'
call add(unstaged, {'type': 'File', 'status': line[1], 'filename': file, 'submodule': ''}) call add(unstaged, {'type': 'File', 'status': line[1], 'filename': file, 'relative': [file], 'submodule': ''})
endif endif
endwhile endwhile
endif endif
@ -2129,8 +2249,10 @@ function! fugitive#BufReadStatus() abort
if push !=# pull if push !=# pull
call s:AddHeader('Push', push) call s:AddHeader('Push', push)
endif endif
if empty(s:Tree()) if get(fugitive#ConfigGetAll('core.bare', config), 0, 'true') !~# '^\%(false\|no|off\|0\|\)$'
call s:AddHeader('Bare', 'yes') call s:AddHeader('Bare', 'yes')
elseif empty(s:Tree())
call s:AddHeader('Error', s:worktree_error)
endif endif
if get(fugitive#ConfigGetAll('advice.statusHints', config), 0, 'true') !~# '^\%(false\|no|off\|0\|\)$' if get(fugitive#ConfigGetAll('advice.statusHints', config), 0, 'true') !~# '^\%(false\|no|off\|0\|\)$'
call s:AddHeader('Help', 'g?') call s:AddHeader('Help', 'g?')
@ -2264,7 +2386,7 @@ function! fugitive#FileWriteCmd(...) abort
endif endif
silent execute "'[,']write !".fugitive#Prepare(dir, 'hash-object', '-w', '--stdin', '--').' > '.tmp silent execute "'[,']write !".fugitive#Prepare(dir, 'hash-object', '-w', '--stdin', '--').' > '.tmp
let sha1 = readfile(tmp)[0] let sha1 = readfile(tmp)[0]
let old_mode = matchstr(s:SystemError([dir, 'ls-files', '--stage', '.' . file])[0], '^\d\+') let old_mode = matchstr(s:ChompError(['ls-files', '--stage', '.' . file], dir)[0], '^\d\+')
if empty(old_mode) if empty(old_mode)
let old_mode = executable(s:Tree(dir) . file) ? '100755' : '100644' let old_mode = executable(s:Tree(dir) . file) ? '100755' : '100644'
endif endif
@ -2549,7 +2671,7 @@ function! s:RunEdit(state, tmp, job) abort
endif endif
call remove(a:state, 'request') call remove(a:state, 'request')
let sentinel = a:state.file . '.edit' let sentinel = a:state.file . '.edit'
let file = FugitiveVimPath(readfile(sentinel, 1)[0]) let file = FugitiveVimPath(readfile(sentinel, '', 1)[0])
exe substitute(a:state.mods, '\<tab\>', '-tab', 'g') 'keepalt split' s:fnameescape(file) exe substitute(a:state.mods, '\<tab\>', '-tab', 'g') 'keepalt split' s:fnameescape(file)
set bufhidden=wipe set bufhidden=wipe
let s:edit_jobs[bufnr('')] = [a:state, a:tmp, a:job, sentinel] let s:edit_jobs[bufnr('')] = [a:state, a:tmp, a:job, sentinel]
@ -2862,6 +2984,9 @@ unlet s:colortype
function! fugitive#Command(line1, line2, range, bang, mods, arg) abort function! fugitive#Command(line1, line2, range, bang, mods, arg) abort
exe s:VersionCheck() exe s:VersionCheck()
let dir = s:Dir() let dir = s:Dir()
if len(dir)
exe s:DirCheck(dir)
endif
let config = copy(fugitive#Config(dir)) let config = copy(fugitive#Config(dir))
let [args, after] = s:SplitExpandChain(a:arg, s:Tree(dir)) let [args, after] = s:SplitExpandChain(a:arg, s:Tree(dir))
let flags = [] let flags = []
@ -3480,16 +3605,18 @@ function! s:StageInfo(...) abort
endif endif
endwhile endwhile
let text = matchstr(getline(lnum), '^[A-Z?] \zs.*') let text = matchstr(getline(lnum), '^[A-Z?] \zs.*')
let file = get(get(b:fugitive_files, heading, {}), text, {})
let relative = get(file, 'relative', len(text) ? [text] : [])
return {'section': matchstr(heading, '^\u\l\+'), return {'section': matchstr(heading, '^\u\l\+'),
\ 'heading': heading, \ 'heading': heading,
\ 'sigil': sigil, \ 'sigil': sigil,
\ 'offset': offset, \ 'offset': offset,
\ 'filename': text, \ 'filename': text,
\ 'relative': reverse(split(text, ' -> ')), \ 'relative': copy(relative),
\ 'paths': map(reverse(split(text, ' -> ')), 's:Tree() . "/" . v:val'), \ 'paths': map(copy(relative), 's:Tree() . "/" . v:val'),
\ 'commit': matchstr(getline(lnum), '^\%(\%(\x\x\x\)\@!\l\+\s\+\)\=\zs[0-9a-f]\{4,\}\ze '), \ 'commit': matchstr(getline(lnum), '^\%(\%(\x\x\x\)\@!\l\+\s\+\)\=\zs[0-9a-f]\{4,\}\ze '),
\ 'status': matchstr(getline(lnum), '^[A-Z?]\ze \|^\%(\x\x\x\)\@!\l\+\ze [0-9a-f]'), \ 'status': matchstr(getline(lnum), '^[A-Z?]\ze \|^\%(\x\x\x\)\@!\l\+\ze [0-9a-f]'),
\ 'submodule': get(get(get(b:fugitive_files, heading, {}), text, {}), 'submodule', ''), \ 'submodule': get(file, 'submodule', ''),
\ 'index': index} \ 'index': index}
endfunction endfunction
@ -3559,12 +3686,14 @@ function! s:Selection(arg1, ...) abort
endif endif
let results[-1].lnum = lnum let results[-1].lnum = lnum
elseif line =~# '^[A-Z?] ' elseif line =~# '^[A-Z?] '
let filename = matchstr(line, '^[A-Z?] \zs.*') let text = matchstr(line, '^[A-Z?] \zs.*')
let file = get(get(b:fugitive_files, template.heading, {}), text, {})
let relative = get(file, 'relative', len(text) ? [text] : [])
call add(results, extend(deepcopy(template), { call add(results, extend(deepcopy(template), {
\ 'lnum': lnum, \ 'lnum': lnum,
\ 'filename': filename, \ 'filename': text,
\ 'relative': reverse(split(filename, ' -> ')), \ 'relative': copy(relative),
\ 'paths': map(reverse(split(filename, ' -> ')), 'root . v:val'), \ 'paths': map(copy(relative), 'root . v:val'),
\ 'status': matchstr(line, '^[A-Z?]'), \ 'status': matchstr(line, '^[A-Z?]'),
\ })) \ }))
elseif line =~# '^\x\x\x\+ ' elseif line =~# '^\x\x\x\+ '
@ -4553,12 +4682,12 @@ function! s:ToolStream(line1, line2, range, bang, mods, options, args, state) ab
let filename = '' let filename = ''
let cmd = [] let cmd = []
let tabnr = tabpagenr() + 1 let tabnr = tabpagenr() + 1
for line in split(s:SystemError(s:shellesc(exec))[0], "\n") for line in split(s:SystemError(exec)[0], "\n")
for item in s:ToolParse(a:state, line) for item in s:ToolParse(a:state, line)
if len(get(item, 'filename', '')) && item.filename != filename if len(get(item, 'filename', '')) && item.filename != filename
call add(cmd, 'tabedit ' . s:fnameescape(item.filename)) call add(cmd, 'tabedit ' . s:fnameescape(item.filename))
for i in reverse(range(len(get(item.context, 'diff', [])))) for i in reverse(range(len(get(item.context, 'diff', []))))
call add(cmd, (i ? 'rightbelow' : 'leftabove') . ' vert Gdiffsplit! ' . s:fnameescape(item.context.diff[i].filename)) call add(cmd, (i ? 'rightbelow' : 'leftabove') . ' vertical Gdiffsplit! ' . s:fnameescape(item.context.diff[i].filename))
endfor endfor
call add(cmd, 'wincmd =') call add(cmd, 'wincmd =')
let filename = item.filename let filename = item.filename
@ -4717,7 +4846,7 @@ function! s:GrepSubcommand(line1, line2, range, bang, mods, options) abort
let cmd = ['--no-pager', 'grep', '-n', '--no-color', '--full-name'] let cmd = ['--no-pager', 'grep', '-n', '--no-color', '--full-name']
let tree = s:Tree(dir) let tree = s:Tree(dir)
let args = a:options.subcommand_args let args = a:options.subcommand_args
if get(args, 0, '') =~# '^-O\|--open-files-in-pager$' if get(args, 0, '') =~# '^\%(-O\|--open-files-in-pager\)$'
let args = args[1:-1] let args = args[1:-1]
endif endif
let name_only = s:HasOpt(args, '-l', '--files-with-matches', '--name-only', '-L', '--files-without-match') let name_only = s:HasOpt(args, '-l', '--files-with-matches', '--name-only', '-L', '--files-without-match')
@ -5066,7 +5195,7 @@ function! s:BlurStatus() abort
endif endif
endfunction endfunction
let s:bang_edits = {'split': 'Git', 'vsplit': 'vert Git', 'tabedit': 'tab Git', 'pedit': 'Git!'} let s:bang_edits = {'split': 'Git', 'vsplit': 'vertical Git', 'tabedit': 'tab Git', 'pedit': 'Git!'}
function! fugitive#Open(cmd, bang, mods, arg, args) abort function! fugitive#Open(cmd, bang, mods, arg, args) abort
exe s:VersionCheck() exe s:VersionCheck()
if a:bang if a:bang
@ -5465,6 +5594,10 @@ function! fugitive#Diffsplit(autodir, keepfocus, mods, arg, args) abort
exe pre exe pre
let mods = (a:autodir ? s:diff_modifier(len(parents) + 1) : '') . s:Mods(mods, 'leftabove') let mods = (a:autodir ? s:diff_modifier(len(parents) + 1) : '') . s:Mods(mods, 'leftabove')
let nr = bufnr('') let nr = bufnr('')
if len(parents) > 1 && !&equalalways
let equalalways = 0
set equalalways
endif
execute mods 'split' s:fnameescape(fugitive#Find(parents[0])) execute mods 'split' s:fnameescape(fugitive#Find(parents[0]))
call s:Map('n', 'dp', ':diffput '.nr.'<Bar>diffupdate<CR>', '<silent>') call s:Map('n', 'dp', ':diffput '.nr.'<Bar>diffupdate<CR>', '<silent>')
let nr2 = bufnr('') let nr2 = bufnr('')
@ -5481,9 +5614,6 @@ function! fugitive#Diffsplit(autodir, keepfocus, mods, arg, args) abort
call s:Map('n', 'd' . (i + 2) . 'o', ':diffget '.nrx.'<Bar>diffupdate<CR>', '<silent>') call s:Map('n', 'd' . (i + 2) . 'o', ':diffget '.nrx.'<Bar>diffupdate<CR>', '<silent>')
endfor endfor
call s:diffthis() call s:diffthis()
if len(parents) > 1
wincmd =
endif
return post return post
elseif len(args) elseif len(args)
let arg = join(args, ' ') let arg = join(args, ' ')
@ -5547,6 +5677,9 @@ function! fugitive#Diffsplit(autodir, keepfocus, mods, arg, args) abort
catch /^fugitive:/ catch /^fugitive:/
return 'echoerr ' . string(v:exception) return 'echoerr ' . string(v:exception)
finally finally
if exists('l:equalalways')
let &l:equalalways = equalalways
endif
if exists('diffopt') if exists('diffopt')
let &diffopt = diffopt let &diffopt = diffopt
endif endif
@ -5760,7 +5893,7 @@ function! s:BlameSubcommand(line1, count, range, bang, mods, options) abort
let i += 1 let i += 1
if i == len(flags) if i == len(flags)
echohl ErrorMsg echohl ErrorMsg
echo s:ChompError(['blame', arg])[0] echo s:ChompError([dir, 'blame', arg])[0]
echohl NONE echohl NONE
return '' return ''
endif endif
@ -6217,15 +6350,9 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
let rev = '' let rev = ''
let result = fugitive#Result() let result = fugitive#Result()
if filereadable(get(result, 'file', '')) if filereadable(get(result, 'file', ''))
for line in readfile(result.file, 4096) let rev = s:fnameescape(result.file)
let rev = s:fnameescape(matchstr(line, '\<https\=://[^[:space:]<>]*[^[:space:]<>.,;:"''!?]')) else
if len(rev) return 'echoerr ' . string('fugitive: could not find prior :Git invocation')
break
endif
endfor
if empty(rev)
return 'echoerr ' . string('fugitive: no URL found in output of last :Git')
endif
endif endif
elseif !exists('l:remote') elseif !exists('l:remote')
let remote = matchstr(arg, '@\zs\%('.validremote.'\)$') let remote = matchstr(arg, '@\zs\%('.validremote.'\)$')
@ -6242,6 +6369,20 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
if expanded =~? '^\a\a\+:[\/][\/]' && expanded !~? '^fugitive:' if expanded =~? '^\a\a\+:[\/][\/]' && expanded !~? '^fugitive:'
return s:BrowserOpen(s:Slash(expanded), a:mods, a:bang) return s:BrowserOpen(s:Slash(expanded), a:mods, a:bang)
endif endif
if !exists('l:result')
let result = s:TempState(empty(expanded) ? @% : expanded)
endif
if !empty(result) && filereadable(get(result, 'file', ''))
for line in readfile(result.file, '', 4096)
let rev = s:fnameescape(matchstr(line, '\<https\=://[^[:space:]<>]*[^[:space:]<>.,;:"''!?]'))
if len(rev)
break
endif
endfor
if empty(rev)
return 'echoerr ' . string('fugitive: no URL found in output of :Git')
endif
endif
exe s:DirCheck(dir) exe s:DirCheck(dir)
if empty(expanded) if empty(expanded)
let bufname = s:BufName('%') let bufname = s:BufName('%')
@ -6256,9 +6397,9 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
endif endif
endif endif
endif endif
let cdir = FugitiveVimPath(fugitive#CommonDir(dir)) let refdir = fugitive#Find('.git/refs', dir)
for subdir in ['tags/', 'heads/', 'remotes/'] for subdir in ['tags/', 'heads/', 'remotes/']
if expanded !~# '^[./]' && filereadable(cdir . '/refs/' . subdir . expanded) if expanded !~# '^[./]' && filereadable(refdir . '/' . subdir . expanded)
let expanded = '.git/refs/' . subdir . expanded let expanded = '.git/refs/' . subdir . expanded
endif endif
endfor endfor
@ -6294,8 +6435,9 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
if type ==# 'tree' && !empty(path) if type ==# 'tree' && !empty(path)
let path = s:sub(path, '/\=$', '/') let path = s:sub(path, '/\=$', '/')
endif endif
if path =~# '^\.git/.*HEAD$' && filereadable(dir . '/' . path[5:-1]) let actual_dir = fugitive#Find('.git/', dir)
let body = readfile(dir . '/' . path[5:-1])[0] if path =~# '^\.git/.*HEAD$' && filereadable(actual_dir . path[5:-1])
let body = readfile(actual_dir . path[5:-1])[0]
if body =~# '^\x\{40,\}$' if body =~# '^\x\{40,\}$'
let commit = body let commit = body
let type = 'commit' let type = 'commit'
@ -6363,7 +6505,7 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
let blame_list = tempname() let blame_list = tempname()
call writefile([commit, ''], blame_list, 'b') call writefile([commit, ''], blame_list, 'b')
let blame_in = tempname() let blame_in = tempname()
silent exe '%write' blame_in silent exe 'noautocmd keepalt %write' blame_in
let [blame, exec_error] = s:LinesError(['-c', 'blame.coloring=none', 'blame', '--contents', blame_in, '-L', line1.','.line2, '-S', blame_list, '-s', '--show-number', './' . path], dir) let [blame, exec_error] = s:LinesError(['-c', 'blame.coloring=none', 'blame', '--contents', blame_in, '-L', line1.','.line2, '-S', blame_list, '-s', '--show-number', './' . path], dir)
if !exec_error if !exec_error
let blame_regex = '^\^\x\+\s\+\zs\d\+\ze\s' let blame_regex = '^\^\x\+\s\+\zs\d\+\ze\s'
@ -6382,7 +6524,7 @@ function! fugitive#BrowseCommand(line1, count, range, bang, mods, arg, args) abo
endif endif
let i = 0 let i = 0
while commit =~# '^ref: ' && i < 10 while commit =~# '^ref: ' && i < 10
let ref_file = cdir . '/' . commit[5:-1] let ref_file = refdir[0 : -5] . commit[5:-1]
if getfsize(ref_file) > 0 if getfsize(ref_file) > 0
let commit = readfile(ref_file, '', 1)[0] let commit = readfile(ref_file, '', 1)[0]
else else

View File

@ -601,20 +601,47 @@ a statusline, this one matches the default when 'ruler' is set:
> >
set statusline=%<%f\ %h%m%r%{FugitiveStatusline()}%=%-14.(%l,%c%V%)\ %P set statusline=%<%f\ %h%m%r%{FugitiveStatusline()}%=%-14.(%l,%c%V%)\ %P
< <
*FugitiveHead(...)* *fugitive#head(...)* AUTOCOMMANDS *fugitive-autocommands*
Use FugitiveHead() to return the name of the current branch. If the current
HEAD is detached, FugitiveHead() will return the empty string, unless the A handful of |User| |autocommands| are provided to allow extending and
optional argument is given, in which case the hash of the current commit will overriding Fugitive behaviors. Example usage:
be truncated to the given number of characters. >
autocmd User FugitiveBlob call s:BlobOverrides()
<
*User_FugitiveIndex*
FugitiveIndex After loading the |fugitive-summary| buffer.
*User_FugitiveTag*
FugitiveTag After loading a tag object.
*User_FugitiveCommit*
FugitiveCommit After loading a commit object.
*User_FugitiveTree*
FugitiveTree After loading a tree (directory) object.
*User_FugitiveBlob*
FugitiveBlob After loading a blob (file) object. This includes
both committed blobs which are read only, and staged
blobs which can be edited and written. Check
&modifiable to distinguish between the two.
*User_FugitiveChanged*
FugitiveChanged After any event which can potentially change the
repository, for example, any invocation of |:Git|.
Originally intended for expiring caches, but can have
other uses.
API *fugitive-api*
Officially supported functions are documented inline in plugin/fugitive.vim.
DEPRECATIONS *fugitive-deprecated* DEPRECATIONS *fugitive-deprecated*
The following commands are softly deprecated in favor of replacements that The following commands are deprecated in favor of replacements that adhere to
adhere to a new naming scheme. They will eventually be removed, but probably a new naming scheme. Remember that |:Git| can be shortened to |:G|, so
not in the near future. replacements using it are just one space character longer than the legacy
version.
Remember that |:Git| can be shortened to |:G|, so replacements using it are
just one space character longer than the legacy version.
*:Gremove* Superseded by |:GRemove|. *:Gremove* Superseded by |:GRemove|.
*:Gdelete* Superseded by |:GDelete|. *:Gdelete* Superseded by |:GDelete|.
@ -640,6 +667,14 @@ just one space character longer than the legacy version.
*:Gtabsplit!* Superseded by :tab Git --paginate. *:Gtabsplit!* Superseded by :tab Git --paginate.
*:Gpedit!* Superseded by :Git! --paginate. *:Gpedit!* Superseded by :Git! --paginate.
*User_Fugitive*
Fugitive used to support `:autocmd User Fugitive` to run an autocommand after
loading any buffer belonging to a Git repository, but this is being phased
out. Instead, one can leverage regular autocommand events like |BufNewFile|
and |BufReadPost|, and check !empty(FugitiveGitDir()) to confirm Fugitive has
found a repository. See also |fugitive-autocommands| for other, more
selective events.
ABOUT *fugitive-about* ABOUT *fugitive-about*
Grab the latest version or report a bug on GitHub: Grab the latest version or report a bug on GitHub:

View File

@ -10,6 +10,10 @@ let g:loaded_fugitive = 1
let s:bad_git_dir = '/$\|^fugitive:' let s:bad_git_dir = '/$\|^fugitive:'
" FugitiveGitDir() returns the detected Git dir for the given buffer number,
" or the current buffer if no argument is passed. This will be an empty
" string if no Git dir was found. Use !empty(FugitiveGitDir()) to check if
" Fugitive is active in the current buffer.
function! FugitiveGitDir(...) abort function! FugitiveGitDir(...) abort
if v:version < 704 if v:version < 704
return '' return ''
@ -18,7 +22,7 @@ function! FugitiveGitDir(...) abort
return g:fugitive_event return g:fugitive_event
endif endif
let dir = get(b:, 'git_dir', '') let dir = get(b:, 'git_dir', '')
if empty(dir) && (empty(bufname('')) || &buftype =~# '^\%(nofile\|acwrite\|quickfix\|prompt\)$') if empty(dir) && (empty(bufname('')) || &buftype =~# '^\%(nofile\|acwrite\|quickfix\|terminal\|prompt\)$')
return FugitiveExtractGitDir(getcwd()) return FugitiveExtractGitDir(getcwd())
elseif (!exists('b:git_dir') || b:git_dir =~# s:bad_git_dir) && empty(&buftype) elseif (!exists('b:git_dir') || b:git_dir =~# s:bad_git_dir) && empty(&buftype)
let b:git_dir = FugitiveExtractGitDir(expand('%:p')) let b:git_dir = FugitiveExtractGitDir(expand('%:p'))
@ -95,9 +99,11 @@ function! FugitiveParse(...) abort
endfunction endfunction
" FugitiveResult() returns an object encapsulating the result of the most " FugitiveResult() returns an object encapsulating the result of the most
" recend :Git command. Will be empty if no result is available. Pass in the " recent :Git command. Will be empty if no result is available. During a
" name of a temp buffer to get the result object for that command instead. " User FugitiveChanged event, this is guaranteed to correspond to the :Git
" Contains the following keys: " command that triggered the event, or be empty if :Git was not the trigger.
" Pass in the name of a temp buffer to get the result object for that command
" instead. Contains the following keys:
" "
" * "args": List of command arguments, starting with the subcommand. Will be " * "args": List of command arguments, starting with the subcommand. Will be
" empty for usages like :Git --help. " empty for usages like :Git --help.
@ -127,13 +133,17 @@ endfunction
" when performing multiple config queries. Do not rely on the internal " when performing multiple config queries. Do not rely on the internal
" structure of the return value as it is not guaranteed. If you want a full " structure of the return value as it is not guaranteed. If you want a full
" dictionary of every config value, use FugitiveConfigGetRegexp('.*'). " dictionary of every config value, use FugitiveConfigGetRegexp('.*').
"
" An optional argument provides the Git dir, or the buffer number of a
" buffer with a Git dir. The default is the current buffer. Pass a blank
" string to limit to the global config.
function! FugitiveConfig(...) abort function! FugitiveConfig(...) abort
return call('fugitive#Config', a:000) return call('fugitive#Config', a:000)
endfunction endfunction
" FugitiveConfigGet() retrieves a Git configuration value. An optional second " FugitiveConfigGet() retrieves a Git configuration value. An optional second
" argument provides the Git dir as with FugitiveFind(). Pass a blank string " argument can be either the object returned by FugitiveConfig(), or a Git
" to limit to the global config. " dir or buffer number to be passed along to FugitiveConfig().
function! FugitiveConfigGet(name, ...) abort function! FugitiveConfigGet(name, ...) abort
return get(call('FugitiveConfigGetAll', [a:name] + (a:0 ? [a:1] : [])), 0, get(a:, 2, '')) return get(call('FugitiveConfigGetAll', [a:name] + (a:0 ? [a:1] : [])), 0, get(a:, 2, ''))
endfunction endfunction
@ -152,10 +162,24 @@ function! FugitiveConfigGetRegexp(pattern, ...) abort
return call('fugitive#ConfigGetRegexp', [a:pattern] + a:000) return call('fugitive#ConfigGetRegexp', [a:pattern] + a:000)
endfunction endfunction
" FugitiveRemoteUrl() retrieves the remote URL for the given remote name,
" defaulting to the current branch's remote or "origin" if no argument is
" given. Similar to `git remote get-url`, but also attempts to resolve HTTP
" redirects and SSH host aliases.
"
" An optional second argument provides the Git dir, or the buffer number of a
" buffer with a Git dir. The default is the current buffer.
function! FugitiveRemoteUrl(...) abort function! FugitiveRemoteUrl(...) abort
return fugitive#RemoteUrl(a:0 ? a:1 : '', FugitiveGitDir(a:0 > 1 ? a:2 : -1), a:0 > 2 ? a:3 : 0) return fugitive#RemoteUrl(a:0 ? a:1 : '', a:0 > 1 ? a:2 : -1, a:0 > 2 ? a:3 : 0)
endfunction endfunction
" FugitiveHead() retrieves the name of the current branch. If the current HEAD
" is detached, FugitiveHead() will return the empty string, unless the
" optional argument is given, in which case the hash of the current commit
" will be truncated to the given number of characters.
"
" An optional second argument provides the Git dir, or the buffer number of a
" buffer with a Git dir. The default is the current buffer.
function! FugitiveHead(...) abort function! FugitiveHead(...) abort
let dir = FugitiveGitDir(a:0 > 1 ? a:2 : -1) let dir = FugitiveGitDir(a:0 > 1 ? a:2 : -1)
if empty(dir) if empty(dir)
@ -176,11 +200,16 @@ function! FugitiveCommonDir(...) abort
if empty(dir) if empty(dir)
return '' return ''
endif endif
return fugitive#CommonDir(dir) return fugitive#Find('.git/refs/..', dir)
endfunction endfunction
function! FugitiveWorkTree(...) abort function! FugitiveWorkTree(...) abort
return s:Tree(FugitiveGitDir(a:0 ? a:1 : -1)) let tree = s:Tree(FugitiveGitDir(a:0 ? a:1 : -1))
if tree isnot# 0 || a:0 > 1
return tree
else
return ''
endif
endfunction endfunction
function! FugitiveIsGitDir(path) abort function! FugitiveIsGitDir(path) abort
@ -204,9 +233,14 @@ function! s:Tree(path) abort
let config_file = dir . '/config' let config_file = dir . '/config'
if filereadable(config_file) if filereadable(config_file)
let config = readfile(config_file,'',10) let config = readfile(config_file,'',10)
call filter(config,'v:val =~# "^\\s*worktree *="') let wt_config = filter(copy(config),'v:val =~# "^\\s*worktree *="')
if len(config) == 1 if len(wt_config) == 1
let worktree = FugitiveVimPath(matchstr(config[0], '= *\zs.*')) let worktree = FugitiveVimPath(matchstr(wt_config[0], '= *\zs.*'))
else
call filter(config,'v:val =~# "^\\s*bare *= *false *$"')
if len(config)
let s:worktree_for_dir[dir] = 0
endif
endif endif
elseif filereadable(dir . '/gitdir') elseif filereadable(dir . '/gitdir')
let worktree = fnamemodify(FugitiveVimPath(readfile(dir . '/gitdir')[0]), ':h') let worktree = fnamemodify(FugitiveVimPath(readfile(dir . '/gitdir')[0]), ':h')
@ -358,7 +392,7 @@ function! s:ProjectionistDetect() abort
if empty(base) if empty(base)
let base = s:Tree(dir) let base = s:Tree(dir)
endif endif
if len(base) if !empty(base)
if exists('+shellslash') && !&shellslash if exists('+shellslash') && !&shellslash
let base = tr(base, '/', '\') let base = tr(base, '/', '\')
endif endif
@ -380,13 +414,13 @@ command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#Complete Git exe
if exists(':Gstatus') != 2 && get(g:, 'fugitive_legacy_commands', 1) if exists(':Gstatus') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bang -bar -range=-1' s:addr_other 'Gstatus exe fugitive#Command(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)' exe 'command! -bang -bar -range=-1' s:addr_other 'Gstatus exe fugitive#Command(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>)'
\ '|echohl WarningMSG|echo ":Gstatus is deprecated in favor of :Git (with no arguments)"|echohl NONE' \ '|echohl WarningMSG|echomsg ":Gstatus is deprecated in favor of :Git (with no arguments)"|echohl NONE'
endif endif
for s:cmd in ['Commit', 'Revert', 'Merge', 'Rebase', 'Pull', 'Push', 'Fetch', 'Blame'] for s:cmd in ['Commit', 'Revert', 'Merge', 'Rebase', 'Pull', 'Push', 'Fetch', 'Blame']
if exists(':G' . tolower(s:cmd)) != 2 && get(g:, 'fugitive_legacy_commands', 1) if exists(':G' . tolower(s:cmd)) != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#' . s:cmd . 'Complete G' . tolower(s:cmd) exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#' . s:cmd . 'Complete G' . tolower(s:cmd)
\ 'echohl WarningMSG|echo ":G' . tolower(s:cmd) . ' is deprecated in favor of :Git ' . tolower(s:cmd) . '"|echohl NONE|' \ 'echohl WarningMSG|echomsg ":G' . tolower(s:cmd) . ' is deprecated in favor of :Git ' . tolower(s:cmd) . '"|echohl NONE|'
\ 'exe fugitive#Command(<line1>, <count>, +"<range>", <bang>0, "<mods>", "' . tolower(s:cmd) . ' " . <q-args>)' \ 'exe fugitive#Command(<line1>, <count>, +"<range>", <bang>0, "<mods>", "' . tolower(s:cmd) . ' " . <q-args>)'
endif endif
endfor endfor
@ -401,7 +435,7 @@ exe 'command! -bang -nargs=? -range=-1' s:addr_wins '-complete=customlist,fugiti
if exists(':Glog') != 2 && get(g:, 'fugitive_legacy_commands', 1) if exists(':Glog') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete Glog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "")' exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete Glog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "")'
\ '|echohl WarningMSG|echo ":Glog is deprecated in favor of :Gclog"|echohl NONE' \ '|echohl WarningMSG|echomsg ":Glog is deprecated in favor of :Gclog"|echohl NONE'
endif endif
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete Gclog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "c")' exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete Gclog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "c")'
exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete GcLog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "c")' exe 'command! -bang -nargs=? -range=-1 -complete=customlist,fugitive#LogComplete GcLog :exe fugitive#LogCommand(<line1>,<count>,+"<range>",<bang>0,"<mods>",<q-args>, "c")'
@ -422,37 +456,37 @@ exe 'command! -bar -bang -nargs=* -range=-1 -complete=customlist,
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gdiffsplit exe fugitive#Diffsplit(1, <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gdiffsplit exe fugitive#Diffsplit(1, <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Ghdiffsplit exe fugitive#Diffsplit(0, <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Ghdiffsplit exe fugitive#Diffsplit(0, <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gvdiffsplit exe fugitive#Diffsplit(0, <bang>0, "vert <mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gvdiffsplit exe fugitive#Diffsplit(0, <bang>0, "vertical <mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gw exe fugitive#WriteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gw exe fugitive#WriteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gwrite exe fugitive#WriteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gwrite exe fugitive#WriteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gwq exe fugitive#WqCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -nargs=* -complete=customlist,fugitive#EditComplete Gwq exe fugitive#WqCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=0 -complete=customlist,fugitive#CompleteObject GRemove exe fugitive#RemoveCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -nargs=0 GRemove exe fugitive#RemoveCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=0 -complete=customlist,fugitive#CompleteObject GDelete exe fugitive#DeleteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -nargs=0 GDelete exe fugitive#DeleteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#CompleteObject GMove exe fugitive#MoveCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#CompleteObject GMove exe fugitive#MoveCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#RenameComplete GRename exe fugitive#RenameCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#RenameComplete GRename exe fugitive#RenameCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
if exists(':Gremove') != 2 && get(g:, 'fugitive_legacy_commands', 1) if exists(':Gremove') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -nargs=0 -complete=customlist,fugitive#CompleteObject Gremove exe fugitive#RemoveCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -nargs=0 Gremove exe fugitive#RemoveCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
\ '|echohl WarningMSG|echo ":Gremove is deprecated in favor of :GRemove"|echohl NONE' \ '|echohl WarningMSG|echomsg ":Gremove is deprecated in favor of :GRemove"|echohl NONE'
endif endif
if exists(':Gdelete') != 2 && get(g:, 'fugitive_legacy_commands', 1) if exists(':Gdelete') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -nargs=0 -complete=customlist,fugitive#CompleteObject Gdelete exe fugitive#DeleteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -nargs=0 Gdelete exe fugitive#DeleteCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
\ '|echohl WarningMSG|echo ":Gdelete is deprecated in favor of :GDelete"|echohl NONE' \ '|echohl WarningMSG|echomsg ":Gdelete is deprecated in favor of :GDelete"|echohl NONE'
endif endif
if exists(':Gmove') != 2 && get(g:, 'fugitive_legacy_commands', 1) if exists(':Gmove') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#CompleteObject Gmove exe fugitive#MoveCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#CompleteObject Gmove exe fugitive#MoveCommand( <line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
\ '|echohl WarningMSG|echo ":Gmove is deprecated in favor of :GMove"|echohl NONE' \ '|echohl WarningMSG|echomsg ":Gmove is deprecated in favor of :GMove"|echohl NONE'
endif endif
if exists(':Grename') != 2 && get(g:, 'fugitive_legacy_commands', 1) if exists(':Grename') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#RenameComplete Grename exe fugitive#RenameCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -nargs=1 -complete=customlist,fugitive#RenameComplete Grename exe fugitive#RenameCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
\ '|echohl WarningMSG|echo ":Grename is deprecated in favor of :GRename"|echohl NONE' \ '|echohl WarningMSG|echomsg ":Grename is deprecated in favor of :GRename"|echohl NONE'
endif endif
exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject GBrowse exe fugitive#BrowseCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject GBrowse exe fugitive#BrowseCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
if exists(':Gbrowse') != 2 && get(g:, 'fugitive_legacy_commands', 1) if exists(':Gbrowse') != 2 && get(g:, 'fugitive_legacy_commands', 1)
exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject Gbrowse exe fugitive#BrowseCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])' exe 'command! -bar -bang -range=-1 -nargs=* -complete=customlist,fugitive#CompleteObject Gbrowse exe fugitive#BrowseCommand(<line1>, <count>, +"<range>", <bang>0, "<mods>", <q-args>, [<f-args>])'
\ '|if <bang>1|redraw!|endif|echohl WarningMSG|echo ":Gbrowse is deprecated in favor of :GBrowse"|echohl NONE' \ '|if <bang>1|redraw!|endif|echohl WarningMSG|echomsg ":Gbrowse is deprecated in favor of :GBrowse"|echohl NONE'
endif endif
if v:version < 704 if v:version < 704

View File

@ -7,8 +7,9 @@ syn spell notoplevel
syn include @fugitiveDiff syntax/diff.vim syn include @fugitiveDiff syntax/diff.vim
syn match fugitiveHeader /^[A-Z][a-z][^:]*:/ nextgroup=fugitiveHash,fugitiveSymbolicRef skipwhite syn match fugitiveHeader /^[A-Z][a-z][^:]*:/
syn match fugitiveBareHeader /^Bare:/ syn match fugitiveHeader /^Head:/ nextgroup=fugitiveHash,fugitiveSymbolicRef skipwhite
syn match fugitiveHeader /^Pull:\|^Rebase:\|^Merge:\|^Push:/ nextgroup=fugitiveSymbolicRef skipwhite
syn match fugitiveHelpHeader /^Help:/ nextgroup=fugitiveHelpTag skipwhite syn match fugitiveHelpHeader /^Help:/ nextgroup=fugitiveHelpTag skipwhite
syn match fugitiveHelpTag /\S\+/ contained syn match fugitiveHelpTag /\S\+/ contained
@ -36,7 +37,6 @@ for s:section in ['Untracked', 'Unstaged', 'Staged']
endfor endfor
unlet s:section unlet s:section
hi def link fugitiveBareHeader fugitiveHeader
hi def link fugitiveHelpHeader fugitiveHeader hi def link fugitiveHelpHeader fugitiveHeader
hi def link fugitiveHeader Label hi def link fugitiveHeader Label
hi def link fugitiveHelpTag Tag hi def link fugitiveHelpTag Tag

View File

@ -179,7 +179,7 @@ endfunction
" - this runs synchronously " - this runs synchronously
" - it ignores unsaved changes in buffers " - it ignores unsaved changes in buffers
" - it does not change to the repo root " - it does not change to the repo root
function! gitgutter#quickfix() function! gitgutter#quickfix(current_file)
let cmd = g:gitgutter_git_executable.' '.g:gitgutter_git_args.' rev-parse --show-cdup' let cmd = g:gitgutter_git_executable.' '.g:gitgutter_git_args.' rev-parse --show-cdup'
let path_to_repo = get(systemlist(cmd), 0, '') let path_to_repo = get(systemlist(cmd), 0, '')
if !empty(path_to_repo) && path_to_repo[-1:] != '/' if !empty(path_to_repo) && path_to_repo[-1:] != '/'
@ -191,6 +191,9 @@ function! gitgutter#quickfix()
\ ' diff --no-ext-diff --no-color -U0'. \ ' diff --no-ext-diff --no-color -U0'.
\ ' --src-prefix=a/'.path_to_repo.' --dst-prefix=b/'.path_to_repo.' '. \ ' --src-prefix=a/'.path_to_repo.' --dst-prefix=b/'.path_to_repo.' '.
\ g:gitgutter_diff_args. ' '. g:gitgutter_diff_base \ g:gitgutter_diff_args. ' '. g:gitgutter_diff_base
if a:current_file
let cmd = cmd.' -- '.expand('%:p')
endif
let diff = systemlist(cmd) let diff = systemlist(cmd)
let lnum = 0 let lnum = 0
for line in diff for line in diff

View File

@ -158,6 +158,11 @@ Commands for jumping between hunks:~
> >
command! Gqf GitGutterQuickFix | copen command! Gqf GitGutterQuickFix | copen
< <
*gitgutter-:GitGutterQuickFixCurrentFile*
:GitGutterQuickFixCurrentFile Same as :GitGutterQuickFix, but only load hunks for
the file in the focused buffer. This has the same
functionality as :GitGutterQuickFix when the focused
buffer is empty.
Commands for operating on a hunk:~ Commands for operating on a hunk:~

View File

@ -118,7 +118,8 @@ command! -bar GitGutterBufferDisable call gitgutter#buffer_disable()
command! -bar GitGutterBufferEnable call gitgutter#buffer_enable() command! -bar GitGutterBufferEnable call gitgutter#buffer_enable()
command! -bar GitGutterBufferToggle call gitgutter#buffer_toggle() command! -bar GitGutterBufferToggle call gitgutter#buffer_toggle()
command! -bar GitGutterQuickFix call gitgutter#quickfix() command! -bar GitGutterQuickFix call gitgutter#quickfix(0)
command! -bar GitGutterQuickFixCurrentFile call gitgutter#quickfix(1)
" }}} " }}}

View File

@ -947,12 +947,27 @@ function Test_quickfix()
call setline(5, ['A', 'B']) call setline(5, ['A', 'B'])
call setline(9, ['C', 'D']) call setline(9, ['C', 'D'])
write write
let bufnr1 = bufnr('')
edit fixture_dos.txt
call setline(2, ['A', 'B'])
write
let bufnr2 = bufnr('')
GitGutterQuickFix GitGutterQuickFix
let expected = [ let expected = [
\ {'lnum': 5, 'bufnr': bufnr(''), 'text': '-e'}, \ {'lnum': 5, 'bufnr': bufnr1, 'text': '-e'},
\ {'lnum': 9, 'bufnr': bufnr(''), 'text': '-i'} \ {'lnum': 9, 'bufnr': bufnr1, 'text': '-i'},
\ {'lnum': 2, 'bufnr': bufnr2, 'text': "-b\r"}
\ ]
call s:assert_list_of_dicts(expected, getqflist())
GitGutterQuickFixCurrentFile
let expected = [
\ {'lnum': 2, 'bufnr': bufnr(''), 'text': "-b\r"},
\ ] \ ]
call s:assert_list_of_dicts(expected, getqflist()) call s:assert_list_of_dicts(expected, getqflist())

View File

@ -2,7 +2,7 @@ GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
diff-lcs (1.2.5) diff-lcs (1.2.5)
rake (12.3.3) rake (10.4.2)
rspec (3.4.0) rspec (3.4.0)
rspec-core (~> 3.4.0) rspec-core (~> 3.4.0)
rspec-expectations (~> 3.4.0) rspec-expectations (~> 3.4.0)

View File

@ -89,6 +89,9 @@ let s:ruby_indent_keywords =
\ '\|\%([=,*/%+-]\|<<\|>>\|:\s\)\s*\zs' . \ '\|\%([=,*/%+-]\|<<\|>>\|:\s\)\s*\zs' .
\ '\<\%(if\|for\|while\|until\|case\|unless\|begin\):\@!\>' \ '\<\%(if\|for\|while\|until\|case\|unless\|begin\):\@!\>'
" Def without an end clause: def method_call(...) = <expression>
let s:ruby_endless_def = '\<def\s\+\k\+[!?]\=\%((.*)\|\s\)\s*='
" Regex used for words that, at the start of a line, remove a level of indent. " Regex used for words that, at the start of a line, remove a level of indent.
let s:ruby_deindent_keywords = let s:ruby_deindent_keywords =
\ '^\s*\zs\<\%(ensure\|else\|rescue\|elsif\|when\|end\):\@!\>' \ '^\s*\zs\<\%(ensure\|else\|rescue\|elsif\|when\|end\):\@!\>'
@ -108,10 +111,26 @@ let s:end_middle_regex = '\<\%(ensure\|else\|\%(\%(^\|;\)\s*\)\@<=\<rescue:\@!\>
" Regex that defines the end-match for the 'end' keyword. " Regex that defines the end-match for the 'end' keyword.
let s:end_end_regex = '\%(^\|[^.:@$]\)\@<=\<end:\@!\>' let s:end_end_regex = '\%(^\|[^.:@$]\)\@<=\<end:\@!\>'
" Expression used for searchpair() call for finding match for 'end' keyword. " Expression used for searchpair() call for finding a match for an 'end' keyword.
let s:end_skip_expr = s:skip_expr . function! s:EndSkipExpr()
\ ' || (expand("<cword>") == "do"' . if eval(s:skip_expr)
\ ' && getline(".") =~ "^\\s*\\<\\(while\\|until\\|for\\):\\@!\\>")' return 1
elseif expand('<cword>') == 'do'
\ && getline(".") =~ '^\s*\<\(while\|until\|for\):\@!\>'
return 1
elseif getline('.') =~ s:ruby_endless_def
return 1
elseif getline('.') =~ '\<def\s\+\k\+[!?]\=([^)]*$'
" Then it's a `def method(` with a possible `) =` later
call search('\<def\s\+\k\+\zs(', 'W', line('.'))
normal! %
return getline('.') =~ ')\s*='
else
return 0
endif
endfunction
let s:end_skip_expr = function('s:EndSkipExpr')
" Regex that defines continuation lines, not including (, {, or [. " Regex that defines continuation lines, not including (, {, or [.
let s:non_bracket_continuation_regex = let s:non_bracket_continuation_regex =
@ -571,6 +590,11 @@ function! s:AfterUnbalancedBracket(pline_info) abort
call cursor(info.plnum, closing.pos + 1) call cursor(info.plnum, closing.pos + 1)
normal! % normal! %
if strpart(info.pline, closing.pos) =~ '^)\s*='
" special case: the closing `) =` of an endless def
return indent(s:GetMSL(line('.')))
endif
if s:Match(line('.'), s:ruby_indent_keywords) if s:Match(line('.'), s:ruby_indent_keywords)
return indent('.') + info.sw return indent('.') + info.sw
else else
@ -609,7 +633,7 @@ function! s:AfterIndentKeyword(pline_info) abort
let info = a:pline_info let info = a:pline_info
let col = s:Match(info.plnum, s:ruby_indent_keywords) let col = s:Match(info.plnum, s:ruby_indent_keywords)
if col > 0 if col > 0 && s:Match(info.plnum, s:ruby_endless_def) <= 0
call cursor(info.plnum, col) call cursor(info.plnum, col)
let ind = virtcol('.') - 1 + info.sw let ind = virtcol('.') - 1 + info.sw
" TODO: make this better (we need to count them) (or, if a searchpair " TODO: make this better (we need to count them) (or, if a searchpair
@ -656,7 +680,7 @@ function! s:IndentingKeywordInMSL(msl_info) abort
" TODO: this does not take into account contrived things such as " TODO: this does not take into account contrived things such as
" module Foo; class Bar; end " module Foo; class Bar; end
let col = s:Match(info.plnum_msl, s:ruby_indent_keywords) let col = s:Match(info.plnum_msl, s:ruby_indent_keywords)
if col > 0 if col > 0 && s:Match(info.plnum_msl, s:ruby_endless_def) <= 0
let ind = indent(info.plnum_msl) + info.sw let ind = indent(info.plnum_msl) + info.sw
if s:Match(info.plnum_msl, s:end_end_regex) if s:Match(info.plnum_msl, s:end_end_regex)
let ind = ind - info.sw let ind = ind - info.sw

View File

@ -27,5 +27,20 @@ describe "Indenting" do
foo = bar; class One; end foo = bar; class One; end
end end
EOF EOF
assert_correct_indenting <<~EOF
nested do
while true do
def foo
if bar
for i in collection
def baz
end
end
end
end
end
end
EOF
end end
end end

View File

@ -37,4 +37,40 @@ describe "Indenting" do
end end
EOF EOF
end end
specify "endless methods" do
# Note: A case that doesn't work at this time:
#
# def foo()
# = 42
#
assert_correct_indenting <<~EOF
indented_block do
def foo(bar) = puts(bar)
def foo!(bar) = puts(bar)
def foo?(bar) = puts(bar)
def foo(bar)=puts(bar)
def foo(bar) = bar + 1
def foo() = 1 + 1
def foo = 1 + 1
private def foo(bar) = bar + 1
def foo(bar) =
bar + 1
def foo(bar = default_function()) = puts(bar)
def foo(bar = default_function()) =
puts(bar)
def foo(
bar
) = puts(bar)
end
EOF
end
end end

View File

@ -65,7 +65,7 @@ endfunction
com! -nargs=* SynFold call s:run_syntax_fold(<q-args>) com! -nargs=* SynFold call s:run_syntax_fold(<q-args>)
" Not-Top Cluster {{{1 " Not-Top Cluster {{{1
syn cluster rubyNotTop contains=@rubyCommentNotTop,@rubyStringNotTop,@rubyRegexpSpecial,@rubyDeclaration,@rubyExceptionHandler,@rubyClassOperator,rubyConditional,rubyModuleName,rubyClassName,rubySymbolDelimiter,rubyParentheses,@Spell syn cluster rubyNotTop contains=@rubyCommentNotTop,@rubyStringNotTop,@rubyRegexpSpecial,@rubyDeclaration,@rubyExceptionHandler,@rubyClassOperator,rubyConditional,rubyModuleName,rubyClassName,rubySymbolDelimiter,rubyDoubleQuoteSymbolDelimiter,rubySingleQuoteSymbolDelimiter,rubyParentheses,@Spell
" Whitespace Errors {{{1 " Whitespace Errors {{{1
if exists("ruby_space_errors") if exists("ruby_space_errors")
@ -464,6 +464,10 @@ syn match rubyDefinedOperator "\%#=1\<defined?" display
syn match rubySymbol "\%(\w\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[?!]\=::\@!"he=e-1 contained containedin=rubyBlockParameterList,rubyCurlyBlock syn match rubySymbol "\%(\w\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[?!]\=::\@!"he=e-1 contained containedin=rubyBlockParameterList,rubyCurlyBlock
syn match rubySymbol "[]})\"':]\@1<!\<\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[!?]\=:[[:space:],;]\@="he=e-1 syn match rubySymbol "[]})\"':]\@1<!\<\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[!?]\=:[[:space:],;]\@="he=e-1
syn match rubySymbol "[[:space:],{(]\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[!?]\=:[[:space:],;]\@="hs=s+1,he=e-1 syn match rubySymbol "[[:space:],{(]\%(\h\|[^\x00-\x7F]\)\%(\w\|[^\x00-\x7F]\)*[!?]\=:[[:space:],;]\@="hs=s+1,he=e-1
syn match rubySingleQuoteSymbolDelimiter "'" contained
syn match rubySymbol "'\%(\\.\|[^']\)*'::\@!"he=e-1 contains=rubyQuoteEscape,rubyBackslashEscape,rubySingleQuoteSymbolDelimiter
syn match rubyDoubleQuoteSymbolDelimiter "\"" contained
syn match rubySymbol "\"\%(\\.\|[^\"]\)*\"::\@!"he=e-1 contains=@rubyStringSpecial,rubyDoubleQuoteSymbolDelimiter
" __END__ Directive {{{1 " __END__ Directive {{{1
SynFold '__END__' syn region rubyData matchgroup=rubyDataDirective start="^__END__$" end="\%$" SynFold '__END__' syn region rubyData matchgroup=rubyDataDirective start="^__END__$" end="\%$"
@ -564,6 +568,8 @@ hi def link rubyHeredocDelimiter rubyStringDelimiter
hi def link rubyPercentRegexpDelimiter rubyRegexpDelimiter hi def link rubyPercentRegexpDelimiter rubyRegexpDelimiter
hi def link rubyPercentStringDelimiter rubyStringDelimiter hi def link rubyPercentStringDelimiter rubyStringDelimiter
hi def link rubyPercentSymbolDelimiter rubySymbolDelimiter hi def link rubyPercentSymbolDelimiter rubySymbolDelimiter
hi def link rubyDoubleQuoteSymbolDelimiter rubySymbolDelimiter
hi def link rubySingleQuoteSymbolDelimiter rubySymbolDelimiter
hi def link rubyRegexpDelimiter rubyStringDelimiter hi def link rubyRegexpDelimiter rubyStringDelimiter
hi def link rubySymbolDelimiter rubySymbol hi def link rubySymbolDelimiter rubySymbol
hi def link rubyString String hi def link rubyString String

View File

@ -70,12 +70,17 @@ endsnippet
snippet here "here document (here)" snippet here "here document (here)"
<<-${2:'${1:TOKEN}'} <<-${2:'${1:TOKEN}'}
$0 $0`echo \\n`${1/['"`](.+)['"`]/$1/}
${1/['"`](.+)['"`]/$1/} endsnippet
snippet /ift(est)?/ "if ... then (if)" rb
if ${2:[ ${1:condition} ]}; then
${0:${VISUAL}}
fi
endsnippet endsnippet
snippet if "if ... then (if)" b snippet if "if ... then (if)" b
if ${2:[[ ${1:condition} ]]}; then if [[ ${1:condition} ]]; then
${0:${VISUAL}} ${0:${VISUAL}}
fi fi
endsnippet endsnippet
@ -92,4 +97,10 @@ while ${2:[[ ${1:condition} ]]}; do
done done
endsnippet endsnippet
snippet func "function() {...}" b
${1:function} () {
${0:${VISUAL}}
}
endsnippet
# vim:ft=snippets: # vim:ft=snippets: