diff --git a/sources_non_forked/ale/ale_linters/astro/eslint.vim b/sources_non_forked/ale/ale_linters/astro/eslint.vim new file mode 100644 index 00000000..9fb51ad2 --- /dev/null +++ b/sources_non_forked/ale/ale_linters/astro/eslint.vim @@ -0,0 +1,11 @@ +" Author: Hyuksang Kwon +" Description: eslint for astro files + +call ale#linter#Define('astro', { +\ 'name': 'eslint', +\ 'output_stream': 'both', +\ 'executable': function('ale#handlers#eslint#GetExecutable'), +\ 'cwd': function('ale#handlers#eslint#GetCwd'), +\ 'command': function('ale#handlers#eslint#GetCommand'), +\ 'callback': 'ale#handlers#eslint#HandleJSON', +\}) diff --git a/sources_non_forked/ale/ale_linters/cmake/cmake_lint.vim b/sources_non_forked/ale/ale_linters/cmake/cmake_lint.vim index 3c44c92f..5942e08d 100644 --- a/sources_non_forked/ale/ale_linters/cmake/cmake_lint.vim +++ b/sources_non_forked/ale/ale_linters/cmake/cmake_lint.vim @@ -15,7 +15,7 @@ function! ale_linters#cmake#cmake_lint#Command(buffer) abort let l:executable = ale_linters#cmake#cmake_lint#Executable(a:buffer) let l:options = ale#Var(a:buffer, 'cmake_cmake_lint_options') - return ale#Escape(l:executable) . ' ' . l:options . ' %t' + return ale#Escape(l:executable) . ' ' . l:options . ' %s' endfunction function! ale_linters#cmake#cmake_lint#Handle(buffer, lines) abort diff --git a/sources_non_forked/ale/ale_linters/css/stylelint.vim b/sources_non_forked/ale/ale_linters/css/stylelint.vim index e508f392..ceb42461 100644 --- a/sources_non_forked/ale/ale_linters/css/stylelint.vim +++ b/sources_non_forked/ale/ale_linters/css/stylelint.vim @@ -11,6 +11,7 @@ endfunction call ale#linter#Define('css', { \ 'name': 'stylelint', +\ 'output_stream': 'both', \ 'executable': {b -> ale#path#FindExecutable(b, 'css_stylelint', [ \ 'node_modules/.bin/stylelint', \ ])}, diff --git a/sources_non_forked/ale/ale_linters/dart/analysis_server.vim b/sources_non_forked/ale/ale_linters/dart/analysis_server.vim index a6870da9..12a5d590 100644 --- a/sources_non_forked/ale/ale_linters/dart/analysis_server.vim +++ b/sources_non_forked/ale/ale_linters/dart/analysis_server.vim @@ -1,6 +1,7 @@ " Author: Nelson Yeung " Description: Check Dart files with dart analysis server LSP +call ale#Set('dart_analysis_server_enable_language_server', 1) call ale#Set('dart_analysis_server_executable', 'dart') function! ale_linters#dart#analysis_server#GetProjectRoot(buffer) abort @@ -12,12 +13,19 @@ function! ale_linters#dart#analysis_server#GetProjectRoot(buffer) abort endfunction function! ale_linters#dart#analysis_server#GetCommand(buffer) abort + let l:language_server = ale#Var(a:buffer, 'dart_analysis_server_enable_language_server') let l:executable = ale#Var(a:buffer, 'dart_analysis_server_executable') let l:dart = resolve(exepath(l:executable)) - - return '%e ' + let l:output = '%e ' \ . fnamemodify(l:dart, ':h') . '/snapshots/analysis_server.dart.snapshot' \ . ' --lsp' + + " Enable new language-server command + if l:language_server == 1 + let l:output = '%e language-server --protocol=lsp' + endif + + return l:output endfunction call ale#linter#Define('dart', { diff --git a/sources_non_forked/ale/ale_linters/elm/ls.vim b/sources_non_forked/ale/ale_linters/elm/ls.vim index 38a5b234..111f3ac2 100644 --- a/sources_non_forked/ale/ale_linters/elm/ls.vim +++ b/sources_non_forked/ale/ale_linters/elm/ls.vim @@ -16,7 +16,7 @@ function! ale_linters#elm#ls#GetProjectRoot(buffer) abort return !empty(l:elm_json) ? fnamemodify(l:elm_json, ':p:h') : '' endfunction -function! ale_linters#elm#ls#GetOptions(buffer) abort +function! ale_linters#elm#ls#GetInitializationOptions(buffer) abort return { \ 'elmPath': ale#Var(a:buffer, 'elm_ls_elm_path'), \ 'elmFormatPath': ale#Var(a:buffer, 'elm_ls_elm_format_path'), @@ -37,5 +37,5 @@ call ale#linter#Define('elm', { \ 'command': '%e --stdio', \ 'project_root': function('ale_linters#elm#ls#GetProjectRoot'), \ 'language': 'elm', -\ 'initialization_options': function('elm_ls#GetOptions') +\ 'initialization_options': function('ale_linters#elm#ls#GetInitializationOptions') \}) diff --git a/sources_non_forked/ale/ale_linters/erlang/elvis.vim b/sources_non_forked/ale/ale_linters/erlang/elvis.vim index 0fb85c07..321a6c72 100644 --- a/sources_non_forked/ale/ale_linters/erlang/elvis.vim +++ b/sources_non_forked/ale/ale_linters/erlang/elvis.vim @@ -26,9 +26,27 @@ function! s:AbbreviateMessage(text) abort endfunction function! s:GetCommand(buffer) abort - let l:file = ale#Escape(expand('#' . a:buffer . ':.')) + let l:cwd = s:GetCwd(a:buffer) - return '%e rock --output-format=parsable ' . l:file + let l:file = !empty(l:cwd) + \ ? expand('#' . a:buffer . ':p')[len(l:cwd) + 1:] + \ : expand('#' . a:buffer . ':.') + + return '%e rock --output-format=parsable ' . ale#Escape(l:file) +endfunction + +function! s:GetCwd(buffer) abort + let l:markers = ['elvis.config', 'rebar.lock', 'erlang.mk'] + + for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h')) + for l:marker in l:markers + if filereadable(l:path . '/' . l:marker) + return l:path + endif + endfor + endfor + + return '' endfunction call ale#linter#Define('erlang', { @@ -36,5 +54,6 @@ call ale#linter#Define('erlang', { \ 'callback': 'ale_linters#erlang#elvis#Handle', \ 'executable': {b -> ale#Var(b, 'erlang_elvis_executable')}, \ 'command': function('s:GetCommand'), +\ 'cwd': function('s:GetCwd'), \ 'lint_file': 1, \}) diff --git a/sources_non_forked/ale/ale_linters/erlang/erlang_ls.vim b/sources_non_forked/ale/ale_linters/erlang/erlang_ls.vim index b747e454..0f070459 100644 --- a/sources_non_forked/ale/ale_linters/erlang/erlang_ls.vim +++ b/sources_non_forked/ale/ale_linters/erlang/erlang_ls.vim @@ -21,7 +21,14 @@ function! s:GetCommand(buffer) abort endfunction function! s:FindProjectRoot(buffer) abort - let l:markers = ['_build/', 'erlang_ls.config', 'rebar.lock'] + let l:markers = [ + \ '_checkouts/', + \ '_build/', + \ 'deps/', + \ 'erlang_ls.config', + \ 'rebar.lock', + \ 'erlang.mk', + \] " This is a way to find Erlang/OTP root (the one that is managed " by kerl or asdf). Useful if :ALEGoToDefinition takes us there. diff --git a/sources_non_forked/ale/ale_linters/erlang/syntaxerl.vim b/sources_non_forked/ale/ale_linters/erlang/syntaxerl.vim index 5d555a8d..bd984fef 100644 --- a/sources_non_forked/ale/ale_linters/erlang/syntaxerl.vim +++ b/sources_non_forked/ale/ale_linters/erlang/syntaxerl.vim @@ -3,29 +3,13 @@ call ale#Set('erlang_syntaxerl_executable', 'syntaxerl') -function! ale_linters#erlang#syntaxerl#RunHelpCommand(buffer) abort - let l:executable = ale#Var(a:buffer, 'erlang_syntaxerl_executable') - - return ale#command#Run( - \ a:buffer, - \ ale#Escape(l:executable) . ' -h', - \ function('ale_linters#erlang#syntaxerl#GetCommand'), - \) -endfunction - -function! ale_linters#erlang#syntaxerl#GetCommand(buffer, output, meta) abort - let l:use_b_option = match(a:output, '\C\V-b, --base\>') > -1 - - return '%e' . (l:use_b_option ? ' -b %s %t' : ' %t') -endfunction - function! ale_linters#erlang#syntaxerl#Handle(buffer, lines) abort let l:pattern = '\v\C:(\d+):( warning:)? (.+)' let l:loclist = [] for l:match in ale#util#GetMatches(a:lines, l:pattern) call add(l:loclist, { - \ 'lnum': l:match[1] + 0, + \ 'lnum': str2nr(l:match[1]), \ 'text': l:match[3], \ 'type': empty(l:match[2]) ? 'E' : 'W', \}) @@ -34,9 +18,27 @@ function! ale_linters#erlang#syntaxerl#Handle(buffer, lines) abort return l:loclist endfunction +function! s:GetExecutable(buffer) abort + return ale#Var(a:buffer, 'erlang_syntaxerl_executable') +endfunction + +function! s:GetCommand(buffer) abort + let l:Callback = function('s:GetCommandFromHelpOutput') + + return ale#command#Run(a:buffer, '%e -h', l:Callback, { + \ 'executable': s:GetExecutable(a:buffer), + \}) +endfunction + +function! s:GetCommandFromHelpOutput(buffer, output, metadata) abort + let l:has_b_option = match(a:output, '\V\C-b, --base\>') > -1 + + return l:has_b_option ? '%e -b %s %t' : '%e %t' +endfunction + call ale#linter#Define('erlang', { \ 'name': 'syntaxerl', -\ 'executable': {b -> ale#Var(b, 'erlang_syntaxerl_executable')}, -\ 'command': {b -> ale_linters#erlang#syntaxerl#RunHelpCommand(b)}, \ 'callback': 'ale_linters#erlang#syntaxerl#Handle', +\ 'executable': function('s:GetExecutable'), +\ 'command': function('s:GetCommand'), \}) diff --git a/sources_non_forked/ale/ale_linters/glimmer/embertemplatelint.vim b/sources_non_forked/ale/ale_linters/glimmer/embertemplatelint.vim new file mode 100644 index 00000000..10b54bb4 --- /dev/null +++ b/sources_non_forked/ale/ale_linters/glimmer/embertemplatelint.vim @@ -0,0 +1,6 @@ +" Author: Sam Saffron +" Description: Ember-template-lint for checking GJS (Glimmer JS) files + +scriptencoding utf-8 + +call ale#handlers#embertemplatelint#DefineLinter('glimmer') diff --git a/sources_non_forked/ale/ale_linters/go/golangci_lint.vim b/sources_non_forked/ale/ale_linters/go/golangci_lint.vim index 78087b5e..a3643370 100644 --- a/sources_non_forked/ale/ale_linters/go/golangci_lint.vim +++ b/sources_non_forked/ale/ale_linters/go/golangci_lint.vim @@ -3,7 +3,7 @@ call ale#Set('go_golangci_lint_options', '') call ale#Set('go_golangci_lint_executable', 'golangci-lint') -call ale#Set('go_golangci_lint_package', 0) +call ale#Set('go_golangci_lint_package', 1) function! ale_linters#go#golangci_lint#GetCommand(buffer) abort let l:filename = expand('#' . a:buffer . ':t') diff --git a/sources_non_forked/ale/ale_linters/handlebars/embertemplatelint.vim b/sources_non_forked/ale/ale_linters/handlebars/embertemplatelint.vim index 14fa3b2e..62b5db03 100644 --- a/sources_non_forked/ale/ale_linters/handlebars/embertemplatelint.vim +++ b/sources_non_forked/ale/ale_linters/handlebars/embertemplatelint.vim @@ -1,62 +1,6 @@ " Author: Adrian Zalewski " Description: Ember-template-lint for checking Handlebars files -call ale#Set('handlebars_embertemplatelint_executable', 'ember-template-lint') -call ale#Set('handlebars_embertemplatelint_use_global', get(g:, 'ale_use_global_executables', 0)) +scriptencoding utf-8 -function! ale_linters#handlebars#embertemplatelint#GetExecutable(buffer) abort - return ale#path#FindExecutable(a:buffer, 'handlebars_embertemplatelint', [ - \ 'node_modules/.bin/ember-template-lint', - \]) -endfunction - -function! ale_linters#handlebars#embertemplatelint#GetCommand(buffer, version) abort - if ale#semver#GTE(a:version, [4, 0, 0]) - " --json was removed in favor of --format=json in ember-template-lint@4.0.0 - return '%e --format=json --filename %s' - endif - - return '%e --json --filename %s' -endfunction - -function! ale_linters#handlebars#embertemplatelint#GetCommandWithVersionCheck(buffer) abort - return ale#semver#RunWithVersionCheck( - \ a:buffer, - \ ale_linters#handlebars#embertemplatelint#GetExecutable(a:buffer), - \ '%e --version', - \ function('ale_linters#handlebars#embertemplatelint#GetCommand'), - \) -endfunction - -function! ale_linters#handlebars#embertemplatelint#Handle(buffer, lines) abort - let l:output = [] - let l:json = ale#util#FuzzyJSONDecode(a:lines, {}) - - for l:error in get(values(l:json), 0, []) - if has_key(l:error, 'fatal') - call add(l:output, { - \ 'lnum': get(l:error, 'line', 1), - \ 'col': get(l:error, 'column', 1), - \ 'text': l:error.message, - \ 'type': l:error.severity == 1 ? 'W' : 'E', - \}) - else - call add(l:output, { - \ 'lnum': l:error.line, - \ 'col': l:error.column, - \ 'text': l:error.rule . ': ' . l:error.message, - \ 'type': l:error.severity == 1 ? 'W' : 'E', - \}) - endif - endfor - - return l:output -endfunction - -call ale#linter#Define('handlebars', { -\ 'name': 'embertemplatelint', -\ 'aliases': ['ember-template-lint'], -\ 'executable': function('ale_linters#handlebars#embertemplatelint#GetExecutable'), -\ 'command': function('ale_linters#handlebars#embertemplatelint#GetCommandWithVersionCheck'), -\ 'callback': 'ale_linters#handlebars#embertemplatelint#Handle', -\}) +call ale#handlers#embertemplatelint#DefineLinter('handlebars') diff --git a/sources_non_forked/ale/ale_linters/html/stylelint.vim b/sources_non_forked/ale/ale_linters/html/stylelint.vim index 6b7aba40..c191c468 100644 --- a/sources_non_forked/ale/ale_linters/html/stylelint.vim +++ b/sources_non_forked/ale/ale_linters/html/stylelint.vim @@ -21,6 +21,7 @@ endfunction call ale#linter#Define('html', { \ 'name': 'stylelint', +\ 'output_stream': 'both', \ 'executable': function('ale_linters#html#stylelint#GetExecutable'), \ 'command': function('ale_linters#html#stylelint#GetCommand'), \ 'callback': 'ale#handlers#css#HandleStyleLintFormat', diff --git a/sources_non_forked/ale/ale_linters/hurl/hurlfmt.vim b/sources_non_forked/ale/ale_linters/hurl/hurlfmt.vim new file mode 100644 index 00000000..fa4252da --- /dev/null +++ b/sources_non_forked/ale/ale_linters/hurl/hurlfmt.vim @@ -0,0 +1,69 @@ +" Description: Hurl linter using hurlfmt --check. +" https://hurl.dev/ + +call ale#Set('hurl_hurlfmt_executable', 'hurlfmt') + +function! ale_linters#hurl#hurlfmt#GetCommand(buffer) abort + return '%e' + \ . ' --check --no-color ' +endfunction + +function! ale_linters#hurl#hurlfmt#HandleOutput(buffer, lines) abort + " Matches patterns: + " + " error: Parsing space + " --> test.hurl:11:48 + " | + " 8 | header "Content-Type"= "application/json; charset=utf-8" + " | ^ expecting a space + " | + " + " error: Parsing URL + " --> test.hurl:11:48 + " | + " 11 | PUT https://jsonplaceholder.typicode.com/posts/{post_id}} + " | ^ illegal character <{> + " | + " + " Note: hurlfmt seems to report always the first error only so we assume + " there is only one error to make parsing easier. + let l:output = [] + + if empty(a:lines) + return l:output + endif + + let l:pattern = '\v(error|warning): (.+) --\> (.+):(\d+):(\d+) .+ \^ (.+) |' + let l:lines = join(a:lines, ' ') + + for l:match in ale#util#GetMatches(l:lines, l:pattern) + call add(l:output, { + \ 'bufnr': a:buffer, + \ 'lnum': match[4] + 0, + \ 'col': match[5] + 0, + \ 'end_col': match[5] + 0, + \ 'text': match[2] . ' : ' . match[6], + \ 'type': (match[1] is# 'error') ? 'E' : 'W' + \}) + endfor + + return l:output +endfunction + +function! ale_linters#hurl#hurlfmt#GetType(severity) abort + if a:severity is? 'convention' + \|| a:severity is? 'warning' + \|| a:severity is? 'refactor' + return 'W' + endif + + return 'E' +endfunction + +call ale#linter#Define('hurl', { +\ 'name': 'hurlfmt', +\ 'output_stream': 'stderr', +\ 'executable': {b -> ale#Var(b, 'hurl_hurlfmt_executable')}, +\ 'command': function('ale_linters#hurl#hurlfmt#GetCommand'), +\ 'callback': 'ale_linters#hurl#hurlfmt#HandleOutput', +\}) diff --git a/sources_non_forked/ale/ale_linters/javascript/biome.vim b/sources_non_forked/ale/ale_linters/javascript/biome.vim new file mode 100644 index 00000000..17714de1 --- /dev/null +++ b/sources_non_forked/ale/ale_linters/javascript/biome.vim @@ -0,0 +1,11 @@ +" Author: Filip Gospodinov +" Description: biome for JavaScript files + +call ale#linter#Define('javascript', { +\ 'name': 'biome', +\ 'lsp': 'stdio', +\ 'language': function('ale#handlers#biome#GetLanguage'), +\ 'executable': function('ale#handlers#biome#GetExecutable'), +\ 'command': '%e lsp-proxy', +\ 'project_root': function('ale#handlers#biome#GetProjectRoot'), +\}) diff --git a/sources_non_forked/ale/ale_linters/json/biome.vim b/sources_non_forked/ale/ale_linters/json/biome.vim new file mode 100644 index 00000000..086ee44a --- /dev/null +++ b/sources_non_forked/ale/ale_linters/json/biome.vim @@ -0,0 +1,10 @@ +" Description: biome for json files + +call ale#linter#Define('json', { +\ 'name': 'biome', +\ 'lsp': 'stdio', +\ 'language': function('ale#handlers#biome#GetLanguage'), +\ 'executable': function('ale#handlers#biome#GetExecutable'), +\ 'command': '%e lsp-proxy', +\ 'project_root': function('ale#handlers#biome#GetProjectRoot'), +\}) diff --git a/sources_non_forked/ale/ale_linters/jsonc/biome.vim b/sources_non_forked/ale/ale_linters/jsonc/biome.vim new file mode 100644 index 00000000..5a691093 --- /dev/null +++ b/sources_non_forked/ale/ale_linters/jsonc/biome.vim @@ -0,0 +1,10 @@ +" Description: biome for jsonc files + +call ale#linter#Define('jsonc', { +\ 'name': 'biome', +\ 'lsp': 'stdio', +\ 'language': function('ale#handlers#biome#GetLanguage'), +\ 'executable': function('ale#handlers#biome#GetExecutable'), +\ 'command': '%e lsp-proxy', +\ 'project_root': function('ale#handlers#biome#GetProjectRoot'), +\}) diff --git a/sources_non_forked/ale/ale_linters/less/stylelint.vim b/sources_non_forked/ale/ale_linters/less/stylelint.vim index 83f784c4..9430fe9b 100644 --- a/sources_non_forked/ale/ale_linters/less/stylelint.vim +++ b/sources_non_forked/ale/ale_linters/less/stylelint.vim @@ -12,6 +12,7 @@ endfunction call ale#linter#Define('less', { \ 'name': 'stylelint', +\ 'output_stream': 'both', \ 'executable': {b -> ale#path#FindExecutable(b, 'less_stylelint', [ \ 'node_modules/.bin/stylelint', \ ])}, diff --git a/sources_non_forked/ale/ale_linters/odin/ols.vim b/sources_non_forked/ale/ale_linters/odin/ols.vim new file mode 100644 index 00000000..242dea0e --- /dev/null +++ b/sources_non_forked/ale/ale_linters/odin/ols.vim @@ -0,0 +1,19 @@ +" Author: Benjamin Block +" Description: A language server for Odin. + +function! ale_linters#odin#ols#GetProjectRoot(buffer) abort + return fnamemodify('', ':h') +endfunction + +call ale#Set('odin_ols_executable', 'ols') +call ale#Set('odin_ols_config', {}) + +call ale#linter#Define('odin', { +\ 'name': 'ols', +\ 'lsp': 'stdio', +\ 'language': 'odin', +\ 'lsp_config': {b -> ale#Var(b, 'odin_ols_config')}, +\ 'executable': {b -> ale#Var(b, 'odin_ols_executable')}, +\ 'command': '%e', +\ 'project_root': function('ale_linters#odin#ols#GetProjectRoot'), +\}) diff --git a/sources_non_forked/ale/ale_linters/php/phpstan.vim b/sources_non_forked/ale/ale_linters/php/phpstan.vim index b0d2a8d3..a0942530 100644 --- a/sources_non_forked/ale/ale_linters/php/phpstan.vim +++ b/sources_non_forked/ale/ale_linters/php/phpstan.vim @@ -57,12 +57,14 @@ function! ale_linters#php#phpstan#Handle(buffer, lines) abort return l:output endif - for l:err in l:res.files[expand('#' . a:buffer .':p')].messages - call add(l:output, { - \ 'lnum': l:err.line, - \ 'text': l:err.message, - \ 'type': 'E', - \}) + for l:key in keys(l:res.files) + for l:err in l:res.files[l:key].messages + call add(l:output, { + \ 'lnum': l:err.line, + \ 'text': l:err.message, + \ 'type': 'E', + \}) + endfor endfor return l:output diff --git a/sources_non_forked/ale/ale_linters/python/bandit.vim b/sources_non_forked/ale/ale_linters/python/bandit.vim index 9cfca7c0..ba48c3a8 100644 --- a/sources_non_forked/ale/ale_linters/python/bandit.vim +++ b/sources_non_forked/ale/ale_linters/python/bandit.vim @@ -7,6 +7,7 @@ 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_auto_pipenv', 0) call ale#Set('python_bandit_auto_poetry', 0) +call ale#Set('python_bandit_auto_uv', 0) function! ale_linters#python#bandit#GetExecutable(buffer) abort if ( @@ -23,6 +24,11 @@ function! ale_linters#python#bandit#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_bandit_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_bandit', ['bandit']) endfunction @@ -39,7 +45,7 @@ function! ale_linters#python#bandit#GetCommand(buffer) abort endif endif - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run bandit' \ : '' diff --git a/sources_non_forked/ale/ale_linters/python/flake8.vim b/sources_non_forked/ale/ale_linters/python/flake8.vim index 9950614a..12dca84a 100644 --- a/sources_non_forked/ale/ale_linters/python/flake8.vim +++ b/sources_non_forked/ale/ale_linters/python/flake8.vim @@ -7,6 +7,7 @@ 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_auto_pipenv', 0) call ale#Set('python_flake8_auto_poetry', 0) +call ale#Set('python_flake8_auto_uv', 0) function! s:UsingModule(buffer) abort return ale#Var(a:buffer, 'python_flake8_options') =~# ' *-m flake8' @@ -23,6 +24,11 @@ function! ale_linters#python#flake8#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_flake8_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + if !s:UsingModule(a:buffer) return ale#python#FindExecutable(a:buffer, 'python_flake8', ['flake8']) endif @@ -68,7 +74,7 @@ endfunction function! ale_linters#python#flake8#GetCommand(buffer, version) abort let l:executable = ale_linters#python#flake8#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run flake8' \ : '' diff --git a/sources_non_forked/ale/ale_linters/python/flakehell.vim b/sources_non_forked/ale/ale_linters/python/flakehell.vim index ffe87e29..9ff0f18f 100644 --- a/sources_non_forked/ale/ale_linters/python/flakehell.vim +++ b/sources_non_forked/ale/ale_linters/python/flakehell.vim @@ -7,6 +7,7 @@ call ale#Set('python_flakehell_use_global', get(g:, 'ale_use_global_executables' call ale#Set('python_flakehell_change_directory', 'project') call ale#Set('python_flakehell_auto_pipenv', 0) call ale#Set('python_flakehell_auto_poetry', 0) +call ale#Set('python_flakehell_auto_uv', 0) function! s:UsingModule(buffer) abort return ale#Var(a:buffer, 'python_flakehell_executable') is? 'python' @@ -23,6 +24,11 @@ function! ale_linters#python#flakehell#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_flakehell_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + if !s:UsingModule(a:buffer) return ale#python#FindExecutable(a:buffer, 'python_flakehell', ['flakehell']) endif @@ -68,7 +74,7 @@ endfunction function! ale_linters#python#flakehell#GetCommand(buffer, version) abort let l:executable = ale_linters#python#flakehell#GetExecutable(a:buffer) - if (l:executable =~? 'pipenv\|poetry$') + if (l:executable =~? 'pipenv\|poetry\|uv$') let l:exec_args = ' run flakehell' elseif (l:executable is? 'python') let l:exec_args = ' -m flakehell' diff --git a/sources_non_forked/ale/ale_linters/python/jedils.vim b/sources_non_forked/ale/ale_linters/python/jedils.vim index e82abd1b..46b2896b 100644 --- a/sources_non_forked/ale/ale_linters/python/jedils.vim +++ b/sources_non_forked/ale/ale_linters/python/jedils.vim @@ -4,6 +4,8 @@ call ale#Set('python_jedils_executable', 'jedi-language-server') call ale#Set('python_jedils_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_jedils_auto_pipenv', 0) +call ale#Set('python_jedils_auto_poetry', 0) +call ale#Set('python_jedils_auto_uv', 0) function! ale_linters#python#jedils#GetExecutable(buffer) abort if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_jedils_auto_pipenv')) @@ -11,12 +13,22 @@ function! ale_linters#python#jedils#GetExecutable(buffer) abort return 'pipenv' endif + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_jedils_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_jedils_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_jedils', ['jedi-language-server']) endfunction function! ale_linters#python#jedils#GetCommand(buffer) abort let l:executable = ale_linters#python#jedils#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run jedi-language-server' \ : '' let l:env_string = '' diff --git a/sources_non_forked/ale/ale_linters/python/mypy.vim b/sources_non_forked/ale/ale_linters/python/mypy.vim index 9d469a1a..586a4381 100644 --- a/sources_non_forked/ale/ale_linters/python/mypy.vim +++ b/sources_non_forked/ale/ale_linters/python/mypy.vim @@ -8,6 +8,7 @@ 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_auto_pipenv', 0) call ale#Set('python_mypy_auto_poetry', 0) +call ale#Set('python_mypy_auto_uv', 0) function! ale_linters#python#mypy#GetExecutable(buffer) abort if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_mypy_auto_pipenv')) @@ -20,6 +21,11 @@ function! ale_linters#python#mypy#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_mypy_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_mypy', ['mypy']) endfunction @@ -43,7 +49,7 @@ endfunction function! ale_linters#python#mypy#GetCommand(buffer) abort let l:executable = ale_linters#python#mypy#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run mypy' \ : '' diff --git a/sources_non_forked/ale/ale_linters/python/prospector.vim b/sources_non_forked/ale/ale_linters/python/prospector.vim index 3623bda0..c40f25c5 100644 --- a/sources_non_forked/ale/ale_linters/python/prospector.vim +++ b/sources_non_forked/ale/ale_linters/python/prospector.vim @@ -3,6 +3,7 @@ call ale#Set('python_prospector_auto_pipenv', 0) call ale#Set('python_prospector_auto_poetry', 0) +call ale#Set('python_prospector_auto_uv', 0) let g:ale_python_prospector_executable = \ get(g:, 'ale_python_prospector_executable', 'prospector') @@ -23,13 +24,18 @@ function! ale_linters#python#prospector#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_prospector_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_prospector', ['prospector']) endfunction function! ale_linters#python#prospector#GetCommand(buffer) abort let l:executable = ale_linters#python#prospector#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run prospector' \ : '' diff --git a/sources_non_forked/ale/ale_linters/python/pycln.vim b/sources_non_forked/ale/ale_linters/python/pycln.vim index 917a9757..774c6b04 100644 --- a/sources_non_forked/ale/ale_linters/python/pycln.vim +++ b/sources_non_forked/ale/ale_linters/python/pycln.vim @@ -7,6 +7,7 @@ call ale#Set('python_pycln_use_global', get(g:, 'ale_use_global_executables', 0) call ale#Set('python_pycln_change_directory', 1) call ale#Set('python_pycln_auto_pipenv', 0) call ale#Set('python_pycln_auto_poetry', 0) +call ale#Set('python_pycln_auto_uv', 0) call ale#Set('python_pycln_config_file', '') function! ale_linters#python#pycln#GetExecutable(buffer) abort @@ -20,6 +21,11 @@ function! ale_linters#python#pycln#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_pycln_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_pycln', ['pycln']) endfunction @@ -36,7 +42,7 @@ endfunction function! ale_linters#python#pycln#GetCommand(buffer, version) abort let l:executable = ale_linters#python#pycln#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run pycln' \ : '' diff --git a/sources_non_forked/ale/ale_linters/python/pycodestyle.vim b/sources_non_forked/ale/ale_linters/python/pycodestyle.vim index 3fb94d69..bd3584b8 100644 --- a/sources_non_forked/ale/ale_linters/python/pycodestyle.vim +++ b/sources_non_forked/ale/ale_linters/python/pycodestyle.vim @@ -6,6 +6,7 @@ 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_auto_pipenv', 0) call ale#Set('python_pycodestyle_auto_poetry', 0) +call ale#Set('python_pycodestyle_auto_uv', 0) function! ale_linters#python#pycodestyle#GetExecutable(buffer) abort if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pycodestyle_auto_pipenv')) @@ -18,13 +19,18 @@ function! ale_linters#python#pycodestyle#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_pycodestyle_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_pycodestyle', ['pycodestyle']) endfunction function! ale_linters#python#pycodestyle#GetCommand(buffer) abort let l:executable = ale_linters#python#pycodestyle#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run pycodestyle' \ : '' diff --git a/sources_non_forked/ale/ale_linters/python/pydocstyle.vim b/sources_non_forked/ale/ale_linters/python/pydocstyle.vim index ef0d818c..b012dd43 100644 --- a/sources_non_forked/ale/ale_linters/python/pydocstyle.vim +++ b/sources_non_forked/ale/ale_linters/python/pydocstyle.vim @@ -6,6 +6,7 @@ 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_auto_pipenv', 0) call ale#Set('python_pydocstyle_auto_poetry', 0) +call ale#Set('python_pydocstyle_auto_uv', 0) function! ale_linters#python#pydocstyle#GetExecutable(buffer) abort if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pydocstyle_auto_pipenv')) @@ -18,12 +19,17 @@ function! ale_linters#python#pydocstyle#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_pydocstyle_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_pydocstyle', ['pydocstyle']) endfunction function! ale_linters#python#pydocstyle#GetCommand(buffer) abort let l:executable = ale_linters#python#pydocstyle#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run pydocstyle' \ : '' diff --git a/sources_non_forked/ale/ale_linters/python/pyflakes.vim b/sources_non_forked/ale/ale_linters/python/pyflakes.vim index 2567c533..fc0a3fa7 100644 --- a/sources_non_forked/ale/ale_linters/python/pyflakes.vim +++ b/sources_non_forked/ale/ale_linters/python/pyflakes.vim @@ -5,6 +5,7 @@ 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_auto_pipenv', 0) call ale#Set('python_pyflakes_auto_poetry', 0) +call ale#Set('python_pyflakes_auto_uv', 0) function! ale_linters#python#pyflakes#GetExecutable(buffer) abort if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pyflakes_auto_pipenv')) @@ -17,13 +18,18 @@ function! ale_linters#python#pyflakes#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_pyflakes_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_pyflakes', ['pyflakes']) endfunction function! ale_linters#python#pyflakes#GetCommand(buffer) abort let l:executable = ale_linters#python#pyflakes#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run pyflakes' \ : '' diff --git a/sources_non_forked/ale/ale_linters/python/pylama.vim b/sources_non_forked/ale/ale_linters/python/pylama.vim index 14f8071a..6555b409 100644 --- a/sources_non_forked/ale/ale_linters/python/pylama.vim +++ b/sources_non_forked/ale/ale_linters/python/pylama.vim @@ -6,6 +6,7 @@ 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_auto_pipenv', 0) call ale#Set('python_pylama_auto_poetry', 0) +call ale#Set('python_pylama_auto_uv', 0) call ale#Set('python_pylama_change_directory', 1) function! ale_linters#python#pylama#GetExecutable(buffer) abort @@ -19,12 +20,17 @@ function! ale_linters#python#pylama#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_pylama_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_pylama', ['pylama']) endfunction function! ale_linters#python#pylama#RunWithVersionCheck(buffer) abort let l:executable = ale_linters#python#pylama#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run pylama' \ : '' @@ -53,7 +59,7 @@ endfunction function! ale_linters#python#pylama#GetCommand(buffer, version) abort let l:executable = ale_linters#python#pylama#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run pylama' \ : '' diff --git a/sources_non_forked/ale/ale_linters/python/pylint.vim b/sources_non_forked/ale/ale_linters/python/pylint.vim index 2ce5376f..90aa5f1c 100644 --- a/sources_non_forked/ale/ale_linters/python/pylint.vim +++ b/sources_non_forked/ale/ale_linters/python/pylint.vim @@ -7,6 +7,7 @@ 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_auto_pipenv', 0) call ale#Set('python_pylint_auto_poetry', 0) +call ale#Set('python_pylint_auto_uv', 0) call ale#Set('python_pylint_use_msg_id', 0) function! ale_linters#python#pylint#GetExecutable(buffer) abort @@ -20,6 +21,11 @@ function! ale_linters#python#pylint#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_pylint_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_pylint', ['pylint']) endfunction @@ -38,7 +44,7 @@ endfunction function! ale_linters#python#pylint#GetCommand(buffer, version) abort let l:executable = ale_linters#python#pylint#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run pylint' \ : '' diff --git a/sources_non_forked/ale/ale_linters/python/pylsp.vim b/sources_non_forked/ale/ale_linters/python/pylsp.vim index a1c31018..d3db6e82 100644 --- a/sources_non_forked/ale/ale_linters/python/pylsp.vim +++ b/sources_non_forked/ale/ale_linters/python/pylsp.vim @@ -6,6 +6,7 @@ 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_auto_uv', 0) call ale#Set('python_pylsp_config', {}) function! ale_linters#python#pylsp#GetExecutable(buffer) abort @@ -19,6 +20,11 @@ function! ale_linters#python#pylsp#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_pylsp_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_pylsp', ['pylsp']) endfunction @@ -37,7 +43,7 @@ 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$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run pylsp' \ : '' let l:env_string = '' diff --git a/sources_non_forked/ale/ale_linters/python/pyre.vim b/sources_non_forked/ale/ale_linters/python/pyre.vim index 5e5786f9..177f1cb5 100644 --- a/sources_non_forked/ale/ale_linters/python/pyre.vim +++ b/sources_non_forked/ale/ale_linters/python/pyre.vim @@ -5,6 +5,7 @@ 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_auto_pipenv', 0) call ale#Set('python_pyre_auto_poetry', 0) +call ale#Set('python_pyre_auto_uv', 0) function! ale_linters#python#pyre#GetExecutable(buffer) abort if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pyre_auto_pipenv')) @@ -17,12 +18,17 @@ function! ale_linters#python#pyre#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_pyre_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_pyre', ['pyre']) endfunction function! ale_linters#python#pyre#GetCommand(buffer) abort let l:executable = ale_linters#python#pyre#GetExecutable(a:buffer) - let l:exec_args = (l:executable =~? 'pipenv\|poetry$' ? ' run pyre' : '') . ' persistent' + let l:exec_args = (l:executable =~? 'pipenv\|poetry\|uv$' ? ' run pyre' : '') . ' persistent' return ale#Escape(l:executable) . l:exec_args endfunction diff --git a/sources_non_forked/ale/ale_linters/python/pyright.vim b/sources_non_forked/ale/ale_linters/python/pyright.vim index e41f7f14..993ed075 100644 --- a/sources_non_forked/ale/ale_linters/python/pyright.vim +++ b/sources_non_forked/ale/ale_linters/python/pyright.vim @@ -3,6 +3,7 @@ call ale#Set('python_pyright_executable', 'pyright-langserver') call ale#Set('python_pyright_config', {}) call ale#Set('python_pyright_auto_pipenv', 0) call ale#Set('python_pyright_auto_poetry', 0) +call ale#Set('python_pyright_auto_uv', 0) " Force the cwd of the server to be the same as the project root to " fix issues with treating local files matching first or third party library @@ -59,12 +60,17 @@ function! ale_linters#python#pyright#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_pyright_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_pyright', ['pyright-langserver']) endfunction function! ale_linters#python#pyright#GetCommand(buffer) abort let l:executable = ale_linters#python#pyright#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run pyright-langserver' \ : '' let l:env_string = '' diff --git a/sources_non_forked/ale/ale_linters/python/refurb.vim b/sources_non_forked/ale/ale_linters/python/refurb.vim index 1ae77b77..7f92948a 100644 --- a/sources_non_forked/ale/ale_linters/python/refurb.vim +++ b/sources_non_forked/ale/ale_linters/python/refurb.vim @@ -7,6 +7,7 @@ call ale#Set('python_refurb_use_global', get(g:, 'ale_use_global_executables', 0 call ale#Set('python_refurb_change_directory', 1) call ale#Set('python_refurb_auto_pipenv', 0) call ale#Set('python_refurb_auto_poetry', 0) +call ale#Set('python_refurb_auto_uv', 0) function! ale_linters#python#refurb#GetExecutable(buffer) abort if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_refurb_auto_pipenv')) @@ -19,6 +20,11 @@ function! ale_linters#python#refurb#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_refurb_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_refurb', ['refurb']) endfunction @@ -35,7 +41,7 @@ endfunction function! ale_linters#python#refurb#GetCommand(buffer) abort let l:executable = ale_linters#python#refurb#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run refurb' \ : '' diff --git a/sources_non_forked/ale/ale_linters/python/ruff.vim b/sources_non_forked/ale/ale_linters/python/ruff.vim index c4f8ad1b..25ae2d91 100644 --- a/sources_non_forked/ale/ale_linters/python/ruff.vim +++ b/sources_non_forked/ale/ale_linters/python/ruff.vim @@ -7,6 +7,7 @@ call ale#Set('python_ruff_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_ruff_change_directory', 1) call ale#Set('python_ruff_auto_pipenv', 0) call ale#Set('python_ruff_auto_poetry', 0) +call ale#Set('python_ruff_auto_uv', 0) call ale#fix#registry#Add('ruff', \ 'ale#fixers#ruff#Fix', @@ -25,6 +26,11 @@ function! ale_linters#python#ruff#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_ruff_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_ruff', ['ruff']) endfunction @@ -41,13 +47,18 @@ endfunction function! ale_linters#python#ruff#GetCommand(buffer, version) abort let l:executable = ale_linters#python#ruff#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run ruff' \ : '' - " NOTE: ruff version `0.0.69` supports liniting input from stdin + " NOTE: ruff 0.3.0 deprecates `ruff ` in favor of `ruff check ` + let l:exec_args = l:exec_args + \ . (ale#semver#GTE(a:version, [0, 3, 0]) ? ' check' : '') + + " NOTE: ruff version `0.0.69` supports linting input from stdin " NOTE: ruff version `0.1.0` deprecates `--format text` return ale#Escape(l:executable) . l:exec_args . ' -q' + \ . ' --no-fix' \ . ale#Pad(ale#Var(a:buffer, 'python_ruff_options')) \ . (ale#semver#GTE(a:version, [0, 1, 0]) ? ' --output-format json-lines' : ' --format json-lines') \ . (ale#semver#GTE(a:version, [0, 0, 69]) ? ' --stdin-filename %s -' : ' %s') @@ -56,17 +67,25 @@ endfunction function! ale_linters#python#ruff#Handle(buffer, lines) abort let l:output = [] + " Read all lines of ruff output and parse use all the valid JSONL lines. for l:line in a:lines - let l:item = json_decode(l:line) - call add(l:output, { - \ 'lnum': l:item.location.row, - \ 'col': l:item.location.column, - \ 'end_lnum': l:item.end_location.row, - \ 'end_col': l:item.end_location.column - 1, - \ 'code': l:item.code, - \ 'text': l:item.message, - \ 'type': l:item.code =~? '\vE\d+' ? 'E' : 'W', - \}) + try + let l:item = json_decode(l:line) + catch + let l:item = v:null + endtry + + if !empty(l:item) + call add(l:output, { + \ 'lnum': l:item.location.row, + \ 'col': l:item.location.column, + \ 'end_lnum': l:item.end_location.row, + \ 'end_col': l:item.end_location.column - 1, + \ 'code': l:item.code, + \ 'text': l:item.message, + \ 'type': l:item.code =~? '\vE\d+' ? 'E' : 'W', + \}) + endif endfor return l:output diff --git a/sources_non_forked/ale/ale_linters/python/unimport.vim b/sources_non_forked/ale/ale_linters/python/unimport.vim index 71fd80f0..06dbc436 100644 --- a/sources_non_forked/ale/ale_linters/python/unimport.vim +++ b/sources_non_forked/ale/ale_linters/python/unimport.vim @@ -5,6 +5,7 @@ call ale#Set('python_unimport_options', '') call ale#Set('python_unimport_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_unimport_auto_pipenv', 0) call ale#Set('python_unimport_auto_poetry', 0) +call ale#Set('python_unimport_auto_uv', 0) function! ale_linters#python#unimport#GetExecutable(buffer) abort if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_unimport_auto_pipenv')) @@ -17,12 +18,17 @@ function! ale_linters#python#unimport#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_unimport_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_unimport', ['unimport']) endfunction function! ale_linters#python#unimport#GetCommand(buffer) abort let l:executable = ale_linters#python#unimport#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run unimport' \ : '' diff --git a/sources_non_forked/ale/ale_linters/python/vulture.vim b/sources_non_forked/ale/ale_linters/python/vulture.vim index a7ba1860..2ac05e43 100644 --- a/sources_non_forked/ale/ale_linters/python/vulture.vim +++ b/sources_non_forked/ale/ale_linters/python/vulture.vim @@ -5,6 +5,9 @@ call ale#Set('python_vulture_executable', 'vulture') call ale#Set('python_vulture_options', '') call ale#Set('python_vulture_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_vulture_change_directory', 1) +call ale#Set('python_vulture_auto_pipenv', 0) +call ale#Set('python_vulture_auto_poetry', 0) +call ale#Set('python_vulture_auto_uv', 0) " The directory to change to before running vulture function! s:GetDir(buffer) abort @@ -16,6 +19,21 @@ function! s:GetDir(buffer) abort endfunction function! ale_linters#python#vulture#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_vulture_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_vulture_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_vulture_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_vulture', ['vulture']) endfunction @@ -29,7 +47,7 @@ endfunction function! ale_linters#python#vulture#GetCommand(buffer) abort let l:executable = ale_linters#python#vulture#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run vulture' \ : '' let l:lint_dest = ale#Var(a:buffer, 'python_vulture_change_directory') diff --git a/sources_non_forked/ale/ale_linters/ruby/steep.vim b/sources_non_forked/ale/ale_linters/ruby/steep.vim new file mode 100644 index 00000000..4fd52620 --- /dev/null +++ b/sources_non_forked/ale/ale_linters/ruby/steep.vim @@ -0,0 +1,172 @@ +call ale#Set('ruby_steep_executable', 'steep') +call ale#Set('ruby_steep_options', '') + +" Find the nearest dir containing a Steepfile +function! ale_linters#ruby#steep#FindRoot(buffer) abort + for l:name in ['Steepfile'] + let l:dir = fnamemodify( + \ ale#path#FindNearestFile(a:buffer, l:name), + \ ':h' + \) + + if l:dir isnot# '.' && isdirectory(l:dir) + return l:dir + endif + endfor + + return '' +endfunction + +" Rename path relative to root +function! ale_linters#ruby#steep#RelativeToRoot(buffer, path) abort + let l:separator = has('win32') ? '\' : '/' + let l:steep_root = ale_linters#ruby#steep#FindRoot(a:buffer) + + " path isn't under root + if l:steep_root is# '' + return '' + endif + + let l:steep_root_prefix = l:steep_root . l:separator + + " win32 path separators get interpreted by substitute, escape them + if has('win32') + let l:steep_root_pat = substitute(l:steep_root_prefix, '\\', '\\\\', 'g') + else + let l:steep_root_pat = l:steep_root_prefix + endif + + return substitute(a:path, l:steep_root_pat, '', '') +endfunction + +function! ale_linters#ruby#steep#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'ruby_steep_executable') + + " steep check needs to apply some config from the file path so: + " - steep check can't use stdin (no path) + " - steep check can't use %t (path outside of project) + " => we can only use %s + + " somehow :ALEInfo shows that ALE still appends '< %t' to the command + " => luckily steep check ignores stdin + + " somehow steep has a problem with absolute path to file but a path + " relative to Steepfile directory works: + " see https://github.com/soutaro/steep/pull/975 + " => change to Steepfile directory and remove leading path + + let l:buffer_filename = fnamemodify(bufname(a:buffer), ':p') + let l:buffer_filename = fnameescape(l:buffer_filename) + + let l:relative = ale_linters#ruby#steep#RelativeToRoot(a:buffer, l:buffer_filename) + + " if file is not under steep root, steep can't type check + if l:relative is# '' + " don't execute + return '' + endif + + return ale#ruby#EscapeExecutable(l:executable, 'steep') + \ . ' check ' + \ . ale#Var(a:buffer, 'ruby_steep_options') + \ . ' ' . fnameescape(l:relative) +endfunction + +function! ale_linters#ruby#steep#GetType(severity) abort + if a:severity is? 'information' + \|| a:severity is? 'hint' + return 'I' + endif + + if a:severity is? 'warning' + return 'W' + endif + + return 'E' +endfunction + +" Handle output from steep +function! ale_linters#ruby#steep#HandleOutput(buffer, lines) abort + let l:output = [] + + let l:in = 0 + let l:item = {} + + for l:line in a:lines + " Look for first line of a message block + " If not in-message (l:in == 0) that's expected + " If in-message (l:in > 0) that's less expected but let's recover + let l:match = matchlist(l:line, '^\([^:]*\):\([0-9]*\):\([0-9]*\): \[\([^]]*\)\] \(.*\)') + + if len(l:match) > 0 + " Something is lingering: recover by pushing what is there + if len(l:item) > 0 + call add(l:output, l:item) + let l:item = {} + endif + + let l:filename = l:match[1] + + " Steep's reported column is offset by 1 (zero-indexed?) + let l:item = { + \ 'lnum': l:match[2] + 0, + \ 'col': l:match[3] + 1, + \ 'type': ale_linters#ruby#steep#GetType(l:match[4]), + \ 'text': l:match[5], + \} + + " Done with this line, mark being in-message and go on with next line + let l:in = 1 + continue + endif + + " We're past the first line of a message block + if l:in > 0 + " Look for code in subsequent lines of the message block + if l:line =~# '^│ Diagnostic ID:' + let l:match = matchlist(l:line, '^│ Diagnostic ID: \(.*\)') + + if len(l:match) > 0 + let l:item.code = l:match[1] + endif + + " Done with the line + continue + endif + + " Look for last line of the message block + if l:line =~# '^└' + " Done with the line, mark looking for underline and go on with the next line + let l:in = 2 + continue + endif + + " Look for underline right after last line + if l:in == 2 + let l:match = matchlist(l:line, '\([~][~]*\)') + + if len(l:match) > 0 + let l:item.end_col = l:item['col'] + len(l:match[1]) - 1 + endif + + call add(l:output, l:item) + + " Done with the line, mark looking for first line and go on with the next line + let l:in = 0 + let l:item = {} + continue + endif + endif + endfor + + return l:output +endfunction + +call ale#linter#Define('ruby', { +\ 'name': 'steep', +\ 'executable': {b -> ale#Var(b, 'ruby_steep_executable')}, +\ 'language': 'ruby', +\ 'command': function('ale_linters#ruby#steep#GetCommand'), +\ 'project_root': function('ale_linters#ruby#steep#FindRoot'), +\ 'callback': 'ale_linters#ruby#steep#HandleOutput', +\}) diff --git a/sources_non_forked/ale/ale_linters/sass/stylelint.vim b/sources_non_forked/ale/ale_linters/sass/stylelint.vim index 22abef9b..651d7fd5 100644 --- a/sources_non_forked/ale/ale_linters/sass/stylelint.vim +++ b/sources_non_forked/ale/ale_linters/sass/stylelint.vim @@ -5,6 +5,7 @@ call ale#Set('sass_stylelint_use_global', get(g:, 'ale_use_global_executables', call ale#linter#Define('sass', { \ 'name': 'stylelint', +\ 'output_stream': 'both', \ 'executable': {b -> ale#path#FindExecutable(b, 'sass_stylelint', [ \ 'node_modules/.bin/stylelint', \ ])}, diff --git a/sources_non_forked/ale/ale_linters/scss/stylelint.vim b/sources_non_forked/ale/ale_linters/scss/stylelint.vim index fea4ea8f..4f82a98a 100644 --- a/sources_non_forked/ale/ale_linters/scss/stylelint.vim +++ b/sources_non_forked/ale/ale_linters/scss/stylelint.vim @@ -11,6 +11,7 @@ endfunction call ale#linter#Define('scss', { \ 'name': 'stylelint', +\ 'output_stream': 'both', \ 'executable': {b -> ale#path#FindExecutable(b, 'scss_stylelint', [ \ 'node_modules/.bin/stylelint', \ ])}, diff --git a/sources_non_forked/ale/ale_linters/sql/sqlfluff.vim b/sources_non_forked/ale/ale_linters/sql/sqlfluff.vim index 0ec062bd..4381e1ab 100644 --- a/sources_non_forked/ale/ale_linters/sql/sqlfluff.vim +++ b/sources_non_forked/ale/ale_linters/sql/sqlfluff.vim @@ -11,7 +11,7 @@ function! ale_linters#sql#sqlfluff#Executable(buffer) abort return ale#Var(a:buffer, 'sql_sqlfluff_executable') endfunction -function! ale_linters#sql#sqlfluff#Command(buffer) abort +function! ale_linters#sql#sqlfluff#Command(buffer, version) abort let l:executable = ale_linters#sql#sqlfluff#Executable(a:buffer) let l:options = ale#Var(a:buffer, 'sql_sqlfluff_options') @@ -35,7 +35,7 @@ function! ale_linters#sql#sqlfluff#Command(buffer) abort return l:cmd endfunction -function! ale_linters#sql#sqlfluff#Handle(buffer, lines) abort +function! ale_linters#sql#sqlfluff#Handle(buffer, version, lines) abort let l:output = [] let l:json_lines = ale#util#FuzzyJSONDecode(a:lines, []) @@ -50,16 +50,31 @@ function! ale_linters#sql#sqlfluff#Handle(buffer, lines) abort return l:output endif - for l:violation in get(l:json, 'violations', []) - call add(l:output, { - \ 'filename': l:json.filepath, - \ 'lnum': l:violation.line_no, - \ 'col': l:violation.line_pos, - \ 'text': l:violation.description, - \ 'code': l:violation.code, - \ 'type': 'W', - \}) - endfor + if ale#semver#GTE(a:version, [3, 0, 0]) + for l:violation in get(l:json, 'violations', []) + call add(l:output, { + \ 'filename': l:json.filepath, + \ 'lnum': l:violation.start_line_no, + \ 'end_lnum': l:violation.end_line_no, + \ 'col': l:violation.start_line_pos, + \ 'end_col': l:violation.end_line_pos, + \ 'text': l:violation.description, + \ 'code': l:violation.code, + \ 'type': 'W', + \}) + endfor + else + for l:violation in get(l:json, 'violations', []) + call add(l:output, { + \ 'filename': l:json.filepath, + \ 'lnum': l:violation.line_no, + \ 'col': l:violation.line_pos, + \ 'text': l:violation.description, + \ 'code': l:violation.code, + \ 'type': 'W', + \}) + endfor + endif return l:output endfunction @@ -67,6 +82,19 @@ endfunction call ale#linter#Define('sql', { \ 'name': 'sqlfluff', \ 'executable': function('ale_linters#sql#sqlfluff#Executable'), -\ 'command': function('ale_linters#sql#sqlfluff#Command'), -\ 'callback': 'ale_linters#sql#sqlfluff#Handle', +\ 'command': {buffer -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale_linters#sql#sqlfluff#Executable(buffer), +\ '%e --version', +\ function('ale_linters#sql#sqlfluff#Command'), +\ )}, +\ 'callback': {buffer, lines -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale_linters#sql#sqlfluff#Executable(buffer), +\ '%e --version', +\ {buffer, version -> ale_linters#sql#sqlfluff#Handle( +\ buffer, +\ l:version, +\ lines)}, +\ )}, \}) diff --git a/sources_non_forked/ale/ale_linters/stylus/stylelint.vim b/sources_non_forked/ale/ale_linters/stylus/stylelint.vim index b60e38ed..652e15d2 100644 --- a/sources_non_forked/ale/ale_linters/stylus/stylelint.vim +++ b/sources_non_forked/ale/ale_linters/stylus/stylelint.vim @@ -12,6 +12,7 @@ endfunction call ale#linter#Define('stylus', { \ 'name': 'stylelint', +\ 'output_stream': 'both', \ 'executable': {b -> ale#path#FindExecutable(b, 'stylus_stylelint', [ \ 'node_modules/.bin/stylelint', \ ])}, diff --git a/sources_non_forked/ale/ale_linters/sugarss/stylelint.vim b/sources_non_forked/ale/ale_linters/sugarss/stylelint.vim index 879ff0ca..a12191b8 100644 --- a/sources_non_forked/ale/ale_linters/sugarss/stylelint.vim +++ b/sources_non_forked/ale/ale_linters/sugarss/stylelint.vim @@ -13,6 +13,7 @@ endfunction call ale#linter#Define('sugarss', { \ 'name': 'stylelint', +\ 'output_stream': 'both', \ 'executable': {b -> ale#path#FindExecutable(b, 'sugarss_stylelint', [ \ 'node_modules/.bin/stylelint', \ ])}, diff --git a/sources_non_forked/ale/ale_linters/tex/chktex.vim b/sources_non_forked/ale/ale_linters/tex/chktex.vim index 160baf0d..9e7be587 100644 --- a/sources_non_forked/ale/ale_linters/tex/chktex.vim +++ b/sources_non_forked/ale/ale_linters/tex/chktex.vim @@ -1,29 +1,34 @@ " Author: Andrew Balmos - " Description: chktex for LaTeX files -let g:ale_tex_chktex_executable = -\ get(g:, 'ale_tex_chktex_executable', 'chktex') +call ale#Set('tex_chktex_executable', 'chktex') +call ale#Set('tex_chktex_options', '-I') -let g:ale_tex_chktex_options = -\ get(g:, 'ale_tex_chktex_options', '-I') +function! ale_linters#tex#chktex#GetExecutable(buffer) abort + return ale#Var(a:buffer, 'tex_chktex_executable') +endfunction -function! ale_linters#tex#chktex#GetCommand(buffer) abort - " Check for optional .chktexrc - let l:chktex_config = ale#path#FindNearestFile( - \ a:buffer, - \ '.chktexrc') +function! ale_linters#tex#chktex#GetCommand(buffer, version) abort + let l:options = '' - let l:command = ale#Var(a:buffer, 'tex_chktex_executable') " Avoid bug when used without -p (last warning has gibberish for a filename) - let l:command .= ' -v0 -p stdin -q' + let l:options .= ' -v0 -p stdin -q' - if !empty(l:chktex_config) - let l:command .= ' -l ' . ale#Escape(l:chktex_config) + " Avoid bug of reporting wrong column when using tabs (issue #723) + if ale#semver#GTE(a:version, [1, 7, 7]) + let l:options .= ' -S TabSize=1' endif - let l:command .= ' ' . ale#Var(a:buffer, 'tex_chktex_options') + " Check for optional .chktexrc + let l:chktex_config = ale#path#FindNearestFile(a:buffer, '.chktexrc') - return l:command + if !empty(l:chktex_config) + let l:options .= ' -l ' . ale#Escape(l:chktex_config) + endif + + let l:options .= ' ' . ale#Var(a:buffer, 'tex_chktex_options') + + return '%e' . l:options endfunction function! ale_linters#tex#chktex#Handle(buffer, lines) abort @@ -48,7 +53,12 @@ endfunction call ale#linter#Define('tex', { \ 'name': 'chktex', -\ 'executable': 'chktex', -\ 'command': function('ale_linters#tex#chktex#GetCommand'), +\ 'executable': function('ale_linters#tex#chktex#GetExecutable'), +\ 'command': {buffer -> ale#semver#RunWithVersionCheck( +\ buffer, +\ ale_linters#tex#chktex#GetExecutable(buffer), +\ '%e --version', +\ function('ale_linters#tex#chktex#GetCommand'), +\ )}, \ 'callback': 'ale_linters#tex#chktex#Handle' \}) diff --git a/sources_non_forked/ale/ale_linters/typescript/biome.vim b/sources_non_forked/ale/ale_linters/typescript/biome.vim new file mode 100644 index 00000000..1730da51 --- /dev/null +++ b/sources_non_forked/ale/ale_linters/typescript/biome.vim @@ -0,0 +1,11 @@ +" Author: Filip Gospodinov +" Description: biome for TypeScript files + +call ale#linter#Define('typescript', { +\ 'name': 'biome', +\ 'lsp': 'stdio', +\ 'language': function('ale#handlers#biome#GetLanguage'), +\ 'executable': function('ale#handlers#biome#GetExecutable'), +\ 'command': '%e lsp-proxy', +\ 'project_root': function('ale#handlers#biome#GetProjectRoot'), +\}) diff --git a/sources_non_forked/ale/ale_linters/verilog/slang.vim b/sources_non_forked/ale/ale_linters/verilog/slang.vim new file mode 100644 index 00000000..40299a34 --- /dev/null +++ b/sources_non_forked/ale/ale_linters/verilog/slang.vim @@ -0,0 +1,53 @@ +" Author: Alvin Rolling +" Description: slang for verilog files + +" Set this option to change Slang lint options +if !exists('g:ale_verilog_slang_options') + let g:ale_verilog_slang_options = '' +endif + +" --lint-only +function! ale_linters#verilog#slang#GetCommand(buffer) abort + return 'slang -Weverything ' + \ . '-I%s:h ' + \ . ale#Var(a:buffer, 'verilog_slang_options') .' ' + \ . '%t' +endfunction + +function! s:RemoveUnicodeQuotes(text) abort + let l:text = a:text + let l:text = substitute(l:text, '[`´‘’]', '''', 'g') + let l:text = substitute(l:text, '[“”]', '"', 'g') + + return l:text +endfunction + +function! ale_linters#verilog#slang#Handle(buffer, lines) abort + let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+)?:?(\d+)?:? ([^:]+): (.+)$' + let l:output = [] + + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:item = { + \ 'lnum': str2nr(l:match[2]), + \ 'type': (l:match[4] is# 'error') ? 'E' : 'W', + \ 'text': s:RemoveUnicodeQuotes(l:match[5]), + \} + + if !empty(l:match[3]) + let l:item.col = str2nr(l:match[3]) + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +call ale#linter#Define('verilog', { +\ 'name': 'slang', +\ 'output_stream': 'stderr', +\ 'executable': 'slang', +\ 'command': function('ale_linters#verilog#slang#GetCommand'), +\ 'callback': 'ale_linters#verilog#slang#Handle', +\ 'read_buffer': 0, +\}) diff --git a/sources_non_forked/ale/ale_linters/yaml/actionlint.vim b/sources_non_forked/ale/ale_linters/yaml/actionlint.vim index 75fe3162..5afe6d48 100644 --- a/sources_non_forked/ale/ale_linters/yaml/actionlint.vim +++ b/sources_non_forked/ale/ale_linters/yaml/actionlint.vim @@ -5,6 +5,11 @@ call ale#Set('yaml_actionlint_executable', 'actionlint') call ale#Set('yaml_actionlint_options', '') function! ale_linters#yaml#actionlint#GetCommand(buffer) abort + " Only execute actionlint on YAML files in /.github/ paths. + if expand('#' . a:buffer . ':p') !~# '\v[/\\]\.github[/\\]' + return '' + endif + let l:options = ale#Var(a:buffer, 'yaml_actionlint_options') if l:options !~# '-no-color' @@ -15,21 +20,33 @@ function! ale_linters#yaml#actionlint#GetCommand(buffer) abort let l:options .= ale#Pad('-oneline') endif - return '%e' . ale#Pad(l:options) + return '%e' . ale#Pad(l:options) . ' - ' endfunction function! ale_linters#yaml#actionlint#Handle(buffer, lines) abort " Matches patterns line the following: ".github/workflows/main.yml:19:0: could not parse as YAML: yaml: line 19: mapping values are not allowed in this context [yaml-syntax] - let l:pattern = '\v^.*:(\d+):(\d+): (.+) \[(.+)\]$' + let l:pattern = '\v^.{-}:(\d+):(\d+): (.+) \[(.+)\]$' let l:output = [] + for l:match in ale#util#GetMatches(a:lines, l:pattern) + let l:code = l:match[4] + let l:text = l:match[3] + + " Handle sub-linter errors like the following: + "validate.yml:19:9: shellcheck reported issue in this script: SC2086:info:1:15: Double quote to prevent globbing and word splitting [shellcheck] + if l:code is# 'shellcheck' + let l:shellcheck_match = matchlist(l:text, '\v^.+: (SC\d{4}):.+:\d+:\d+: (.+)$') + let l:text = l:shellcheck_match[2] + let l:code = 'shellcheck ' . l:shellcheck_match[1] + endif + let l:item = { \ 'lnum': l:match[1] + 0, \ 'col': l:match[2] + 0, - \ 'text': l:match[3], - \ 'code': l:match[4], + \ 'text': l:text, + \ 'code': l:code, \ 'type': 'E', \} diff --git a/sources_non_forked/ale/autoload/ale/definition.vim b/sources_non_forked/ale/autoload/ale/definition.vim index 251bdcc5..210ee038 100644 --- a/sources_non_forked/ale/autoload/ale/definition.vim +++ b/sources_non_forked/ale/autoload/ale/definition.vim @@ -35,22 +35,94 @@ function! ale#definition#UpdateTagStack() abort endif endfunction +function! ale#definition#FormatTSServerResponse(response_item, options) abort + if get(a:options, 'open_in') is# 'quickfix' + return { + \ 'filename': a:response_item.file, + \ 'lnum': a:response_item.start.line, + \ 'col': a:response_item.start.offset, + \} + else + return { + \ 'filename': a:response_item.file, + \ 'line': a:response_item.start.line, + \ 'column': a:response_item.start.offset, + \} + endif +endfunction + function! ale#definition#HandleTSServerResponse(conn_id, response) abort if has_key(a:response, 'request_seq') \&& has_key(s:go_to_definition_map, a:response.request_seq) let l:options = remove(s:go_to_definition_map, a:response.request_seq) if get(a:response, 'success', v:false) is v:true && !empty(a:response.body) - let l:filename = a:response.body[0].file - let l:line = a:response.body[0].start.line - let l:column = a:response.body[0].start.offset + let l:item_list = [] - call ale#definition#UpdateTagStack() - call ale#util#Open(l:filename, l:line, l:column, l:options) + for l:response_item in a:response.body + call add( + \ l:item_list, + \ ale#definition#FormatTSServerResponse(l:response_item, l:options) + \) + endfor + + if empty(l:item_list) + call ale#util#Execute('echom ''No definitions found''') + elseif len(l:item_list) == 1 + let l:filename = l:item_list[0].filename + + if get(l:options, 'open_in') is# 'quickfix' + let l:line = l:item_list[0].lnum + let l:column = l:item_list[0].col + else + let l:line = l:item_list[0].line + let l:column = l:item_list[0].column + endif + + call ale#definition#UpdateTagStack() + call ale#util#Open(l:filename, l:line, l:column, l:options) + else + if get(l:options, 'open_in') is# 'quickfix' + call setqflist([], 'r') + call setqflist(l:item_list, 'a') + call ale#util#Execute('cc 1') + else + call ale#definition#UpdateTagStack() + call ale#preview#ShowSelection(l:item_list, l:options) + endif + endif endif endif endfunction +function! ale#definition#FormatLSPResponse(response_item, options) abort + if has_key(a:response_item, 'targetUri') + " LocationLink items use targetUri + let l:uri = a:response_item.targetUri + let l:line = a:response_item.targetRange.start.line + 1 + let l:column = a:response_item.targetRange.start.character + 1 + else + " LocationLink items use uri + let l:uri = a:response_item.uri + let l:line = a:response_item.range.start.line + 1 + let l:column = a:response_item.range.start.character + 1 + endif + + if get(a:options, 'open_in') is# 'quickfix' + return { + \ 'filename': ale#util#ToResource(l:uri), + \ 'lnum': l:line, + \ 'col': l:column, + \} + else + return { + \ 'filename': ale#util#ToResource(l:uri), + \ 'line': l:line, + \ 'column': l:column, + \} + endif +endfunction + function! ale#definition#HandleLSPResponse(conn_id, response) abort if has_key(a:response, 'id') \&& has_key(s:go_to_definition_map, a:response.id) @@ -65,21 +137,29 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort let l:result = [] endif - for l:item in l:result - if has_key(l:item, 'targetUri') - " LocationLink items use targetUri - let l:uri = l:item.targetUri - let l:line = l:item.targetRange.start.line + 1 - let l:column = l:item.targetRange.start.character + 1 - else - " LocationLink items use uri - let l:uri = l:item.uri - let l:line = l:item.range.start.line + 1 - let l:column = l:item.range.start.character + 1 - endif + let l:item_list = [] + for l:response_item in l:result + call add(l:item_list, + \ ale#definition#FormatLSPResponse(l:response_item, l:options) + \) + endfor + + if empty(l:item_list) + call ale#util#Execute('echom ''No definitions found''') + elseif len(l:item_list) == 1 call ale#definition#UpdateTagStack() + let l:uri = ale#util#ToURI(l:item_list[0].filename) + + if get(l:options, 'open_in') is# 'quickfix' + let l:line = l:item_list[0].lnum + let l:column = l:item_list[0].col + else + let l:line = l:item_list[0].line + let l:column = l:item_list[0].column + endif + let l:uri_handler = ale#uri#GetURIHandler(l:uri) if l:uri_handler is# v:null @@ -88,9 +168,16 @@ function! ale#definition#HandleLSPResponse(conn_id, response) abort else call l:uri_handler.OpenURILink(l:uri, l:line, l:column, l:options, a:conn_id) endif - - break - endfor + else + if get(l:options, 'open_in') is# 'quickfix' + call setqflist([], 'r') + call setqflist(l:item_list, 'a') + call ale#util#Execute('cc 1') + else + call ale#definition#UpdateTagStack() + call ale#preview#ShowSelection(l:item_list, l:options) + endif + endif endif endfunction diff --git a/sources_non_forked/ale/autoload/ale/fix/registry.vim b/sources_non_forked/ale/autoload/ale/fix/registry.vim index 050cc6c7..661fa1e1 100644 --- a/sources_non_forked/ale/autoload/ale/fix/registry.vim +++ b/sources_non_forked/ale/autoload/ale/fix/registry.vim @@ -37,6 +37,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['bib'], \ 'description': 'Format bib files using bibclean.', \ }, +\ 'biome': { +\ 'function': 'ale#fixers#biome#Fix', +\ 'suggested_filetypes': ['javascript', 'typescript', 'json', 'jsonc'], +\ 'description': 'Fix JavaScript and TypeScript using biome.', +\ }, \ 'black': { \ 'function': 'ale#fixers#black#Fix', \ 'suggested_filetypes': ['python'], @@ -98,6 +103,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['javascript', 'css', 'html'], \ 'description': 'Apply fecs format to a file.', \ }, +\ 'hurlfmt': { +\ 'function': 'ale#fixers#hurlfmt#Fix', +\ 'suggested_filetypes': ['hurl'], +\ 'description': 'Fix hurl files with hurlfmt.', +\ }, \ 'tidy': { \ 'function': 'ale#fixers#tidy#Fix', \ 'suggested_filetypes': ['html'], @@ -127,7 +137,7 @@ let s:default_registry = { \ }, \ 'eslint': { \ 'function': 'ale#fixers#eslint#Fix', -\ 'suggested_filetypes': ['javascript', 'typescript'], +\ 'suggested_filetypes': ['javascript', 'typescript', 'astro'], \ 'description': 'Apply eslint --fix to a file.', \ }, \ 'mix_format': { @@ -142,7 +152,7 @@ let s:default_registry = { \ }, \ 'prettier': { \ 'function': 'ale#fixers#prettier#Fix', -\ 'suggested_filetypes': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue', 'svelte', 'html', 'yaml', 'openapi', 'ruby'], +\ 'suggested_filetypes': ['javascript', 'typescript', 'css', 'less', 'scss', 'json', 'json5', 'graphql', 'markdown', 'vue', 'svelte', 'html', 'yaml', 'openapi', 'ruby', 'astro'], \ 'description': 'Apply prettier to a file.', \ }, \ 'prettier_eslint': { @@ -291,6 +301,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['solidity'], \ 'description': 'Fix Solidity files with forge fmt.', \ }, +\ 'gleam_format': { +\ 'function': 'ale#fixers#gleam_format#Fix', +\ 'suggested_filetypes': ['gleam'], +\ 'description': 'Fix Gleam files with gleam format.', +\ }, \ 'gofmt': { \ 'function': 'ale#fixers#gofmt#Fix', \ 'suggested_filetypes': ['go'], @@ -546,6 +561,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['html', 'htmldjango'], \ 'description': 'Fix HTML files with html-beautify from js-beautify.', \ }, +\ 'htmlbeautifier': { +\ 'function': 'ale#fixers#htmlbeautifier#Fix', +\ 'suggested_filetypes': ['eruby'], +\ 'description': 'Fix ERB files with htmlbeautifier gem.', +\ }, \ 'lua-format': { \ 'function': 'ale#fixers#lua_format#Fix', \ 'suggested_filetypes': ['lua'], @@ -641,6 +661,11 @@ let s:default_registry = { \ 'suggested_filetypes': ['nickel'], \ 'description': 'Fix nickel files with nickel format', \ }, +\ 'rubyfmt': { +\ 'function': 'ale#fixers#rubyfmt#Fix', +\ 'suggested_filetypes': ['ruby'], +\ 'description': 'A formatter for Ruby source code', +\ }, \} " Reset the function registry to the default entries. diff --git a/sources_non_forked/ale/autoload/ale/fixers/autoflake.vim b/sources_non_forked/ale/autoload/ale/fixers/autoflake.vim index e2ad6536..c2530051 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/autoflake.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/autoflake.vim @@ -4,22 +4,40 @@ 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', '') +call ale#Set('python_autoflake_auto_pipenv', 0) +call ale#Set('python_autoflake_auto_poetry', 0) +call ale#Set('python_autoflake_auto_uv', 0) + +function! ale#fixers#autoflake#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_autoflake_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_autoflake_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_autoflake_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_autoflake', ['autoflake']) +endfunction function! ale#fixers#autoflake#Fix(buffer) abort - let l:executable = ale#python#FindExecutable( - \ a:buffer, - \ 'python_autoflake', - \ ['autoflake'], - \) + let l:executable = ale#fixers#autoflake#GetExecutable(a:buffer) - if !executable(l:executable) - return 0 - endif + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' + \ ? ' run autoflake' + \ : '' let l:options = ale#Var(a:buffer, 'python_autoflake_options') return { - \ 'command': ale#Escape(l:executable) + \ 'command': ale#Escape(l:executable) . l:exec_args \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' --in-place ' \ . ' %t', diff --git a/sources_non_forked/ale/autoload/ale/fixers/autoimport.vim b/sources_non_forked/ale/autoload/ale/fixers/autoimport.vim index 700d36b5..686da124 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/autoimport.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/autoimport.vim @@ -4,23 +4,41 @@ call ale#Set('python_autoimport_executable', 'autoimport') call ale#Set('python_autoimport_options', '') call ale#Set('python_autoimport_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_autoimport_auto_pipenv', 0) +call ale#Set('python_autoimport_auto_poetry', 0) +call ale#Set('python_autoimport_auto_uv', 0) + +function! ale#fixers#autoimport#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_autoimport_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_autoimport_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_autoimport_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_autoimport', ['autoimport']) +endfunction function! ale#fixers#autoimport#Fix(buffer) abort + let l:executable = ale#fixers#autoimport#GetExecutable(a:buffer) + + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' + \ ? ' run autoimport' + \ : '' + let l:options = ale#Var(a:buffer, 'python_autoimport_options') - let l:executable = ale#python#FindExecutable( - \ a:buffer, - \ 'python_autoimport', - \ ['autoimport'], - \) - - if !executable(l:executable) - return 0 - endif - return { \ 'cwd': '%s:h', - \ 'command': ale#Escape(l:executable) + \ 'command': ale#Escape(l:executable) . l:exec_args \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' -', \} diff --git a/sources_non_forked/ale/autoload/ale/fixers/autopep8.vim b/sources_non_forked/ale/autoload/ale/fixers/autopep8.vim index 5798d827..6b5adfce 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/autopep8.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/autopep8.vim @@ -4,22 +4,40 @@ call ale#Set('python_autopep8_executable', 'autopep8') call ale#Set('python_autopep8_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_autopep8_options', '') +call ale#Set('python_autopep8_auto_pipenv', 0) +call ale#Set('python_autopep8_auto_poetry', 0) +call ale#Set('python_autopep8_auto_uv', 0) + +function! ale#fixers#autopep8#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_autopep8_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_autopep8_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_autopep8_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_autopep8', ['autopep8']) +endfunction function! ale#fixers#autopep8#Fix(buffer) abort - let l:executable = ale#python#FindExecutable( - \ a:buffer, - \ 'python_autopep8', - \ ['autopep8'], - \) + let l:executable = ale#fixers#autopep8#GetExecutable(a:buffer) - if !executable(l:executable) - return 0 - endif + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' + \ ? ' run autopep8' + \ : '' let l:options = ale#Var(a:buffer, 'python_autopep8_options') return { - \ 'command': ale#Escape(l:executable) + \ 'command': ale#Escape(l:executable) . l:exec_args \ . (!empty(l:options) ? ' ' . l:options : '') \ . ' -', \} diff --git a/sources_non_forked/ale/autoload/ale/fixers/biome.vim b/sources_non_forked/ale/autoload/ale/fixers/biome.vim index 3a45fa3e..63c0fdbc 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/biome.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/biome.vim @@ -1,17 +1,12 @@ -" Author: Akiomi Kamakura -" Description: Fixing files with biome (ex.rome). - function! ale#fixers#biome#Fix(buffer) abort let l:executable = ale#handlers#biome#GetExecutable(a:buffer) - let l:options = ale#Var(a:buffer, 'javascript_biome_options') - let l:node = ale#Var(a:buffer, 'javascript_biome_node_executable') + let l:options = ale#Var(a:buffer, 'biome_options') + let l:apply = ale#Var(a:buffer, 'biome_fixer_apply_unsafe') ? '--apply-unsafe' : '--apply' return { - \ 'command': (has('win32') ? (ale#Escape(l:node) . ' ') : '') - \ . ale#Escape(l:executable) - \ . ' check --apply' - \ . ale#Pad(l:options) - \ . ' %t', \ 'read_temporary_file': 1, + \ 'command': ale#Escape(l:executable) . ' check ' . l:apply + \ . (!empty(l:options) ? ' ' . l:options : '') + \ . ' %t' \} endfunction diff --git a/sources_non_forked/ale/autoload/ale/fixers/black.vim b/sources_non_forked/ale/autoload/ale/fixers/black.vim index 4a88c5cd..4fe239ff 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/black.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/black.vim @@ -6,6 +6,7 @@ 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_auto_pipenv', 0) call ale#Set('python_black_auto_poetry', 0) +call ale#Set('python_black_auto_uv', 0) call ale#Set('python_black_change_directory', 1) function! ale#fixers#black#GetExecutable(buffer) abort @@ -19,6 +20,11 @@ function! ale#fixers#black#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_black_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_black', ['black']) endfunction @@ -26,7 +32,7 @@ function! ale#fixers#black#Fix(buffer) abort let l:executable = ale#fixers#black#GetExecutable(a:buffer) let l:cmd = [ale#Escape(l:executable)] - if l:executable =~? 'pipenv\|poetry$' + if l:executable =~? 'pipenv\|poetry\|uv$' call extend(l:cmd, ['run', 'black']) endif diff --git a/sources_non_forked/ale/autoload/ale/fixers/htmlbeautifier.vim b/sources_non_forked/ale/autoload/ale/fixers/htmlbeautifier.vim new file mode 100644 index 00000000..756d4a05 --- /dev/null +++ b/sources_non_forked/ale/autoload/ale/fixers/htmlbeautifier.vim @@ -0,0 +1,13 @@ +" Author: Arash Mousavi +" Description: Support for HTML Beautifier https://github.com/threedaymonk/htmlbeautifier + +call ale#Set('eruby_htmlbeautifier_executable', 'htmlbeautifier') + +function! ale#fixers#htmlbeautifier#Fix(buffer) abort + let l:executable = ale#Var(a:buffer, 'eruby_htmlbeautifier_executable') + + return { + \ 'command': ale#Escape(l:executable) . ' %t', + \ 'read_temporary_file': 1, + \} +endfunction diff --git a/sources_non_forked/ale/autoload/ale/fixers/hurlfmt.vim b/sources_non_forked/ale/autoload/ale/fixers/hurlfmt.vim new file mode 100644 index 00000000..fc19fa83 --- /dev/null +++ b/sources_non_forked/ale/autoload/ale/fixers/hurlfmt.vim @@ -0,0 +1,15 @@ +call ale#Set('hurl_hurlfmt_executable', 'hurlfmt') + +function! ale#fixers#hurlfmt#GetCommand(buffer) abort + let l:executable = ale#Var(a:buffer, 'hurl_hurlfmt_executable') + + return ale#Escape(l:executable) + \ . ' --out hurl' +endfunction + +function! ale#fixers#hurlfmt#Fix(buffer) abort + return { + \ 'command': ale#fixers#hurlfmt#GetCommand(a:buffer) + \} +endfunction + diff --git a/sources_non_forked/ale/autoload/ale/fixers/isort.vim b/sources_non_forked/ale/autoload/ale/fixers/isort.vim index 6eb6a67c..c4eef3cc 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/isort.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/isort.vim @@ -6,6 +6,7 @@ call ale#Set('python_isort_use_global', get(g:, 'ale_use_global_executables', 0) call ale#Set('python_isort_options', '') call ale#Set('python_isort_auto_pipenv', 0) call ale#Set('python_isort_auto_poetry', 0) +call ale#Set('python_isort_auto_uv', 0) function! ale#fixers#isort#GetExecutable(buffer) abort if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_isort_auto_pipenv')) @@ -18,6 +19,11 @@ function! ale#fixers#isort#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_isort_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_isort', ['isort']) endfunction @@ -25,7 +31,7 @@ function! ale#fixers#isort#GetCmd(buffer) abort let l:executable = ale#fixers#isort#GetExecutable(a:buffer) let l:cmd = [ale#Escape(l:executable)] - if l:executable =~? 'pipenv\|poetry$' + if l:executable =~? 'pipenv\|poetry\|uv$' call extend(l:cmd, ['run', 'isort']) endif @@ -36,7 +42,7 @@ function! ale#fixers#isort#FixForVersion(buffer, version) abort let l:executable = ale#fixers#isort#GetExecutable(a:buffer) let l:cmd = [ale#Escape(l:executable)] - if l:executable =~? 'pipenv\|poetry$' + if l:executable =~? 'pipenv\|poetry\|uv$' call extend(l:cmd, ['run', 'isort']) endif diff --git a/sources_non_forked/ale/autoload/ale/fixers/php_cs_fixer.vim b/sources_non_forked/ale/autoload/ale/fixers/php_cs_fixer.vim index c8f9c7b0..96c6445c 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/php_cs_fixer.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/php_cs_fixer.vim @@ -4,6 +4,7 @@ call ale#Set('php_cs_fixer_executable', 'php-cs-fixer') call ale#Set('php_cs_fixer_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('php_cs_fixer_options', '') +call ale#Set('php_cs_fixer_fix_options', '') function! ale#fixers#php_cs_fixer#GetExecutable(buffer) abort return ale#path#FindExecutable(a:buffer, 'php_cs_fixer', [ @@ -18,7 +19,8 @@ function! ale#fixers#php_cs_fixer#Fix(buffer) abort return { \ 'command': ale#Escape(l:executable) \ . ' ' . ale#Var(a:buffer, 'php_cs_fixer_options') - \ . ' fix %t', + \ . ' fix ' . ale#Var(a:buffer, 'php_cs_fixer_fix_options') + \ . ' %t', \ 'read_temporary_file': 1, \} endfunction diff --git a/sources_non_forked/ale/autoload/ale/fixers/prettier.vim b/sources_non_forked/ale/autoload/ale/fixers/prettier.vim index 8a67e2ff..c9210e63 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/prettier.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/prettier.vim @@ -79,6 +79,7 @@ function! ale#fixers#prettier#ApplyFixForVersion(buffer, version) abort \ 'openapi': 'yaml', \ 'html': 'html', \ 'ruby': 'ruby', + \ 'astro': 'astro', \} for l:filetype in l:filetypes diff --git a/sources_non_forked/ale/autoload/ale/fixers/pycln.vim b/sources_non_forked/ale/autoload/ale/fixers/pycln.vim index 1f61d083..4ee2373d 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/pycln.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/pycln.vim @@ -7,6 +7,7 @@ call ale#Set('python_pycln_use_global', get(g:, 'ale_use_global_executables', 0) call ale#Set('python_pycln_change_directory', 1) call ale#Set('python_pycln_auto_pipenv', 0) call ale#Set('python_pycln_auto_poetry', 0) +call ale#Set('python_pycln_auto_uv', 0) call ale#Set('python_pycln_config_file', '') function! ale#fixers#pycln#GetCwd(buffer) abort @@ -31,12 +32,17 @@ function! ale#fixers#pycln#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_pycln_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_pycln', ['pycln']) endfunction function! ale#fixers#pycln#GetCommand(buffer) abort let l:executable = ale#fixers#pycln#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run pycln' \ : '' @@ -47,7 +53,7 @@ function! ale#fixers#pycln#FixForVersion(buffer, version) abort let l:executable = ale#fixers#pycln#GetExecutable(a:buffer) let l:cmd = [ale#Escape(l:executable)] - if l:executable =~? 'pipenv\|poetry$' + if l:executable =~? 'pipenv\|poetry\|uv$' call extend(l:cmd, ['run', 'pycln']) endif diff --git a/sources_non_forked/ale/autoload/ale/fixers/pyflyby.vim b/sources_non_forked/ale/autoload/ale/fixers/pyflyby.vim index 81c0f05e..f6f289e3 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/pyflyby.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/pyflyby.vim @@ -7,6 +7,7 @@ call ale#Set('python_pyflyby_use_global', get(g:, 'ale_use_global_executables', call ale#Set('python_pyflyby_options', '') call ale#Set('python_pyflyby_auto_pipenv', 0) call ale#Set('python_pyflyby_auto_poetry', 0) +call ale#Set('python_pyflyby_auto_uv', 0) function! ale#fixers#pyflyby#GetExecutable(buffer) abort if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pyflyby_auto_pipenv')) @@ -19,6 +20,11 @@ function! ale#fixers#pyflyby#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_pyflyby_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_pyflyby', ['tidy-imports']) endfunction @@ -27,7 +33,7 @@ function! ale#fixers#pyflyby#Fix(buffer) abort let l:executable = ale#fixers#pyflyby#GetExecutable(a:buffer) let l:cmd = [ale#Escape(l:executable)] - if l:executable =~? 'pipenv\|poetry$' + if l:executable =~? 'pipenv\|poetry\|uv$' call extend(l:cmd, ['run', 'tidy-imports']) endif diff --git a/sources_non_forked/ale/autoload/ale/fixers/reorder_python_imports.vim b/sources_non_forked/ale/autoload/ale/fixers/reorder_python_imports.vim index 42a0a6e2..3cc76a9f 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/reorder_python_imports.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/reorder_python_imports.vim @@ -4,22 +4,40 @@ call ale#Set('python_reorder_python_imports_executable', 'reorder-python-imports') call ale#Set('python_reorder_python_imports_options', '') call ale#Set('python_reorder_python_imports_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_reorder_python_imports_auto_pipenv', 0) +call ale#Set('python_reorder_python_imports_auto_poetry', 0) +call ale#Set('python_reorder_python_imports_auto_uv', 0) + +function! ale#fixers#reorder_python_imports#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_reorder_python_imports_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_reorder_python_imports_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_reorder_python_imports_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_reorder_python_imports', ['reorder-python-imports']) +endfunction function! ale#fixers#reorder_python_imports#Fix(buffer) abort - let l:executable = ale#python#FindExecutable( - \ a:buffer, - \ 'python_reorder_python_imports', - \ ['reorder-python-imports'], - \) + let l:executable = ale#fixers#reorder_python_imports#GetExecutable(a:buffer) - if !executable(l:executable) - return 0 - endif + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' + \ ? ' run reorder-python-imports' + \ : '' let l:options = ale#Var(a:buffer, 'python_reorder_python_imports_options') return { - \ 'command': ale#Escape(l:executable) + \ 'command': ale#Escape(l:executable) . l:exec_args \ . (!empty(l:options) ? ' ' . l:options : '') . ' -', \} endfunction diff --git a/sources_non_forked/ale/autoload/ale/fixers/ruff.vim b/sources_non_forked/ale/autoload/ale/fixers/ruff.vim index 56bcf3df..c2bea3e3 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/ruff.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/ruff.vim @@ -7,6 +7,7 @@ call ale#Set('python_ruff_use_global', get(g:, 'ale_use_global_executables', 0)) call ale#Set('python_ruff_change_directory', 1) call ale#Set('python_ruff_auto_pipenv', 0) call ale#Set('python_ruff_auto_poetry', 0) +call ale#Set('python_ruff_auto_uv', 0) function! ale#fixers#ruff#GetCwd(buffer) abort if ale#Var(a:buffer, 'python_ruff_change_directory') @@ -30,12 +31,17 @@ function! ale#fixers#ruff#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_ruff_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_ruff', ['ruff']) endfunction function! ale#fixers#ruff#GetCommand(buffer) abort let l:executable = ale#fixers#ruff#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run ruff' \ : '' @@ -46,10 +52,15 @@ function! ale#fixers#ruff#FixForVersion(buffer, version) abort let l:executable = ale#fixers#ruff#GetExecutable(a:buffer) let l:cmd = [ale#Escape(l:executable)] - if l:executable =~? 'pipenv\|poetry$' + if l:executable =~? 'pipenv\|poetry\|uv$' call extend(l:cmd, ['run', 'ruff']) endif + " NOTE: ruff 0.5.0 removes `ruff ` in favor of `ruff check ` + if ale#semver#GTE(a:version, [0, 5, 0]) + call extend(l:cmd, ['check']) + endif + let l:options = ale#Var(a:buffer, 'python_ruff_options') if !empty(l:options) diff --git a/sources_non_forked/ale/autoload/ale/fixers/ruff_format.vim b/sources_non_forked/ale/autoload/ale/fixers/ruff_format.vim index 86858745..e852dd24 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/ruff_format.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/ruff_format.vim @@ -7,6 +7,7 @@ call ale#Set('python_ruff_format_use_global', get(g:, 'ale_use_global_executable call ale#Set('python_ruff_format_change_directory', 1) call ale#Set('python_ruff_format_auto_pipenv', 0) call ale#Set('python_ruff_format_auto_poetry', 0) +call ale#Set('python_ruff_format_auto_uv', 0) function! ale#fixers#ruff_format#GetCwd(buffer) abort if ale#Var(a:buffer, 'python_ruff_format_change_directory') @@ -30,12 +31,17 @@ function! ale#fixers#ruff_format#GetExecutable(buffer) abort return 'poetry' endif + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_ruff_format_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + return ale#python#FindExecutable(a:buffer, 'python_ruff_format', ['ruff']) endfunction function! ale#fixers#ruff_format#GetCommand(buffer) abort let l:executable = ale#fixers#ruff_format#GetExecutable(a:buffer) - let l:exec_args = l:executable =~? 'pipenv\|poetry$' + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' \ ? ' run ruff' \ : '' @@ -46,7 +52,7 @@ function! ale#fixers#ruff_format#Fix(buffer) abort let l:executable = ale#fixers#ruff_format#GetExecutable(a:buffer) let l:cmd = [ale#Escape(l:executable)] - if l:executable =~? 'pipenv\|poetry$' + if l:executable =~? 'pipenv\|poetry\|uv$' call extend(l:cmd, ['run', 'ruff']) endif diff --git a/sources_non_forked/ale/autoload/ale/fixers/yapf.vim b/sources_non_forked/ale/autoload/ale/fixers/yapf.vim index f04bb1f9..22822a6e 100644 --- a/sources_non_forked/ale/autoload/ale/fixers/yapf.vim +++ b/sources_non_forked/ale/autoload/ale/fixers/yapf.vim @@ -3,17 +3,35 @@ call ale#Set('python_yapf_executable', 'yapf') call ale#Set('python_yapf_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_yapf_auto_pipenv', 0) +call ale#Set('python_yapf_auto_poetry', 0) +call ale#Set('python_yapf_auto_uv', 0) + +function! ale#fixers#yapf#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_yapf_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_yapf_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + + if (ale#Var(a:buffer, 'python_auto_uv') || ale#Var(a:buffer, 'python_yapf_auto_uv')) + \ && ale#python#UvPresent(a:buffer) + return 'uv' + endif + + return ale#python#FindExecutable(a:buffer, 'python_yapf', ['yapf']) +endfunction function! ale#fixers#yapf#Fix(buffer) abort - let l:executable = ale#python#FindExecutable( - \ a:buffer, - \ 'python_yapf', - \ ['yapf'], - \) + let l:executable = ale#fixers#yapf#GetExecutable(a:buffer) - if !executable(l:executable) - return 0 - endif + let l:exec_args = l:executable =~? 'pipenv\|poetry\|uv$' + \ ? ' run yapf' + \ : '' let l:config = ale#path#FindNearestFile(a:buffer, '.style.yapf') let l:config_options = !empty(l:config) @@ -21,6 +39,6 @@ function! ale#fixers#yapf#Fix(buffer) abort \ : '' return { - \ 'command': ale#Escape(l:executable) . l:config_options, + \ 'command': ale#Escape(l:executable) . l:exec_args . l:config_options, \} endfunction diff --git a/sources_non_forked/ale/autoload/ale/handlers/biome.vim b/sources_non_forked/ale/autoload/ale/handlers/biome.vim index 8d75e3bc..b22c1c46 100644 --- a/sources_non_forked/ale/autoload/ale/handlers/biome.vim +++ b/sources_non_forked/ale/autoload/ale/handlers/biome.vim @@ -1,14 +1,58 @@ -" Author: Akiomi Kamakura -" Description: Functions for working with biome, for fixing files. +" Author: Filip Gospodinov +" Description: Functions for working with biome, for checking or fixing files. -call ale#Set('javascript_biome_node_executable', 'node.exe') -call ale#Set('javascript_biome_executable', 'biome') -call ale#Set('javascript_biome_use_global', get(g:, 'ale_use_global_executables', 0)) -call ale#Set('javascript_biome_options', '') +call ale#Set('biome_executable', 'biome') +call ale#Set('biome_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('biome_options', '') +call ale#Set('biome_fixer_apply_unsafe', 0) +call ale#Set('biome_lsp_project_root', '') function! ale#handlers#biome#GetExecutable(buffer) abort - return ale#path#FindExecutable(a:buffer, 'javascript_biome', [ + return ale#path#FindExecutable(a:buffer, 'biome', [ + \ 'node_modules/@biomejs/cli-linux-x64/biome', + \ 'node_modules/@biomejs/cli-linux-arm64/biome', + \ 'node_modules/@biomejs/cli-win32-x64/biome.exe', + \ 'node_modules/@biomejs/cli-win32-arm64/biome.exe', + \ 'node_modules/@biomejs/cli-darwin-x64/biome', + \ 'node_modules/@biomejs/cli-darwin-arm64/biome', \ 'node_modules/.bin/biome', - \ 'node_modules/@biomejs/biome/bin/biome', \]) endfunction + +function! ale#handlers#biome#GetLanguage(buffer) abort + return getbufvar(a:buffer, '&filetype') +endfunction + +function! ale#handlers#biome#GetProjectRoot(buffer) abort + let l:project_root = ale#Var(a:buffer, 'biome_lsp_project_root') + + if !empty(l:project_root) + return l:project_root + endif + + let l:possible_project_roots = [ + \ 'biome.json', + \ 'biome.jsonc', + \ 'package.json', + \ '.git', + \ bufname(a:buffer), + \] + + for l:possible_root in l:possible_project_roots + let l:project_root = ale#path#FindNearestFile(a:buffer, l:possible_root) + + if empty(l:project_root) + let l:project_root = ale#path#FindNearestDirectory(a:buffer, l:possible_root) + endif + + if !empty(l:project_root) + " dir:p expands to /full/path/to/dir/ whereas + " file:p expands to /full/path/to/file (no trailing slash) + " Appending '/' ensures that :h:h removes the path's last segment + " regardless of whether it is a directory or not. + return fnamemodify(l:project_root . '/', ':p:h:h') + endif + endfor + + return '' +endfunction diff --git a/sources_non_forked/ale/autoload/ale/handlers/cspell.vim b/sources_non_forked/ale/autoload/ale/handlers/cspell.vim index 6137bdeb..a59002bb 100644 --- a/sources_non_forked/ale/autoload/ale/handlers/cspell.vim +++ b/sources_non_forked/ale/autoload/ale/handlers/cspell.vim @@ -11,12 +11,31 @@ function! ale#handlers#cspell#GetExecutable(buffer) abort \) endfunction +function! ale#handlers#cspell#GetLanguageId(buffer) abort + let l:filetype = getbufvar(a:buffer, '&filetype') + + if l:filetype is# 'tex' + " Vim's tex corresponds to latex language-id in cspell + return 'latex' + elseif l:filetype is# 'plaintex' + " Vim's plaintex corresponds to tex language-id in cspell + return 'tex' + else + " Fallback to filetype for everything else. + return l:filetype + endif +endfunction + function! ale#handlers#cspell#GetCommand(buffer) abort let l:executable = ale#handlers#cspell#GetExecutable(a:buffer) let l:options = ale#Var(a:buffer, 'cspell_options') + let l:language_id = ale#handlers#cspell#GetLanguageId(a:buffer) + + let l:language_id_option = empty(l:language_id) ? '' : '--language-id="' . l:language_id . '"' return ale#node#Executable(a:buffer, l:executable) \ . ' lint --no-color --no-progress --no-summary' + \ . ale#Pad(l:language_id_option) \ . ale#Pad(l:options) \ . ' -- stdin' endfunction diff --git a/sources_non_forked/ale/autoload/ale/handlers/embertemplatelint.vim b/sources_non_forked/ale/autoload/ale/handlers/embertemplatelint.vim new file mode 100644 index 00000000..d2e83400 --- /dev/null +++ b/sources_non_forked/ale/autoload/ale/handlers/embertemplatelint.vim @@ -0,0 +1,66 @@ +" Author: Adrian Zalewski +" Description: Ember-template-lint for checking Handlebars files + +function! ale#handlers#embertemplatelint#GetExecutable(buffer) abort + return ale#path#FindExecutable(a:buffer, 'handlebars_embertemplatelint', [ + \ 'node_modules/.bin/ember-template-lint', + \]) +endfunction + +function! ale#handlers#embertemplatelint#GetCommand(buffer, version) abort + if ale#semver#GTE(a:version, [4, 0, 0]) + " --json was removed in favor of --format=json in ember-template-lint@4.0.0 + return '%e --format=json --filename %s' + endif + + return '%e --json --filename %s' +endfunction + +function! ale#handlers#embertemplatelint#GetCommandWithVersionCheck(buffer) abort + return ale#semver#RunWithVersionCheck( + \ a:buffer, + \ ale#handlers#embertemplatelint#GetExecutable(a:buffer), + \ '%e --version', + \ function('ale#handlers#embertemplatelint#GetCommand'), + \) +endfunction + +function! ale#handlers#embertemplatelint#Handle(buffer, lines) abort + let l:output = [] + let l:json = ale#util#FuzzyJSONDecode(a:lines, {}) + + for l:error in get(values(l:json), 0, []) + if has_key(l:error, 'fatal') + call add(l:output, { + \ 'lnum': get(l:error, 'line', 1), + \ 'col': get(l:error, 'column', 1), + \ 'text': l:error.message, + \ 'type': l:error.severity == 1 ? 'W' : 'E', + \}) + else + call add(l:output, { + \ 'lnum': l:error.line, + \ 'col': l:error.column, + \ 'text': l:error.rule . ': ' . l:error.message, + \ 'type': l:error.severity == 1 ? 'W' : 'E', + \}) + endif + endfor + + return l:output +endfunction + +function! ale#handlers#embertemplatelint#DefineLinter(filetype) abort + call ale#Set('handlebars_embertemplatelint_executable', 'ember-template-lint') + call ale#Set('handlebars_embertemplatelint_use_global', get(g:, 'ale_use_global_executables', 0)) + + call ale#linter#Define(a:filetype, { + \ 'name': 'embertemplatelint', + \ 'aliases': ['ember-template-lint'], + \ 'executable': function('ale#handlers#embertemplatelint#GetExecutable'), + \ 'command': function('ale#handlers#embertemplatelint#GetCommandWithVersionCheck'), + \ 'callback': 'ale#handlers#embertemplatelint#Handle', + \}) +endfunction + + diff --git a/sources_non_forked/ale/autoload/ale/handlers/eslint.vim b/sources_non_forked/ale/autoload/ale/handlers/eslint.vim index 374460bc..eea06f51 100644 --- a/sources_non_forked/ale/autoload/ale/handlers/eslint.vim +++ b/sources_non_forked/ale/autoload/ale/handlers/eslint.vim @@ -18,7 +18,11 @@ call ale#Set('javascript_eslint_suppress_missing_config', 0) function! ale#handlers#eslint#FindConfig(buffer) abort for l:path in ale#path#Upwards(expand('#' . a:buffer . ':p:h')) for l:basename in [ + \ 'eslint.config.js', + \ 'eslint.config.mjs', + \ 'eslint.config.cjs', \ '.eslintrc.js', + \ '.eslintrc.cjs', \ '.eslintrc.yaml', \ '.eslintrc.yml', \ '.eslintrc.json', @@ -41,31 +45,7 @@ endfunction " Given a buffer, return an appropriate working directory for ESLint. function! ale#handlers#eslint#GetCwd(buffer) abort - " ESLint 6 loads plugins/configs/parsers from the project root - " By default, the project root is simply the CWD of the running process. - " https://github.com/eslint/rfcs/blob/master/designs/2018-simplified-package-loading/README.md - " https://github.com/dense-analysis/ale/issues/2787 - " - " If eslint is installed in a directory which contains the buffer, assume - " it is the ESLint project root. Otherwise, use nearest node_modules. - " Note: If node_modules not present yet, can't load local deps anyway. - let l:executable = ale#path#FindNearestExecutable(a:buffer, s:executables) - - if !empty(l:executable) - let l:modules_index = strridx(l:executable, 'node_modules') - let l:modules_root = l:modules_index > -1 ? l:executable[0:l:modules_index - 2] : '' - - let l:sdks_index = strridx(l:executable, ale#path#Simplify('.yarn/sdks')) - let l:sdks_root = l:sdks_index > -1 ? l:executable[0:l:sdks_index - 2] : '' - else - let l:modules_dir = ale#path#FindNearestDirectory(a:buffer, 'node_modules') - let l:modules_root = !empty(l:modules_dir) ? fnamemodify(l:modules_dir, ':h:h') : '' - - let l:sdks_dir = ale#path#FindNearestDirectory(a:buffer, ale#path#Simplify('.yarn/sdks')) - let l:sdks_root = !empty(l:sdks_dir) ? fnamemodify(l:sdks_dir, ':h:h:h') : '' - endif - - return strlen(l:modules_root) > strlen(l:sdks_root) ? l:modules_root : l:sdks_root + return ale#path#Dirname(ale#handlers#eslint#FindConfig(a:buffer)) endfunction function! ale#handlers#eslint#GetCommand(buffer) abort diff --git a/sources_non_forked/ale/autoload/ale/handlers/shellcheck.vim b/sources_non_forked/ale/autoload/ale/handlers/shellcheck.vim index fd540e8e..002c4651 100644 --- a/sources_non_forked/ale/autoload/ale/handlers/shellcheck.vim +++ b/sources_non_forked/ale/autoload/ale/handlers/shellcheck.vim @@ -49,6 +49,7 @@ function! ale#handlers#shellcheck#GetCommand(buffer, version) abort let l:exclude_option = ale#Var(a:buffer, 'sh_shellcheck_exclusions') let l:dialect = ale#Var(a:buffer, 'sh_shellcheck_dialect') let l:external_option = ale#semver#GTE(a:version, [0, 4, 0]) ? ' -x' : '' + let l:format = ale#semver#GTE(a:version, [0, 7, 0]) ? 'json1' : 'gcc' if l:dialect is# 'auto' let l:dialect = ale#handlers#shellcheck#GetDialectArgument(a:buffer) @@ -59,10 +60,69 @@ function! ale#handlers#shellcheck#GetCommand(buffer, version) abort \ . (!empty(l:options) ? ' ' . l:options : '') \ . (!empty(l:exclude_option) ? ' -e ' . l:exclude_option : '') \ . l:external_option - \ . ' -f gcc -' + \ . ' -f ' . l:format . ' -' endfunction -function! ale#handlers#shellcheck#Handle(buffer, lines) abort +function! s:HandleShellcheckJSON(buffer, lines) abort + try + let l:errors = json_decode(a:lines[0]) + catch + return [] + endtry + + if !has_key(l:errors, 'comments') + return [] + endif + + let l:output = [] + + for l:error in l:errors['comments'] + if l:error['level'] is# 'error' + let l:type = 'E' + elseif l:error['level'] is# 'info' + let l:type = 'I' + elseif l:error['level'] is# 'style' + let l:type = 'I' + else + let l:type = 'W' + endif + + let l:item = { + \ 'lnum': l:error['line'], + \ 'type': l:type, + \ 'text': l:error['message'], + \ 'code': 'SC' . l:error['code'], + \ 'detail': l:error['message'] . "\n\nFor more information:\n https://www.shellcheck.net/wiki/SC" . l:error['code'], + \} + + if has_key(l:error, 'column') + let l:item.col = l:error['column'] + endif + + if has_key(l:error, 'endColumn') + let l:item.end_col = l:error['endColumn'] - 1 + endif + + if has_key(l:error, 'endLine') + let l:item.end_lnum = l:error['endLine'] + endif + + + " If the filename is something like , or -, then + " this is an error for the file we checked. + if has_key(l:error, 'file') + if l:error['file'] isnot# '-' && l:error['file'][0] isnot# '<' + let l:item['filename'] = l:error['file'] + endif + endif + + call add(l:output, l:item) + endfor + + return l:output +endfunction + +function! s:HandleShellcheckGCC(buffer, lines) abort let l:pattern = '\v^([a-zA-Z]?:?[^:]+):(\d+):(\d+)?:? ([^:]+): (.+) \[([^\]]+)\]$' let l:output = [] @@ -80,6 +140,7 @@ function! ale#handlers#shellcheck#Handle(buffer, lines) abort \ 'type': l:type, \ 'text': l:match[5], \ 'code': l:match[6], + \ 'detail': l:match[5] . "\n\nFor more information:\n https://www.shellcheck.net/wiki/" . l:match[6], \} if !empty(l:match[3]) @@ -98,6 +159,12 @@ function! ale#handlers#shellcheck#Handle(buffer, lines) abort return l:output endfunction +function! ale#handlers#shellcheck#Handle(buffer, version, lines) abort + return ale#semver#GTE(a:version, [0, 7, 0]) + \ ? s:HandleShellcheckJSON(a:buffer, a:lines) + \ : s:HandleShellcheckGCC(a:buffer, a:lines) +endfunction + function! ale#handlers#shellcheck#DefineLinter(filetype) abort " This global variable can be set with a string of comma-separated error " codes to exclude from shellcheck. For example: @@ -118,6 +185,14 @@ function! ale#handlers#shellcheck#DefineLinter(filetype) abort \ '%e --version', \ function('ale#handlers#shellcheck#GetCommand'), \ )}, - \ 'callback': 'ale#handlers#shellcheck#Handle', + \ 'callback': {buffer, lines -> ale#semver#RunWithVersionCheck( + \ buffer, + \ ale#Var(buffer, 'sh_shellcheck_executable'), + \ '%e --version', + \ {buffer, version -> ale#handlers#shellcheck#Handle( + \ buffer, + \ l:version, + \ lines)}, + \ )}, \}) endfunction diff --git a/sources_non_forked/ale/autoload/ale/hover.vim b/sources_non_forked/ale/autoload/ale/hover.vim index 1202e08e..a42766eb 100644 --- a/sources_non_forked/ale/autoload/ale/hover.vim +++ b/sources_non_forked/ale/autoload/ale/hover.vim @@ -117,10 +117,10 @@ function! ale#hover#ParseLSPResult(contents) abort for l:line in split(l:item, "\n") if l:fence_language is v:null " Look for the start of a code fence. (```python, etc.) - let l:match = matchlist(l:line, '^``` *\([^ ]\+\) *$') + let l:match = matchlist(l:line, '^``` *\([^ ]\+\)\? *$') if !empty(l:match) - let l:fence_language = l:match[1] + let l:fence_language = len(l:match) > 1 ? l:match[1] : 'text' if !empty(l:marked_list) call add(l:fence_lines, '') diff --git a/sources_non_forked/ale/autoload/ale/linter.vim b/sources_non_forked/ale/autoload/ale/linter.vim index 20104fbc..618557d7 100644 --- a/sources_non_forked/ale/autoload/ale/linter.vim +++ b/sources_non_forked/ale/autoload/ale/linter.vim @@ -40,6 +40,7 @@ let s:default_ale_linter_aliases = { " NOTE: Update the g:ale_linters documentation when modifying this. let s:default_ale_linters = { \ 'apkbuild': ['apkbuild_lint', 'secfixes_check'], +\ 'astro': ['eslint'], \ 'csh': ['shell'], \ 'elixir': ['credo', 'dialyxir', 'dogma'], \ 'go': ['gofmt', 'golangci-lint', 'gopls', 'govet'], @@ -47,9 +48,9 @@ let s:default_ale_linters = { \ 'hack': ['hack'], \ 'help': [], \ 'inko': ['inko'], -\ 'json': ['jsonlint', 'spectral', 'vscodejson'], +\ 'json': ['biome', 'jsonlint', 'spectral', 'vscodejson'], \ 'json5': [], -\ 'jsonc': [], +\ 'jsonc': ['biome'], \ 'perl': ['perlcritic'], \ 'perl6': [], \ 'python': ['flake8', 'mypy', 'pylint', 'pyright', 'ruff'], @@ -60,7 +61,7 @@ let s:default_ale_linters = { \ 'vue': ['eslint', 'vls'], \ 'zsh': ['shell'], \ 'v': ['v'], -\ 'yaml': ['spectral', 'yaml-language-server', 'yamllint'], +\ 'yaml': ['actionlint', 'spectral', 'yaml-language-server', 'yamllint'], \} " Testing/debugging helper to unload all linters. diff --git a/sources_non_forked/ale/autoload/ale/python.vim b/sources_non_forked/ale/autoload/ale/python.vim index 2c7e0049..9eb198fb 100644 --- a/sources_non_forked/ale/autoload/ale/python.vim +++ b/sources_non_forked/ale/autoload/ale/python.vim @@ -3,6 +3,7 @@ call ale#Set('python_auto_pipenv', '0') call ale#Set('python_auto_poetry', '0') +call ale#Set('python_auto_uv', '0') let s:sep = has('win32') ? '\' : '/' " bin is used for Unix virtualenv directories, and Scripts is for Windows. @@ -43,6 +44,7 @@ function! ale#python#FindProjectRootIni(buffer) abort \|| filereadable(l:path . '/poetry.lock') \|| filereadable(l:path . '/pyproject.toml') \|| filereadable(l:path . '/.tool-versions') + \|| filereadable(l:path . '/uv.lock') return l:path endif endfor @@ -192,3 +194,8 @@ endfunction function! ale#python#PoetryPresent(buffer) abort return findfile('poetry.lock', expand('#' . a:buffer . ':p:h') . ';') isnot# '' endfunction + +" Detects whether a poetry environment is present. +function! ale#python#UvPresent(buffer) abort + return findfile('uv.lock', expand('#' . a:buffer . ':p:h') . ';') isnot# '' +endfunction diff --git a/sources_non_forked/ale/autoload/ale/sign.vim b/sources_non_forked/ale/autoload/ale/sign.vim index 15517bf8..e78ce468 100644 --- a/sources_non_forked/ale/autoload/ale/sign.vim +++ b/sources_non_forked/ale/autoload/ale/sign.vim @@ -161,7 +161,7 @@ endfunction function! s:GroupCmd() abort if s:supports_sign_groups - return ' group=ale ' + return ' group=ale_signs ' else return ' ' endif @@ -180,13 +180,13 @@ endfunction function! ale#sign#ParsePattern() abort if s:supports_sign_groups " Matches output like : - " line=4 id=1 group=ale name=ALEErrorSign - " строка=1 id=1000001 группа=ale имя=ALEErrorSign - " 行=1 識別子=1000001 グループ=ale 名前=ALEWarningSign - " línea=12 id=1000001 grupo=ale nombre=ALEWarningSign - " riga=1 id=1000001 gruppo=ale nome=ALEWarningSign - " Zeile=235 id=1000001 Gruppe=ale Name=ALEErrorSign - let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=ale>.*\=(ALE[a-zA-Z]+Sign)' + " line=4 id=1 group=ale_signs name=ALEErrorSign + " строка=1 id=1000001 группа=ale_signs имя=ALEErrorSign + " 行=1 識別子=1000001 グループ=ale_signs 名前=ALEWarningSign + " línea=12 id=1000001 grupo=ale_signs nombre=ALEWarningSign + " riga=1 id=1000001 gruppo=ale_signs nome=ALEWarningSign + " Zeile=235 id=1000001 Gruppe=ale_signs Name=ALEErrorSign + let l:pattern = '\v^.*\=(\d+).*\=(\d+).*\=ale_signs>.*\=(ALE[a-zA-Z]+Sign)' else " Matches output like : " line=4 id=1 name=ALEErrorSign @@ -203,7 +203,7 @@ endfunction " Given a buffer number, return a List of placed signs [line, id, group] function! ale#sign#ParseSignsWithGetPlaced(buffer) abort - let l:signs = sign_getplaced(a:buffer, { 'group': s:supports_sign_groups ? 'ale' : '' })[0].signs + let l:signs = sign_getplaced(a:buffer, { 'group': s:supports_sign_groups ? 'ale_signs' : '' })[0].signs let l:result = [] let l:is_dummy_sign_set = 0 @@ -489,7 +489,7 @@ endfunction " Remove all signs. function! ale#sign#Clear() abort if s:supports_sign_groups - sign unplace group=ale * + sign unplace group=ale_signs * else sign unplace * endif diff --git a/sources_non_forked/ale/doc/ale-astro.txt b/sources_non_forked/ale/doc/ale-astro.txt new file mode 100644 index 00000000..0132aa80 --- /dev/null +++ b/sources_non_forked/ale/doc/ale-astro.txt @@ -0,0 +1,16 @@ +=============================================================================== +ALE Astro Integration *ale-astro-options* + + +=============================================================================== +eslint *ale-astro-eslint* + +See |ale-javascript-eslint| for information about the available options. + +=============================================================================== +prettier *ale-astro-prettier* + +See |ale-javascript-prettier| for information about the available options. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/sources_non_forked/ale/doc/ale-dart.txt b/sources_non_forked/ale/doc/ale-dart.txt index 4824e82e..8761515e 100644 --- a/sources_non_forked/ale/doc/ale-dart.txt +++ b/sources_non_forked/ale/doc/ale-dart.txt @@ -27,6 +27,19 @@ g:ale_dart_analysis_server_executable *g:ale_dart_analysis_server_executable* This variable can be set to change the path of dart. +g:ale_dart_analysis_server_enable_language_server + *g:ale_dart_analysis_server_enable_language_server* + *b:ale_dart_analysis_server_enable_language_server* + Type: |Number| + Default: `1` + + When set to `1`, ALE will use the new `dart language-server` command, + available from Dart version 2.16.0, to launch the language server. When set + to `0`, ALE will instead use the deprecated + `./snapshots/analysis_server.dart.snapshot --lsp` command used by older + versions of Dart. + + =============================================================================== dart-analyze *ale-dart-analyze* diff --git a/sources_non_forked/ale/doc/ale-eruby.txt b/sources_non_forked/ale/doc/ale-eruby.txt index 65bd8a30..82fe685a 100644 --- a/sources_non_forked/ale/doc/ale-eruby.txt +++ b/sources_non_forked/ale/doc/ale-eruby.txt @@ -7,6 +7,7 @@ There are four linters for `eruby` files: - `erblint` - `erubis` - `erubi` +- `htmlbeautifier` - `ruumba` `erb` is in the Ruby standard library and is mostly universal. `erubis` is the @@ -47,6 +48,18 @@ g:ale_eruby_erblint_options *g:ale_ruby_erblint_options* This variable can be change to modify flags given to erblint. +=============================================================================== +htmlbeautifier *ale-eruby-htmlbeautifier* + +g:ale_eruby_htmlbeautifier_executable *g:ale_eruby_htmlbeautifier_executable* + *b:ale_eruby_htmlbeautifier_executable* + Type: |String| + Default: `'htmlbeautifier'` + + Override the invoked htmlbeautifier binary. This is useful for running + htmlbeautifier from binstubs or a bundle. + + =============================================================================== ruumba *ale-eruby-ruumba* diff --git a/sources_non_forked/ale/doc/ale-hurl.txt b/sources_non_forked/ale/doc/ale-hurl.txt new file mode 100644 index 00000000..6c4d726b --- /dev/null +++ b/sources_non_forked/ale/doc/ale-hurl.txt @@ -0,0 +1,17 @@ +=============================================================================== +ALE Hurl Integration *ale-hurl-options* + + +=============================================================================== +hurlfmt *ale-hurl-hurlfmt* + +g:ale_hurl_hurlfmt_executable *g:ale_hurl_hurlfmt_executable* + *b:ale_hurl_hurlfmt_executable* + Type: |String| + Default: `'hurlfmt'` + + Override the invoked hurlfmt binary. + + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/sources_non_forked/ale/doc/ale-javascript.txt b/sources_non_forked/ale/doc/ale-javascript.txt index a55cd643..7e594f2a 100644 --- a/sources_non_forked/ale/doc/ale-javascript.txt +++ b/sources_non_forked/ale/doc/ale-javascript.txt @@ -25,6 +25,12 @@ To this: > < +=============================================================================== +biome *ale-javascript-biome* + +Check the docs over at |ale-typescript-biome|. + + =============================================================================== clang-format *ale-javascript-clangformat* diff --git a/sources_non_forked/ale/doc/ale-json.txt b/sources_non_forked/ale/doc/ale-json.txt index 7b240373..8822a697 100644 --- a/sources_non_forked/ale/doc/ale-json.txt +++ b/sources_non_forked/ale/doc/ale-json.txt @@ -2,6 +2,12 @@ ALE JSON Integration *ale-json-options* +=============================================================================== +biome *ale-json-biome* + +Check the docs over at |ale-typescript-biome|. + + =============================================================================== clang-format *ale-json-clangformat* diff --git a/sources_non_forked/ale/doc/ale-jsonc.txt b/sources_non_forked/ale/doc/ale-jsonc.txt index 92247cd4..b05fa6e6 100644 --- a/sources_non_forked/ale/doc/ale-jsonc.txt +++ b/sources_non_forked/ale/doc/ale-jsonc.txt @@ -2,6 +2,12 @@ ALE JSONC Integration *ale-jsonc-options* +=============================================================================== +biome *ale-jsonc-biome* + +Check the docs over at |ale-typescript-biome|. + + =============================================================================== eslint *ale-jsonc-eslint* diff --git a/sources_non_forked/ale/doc/ale-odin.txt b/sources_non_forked/ale/doc/ale-odin.txt new file mode 100644 index 00000000..826411de --- /dev/null +++ b/sources_non_forked/ale/doc/ale-odin.txt @@ -0,0 +1,29 @@ +=============================================================================== +ALE Odin Integration *ale-odin-options* + *ale-integration-odin* + +=============================================================================== +Integration Information + + Currently, the only supported linter for Odin is ols. + +=============================================================================== +ols *ale-odin-ols* + +g:ale_odin_ols_executable *g:ale_odin_ols_executable* + *b:ale_odin_ols_executable* + Type: |String| + Default: `'ols'` + + This variable can be modified to change the executable path for `ols`. + + +g:ale_odin_ols_config *g:ale_odin_ols_config* + *b:ale_odin_ols_config* + Type: |Dictionary| + Default: `{}` + + Dictionary with configuration settings for ols. + +=============================================================================== + vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/sources_non_forked/ale/doc/ale-python.txt b/sources_non_forked/ale/doc/ale-python.txt index ec118c5a..4798baaf 100644 --- a/sources_non_forked/ale/doc/ale-python.txt +++ b/sources_non_forked/ale/doc/ale-python.txt @@ -20,6 +20,15 @@ g:ale_python_auto_poetry *g:ale_python_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_auto_uv *g:ale_python_auto_uv* + *b:ale_python_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + g:ale_python_auto_virtualenv *g:ale_python_auto_virtualenv* *b:ale_python_auto_virtualenv* Type: |Number| @@ -96,6 +105,33 @@ g:ale_python_autoflake_use_global *g:ale_python_autoflake_use_global* See |ale-integrations-local-executables| +g:ale_python_autoflake_auto_pipenv *g:ale_python_autoflake_auto_pipenv* + *b:ale_python_autoflake_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +g:ale_python_autoflake_auto_poetry *g:ale_python_autoflake_auto_poetry* + *b:ale_python_autoflake_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_autoflake_auto_uv *g:ale_python_autoflake_auto_uv* + *b:ale_python_autoflake_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== autoimport *ale-python-autoimport* @@ -123,6 +159,33 @@ g:ale_python_autoimport_use_global *g:ale_python_autoimport_use_global* See |ale-integrations-local-executables| +g:ale_python_autoimport_auto_pipenv *g:ale_python_autoimport_auto_pipenv* + *b:ale_python_autoimport_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +g:ale_python_autoimport_auto_poetry *g:ale_python_autoimport_auto_poetry* + *b:ale_python_autoimport_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_autoimport_auto_uv *g:ale_python_autoimport_auto_uv* + *b:ale_python_autoimport_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== autopep8 *ale-python-autopep8* @@ -150,6 +213,33 @@ g:ale_python_autopep8_use_global *g:ale_python_autopep8_use_global* See |ale-integrations-local-executables| +g:ale_python_autopep8_auto_pipenv *g:ale_python_autopep8_auto_pipenv* + *b:ale_python_autopep8_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +g:ale_python_autopep8_auto_poetry *g:ale_python_autopep8_auto_poetry* + *b:ale_python_autopep8_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_autopep8_auto_uv *g:ale_python_autopep8_auto_uv* + *b:ale_python_autopep8_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== bandit *ale-python-bandit* @@ -210,6 +300,15 @@ g:ale_python_bandit_auto_poetry *g:ale_python_bandit_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_bandit_auto_uv *g:ale_python_bandit_auto_uv* + *b:ale_python_bandit_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== black *ale-python-black* @@ -255,6 +354,15 @@ g:ale_python_black_auto_poetry *g:ale_python_black_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_black_auto_uv *g:ale_python_black_auto_uv* + *b:ale_python_black_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + g:ale_python_black_change_directory *g:ale_python_black_change_directory* *b:ale_python_black_change_directory* Type: |Number| @@ -345,6 +453,15 @@ g:ale_python_flake8_auto_poetry *g:ale_python_flake8_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_flake8_auto_uv *g:ale_python_flake8_auto_uv* + *b:ale_python_flake8_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== flakehell *ale-python-flakehell* @@ -410,6 +527,15 @@ g:ale_python_flakehell_auto_poetry *g:ale_python_flakehell_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_flakehell_auto_uv *g:ale_python_flakehell_auto_uv* + *b:ale_python_flakehell_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== isort *ale-python-isort* @@ -455,6 +581,15 @@ g:ale_python_isort_auto_poetry *g:ale_python_isort_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_isort_auto_uv *g:ale_python_isort_auto_uv* + *b:ale_python_isort_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== mypy *ale-python-mypy* @@ -483,6 +618,15 @@ g:ale_python_mypy_auto_poetry *g:ale_python_mypy_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_mypy_auto_uv *g:ale_python_mypy_auto_uv* + *b:ale_python_mypy_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + g:ale_python_mypy_executable *g:ale_python_mypy_executable* *b:ale_python_mypy_executable* Type: |String| @@ -591,6 +735,15 @@ g:ale_python_prospector_auto_poetry *g:ale_python_prospector_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_prospector_auto_uv *g:ale_python_prospector_auto_uv* + *b:ale_python_prospector_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== pycln *ale-python-pycln* @@ -663,6 +816,15 @@ g:ale_python_pycln_auto_poetry *g:ale_python_pycln_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_pycln_auto_uv *g:ale_python_pycln_auto_uv* + *b:ale_python_pycln_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== pycodestyle *ale-python-pycodestyle* @@ -712,6 +874,15 @@ g:ale_python_pycodestyle_auto_poetry *g:ale_python_pycodestyle_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_pycodestyle_auto_uv *g:ale_python_pycodestyle_auto_uv* + *b:ale_python_pycodestyle_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== pydocstyle *ale-python-pydocstyle* @@ -761,6 +932,15 @@ g:ale_python_pydocstyle_auto_poetry *g:ale_python_pydocstyle_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_pydocstyle_auto_uv *g:ale_python_pydocstyle_auto_uv* + *b:ale_python_pydocstyle_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== pyflakes *ale-python-pyflakes* @@ -793,6 +973,15 @@ g:ale_python_pyflakes_auto_poetry *g:ale_python_pyflakes_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_pyflakes_auto_uv *g:ale_python_pyflakes_auto_uv* + *b:ale_python_pyflakes_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== pyflyby *ale-python-pyflyby* @@ -839,6 +1028,15 @@ g:ale_python_pyflyby_auto_poetry *g:ale_python_pyflyby_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_pyflyby_auto_uv *g:ale_python_pyflyby_auto_uv* + *b:ale_python_pyflyby_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== pylama *ale-python-pylama* @@ -902,6 +1100,14 @@ g:ale_python_pylama_auto_poetry *g:ale_python_pylama_auto_poetry* 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_pylama_auto_uv *g:ale_python_pylama_auto_uv* + *b:ale_python_pylama_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + =============================================================================== pylint *ale-python-pylint* @@ -976,6 +1182,15 @@ g:ale_python_pylint_auto_poetry *g:ale_python_pylint_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_pylint_auto_uv *g:ale_python_pylint_auto_uv* + *b:ale_python_pylint_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + g:ale_python_pylint_use_msg_id *g:ale_python_pylint_use_msg_id* *b:ale_python_pylint_use_msg_id* Type: |Number| @@ -1028,6 +1243,15 @@ g:ale_python_pylsp_auto_poetry *g:ale_python_pylsp_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_pylsp_auto_uv *g:ale_python_pylsp_auto_uv* + *b:ale_python_pylsp_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` 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| @@ -1109,6 +1333,15 @@ g:ale_python_pyre_auto_poetry *g:ale_python_pyre_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_pyre_auto_uv *g:ale_python_pyre_auto_uv* + *b:ale_python_pyre_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== pyright *ale-python-pyright* @@ -1168,6 +1401,33 @@ g:ale_python_pyright_config *g:ale_python_pyright_config* \} < +g:ale_python_pyright_auto_pipenv *g:ale_python_pyright_auto_pipenv* + *b:ale_python_pyright_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +g:ale_python_pyright_auto_poetry *g:ale_python_pyright_auto_poetry* + *b:ale_python_pyright_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_pyright_auto_uv *g:ale_python_pyright_auto_uv* + *b:ale_python_pyright_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== refurb *ale-python-refurb* @@ -1229,6 +1489,15 @@ g:ale_python_refurb_auto_poetry *g:ale_python_refurb_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_refurb_auto_uv *g:ale_python_refurb_auto_uv* + *b:ale_python_refurb_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== reorder-python-imports *ale-python-reorder_python_imports* @@ -1259,6 +1528,36 @@ g:ale_python_reorder_python_imports_use_global See |ale-integrations-local-executables| +g:ale_python_reorder_python_imports_auto_pipenv + *g:ale_python_reorder_python_imports_auto_pipenv* + *b:ale_python_reorder_python_imports_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +g:ale_python_reorder_python_imports_auto_poetry + *g:ale_python_reorder_python_imports_auto_poetry* + *b:ale_python_reorder_python_imports_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_reorder_python_imports_auto_uv + *g:ale_python_reorder_python_imports_auto_uv* + *b:ale_python_reorder_python_imports_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== ruff *ale-python-ruff* @@ -1322,6 +1621,15 @@ g:ale_python_ruff_auto_poetry *g:ale_python_ruff_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_ruff_auto_uv *g:ale_python_ruff_auto_uv* + *b:ale_python_ruff_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== ruff-format *ale-python-ruff-format* @@ -1386,6 +1694,15 @@ g:ale_python_ruff_format_auto_poetry *g:ale_python_ruff_format_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_ruff_format_auto_uv *g:ale_python_ruff_format_auto_uv* + *b:ale_python_ruff_format_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== unimport *ale-python-unimport* @@ -1410,6 +1727,15 @@ g:ale_python_unimport_auto_poetry *g:ale_python_unimport_auto_poetry* if true. This is overridden by a manually-set executable. +g:ale_python_unimport_auto_uv *g:ale_python_unimport_auto_uv* + *b:ale_python_unimport_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + g:ale_python_unimport_executable *g:ale_python_unimport_executable* *b:ale_python_unimport_executable* Type: |String| @@ -1476,6 +1802,32 @@ g:ale_python_vulture_use_global *g:ale_python_vulture_use_global* See |ale-integrations-local-executables| +g:ale_python_vulture_auto_pipenv *g:ale_python_vulture_auto_pipenv* + *b:ale_python_vulture_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +g:ale_python_vulture_auto_poetry *g:ale_python_vulture_auto_poetry* + *b:ale_python_vulture_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_vulture_auto_uv *g:ale_python_vulture_auto_uv* + *b:ale_python_vulture_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + =============================================================================== yapf *ale-python-yapf* @@ -1496,5 +1848,32 @@ g:ale_python_yapf_use_global *g:ale_python_yapf_use_global* See |ale-integrations-local-executables| +g:ale_python_yapf_auto_pipenv *g:ale_python_yapf_auto_pipenv* + *b:ale_python_yapf_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +g:ale_python_yapf_auto_poetry *g:ale_python_yapf_auto_poetry* + *b:ale_python_yapf_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_yapf_auto_uv *g:ale_python_yapf_auto_uv* + *b:ale_python_yapf_auto_uv* + Type: |Number| + Default: `0` + + Set the executable to `uv` if true. This is overridden by a manually-set + executable. + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/sources_non_forked/ale/doc/ale-ruby.txt b/sources_non_forked/ale/doc/ale-ruby.txt index ff9aa798..ff5a371f 100644 --- a/sources_non_forked/ale/doc/ale-ruby.txt +++ b/sources_non_forked/ale/doc/ale-ruby.txt @@ -258,6 +258,24 @@ g:ale_ruby_syntax_tree_options *g:ale_ruby_syntax_tree_options* This variable can be changed to modify flags given to SyntaxTree. +=============================================================================== +rubyfmt *ale-ruby-rubyfmt* + +g:ale_ruby_rubyfmt_executable *g:ale_ruby_rubyfmt_executable* + *b:ale_ruby_rubyfmt_executable* + Type: |String| + Default: `'rubyfmt'` + + This option can be changed to change the path for `rubyfmt`. + + +g:ale_ruby_rubyfmt_options *g:ale_ruby_rubyfmt_options* + *b:ale_ruby_rubyfmt_options* + Type: |String| + Default: `''` + + This option can be changed to pass extra options to `'rubyfmt'`. + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/sources_non_forked/ale/doc/ale-supported-languages-and-tools.txt b/sources_non_forked/ale/doc/ale-supported-languages-and-tools.txt index aa49a1b1..ec787d22 100644 --- a/sources_non_forked/ale/doc/ale-supported-languages-and-tools.txt +++ b/sources_non_forked/ale/doc/ale-supported-languages-and-tools.txt @@ -37,6 +37,9 @@ Notes: * ASM * `gcc` * `llvm-mc` +* Astro + * `eslint` + * `prettier` * AVRA * `avra` * Awk @@ -182,6 +185,7 @@ Notes: * `erblint` * `erubi` * `erubis` + * `htmlbeautifier` * `ruumba` * Erlang * `SyntaxErl` @@ -202,6 +206,9 @@ Notes: * `fusion-lint` * Git Commit Messages * `gitlint` +* Gleam + * `gleam_format` + * `gleamlsp` * GLSL * `glslang` * `glslls` @@ -271,6 +278,8 @@ Notes: * `rustywind` * `tidy` * `write-good` +* Hurl + * `hurlfmt` * Idris * `idris` * Ink @@ -290,6 +299,7 @@ Notes: * `javalsp` * `uncrustify` * JavaScript + * `biome` * `clang-format` * `cspell` * `deno` @@ -307,6 +317,7 @@ Notes: * `xo` * JSON * `VSCode JSON language server` + * `biome` * `clang-format` * `cspell` * `dprint` @@ -319,6 +330,7 @@ Notes: * JSON5 * `eslint` * JSONC + * `biome` * `eslint` * Jsonnet * `jsonnet-lint` @@ -418,6 +430,8 @@ Notes: * `ocamllsp` * `ocp-indent` * `ols` +* Odin + * `ols` * OpenApi * `ibm_validator` * `prettier` @@ -558,10 +572,12 @@ Notes: * `reek` * `rubocop` * `ruby` + * `rubyfmt` * `rufo` * `solargraph` * `sorbet` * `standardrb` + * `steep` * `syntax_tree` * Rust * `cargo`!! @@ -650,6 +666,7 @@ Notes: * TOML * `dprint` * TypeScript + * `biome` * `cspell` * `deno` * `dprint` @@ -669,6 +686,7 @@ Notes: * Verilog * `hdl-checker` * `iverilog` + * slang * `verilator` * `vlog` * `xvlog` diff --git a/sources_non_forked/ale/doc/ale-typescript.txt b/sources_non_forked/ale/doc/ale-typescript.txt index ab3f17bd..22fbe7b4 100644 --- a/sources_non_forked/ale/doc/ale-typescript.txt +++ b/sources_non_forked/ale/doc/ale-typescript.txt @@ -2,6 +2,56 @@ ALE TypeScript Integration *ale-typescript-options* +=============================================================================== +biome *ale-typescript-biome* + +g:ale_biome_executable *g:ale_biome_executable* + *b:ale_biome_executable* + Type: |String| + Default: `'biome'` + + +g:ale_biome_options *g:ale_biome_options* + *b:ale_biome_options* + Type: |String| + Default: `''` + + This variable can be set to pass additional options to `biome check` when + applying fixes. + + +g:ale_biome_use_global *g:ale_biome_use_global* + *b:ale_biome_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_biome_fixer_apply_unsafe *g:ale_biome_fixer_apply_unsafe* + *b:ale_biome_fixer_apply_unsafe* + Type: |Number| + Default: `0` + + If set to `1`, biome will apply unsafe fixes along with safe fixes. + + +g:ale_biome_lsp_project_root *g:ale_biome_lsp_project_root* + *b:ale_biome_lsp_project_root* + Type: |String| + Default: `''` + + If this variable is left unset, ALE will try to find the project root by + executing the following steps in the given order: + + 1. Find an ancestor directory containing a biome.json. + 2. Find an ancestor directory containing a biome.jsonc. + 3. Find an ancestor directory containing a package.json. + 4. Find an ancestor directory containing a .git folder. + 5. Use the directory of the current buffer (if the buffer was opened from + a file). + + =============================================================================== cspell *ale-typescript-cspell* diff --git a/sources_non_forked/ale/doc/ale-verilog.txt b/sources_non_forked/ale/doc/ale-verilog.txt index 611ed2f9..83e4f31e 100644 --- a/sources_non_forked/ale/doc/ale-verilog.txt +++ b/sources_non_forked/ale/doc/ale-verilog.txt @@ -3,7 +3,7 @@ ALE Verilog/SystemVerilog Integration *ale-verilog-options* =============================================================================== -ALE can use six different linters for Verilog HDL: +ALE can use seven different linters for Verilog HDL: HDL Checker Using `hdl_checker --lsp` @@ -11,6 +11,9 @@ ALE can use six different linters for Verilog HDL: iverilog: Using `iverilog -t null -Wall` + slang: + Using `slang -Weverything` + verilator Using `verilator --lint-only -Wall` @@ -21,7 +24,7 @@ ALE can use six different linters for Verilog HDL: Using `xvlog` Yosys - Using `ysoys -Q -T -p 'read_verilog'` + Using `yosys -Q -T -p 'read_verilog'` By default, both 'verilog' and 'systemverilog' filetypes are checked. @@ -64,6 +67,15 @@ iverilog *ale-verilog-iverilog* No additional options +=============================================================================== +slang *ale-verilog-slang* + +g:ale_verilog_slang_option *g:ale_verilog_slang_options* + *b:ale_verilog_slang_options* + Type: String + Default: '' + + This variable can be changed to modify 'slang' command arguments. =============================================================================== verilator *ale-verilog-verilator* @@ -73,7 +85,7 @@ g:ale_verilog_verilator_options *g:ale_verilog_verilator_options* Type: |String| Default: `''` - This variable can be changed to modify 'verilator' command arguments + This variable can be changed to modify 'verilator' command arguments. For example `'-sv --default-language "1800-2012"'` if you want to enable SystemVerilog parsing and select the 2012 version of the language. diff --git a/sources_non_forked/ale/doc/ale.txt b/sources_non_forked/ale/doc/ale.txt index 5f7999b8..d9be7682 100644 --- a/sources_non_forked/ale/doc/ale.txt +++ b/sources_non_forked/ale/doc/ale.txt @@ -186,11 +186,11 @@ script like so. > exec docker run -i --rm -v "$(pwd):/data" cytopia/pylint "$@" < -You will run to run Docker commands with `-i` in order to read from stdin. +You will want to run Docker commands with `-i` in order to read from stdin. With the above script in mind, you might configure ALE to lint your Python project with `pylint` by providing the path to the script to execute, and -mappings which describe how to between the two file systems in your +mappings which describe how to change between the two file systems in your `python.vim` |ftplugin| file, like so: > if expand('%:p') =~# '^/home/w0rp/git/test-pylint/' @@ -1670,7 +1670,7 @@ g:ale_linters *g:ale_linters* \ 'vue': ['eslint', 'vls'], \ 'zsh': ['shell'], \ 'v': ['v'], - \ 'yaml': ['spectral', 'yaml-language-server', 'yamllint'], + \ 'yaml': ['actionlint', 'spectral', 'yaml-language-server', 'yamllint'], \} < This option can be used to enable only a particular set of linters for a @@ -2899,6 +2899,9 @@ documented in additional help files. asm.....................................|ale-asm-options| gcc...................................|ale-asm-gcc| llvm_mc...............................|ale-asm-llvm_mc| + astro...................................|ale-astro-options| + eslint................................|ale-astro-eslint| + prettier..............................|ale-astro-prettier| avra....................................|ale-avra-options| avra..................................|ale-avra-avra| awk.....................................|ale-awk-options| @@ -3020,6 +3023,7 @@ documented in additional help files. eruby...................................|ale-eruby-options| erb-formatter.........................|ale-eruby-erbformatter| erblint...............................|ale-eruby-erblint| + htmlbeautifier........................|ale-eruby-htmlbeautifier| ruumba................................|ale-eruby-ruumba| fish....................................|ale-fish-options| fish_indent...........................|ale-fish-fish_indent| @@ -3031,6 +3035,9 @@ documented in additional help files. fusion-lint...........................|ale-fuse-fusionlint| git commit..............................|ale-gitcommit-options| gitlint...............................|ale-gitcommit-gitlint| + gleam...................................|ale-gleam-options| + gleam_format..........................|ale-gleam-gleam_format| + gleamlsp..............................|ale-gleam-gleamlsp| glsl....................................|ale-glsl-options| glslang...............................|ale-glsl-glslang| glslls................................|ale-glsl-glslls| @@ -3095,6 +3102,8 @@ documented in additional help files. tidy..................................|ale-html-tidy| vscodehtml............................|ale-html-vscode| write-good............................|ale-html-write-good| + hurl....................................|ale-hurl-options| + hurlfmt...............................|ale-hurl-hurlfmt| idris...................................|ale-idris-options| idris.................................|ale-idris-idris| ink.....................................|ale-ink-options| @@ -3114,6 +3123,7 @@ documented in additional help files. eclipselsp............................|ale-java-eclipselsp| uncrustify............................|ale-java-uncrustify| javascript..............................|ale-javascript-options| + biome.................................|ale-javascript-biome| clang-format..........................|ale-javascript-clangformat| cspell................................|ale-javascript-cspell| deno..................................|ale-javascript-deno| @@ -3130,6 +3140,7 @@ documented in additional help files. standard..............................|ale-javascript-standard| xo....................................|ale-javascript-xo| json....................................|ale-json-options| + biome.................................|ale-json-biome| clang-format..........................|ale-json-clangformat| cspell................................|ale-json-cspell| dprint................................|ale-json-dprint| @@ -3141,6 +3152,7 @@ documented in additional help files. spectral..............................|ale-json-spectral| vscodejson............................|ale-json-vscode| jsonc...................................|ale-jsonc-options| + biome.................................|ale-jsonc-biome| eslint................................|ale-jsonc-eslint| jsonnet.................................|ale-jsonnet-options| jsonnetfmt............................|ale-jsonnet-jsonnetfmt| @@ -3220,6 +3232,8 @@ documented in additional help files. ols...................................|ale-ocaml-ols| ocamlformat...........................|ale-ocaml-ocamlformat| ocp-indent............................|ale-ocaml-ocp-indent| + odin....................................|ale-odin-options| + ols...................................|ale-odin-ols| openapi.................................|ale-openapi-options| ibm_validator.........................|ale-openapi-ibm-validator| prettier..............................|ale-openapi-prettier| @@ -3350,6 +3364,7 @@ documented in additional help files. sorbet................................|ale-ruby-sorbet| standardrb............................|ale-ruby-standardrb| syntax_tree...........................|ale-ruby-syntax_tree| + rubyfmt...............................|ale-ruby-rubyfmt| rust....................................|ale-rust-options| analyzer..............................|ale-rust-analyzer| cargo.................................|ale-rust-cargo| @@ -3436,6 +3451,7 @@ documented in additional help files. toml....................................|ale-toml-options| dprint................................|ale-toml-dprint| typescript..............................|ale-typescript-options| + biome.................................|ale-typescript-biome| cspell................................|ale-typescript-cspell| deno..................................|ale-typescript-deno| dprint................................|ale-typescript-dprint| @@ -3453,6 +3469,7 @@ documented in additional help files. verilog/systemverilog...................|ale-verilog-options| hdl-checker...........................|ale-verilog-hdl-checker| iverilog..............................|ale-verilog-iverilog| + slang.................................|ale-verilog-slang| verilator.............................|ale-verilog-verilator| vlog..................................|ale-verilog-vlog| xvlog.................................|ale-verilog-xvlog| diff --git a/sources_non_forked/ale/plugin/ale.vim b/sources_non_forked/ale/plugin/ale.vim index 47934fa0..054e9596 100644 --- a/sources_non_forked/ale/plugin/ale.vim +++ b/sources_non_forked/ale/plugin/ale.vim @@ -183,6 +183,9 @@ 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) +" Enable automatic detection of uv for Python linters. +let g:ale_python_auto_uv = get(g:, 'ale_python_auto_uv', 0) + " Enable automatic adjustment of environment variables for Python linters. " The variables are set based on ALE's virtualenv detection. let g:ale_python_auto_virtualenv = get(g:, 'ale_python_auto_virtualenv', 0) diff --git a/sources_non_forked/ale/supported-tools.md b/sources_non_forked/ale/supported-tools.md index 6431cfe6..f49b5a02 100644 --- a/sources_non_forked/ale/supported-tools.md +++ b/sources_non_forked/ale/supported-tools.md @@ -46,6 +46,9 @@ formatting. * ASM * [gcc](https://gcc.gnu.org) * [llvm-mc](https://llvm.org) +* Astro + * [eslint](http://eslint.org/) + * [prettier](https://github.com/prettier/prettier) * AVRA * [avra](https://github.com/Ro5bert/avra) * Awk @@ -191,6 +194,7 @@ formatting. * [erblint](https://github.com/Shopify/erb-lint) * [erubi](https://github.com/jeremyevans/erubi) * [erubis](https://github.com/kwatch/erubis) + * [htmlbeautifier](https://github.com/threedaymonk/htmlbeautifier) * [ruumba](https://github.com/ericqweinstein/ruumba) * Erlang * [SyntaxErl](https://github.com/ten0s/syntaxerl) @@ -211,6 +215,9 @@ formatting. * [fusion-lint](https://github.com/RyanSquared/fusionscript) * Git Commit Messages * [gitlint](https://github.com/jorisroovers/gitlint) +* Gleam + * [gleam_format](https://github.com/gleam-lang/gleam) + * [gleamlsp](https://github.com/gleam-lang/gleam) * GLSL * [glslang](https://github.com/KhronosGroup/glslang) * [glslls](https://github.com/svenstaro/glsl-language-server) @@ -280,6 +287,8 @@ formatting. * [rustywind](https://github.com/avencera/rustywind) * [tidy](http://www.html-tidy.org/) * [write-good](https://github.com/btford/write-good) +* Hurl + * [hurlfmt](https://hurl.dev) * Idris * [idris](http://www.idris-lang.org/) * Ink @@ -299,6 +308,7 @@ formatting. * [javalsp](https://github.com/georgewfraser/vscode-javac) * [uncrustify](https://github.com/uncrustify/uncrustify) * JavaScript + * [biome](https://biomejs.dev/) * [clang-format](https://clang.llvm.org/docs/ClangFormat.html) * [cspell](https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell) * [deno](https://deno.land/) @@ -316,6 +326,7 @@ formatting. * [xo](https://github.com/sindresorhus/xo) * JSON * [VSCode JSON language server](https://github.com/hrsh7th/vscode-langservers-extracted) + * [biome](https://biomejs.dev/) * [clang-format](https://clang.llvm.org/docs/ClangFormat.html) * [cspell](https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell) :warning: * [dprint](https://dprint.dev) @@ -328,6 +339,7 @@ formatting. * JSON5 * [eslint](http://eslint.org/) :warning: * JSONC + * [biome](https://biomejs.dev/) * [eslint](http://eslint.org/) :warning: * Jsonnet * [jsonnet-lint](https://jsonnet.org/learning/tools.html) @@ -427,6 +439,8 @@ formatting. * [ocamllsp](https://github.com/ocaml/ocaml-lsp) * [ocp-indent](https://github.com/OCamlPro/ocp-indent) * [ols](https://github.com/freebroccolo/ocaml-language-server) +* Odin + * [ols](https://github.com/DanielGavin/ols) * OpenApi * [ibm_validator](https://github.com/IBM/openapi-validator) * [prettier](https://github.com/prettier/prettier) @@ -567,10 +581,12 @@ formatting. * [reek](https://github.com/troessner/reek) * [rubocop](https://github.com/bbatsov/rubocop) * [ruby](https://www.ruby-lang.org) + * [rubyfmt](https://github.com/fables-tales/rubyfmt) * [rufo](https://github.com/ruby-formatter/rufo) * [solargraph](https://solargraph.org) * [sorbet](https://github.com/sorbet/sorbet) * [standardrb](https://github.com/testdouble/standard) + * [steep](https://github.com/soutaro/steep) * [syntax_tree](https://github.com/ruby-syntax-tree/syntax_tree) * Rust * [cargo](https://github.com/rust-lang/cargo) :floppy_disk: (see `:help ale-integration-rust` for configuration instructions) @@ -659,6 +675,7 @@ formatting. * TOML * [dprint](https://dprint.dev) * TypeScript + * [biome](https://biomejs.dev/) * [cspell](https://github.com/streetsidesoftware/cspell/tree/main/packages/cspell) * [deno](https://deno.land/) * [dprint](https://dprint.dev/) @@ -678,6 +695,7 @@ formatting. * Verilog * [hdl-checker](https://pypi.org/project/hdl-checker) * [iverilog](https://github.com/steveicarus/iverilog) + * [slang](https://github.com/MikePopoloski/slang) * [verilator](http://www.veripool.org/projects/verilator/wiki/Intro) * [vlog](https://www.mentor.com/products/fv/questa/) * [xvlog](https://www.xilinx.com/products/design-tools/vivado.html) @@ -708,7 +726,7 @@ formatting. * XML * [xmllint](http://xmlsoft.org/xmllint.html) * YAML - * [actionlint](https://github.com/rhysd/actionlint) :warning: + * [actionlint](https://github.com/rhysd/actionlint) * [circleci](https://circleci.com/docs/2.0/local-cli) :floppy_disk: :warning: * [gitlablint](https://github.com/elijah-roberts/gitlab-lint) * [prettier](https://github.com/prettier/prettier) diff --git a/sources_non_forked/ale/test-files/python/no_uv/whatever.py b/sources_non_forked/ale/test-files/python/no_uv/whatever.py new file mode 100644 index 00000000..e69de29b diff --git a/sources_non_forked/bufexplorer/.gitignore b/sources_non_forked/bufexplorer/.gitignore index 42d5d592..0d0e6876 100644 --- a/sources_non_forked/bufexplorer/.gitignore +++ b/sources_non_forked/bufexplorer/.gitignore @@ -4,3 +4,7 @@ dist.bat *.zip tags *.sw[a-p] + +# Github token. +github_token + diff --git a/sources_non_forked/bufexplorer/.goreleaser.yaml b/sources_non_forked/bufexplorer/.goreleaser.yaml new file mode 100644 index 00000000..4a1fa1cc --- /dev/null +++ b/sources_non_forked/bufexplorer/.goreleaser.yaml @@ -0,0 +1,54 @@ +# This is an example .goreleaser.yml file with some sensible defaults. +# Make sure to check the documentation at https://goreleaser.com + +# The lines below are called `modelines`. See `:help modeline` +# Feel free to remove those if you don't want/need to use them. +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj + +#version: 1 + +env_files: + # GoReleaser requires an API token with the 'repo' scope selected to deploy + # the artifacts to GitHub. You can create one here + # https://github.com/settings/tokens/new. + github_token: ./github_token + +#before: +# hooks: +# # You may remove this if you don't use go modules. +# - go mod tidy +# # you may remove this if you don't need go generate +# - go generate ./... + +builds: + - skip: true + +archives: + - format: tar.gz + # this name template makes the OS and Arch compatible with the results of `uname`. + name_template: >- + {{ .ProjectName }}_ + {{- title .Os }}_ + {{- if eq .Arch "amd64" }}x86_64 + {{- else if eq .Arch "386" }}i386 + {{- else }}{{ .Arch }}{{ end }} + {{- if .Arm }}v{{ .Arm }}{{ end }} + # use zip for windows archives + format_overrides: + - goos: windows + format: zip + +checksum: + name_template: 'checksums.txt' + +snapshot: + name_template: '{{ .Tag }}-next' + +changelog: + use: github-native + sort: asc + +release: + draft: false + replace_existing_draft: true diff --git a/sources_non_forked/bufexplorer/doc/bufexplorer.txt b/sources_non_forked/bufexplorer/doc/bufexplorer.txt index 6e1e1b51..6f82611e 100644 --- a/sources_non_forked/bufexplorer/doc/bufexplorer.txt +++ b/sources_non_forked/bufexplorer/doc/bufexplorer.txt @@ -1,7 +1,7 @@ -*bufexplorer.txt* Buffer Explorer Last Change: 01 May 2023 +*bufexplorer.txt* Buffer Explorer Last Change: 13 Aug 2024 Buffer Explorer *buffer-explorer* *bufexplorer* - Version 7.4.26 + Version 7.4.27 Plugin for easily exploring (or browsing) Vim|:buffers|. @@ -263,6 +263,10 @@ The default is 1. =============================================================================== CHANGE LOG *bufexplorer-changelog* +7.4.27 May 30, 2024 + - Thanks to GitHub user NotNormallyAGitUser, for the recommendation to + change the display of the relative path to replace $HOME with "~". + This save valuable screen real estate. 7.4.26 May 01, 2023 What's Changed - wipe explorer buffer on hide by @basharh in @@ -795,9 +799,9 @@ TODO *bufexplorer-todo* =============================================================================== CREDITS *bufexplorer-credits* -Author: Jeff Lanzarotta +Author: Jeff Lanzarotta -Credit must go out to Bram Moolenaar and all the Vim developers for +Credit must go out to Bram Moolenaar (RIP) and all the Vim developers for making the world's best editor (IMHO). I also want to thank everyone who helped and gave me suggestions. I wouldn't want to leave anyone out so I won't list names. @@ -805,7 +809,7 @@ won't list names. =============================================================================== COPYRIGHT *bufexplorer-copyright* -Copyright (c) 2001-2022, Jeff Lanzarotta +Copyright (c) 2001-2024, Jeff Lanzarotta All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/sources_non_forked/bufexplorer/how_to_release.txt b/sources_non_forked/bufexplorer/how_to_release.txt new file mode 100644 index 00000000..f3f565d8 --- /dev/null +++ b/sources_non_forked/bufexplorer/how_to_release.txt @@ -0,0 +1,16 @@ +https://goreleaser.com/quick-start/ + +To make a release... + +1. Make changes. +2. Commit and push changes. +3. git tag -a v7.4.27 -m "Release v7.4.27." +4. git push origin v7.4.27 +5. goreleaser release --clean +6. Go to github and make the release. + +If something happens and the tag is messed up, you will need to delete the +local and remote tag and release again. To delete the tag: + +1. git tag -d v7.4.27 +2. git push --delete origin v7.4.27 diff --git a/sources_non_forked/bufexplorer/plugin/bufexplorer.vim b/sources_non_forked/bufexplorer/plugin/bufexplorer.vim index c5c04e71..f5a74613 100644 --- a/sources_non_forked/bufexplorer/plugin/bufexplorer.vim +++ b/sources_non_forked/bufexplorer/plugin/bufexplorer.vim @@ -1,5 +1,5 @@ "============================================================================ -" Copyright: Copyright (c) 2001-2023, Jeff Lanzarotta +" Copyright: Copyright (c) 2001-2024, Jeff Lanzarotta " All rights reserved. " " Redistribution and use in source and binary forms, with or @@ -36,7 +36,7 @@ " Name Of File: bufexplorer.vim " Description: Buffer Explorer Vim Plugin " Maintainer: Jeff Lanzarotta (my name at gmail dot com) -" Last Changed: Monday, 01 May 2023 +" Last Changed: Tuesday, 13 August 2024 " Version: See g:bufexplorer_version for version number. " Usage: This file should reside in the plugin directory and be " automatically sourced. @@ -74,7 +74,7 @@ endif "1}}} " Version number -let g:bufexplorer_version = "7.4.26" +let g:bufexplorer_version = "7.4.27" " Plugin Code {{{1 " Check for Vim version {{{2 @@ -770,12 +770,12 @@ function! s:BuildBufferList() " Are we to split the path and file name? if g:bufExplorerSplitOutPathName let type = (g:bufExplorerShowRelativePath) ? "relativepath" : "path" - let path = buf[type] + let path = substitute( buf[type], $HOME."\\>", "~", "" ) let pad = (g:bufExplorerShowUnlisted) ? s:allpads.shortname : s:listedpads.shortname let line .= buf.shortname." ".strpart(pad.path, s:StringWidth(buf.shortname)) else let type = (g:bufExplorerShowRelativePath) ? "relativename" : "fullname" - let path = buf[type] + let path = substitute( buf[type], $HOME."\\>", "~", "" ) let line .= path endif diff --git a/sources_non_forked/copilot.vim/.github/workflows/auto-close-pr.yml b/sources_non_forked/copilot.vim/.github/workflows/auto-close-pr.yml new file mode 100644 index 00000000..043c2a92 --- /dev/null +++ b/sources_non_forked/copilot.vim/.github/workflows/auto-close-pr.yml @@ -0,0 +1,20 @@ +name: Auto-close PR +on: + pull_request_target: + types: [opened, reopened] + +jobs: + close: + name: Run + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - run: | + gh pr close ${{ github.event.pull_request.number }} --comment \ + "At the moment we are not accepting contributions to the repository. + + Feedback for Copilot.vim can be given in the [Copilot community discussions](https://github.com/orgs/community/discussions/categories/copilot)." + env: + GH_REPO: ${{ github.repository }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/sources_non_forked/copilot.vim/README.md b/sources_non_forked/copilot.vim/README.md index 9f15e9a9..c6b8dae9 100644 --- a/sources_non_forked/copilot.vim/README.md +++ b/sources_non_forked/copilot.vim/README.md @@ -1,4 +1,4 @@ -# Copilot.vim +# GitHub Copilot for Vim and Neovim GitHub Copilot uses OpenAI Codex to suggest code and entire functions in real-time right from your editor. Trained on billions of lines of public @@ -48,7 +48,7 @@ Terms](https://docs.github.com/en/site-policy/github-terms/github-terms-for-addi git clone https://github.com/github/copilot.vim.git ` $HOME/AppData/Local/nvim/pack/github/start/copilot.vim -4. Start Neovim and invoke `:Copilot setup`. +4. Start Vim/Neovim and invoke `:Copilot setup`. [Node.js]: https://nodejs.org/en/download/ [Neovim]: https://github.com/neovim/neovim/releases/latest diff --git a/sources_non_forked/copilot.vim/autoload/copilot.vim b/sources_non_forked/copilot.vim/autoload/copilot.vim index 920aa72f..5016a039 100644 --- a/sources_non_forked/copilot.vim/autoload/copilot.vim +++ b/sources_non_forked/copilot.vim/autoload/copilot.vim @@ -1,11 +1,6 @@ -if exists('g:autoloaded_copilot') - finish -endif -let g:autoloaded_copilot = 1 - scriptencoding utf-8 -let s:has_nvim_ghost_text = has('nvim-0.6') && exists('*nvim_buf_get_mark') +let s:has_nvim_ghost_text = has('nvim-0.7') && exists('*nvim_buf_get_mark') let s:vim_minimum_version = '9.0.0185' let s:has_vim_ghost_text = has('patch-' . s:vim_minimum_version) && has('textprop') let s:has_ghost_text = s:has_nvim_ghost_text || s:has_vim_ghost_text @@ -39,81 +34,68 @@ function! s:EditorConfiguration() abort \ } endfunction -function! s:StatusNotification(params, ...) abort - let status = get(a:params, 'status', '') - if status ==? 'error' - let s:agent_error = a:params.message - else - unlet! s:agent_error - endif -endfunction - function! copilot#Init(...) abort - call timer_start(0, { _ -> s:Start() }) + call copilot#util#Defer({ -> exists('s:client') || s:Start() }) endfunction function! s:Running() abort - return exists('s:agent.job') || exists('s:agent.client_id') + return exists('s:client.job') || exists('s:client.client_id') endfunction function! s:Start() abort - if s:Running() + if s:Running() || exists('s:client.startup_error') return endif - let s:agent = copilot#agent#New({'methods': { - \ 'statusNotification': function('s:StatusNotification'), - \ 'PanelSolution': function('copilot#panel#Solution'), - \ 'PanelSolutionsDone': function('copilot#panel#SolutionsDone'), - \ 'copilot/openURL': function('s:OpenURL'), - \ }, - \ 'editorConfiguration' : s:EditorConfiguration()}) + let s:client = copilot#client#New({'editorConfiguration' : s:EditorConfiguration()}) endfunction function! s:Stop() abort - if exists('s:agent') - let agent = remove(s:, 'agent') - call agent.Close() + if exists('s:client') + let client = remove(s:, 'client') + call client.Close() endif endfunction -function! copilot#Agent() abort +function! copilot#Client() abort call s:Start() - return s:agent + return s:client endfunction -function! copilot#RunningAgent() abort +function! copilot#RunningClient() abort if s:Running() - return s:agent + return s:client else return v:null endif endfunction -function! s:NodeVersionWarning() abort - if exists('s:agent.node_version') && s:agent.node_version =~# '^16\.' +if has('nvim-0.7') && !has(luaeval('vim.version().api_prerelease') ? 'nvim-0.8.1' : 'nvim-0.8.0') + let s:editor_warning = 'Neovim 0.7 support is deprecated and will be dropped in a future release of copilot.vim.' +endif +if has('vim_starting') && exists('s:editor_warning') + call copilot#logger#Warn(s:editor_warning) +endif +function! s:EditorVersionWarning() abort + if exists('s:editor_warning') echohl WarningMsg - echo "Warning: Node.js 16 is approaching end of life and support will be dropped in a future release of copilot.vim." - echohl NONE - elseif exists('s:agent.node_version_warning') - echohl WarningMsg - echo 'Warning:' s:agent.node_version_warning - echohl NONE + echo 'Warning: ' . s:editor_warning + echohl None endif endfunction function! copilot#Request(method, params, ...) abort - let agent = copilot#Agent() - return call(agent.Request, [a:method, a:params] + a:000) + let client = copilot#Client() + return call(client.Request, [a:method, a:params] + a:000) endfunction function! copilot#Call(method, params, ...) abort - let agent = copilot#Agent() - return call(agent.Call, [a:method, a:params] + a:000) + let client = copilot#Client() + return call(client.Call, [a:method, a:params] + a:000) endfunction function! copilot#Notify(method, params, ...) abort - let agent = copilot#Agent() - return call(agent.Notify, [a:method, a:params] + a:000) + let client = copilot#Client() + return call(client.Notify, [a:method, a:params] + a:000) endfunction function! copilot#NvimNs() abort @@ -125,37 +107,21 @@ function! copilot#Clear() abort call timer_stop(remove(g:, '_copilot_timer')) endif if exists('b:_copilot') - call copilot#agent#Cancel(get(b:_copilot, 'first', {})) - call copilot#agent#Cancel(get(b:_copilot, 'cycling', {})) + call copilot#client#Cancel(get(b:_copilot, 'first', {})) + call copilot#client#Cancel(get(b:_copilot, 'cycling', {})) endif call s:UpdatePreview() unlet! b:_copilot return '' endfunction -function! s:Reject(bufnr) abort - try - let dict = getbufvar(a:bufnr, '_copilot') - if type(dict) == v:t_dict && !empty(get(dict, 'shown_choices', {})) - call copilot#Request('notifyRejected', {'uuids': keys(dict.shown_choices)}) - let dict.shown_choices = {} - endif - catch - call copilot#logger#Exception() - endtry -endfunction - function! copilot#Dismiss() abort - call s:Reject('%') call copilot#Clear() call s:UpdatePreview() return '' endfunction let s:filetype_defaults = { - \ 'yaml': 0, - \ 'markdown': 0, - \ 'help': 0, \ 'gitcommit': 0, \ 'gitrebase': 0, \ 'hgcommit': 0, @@ -192,26 +158,41 @@ endfunction function! copilot#Enabled() abort return get(g:, 'copilot_enabled', 1) \ && empty(s:BufferDisabled()) - \ && empty(copilot#Agent().StartupError()) endfunction +let s:inline_invoked = 1 +let s:inline_automatic = 2 + function! copilot#Complete(...) abort if exists('g:_copilot_timer') call timer_stop(remove(g:, '_copilot_timer')) endif - let params = copilot#doc#Params() - if !exists('b:_copilot.params') || b:_copilot.params !=# params - let b:_copilot = {'params': params, 'first': - \ copilot#Request('getCompletions', params)} + let target = [bufnr(''), getbufvar('', 'changedtick'), line('.'), col('.')] + if !exists('b:_copilot.target') || b:_copilot.target !=# target + if exists('b:_copilot.first') + call copilot#client#Cancel(b:_copilot.first) + endif + if exists('b:_copilot.cycling') + call copilot#client#Cancel(b:_copilot.cycling) + endif + let params = { + \ 'textDocument': {'uri': bufnr('')}, + \ 'position': copilot#util#AppendPosition(), + \ 'formattingOptions': {'insertSpaces': &expandtab ? v:true : v:false, 'tabSize': shiftwidth()}, + \ 'context': {'triggerKind': s:inline_automatic}} + let b:_copilot = { + \ 'target': target, + \ 'params': params, + \ 'first': copilot#Request('textDocument/inlineCompletion', params)} let g:_copilot_last = b:_copilot endif let completion = b:_copilot.first if !a:0 return completion.Await() else - call copilot#agent#Result(completion, a:1) + call copilot#client#Result(completion, function(a:1, [b:_copilot])) if a:0 > 1 - call copilot#agent#Error(completion, a:2) + call copilot#client#Error(completion, function(a:2, [b:_copilot])) endif endif endfunction @@ -221,37 +202,37 @@ function! s:HideDuringCompletion() abort endfunction function! s:SuggestionTextWithAdjustments() abort + let empty = ['', 0, 0, {}] try if mode() !~# '^[iR]' || (s:HideDuringCompletion() && pumvisible()) || !exists('b:_copilot.suggestions') - return ['', 0, 0, ''] + return empty endif let choice = get(b:_copilot.suggestions, b:_copilot.choice, {}) - if !has_key(choice, 'range') || choice.range.start.line != line('.') - 1 || type(choice.text) !=# v:t_string - return ['', 0, 0, ''] + if !has_key(choice, 'range') || choice.range.start.line != line('.') - 1 || type(choice.insertText) !=# v:t_string + return empty endif let line = getline('.') let offset = col('.') - 1 - let choice_text = strpart(line, 0, copilot#doc#UTF16ToByteIdx(line, choice.range.start.character)) . choice.text + let choice_text = strpart(line, 0, copilot#util#UTF16ToByteIdx(line, choice.range.start.character)) . substitute(choice.insertText, "\n*$", '', '') let typed = strpart(line, 0, offset) - let end_offset = copilot#doc#UTF16ToByteIdx(line, choice.range.end.character) + let end_offset = copilot#util#UTF16ToByteIdx(line, choice.range.end.character) if end_offset < 0 let end_offset = len(line) endif let delete = strpart(line, offset, end_offset - offset) - let uuid = get(choice, 'uuid', '') if typed =~# '^\s*$' let leading = matchstr(choice_text, '^\s\+') let unindented = strpart(choice_text, len(leading)) if strpart(typed, 0, len(leading)) == leading && unindented !=# delete - return [unindented, len(typed) - len(leading), strchars(delete), uuid] + return [unindented, len(typed) - len(leading), strchars(delete), choice] endif elseif typed ==# strpart(choice_text, 0, offset) - return [strpart(choice_text, offset), 0, strchars(delete), uuid] + return [strpart(choice_text, offset), 0, strchars(delete), choice] endif catch call copilot#logger#Exception() endtry - return ['', 0, 0, ''] + return empty endfunction @@ -271,12 +252,12 @@ function! s:GetSuggestionsCyclingCallback(context, result) abort let callbacks = remove(a:context, 'cycling_callbacks') let seen = {} for suggestion in a:context.suggestions - let seen[suggestion.text] = 1 + let seen[suggestion.insertText] = 1 endfor - for suggestion in get(a:result, 'completions', []) - if !has_key(seen, suggestion.text) + for suggestion in get(a:result, 'items', []) + if !has_key(seen, suggestion.insertText) call add(a:context.suggestions, suggestion) - let seen[suggestion.text] = 1 + let seen[suggestion.insertText] = 1 endif endfor for Callback in callbacks @@ -290,9 +271,11 @@ function! s:GetSuggestionsCycling(callback) abort elseif exists('b:_copilot.cycling') call a:callback(b:_copilot) elseif exists('b:_copilot.suggestions') + let params = deepcopy(b:_copilot.first.params) + let params.context.triggerKind = s:inline_invoked let b:_copilot.cycling_callbacks = [a:callback] - let b:_copilot.cycling = copilot#Request('getCompletionsCycling', - \ b:_copilot.first.params, + let b:_copilot.cycling = copilot#Request('textDocument/inlineCompletion', + \ params, \ function('s:GetSuggestionsCyclingCallback', [b:_copilot]), \ function('s:GetSuggestionsCyclingCallback', [b:_copilot]), \ ) @@ -310,10 +293,10 @@ function! copilot#Previous() abort endfunction function! copilot#GetDisplayedSuggestion() abort - let [text, outdent, delete, uuid] = s:SuggestionTextWithAdjustments() + let [text, outdent, delete, item] = s:SuggestionTextWithAdjustments() return { - \ 'uuid': uuid, + \ 'item': item, \ 'text': text, \ 'outdentSize': outdent, \ 'deleteSize': delete} @@ -330,8 +313,8 @@ endfunction function! s:UpdatePreview() abort try - let [text, outdent, delete, uuid] = s:SuggestionTextWithAdjustments() - let text = split(text, "\n", 1) + let [text, outdent, delete, item] = s:SuggestionTextWithAdjustments() + let text = split(text, "\r\n\\=\\|\n", 1) if empty(text[-1]) call remove(text, -1) endif @@ -348,7 +331,7 @@ function! s:UpdatePreview() abort call s:ClearPreview() if s:has_nvim_ghost_text let data = {'id': 1} - let data.virt_text_win_col = virtcol('.') - 1 + let data.virt_text_pos = 'overlay' let append = strpart(getline('.'), col('.') - 1 + delete) let data.virt_text = [[text[0] . append . repeat(' ', delete - len(text[0])), s:hlgroup]] if len(text) > 1 @@ -361,8 +344,27 @@ function! s:UpdatePreview() abort endif let data.hl_mode = 'combine' call nvim_buf_set_extmark(0, copilot#NvimNs(), line('.')-1, col('.')-1, data) - else - call prop_add(line('.'), col('.'), {'type': s:hlgroup, 'text': text[0]}) + elseif s:has_vim_ghost_text + let new_suffix = text[0] + let current_suffix = getline('.')[col('.') - 1 :] + let inset = '' + while delete > 0 && !empty(new_suffix) + let last_char = matchstr(new_suffix, '.$') + let new_suffix = matchstr(new_suffix, '^.\{-\}\ze.$') + if last_char ==# matchstr(current_suffix, '.$') + if !empty(inset) + call prop_add(line('.'), col('.') + len(current_suffix), {'type': s:hlgroup, 'text': inset}) + let inset = '' + endif + let current_suffix = matchstr(current_suffix, '^.\{-\}\ze.$') + let delete -= 1 + else + let inset = last_char . inset + endif + endwhile + if !empty(new_suffix . inset) + call prop_add(line('.'), col('.'), {'type': s:hlgroup, 'text': new_suffix . inset}) + endif for line in text[1:] call prop_add(line('.'), 0, {'type': s:hlgroup, 'text_align': 'below', 'text': line}) endfor @@ -370,28 +372,35 @@ function! s:UpdatePreview() abort call prop_add(line('.'), col('$'), {'type': s:annot_hlgroup, 'text': ' ' . annot}) endif endif - if !has_key(b:_copilot.shown_choices, uuid) - let b:_copilot.shown_choices[uuid] = v:true - call copilot#Request('notifyShown', {'uuid': uuid}) - endif + call copilot#Notify('textDocument/didShowCompletion', {'item': item}) catch return copilot#logger#Exception() endtry endfunction -function! s:HandleTriggerResult(result) abort - if !exists('b:_copilot') - return +function! s:HandleTriggerResult(state, result) abort + let a:state.suggestions = type(a:result) == type([]) ? a:result : get(empty(a:result) ? {} : a:result, 'items', []) + let a:state.choice = 0 + if get(b:, '_copilot') is# a:state + call s:UpdatePreview() + endif +endfunction + +function! s:HandleTriggerError(state, result) abort + let a:state.suggestions = [] + let a:state.choice = 0 + let a:state.error = a:result + if get(b:, '_copilot') is# a:state + call s:UpdatePreview() endif - let b:_copilot.suggestions = get(a:result, 'completions', []) - let b:_copilot.choice = 0 - let b:_copilot.shown_choices = {} - call s:UpdatePreview() endfunction function! copilot#Suggest() abort + if !s:Running() + return '' + endif try - call copilot#Complete(function('s:HandleTriggerResult'), function('s:HandleTriggerResult')) + call copilot#Complete(function('s:HandleTriggerResult'), function('s:HandleTriggerError')) catch call copilot#logger#Exception() endtry @@ -400,30 +409,52 @@ endfunction function! s:Trigger(bufnr, timer) abort let timer = get(g:, '_copilot_timer', -1) - unlet! g:_copilot_timer if a:bufnr !=# bufnr('') || a:timer isnot# timer || mode() !=# 'i' return endif + unlet! g:_copilot_timer return copilot#Suggest() endfunction -function! copilot#IsMapped() abort - return get(g:, 'copilot_assume_mapped') || - \ hasmapto('copilot#Accept(', 'i') -endfunction - -function! copilot#Schedule(...) abort - if !s:has_ghost_text || !copilot#Enabled() || !copilot#IsMapped() +function! copilot#Schedule() abort + if !s:has_ghost_text || !s:Running() || !copilot#Enabled() call copilot#Clear() return endif call s:UpdatePreview() - let delay = a:0 ? a:1 : get(g:, 'copilot_idle_delay', 15) + let delay = get(g:, 'copilot_idle_delay', 45) + call timer_stop(get(g:, '_copilot_timer', -1)) let g:_copilot_timer = timer_start(delay, function('s:Trigger', [bufnr('')])) endfunction -function! copilot#OnInsertLeave() abort - return copilot#Clear() +function! s:Attach(bufnr, ...) abort + try + return copilot#Client().Attach(a:bufnr) + catch + call copilot#logger#Exception() + endtry +endfunction + +function! copilot#OnFileType() abort + if empty(s:BufferDisabled()) && &l:modifiable && &l:buflisted + call copilot#util#Defer(function('s:Attach'), bufnr('')) + endif +endfunction + +function! s:Focus(bufnr, ...) abort + if s:Running() && copilot#Client().IsAttached(a:bufnr) + call copilot#Client().Notify('textDocument/didFocus', {'textDocument': {'uri': copilot#Client().Attach(a:bufnr).uri}}) + endif +endfunction + +function! copilot#OnBufEnter() abort + let bufnr = bufnr('') + call copilot#util#Defer(function('s:Focus'), bufnr) +endfunction + +function! copilot#OnInsertLeavePre() abort + call copilot#Clear() + call s:ClearPreview() endfunction function! copilot#OnInsertEnter() abort @@ -443,7 +474,6 @@ function! copilot#OnCursorMovedI() abort endfunction function! copilot#OnBufUnload() abort - call s:Reject(+expand('')) endfunction function! copilot#OnVimLeavePre() abort @@ -468,11 +498,19 @@ function! copilot#Accept(...) abort if empty(text) let text = s.text endif - call copilot#Request('notifyAccepted', {'uuid': s.uuid, 'acceptedLength': copilot#doc#UTF16Width(text)}) + if text ==# s.text && has_key(s.item, 'command') + call copilot#Request('workspace/executeCommand', s.item.command) + else + let line_text = strpart(getline('.'), 0, col('.') - 1) . text + call copilot#Notify('textDocument/didPartiallyAcceptCompletion', { + \ 'item': s.item, + \ 'acceptedLength': copilot#util#UTF16Width(line_text) - s.item.range.start.character}) + endif call s:ClearPreview() let s:suggestion_text = text + let recall = text =~# "\n" ? "\\=" : "\\=" return repeat("\\", s.outdentSize) . repeat("\", s.deleteSize) . - \ "\\=copilot#TextQueuedForInsertion()\" . (a:0 > 1 ? '' : "\") + \ recall . "copilot#TextQueuedForInsertion()\" . (a:0 > 1 ? '' : "\") endif let default = get(g:, 'copilot_tab_fallback', pumvisible() ? "\" : "\t") if !a:0 @@ -525,21 +563,6 @@ function! copilot#Browser() abort endif endfunction -function! s:OpenURL(params) abort - echo a:params.target - let browser = copilot#Browser() - if empty(browser) - return v:false - endif - let status = {} - call copilot#job#Stream(browser + [a:params.target], v:null, v:null, function('s:BrowserCallback', [status])) - let time = reltime() - while empty(status) && reltimefloat(reltime(time)) < 1 - sleep 10m - endwhile - return get(status, 'code') ? v:false : v:true -endfunction - let s:commands = {} function! s:EnabledStatusMessage() abort @@ -550,8 +573,6 @@ function! s:EnabledStatusMessage() abort else return "Vim " . s:vim_minimum_version . " required to support ghost text" endif - elseif !copilot#IsMapped() - return ' map has been disabled or is claimed by another plugin' elseif !get(g:, 'copilot_enabled', 1) return 'Disabled globally by :Copilot disable' elseif buf_disabled is# 5 @@ -572,7 +593,7 @@ function! s:EnabledStatusMessage() abort endfunction function! s:VerifySetup() abort - let error = copilot#Agent().StartupError() + let error = copilot#Client().StartupError() if !empty(error) echo 'Copilot: ' . error return @@ -589,6 +610,12 @@ function! s:VerifySetup() abort echo 'Copilot: Telemetry terms not accepted. Invoke :Copilot setup' return endif + + if status.status ==# 'NotAuthorized' + echo "Copilot: You don't have access to GitHub Copilot. Sign up by visiting https://github.com/settings/copilot" + return + endif + return 1 endfunction @@ -597,31 +624,22 @@ function! s:commands.status(opts) abort return endif + if exists('s:client.status.status') && s:client.status.status =~# 'Warning\|Error' + echo 'Copilot: ' . s:client.status.status + if !empty(get(s:client.status, 'message', '')) + echon ': ' . s:client.status.message + endif + return + endif + let status = s:EnabledStatusMessage() if !empty(status) echo 'Copilot: ' . status return endif - let startup_error = copilot#Agent().StartupError() - if !empty(startup_error) - echo 'Copilot: ' . startup_error - return - endif - - if exists('s:agent_error') - echo 'Copilot: ' . s:agent_error - return - endif - - let status = copilot#Call('checkStatus', {}) - if status.status ==# 'NotAuthorized' - echo 'Copilot: Not authorized' - return - endif - - echo 'Copilot: Enabled and online' - call s:NodeVersionWarning() + echo 'Copilot: Ready' + call s:EditorVersionWarning() endfunction function! s:commands.signout(opts) abort @@ -635,7 +653,7 @@ function! s:commands.signout(opts) abort endfunction function! s:commands.setup(opts) abort - let startup_error = copilot#Agent().StartupError() + let startup_error = copilot#Client().StartupError() if !empty(startup_error) echo 'Copilot: ' . startup_error return @@ -645,7 +663,7 @@ function! s:commands.setup(opts) abort let status = copilot#Call('checkStatus', {}) if has_key(status, 'user') - let data = {} + let data = {'status': 'AlreadySignedIn', 'user': status.user} else let data = copilot#Call('signInInitiate', {}) endif @@ -653,23 +671,25 @@ function! s:commands.setup(opts) abort if has_key(data, 'verificationUri') let uri = data.verificationUri if has('clipboard') - let @+ = data.userCode - let @* = data.userCode + try + let @+ = data.userCode + catch + endtry + try + let @* = data.userCode + catch + endtry endif - call s:Echo("First copy your one-time code: " . data.userCode) + let codemsg = "First copy your one-time code: " . data.userCode . "\n" try if len(&mouse) let mouse = &mouse set mouse= endif if get(a:opts, 'bang') - call s:Echo("In your browser, visit " . uri) + call s:Echo(codemsg . "In your browser, visit " . uri) elseif len(browser) - call s:Echo("Press ENTER to open GitHub in your browser") - let c = getchar() - while c isnot# 13 && c isnot# 10 && c isnot# 0 - let c = getchar() - endwhile + call input(codemsg . "Press ENTER to open GitHub in your browser\n") let status = {} call copilot#job#Stream(browser + [uri], v:null, v:null, function('s:BrowserCallback', [status])) let time = reltime() @@ -682,9 +702,9 @@ function! s:commands.setup(opts) abort call s:Echo("Opened " . uri) endif else - call s:Echo("Could not find browser. Visit " . uri) + call s:Echo(codemsg . "Could not find browser. Visit " . uri) endif - call s:Echo("Waiting (could take up to 5 seconds)") + call s:Echo("Waiting (could take up to 10 seconds)") let request = copilot#Request('signInConfirm', {'userCode': data.userCode}).Wait() finally if exists('mouse') @@ -696,6 +716,8 @@ function! s:commands.setup(opts) abort else let status = request.result endif + elseif get(data, 'status', '') isnot# 'AlreadySignedIn' + return 'echoerr ' . string('Copilot: Something went wrong') endif let user = get(status, 'user', '') @@ -704,22 +726,46 @@ function! s:commands.setup(opts) abort endfunction let s:commands.auth = s:commands.setup +let s:commands.signin = s:commands.setup function! s:commands.help(opts) abort return a:opts.mods . ' help ' . (len(a:opts.arg) ? ':Copilot_' . a:opts.arg : 'copilot') endfunction function! s:commands.version(opts) abort - let info = copilot#agent#EditorInfo() - echo 'copilot.vim ' .info.editorPluginInfo.version - echo info.editorInfo.name . ' ' . info.editorInfo.version - if exists('s:agent.node_version') - echo 'dist/agent.js ' . s:agent.Call('getVersion', {}).version - echo 'Node.js ' . s:agent.node_version - call s:NodeVersionWarning() + echo 'copilot.vim ' .copilot#client#EditorPluginInfo().version + let editorInfo = copilot#client#EditorInfo() + echo editorInfo.name . ' ' . editorInfo.version + if s:Running() + let versions = s:client.Request('getVersion', {}) + if exists('s:client.serverInfo.version') + echo s:client.serverInfo.name . ' ' . s:client.serverInfo.version + else + echo 'GitHub Copilot Language Server ' . versions.Await().version + endif + if exists('s:client.node_version') + echo 'Node.js ' . s:client.node_version + else + echo 'Node.js ' . substitute(get(versions.Await(), 'runtimeVersion', '?'), '^node/', '', 'g') + endif else - echo 'dist/agent.js not running' + echo 'Not running' + if exists('s:client.node_version') + echo 'Node.js ' . s:client.node_version + endif endif + if has('win32') + echo 'Windows' + elseif has('macunix') + echo 'macOS' + elseif !has('unix') + echo 'Unknown OS' + elseif isdirectory('/sys/kernel') + echo 'Linux' + else + echo 'UNIX' + endif + call s:EditorVersionWarning() endfunction function! s:UpdateEditorConfiguration() abort @@ -743,11 +789,8 @@ endfunction function! s:commands.restart(opts) abort call s:Stop() - let err = copilot#Agent().StartupError() - if !empty(err) - return 'echoerr ' . string('Copilot: ' . err) - endif - echo 'Copilot: Restarting agent.' + echo 'Copilot: Restarting language server' + call s:Start() endfunction function! s:commands.disable(opts) abort @@ -766,6 +809,10 @@ function! s:commands.panel(opts) abort endif endfunction +function! s:commands.log(opts) abort + return a:opts.mods . ' split +$ copilot:///log' +endfunction + function! copilot#CommandComplete(arg, lead, pos) abort let args = matchstr(strpart(a:lead, 0, a:pos), 'C\%[opilot][! ] *\zs.*') if args !~# ' ' @@ -779,33 +826,28 @@ endfunction function! copilot#Command(line1, line2, range, bang, mods, arg) abort let cmd = matchstr(a:arg, '^\%(\\.\|\S\)\+') let arg = matchstr(a:arg, '\s\zs\S.*') - if cmd ==# 'log' - return a:mods . ' split +$ ' . fnameescape(copilot#logger#File()) - endif if !empty(cmd) && !has_key(s:commands, tr(cmd, '-', '_')) return 'echoerr ' . string('Copilot: unknown command ' . string(cmd)) endif try - let err = copilot#Agent().StartupError() - if !empty(err) - return 'echo ' . string('Copilot: ' . err) - endif - try - let opts = copilot#Call('checkStatus', {'options': {'localChecksOnly': v:true}}) - catch - call copilot#logger#Exception() - let opts = {'status': 'VimException'} - endtry if empty(cmd) - if opts.status ==# 'VimException' - return a:mods . ' split +$ ' . fnameescape(copilot#logger#File()) - elseif opts.status !=# 'OK' && opts.status !=# 'MaybeOK' - let cmd = 'setup' + if !s:Running() + let cmd = 'restart' else - let cmd = 'panel' + try + let opts = copilot#Call('checkStatus', {'options': {'localChecksOnly': v:true}}) + if opts.status !=# 'OK' && opts.status !=# 'MaybeOK' + let cmd = 'setup' + else + let cmd = 'panel' + endif + catch + call copilot#logger#Exception() + let cmd = 'log' + endtry endif endif - call extend(opts, {'line1': a:line1, 'line2': a:line2, 'range': a:range, 'bang': a:bang, 'mods': a:mods, 'arg': arg}) + let opts = {'line1': a:line1, 'line2': a:line2, 'range': a:range, 'bang': a:bang, 'mods': a:mods, 'arg': arg} let retval = s:commands[tr(cmd, '-', '_')](opts) if type(retval) == v:t_string return retval diff --git a/sources_non_forked/copilot.vim/autoload/copilot/agent.vim b/sources_non_forked/copilot.vim/autoload/copilot/agent.vim deleted file mode 100644 index b53a8478..00000000 --- a/sources_non_forked/copilot.vim/autoload/copilot/agent.vim +++ /dev/null @@ -1,603 +0,0 @@ -if exists('g:autoloaded_copilot_agent') - finish -endif -let g:autoloaded_copilot_agent = 1 - -scriptencoding utf-8 - -let s:plugin_version = '1.13.0' - -let s:error_exit = -1 - -let s:root = expand(':h:h:h') - -if !exists('s:instances') - let s:instances = {} -endif - -" allow sourcing this file to reload the Lua file too -if has('nvim') - lua package.loaded._copilot = nil -endif - -let s:jobstop = function(exists('*jobstop') ? 'jobstop' : 'job_stop') -function! s:Kill(agent, ...) abort - if has_key(a:agent, 'job') - call s:jobstop(a:agent.job) - endif -endfunction - -function! s:AgentClose() dict abort - if !has_key(self, 'job') - return - endif - if exists('*chanclose') - call chanclose(self.job, 'stdin') - else - call ch_close_in(self.job) - endif - call copilot#logger#Info('agent stopped') - call timer_start(2000, function('s:Kill', [self])) -endfunction - -function! s:LogSend(request, line) abort - return '--> ' . a:line -endfunction - -function! s:RejectRequest(request, error) abort - if a:request.status ==# 'canceled' - return - endif - let a:request.waiting = {} - call remove(a:request, 'resolve') - let reject = remove(a:request, 'reject') - let a:request.status = 'error' - let a:request.error = a:error - for Cb in reject - let a:request.waiting[timer_start(0, function('s:Callback', [a:request, 'error', Cb]))] = 1 - endfor -endfunction - -function! s:Send(agent, request) abort - try - call ch_sendexpr(a:agent.job, a:request) - return v:true - catch /^Vim\%((\a\+)\)\=:E631:/ - return v:false - endtry -endfunction - -function! s:AgentNotify(method, params) dict abort - return s:Send(self, {'method': a:method, 'params': a:params}) -endfunction - -function! s:RequestWait() dict abort - while self.status ==# 'running' - sleep 1m - endwhile - while !empty(get(self, 'waiting', {})) - sleep 1m - endwhile - return self -endfunction - -function! s:RequestAwait() dict abort - call self.Wait() - if has_key(self, 'result') - return self.result - endif - throw 'copilot#agent(' . self.error.code . '): ' . self.error.message -endfunction - -function! s:RequestAgent() dict abort - return get(s:instances, self.agent_id, v:null) -endfunction - -if !exists('s:id') - let s:id = 0 -endif - -function! s:SetUpRequest(agent, id, method, params, ...) abort - let request = { - \ 'agent_id': a:agent.id, - \ 'id': a:id, - \ 'method': a:method, - \ 'params': a:params, - \ 'Agent': function('s:RequestAgent'), - \ 'Wait': function('s:RequestWait'), - \ 'Await': function('s:RequestAwait'), - \ 'Cancel': function('s:RequestCancel'), - \ 'resolve': [], - \ 'reject': [], - \ 'status': 'running'} - let a:agent.requests[a:id] = request - let args = a:000[2:-1] - if len(args) - if !empty(a:1) - call add(request.resolve, { v -> call(a:1, [v] + args)}) - endif - if !empty(a:2) - call add(request.reject, { v -> call(a:2, [v] + args)}) - endif - return request - endif - if a:0 && !empty(a:1) - call add(request.resolve, a:1) - endif - if a:0 > 1 && !empty(a:2) - call add(request.reject, a:2) - endif - return request -endfunction - -function! s:UrlEncode(str) abort - return substitute(iconv(a:str, 'latin1', 'utf-8'),'[^A-Za-z0-9._~!$&''()*+,;=:@/-]','\="%".printf("%02X",char2nr(submatch(0)))','g') -endfunction - -let s:slash = exists('+shellslash') ? '\' : '/' -function! s:UriFromBufnr(bufnr) abort - let absolute = tr(bufname(a:bufnr), s:slash, '/') - if absolute !~# '^\a\+:\|^/\|^$' && getbufvar(a:bufnr, 'buftype') =~# '^\%(nowrite\)\=$' - let absolute = substitute(tr(getcwd(), s:slash, '/'), '/\=$', '/', '') . absolute - endif - if has('win32') && absolute =~# '^\a://\@!' - return 'file:///' . strpart(absolute, 0, 2) . s:UrlEncode(strpart(absolute, 2)) - elseif absolute =~# '^/' - return 'file://' . s:UrlEncode(absolute) - elseif absolute =~# '^\a[[:alnum:].+-]*:\|^$' - return absolute - else - return '' - endif -endfunction - -function! s:BufferText(bufnr) abort - return join(getbufline(a:bufnr, 1, '$'), "\n") . "\n" -endfunction - -function! s:LogMessage(params) abort - call copilot#logger#Raw(get(a:params, 'level', 3), get(a:params, 'message', '')) -endfunction - -function! s:ShowMessageRequest(params) abort - let choice = inputlist([a:params.message . "\n\nRequest Actions:"] + - \ map(copy(get(a:params, 'actions', [])), { i, v -> (i + 1) . '. ' . v.title})) - return choice > 0 ? get(a:params.actions, choice - 1, v:null) : v:null -endfunction - -function! s:SendRequest(agent, request) abort - if empty(s:Send(a:agent, a:request)) && has_key(a:agent.requests, a:request.id) - call s:RejectRequest(remove(a:agent.requests, a:request.id), {'code': 257, 'message': 'Write failed'}) - endif -endfunction - -function! s:AgentRequest(method, params, ...) dict abort - let s:id += 1 - let request = {'method': a:method, 'params': deepcopy(a:params), 'id': s:id} - for doc in filter([get(request.params, 'doc', {}), get(request.params, 'textDocument',{})], 'type(get(v:val, "uri", "")) == v:t_number') - let bufnr = doc.uri - let doc.uri = s:UriFromBufnr(doc.uri) - let uri = doc.uri - let languageId = copilot#doc#LanguageForFileType(getbufvar(bufnr, '&filetype')) - let doc_version = getbufvar(bufnr, 'changedtick') - if has_key(self.open_buffers, bufnr) && ( - \ self.open_buffers[bufnr].uri !=# doc.uri || - \ self.open_buffers[bufnr].languageId !=# languageId) - call remove(self.open_buffers, bufnr) - sleep 1m - endif - if !has_key(self.open_buffers, bufnr) - let td_item = { - \ 'uri': doc.uri, - \ 'version': doc_version, - \ 'languageId': languageId, - \ 'text': s:BufferText(bufnr)} - call self.Notify('textDocument/didOpen', {'textDocument': td_item}) - let self.open_buffers[bufnr] = { - \ 'uri': doc.uri, - \ 'version': doc_version, - \ 'languageId': languageId} - else - let vtd_id = { - \ 'uri': doc.uri, - \ 'version': doc_version} - call self.Notify('textDocument/didChange', { - \ 'textDocument': vtd_id, - \ 'contentChanges': [{'text': s:BufferText(bufnr)}]}) - let self.open_buffers[bufnr].version = doc_version - endif - let doc.version = doc_version - endfor - call timer_start(0, { _ -> s:SendRequest(self, request) }) - return call('s:SetUpRequest', [self, s:id, a:method, a:params] + a:000) -endfunction - -function! s:AgentCall(method, params, ...) dict abort - let request = call(self.Request, [a:method, a:params] + a:000) - if a:0 - return request - endif - return request.Await() -endfunction - -function! s:AgentCancel(request) dict abort - if has_key(self.requests, get(a:request, 'id', '')) - call remove(self.requests, a:request.id) - call self.Notify('$/cancelRequest', {'id': a:request.id}) - endif - if get(a:request, 'status', '') ==# 'running' - let a:request.status = 'canceled' - endif -endfunction - -function! s:RequestCancel() dict abort - let agent = self.Agent() - if !empty(agent) - call agent.Cancel(self) - elseif get(self, 'status', '') ==# 'running' - let self.status = 'canceled' - endif - return self -endfunction - -function! s:DispatchMessage(agent, handler, id, params, ...) abort - try - let response = {'result': call(a:handler, [a:params])} - if response.result is# 0 - let response.result = v:null - endif - catch - call copilot#logger#Exception() - let response = {'error': {'code': -32000, 'message': v:exception}} - endtry - if !empty(a:id) - call s:Send(a:agent, extend({'id': a:id}, response)) - endif - return response -endfunction - -function! s:OnMessage(agent, body, ...) abort - if !has_key(a:body, 'method') - return s:OnResponse(a:agent, a:body) - endif - let request = a:body - let id = get(request, 'id', v:null) - let params = get(request, 'params', v:null) - if has_key(a:agent.methods, request.method) - return s:DispatchMessage(a:agent, a:agent.methods[request.method], id, params) - elseif !empty(id) - call s:Send(a:agent, {"id": id, "error": {"code": -32700, "message": "Method not found: " . request.method}}) - endif -endfunction - -function! s:OnResponse(agent, response, ...) abort - let response = a:response - let id = get(a:response, 'id', v:null) - if !has_key(a:agent.requests, id) - return - endif - let request = remove(a:agent.requests, id) - if request.status ==# 'canceled' - return - endif - let request.waiting = {} - let resolve = remove(request, 'resolve') - let reject = remove(request, 'reject') - if has_key(response, 'result') - let request.status = 'success' - let request.result = response.result - for Cb in resolve - let request.waiting[timer_start(0, function('s:Callback', [request, 'result', Cb]))] = 1 - endfor - else - let request.status = 'error' - let request.error = response.error - for Cb in reject - let request.waiting[timer_start(0, function('s:Callback', [request, 'error', Cb]))] = 1 - endfor - endif -endfunction - -function! s:OnErr(agent, line, ...) abort - call copilot#logger#Debug('<-! ' . a:line) -endfunction - -function! s:OnExit(agent, code, ...) abort - let a:agent.exit_status = a:code - if has_key(a:agent, 'job') - call remove(a:agent, 'job') - endif - if has_key(a:agent, 'client_id') - call remove(a:agent, 'client_id') - endif - let code = a:code < 0 || a:code > 255 ? 256 : a:code - for id in sort(keys(a:agent.requests), { a, b -> +a > +b }) - call s:RejectRequest(remove(a:agent.requests, id), {'code': code, 'message': 'Agent exited', 'data': {'status': a:code}}) - endfor - call timer_start(0, { _ -> get(s:instances, a:agent.id) is# a:agent ? remove(s:instances, a:agent.id) : {} }) - call copilot#logger#Info('agent exited with status ' . a:code) -endfunction - -function! copilot#agent#LspInit(agent_id, initialize_result) abort - if !has_key(s:instances, a:agent_id) - return - endif - let instance = s:instances[a:agent_id] - call timer_start(0, { _ -> s:GetCapabilitiesResult(a:initialize_result, instance)}) -endfunction - -function! copilot#agent#LspExit(agent_id, code, signal) abort - if !has_key(s:instances, a:agent_id) - return - endif - let instance = remove(s:instances, a:agent_id) - call s:OnExit(instance, a:code) -endfunction - -function! copilot#agent#LspResponse(agent_id, opts, ...) abort - if !has_key(s:instances, a:agent_id) - return - endif - call s:OnResponse(s:instances[a:agent_id], a:opts) -endfunction - -function! s:LspRequest(method, params, ...) dict abort - let id = v:lua.require'_copilot'.lsp_request(self.id, a:method, a:params) - if id isnot# v:null - return call('s:SetUpRequest', [self, id, a:method, a:params] + a:000) - endif - if has_key(self, 'client_id') - call copilot#agent#LspExit(self.client_id, -1, -1) - endif - throw 'copilot#agent: LSP client not available' -endfunction - -function! s:LspClose() dict abort - if !has_key(self, 'client_id') - return - endif - return luaeval('vim.lsp.get_client_by_id(_A).stop()', self.client_id) -endfunction - -function! s:LspNotify(method, params) dict abort - return v:lua.require'_copilot'.rpc_notify(self.id, a:method, a:params) -endfunction - -function! copilot#agent#LspHandle(agent_id, request) abort - if !has_key(s:instances, a:agent_id) - return - endif - return s:OnMessage(s:instances[a:agent_id], a:request) -endfunction - -function! s:GetNodeVersion(command) abort - let out = [] - let err = [] - let status = copilot#job#Stream(a:command + ['--version'], function('add', [out]), function('add', [err])) - let string = matchstr(join(out, ''), '^v\zs\d\+\.[^[:space:]]*') - if status != 0 - let string = '' - endif - let major = str2nr(string) - let minor = str2nr(matchstr(string, '\.\zs\d\+')) - return {'status': status, 'string': string, 'major': major, 'minor': minor} -endfunction - -function! s:Command() abort - if !has('nvim-0.6') && v:version < 900 - return [v:null, '', 'Vim version too old'] - endif - let node = get(g:, 'copilot_node_command', '') - if empty(node) - let node = ['node'] - elseif type(node) == type('') - let node = [expand(node)] - endif - if !executable(get(node, 0, '')) - if get(node, 0, '') ==# 'node' - return [v:null, '', 'Node.js not found in PATH'] - else - return [v:null, '', 'Node.js executable `' . get(node, 0, '') . "' not found"] - endif - endif - let node_version = s:GetNodeVersion(node) - let warning = '' - if !get(g:, 'copilot_ignore_node_version') && node_version.major < 18 && get(node, 0, '') !=# 'node' && executable('node') - let node_version_from_path = s:GetNodeVersion(['node']) - if node_version_from_path.major >= 18 - let warning = 'Ignoring g:copilot_node_command: Node.js ' . node_version.string . ' is end-of-life' - let node = ['node'] - let node_version = node_version_from_path - endif - endif - if node_version.status != 0 - return [v:null, '', 'Node.js exited with status ' . node_version.status] - endif - if !get(g:, 'copilot_ignore_node_version') - if node_version.major == 0 - return [v:null, node_version.string, 'Could not determine Node.js version'] - elseif node_version.major < 16 || node_version.major == 16 && node_version.minor < 14 || node_version.major == 17 && node_version.minor < 3 - " 16.14+ and 17.3+ still work for now, but are end-of-life - return [v:null, node_version.string, 'Node.js version 18.x or newer required but found ' . node_version.string] - endif - endif - let agent = get(g:, 'copilot_agent_command', '') - if empty(agent) || !filereadable(agent) - let agent = s:root . '/dist/agent.js' - if !filereadable(agent) - return [v:null, node_version.string, 'Could not find dist/agent.js (bad install?)'] - endif - endif - return [node + [agent, '--stdio'], node_version.string, warning] -endfunction - -function! s:UrlDecode(str) abort - return substitute(a:str, '%\(\x\x\)', '\=iconv(nr2char("0x".submatch(1)), "utf-8", "latin1")', 'g') -endfunction - -function! copilot#agent#EditorInfo() abort - if !exists('s:editor_version') - if has('nvim') - let s:editor_version = matchstr(execute('version'), 'NVIM v\zs[^[:space:]]\+') - else - let s:editor_version = (v:version / 100) . '.' . (v:version % 100) . (exists('v:versionlong') ? printf('.%04d', v:versionlong % 1000) : '') - endif - endif - let info = { - \ 'editorInfo': {'name': has('nvim') ? 'Neovim': 'Vim', 'version': s:editor_version}, - \ 'editorPluginInfo': {'name': 'copilot.vim', 'version': s:plugin_version}} - if type(get(g:, 'copilot_proxy')) == v:t_string - let proxy = g:copilot_proxy - else - let proxy = '' - endif - let match = matchlist(proxy, '\c^\%([^:]\+://\)\=\%(\([^/#]\+@\)\)\=\%(\([^/:#]\+\)\|\[\([[:xdigit:]:]\+\)\]\)\%(:\(\d\+\)\)\=\%(/\|$\|?strict_\=ssl=\(.*\)\)') - if !empty(match) - let info.networkProxy = {'host': match[2] . match[3], 'port': empty(match[4]) ? 80 : +match[4]} - if match[5] =~? '^[0f]' - let info.networkProxy.rejectUnauthorized = v:false - elseif match[5] =~? '^[1t]' - let info.networkProxy.rejectUnauthorized = v:true - elseif exists('g:copilot_proxy_strict_ssl') - let info.networkProxy.rejectUnauthorized = empty(g:copilot_proxy_strict_ssl) ? v:false : v:true - endif - if !empty(match[1]) - let info.networkProxy.username = s:UrlDecode(matchstr(match[1], '^[^:@]*')) - let info.networkProxy.password = s:UrlDecode(matchstr(match[1], ':\zs[^@]*')) - endif - endif - return info -endfunction - -function! s:GetCapabilitiesResult(result, agent) abort - let a:agent.capabilities = get(a:result, 'capabilities', {}) - let info = copilot#agent#EditorInfo() - call a:agent.Request('setEditorInfo', extend({'editorConfiguration': a:agent.editorConfiguration}, info)) -endfunction - -function! s:GetCapabilitiesError(error, agent) abort - if a:error.code == s:error_exit - let a:agent.startup_error = 'Agent exited with status ' . a:error.data.status - else - let a:agent.startup_error = 'Unexpected error ' . a:error.code . ' calling agent: ' . a:error.message - call a:agent.Close() - endif -endfunction - -function! s:AgentStartupError() dict abort - while (has_key(self, 'job') || has_key(self, 'client_id')) && !has_key(self, 'startup_error') && !has_key(self, 'capabilities') - sleep 10m - endwhile - if has_key(self, 'capabilities') - return '' - else - return get(self, 'startup_error', 'Something unexpected went wrong spawning the agent') - endif -endfunction - -function! copilot#agent#New(...) abort - let opts = a:0 ? a:1 : {} - let instance = {'requests': {}, - \ 'editorConfiguration': get(opts, 'editorConfiguration', {}), - \ 'Close': function('s:AgentClose'), - \ 'Notify': function('s:AgentNotify'), - \ 'Request': function('s:AgentRequest'), - \ 'Call': function('s:AgentCall'), - \ 'Cancel': function('s:AgentCancel'), - \ 'StartupError': function('s:AgentStartupError'), - \ } - let instance.methods = extend({ - \ 'LogMessage': function('s:LogMessage'), - \ 'window/logMessage': function('s:LogMessage'), - \ }, get(opts, 'methods', {})) - let [command, node_version, command_error] = s:Command() - if len(command_error) - if empty(command) - let instance.id = -1 - let instance.startup_error = command_error - return instance - else - let instance.node_version_warning = command_error - endif - endif - let instance.node_version = node_version - if has('nvim') - call extend(instance, { - \ 'Close': function('s:LspClose'), - \ 'Notify': function('s:LspNotify'), - \ 'Request': function('s:LspRequest')}) - let instance.client_id = v:lua.require'_copilot'.lsp_start_client(command, keys(instance.methods)) - let instance.id = instance.client_id - else - let state = {'headers': {}, 'mode': 'headers', 'buffer': ''} - let instance.open_buffers = {} - let instance.methods = extend({'window/showMessageRequest': function('s:ShowMessageRequest')}, instance.methods) - let instance.job = job_start(command, { - \ 'cwd': copilot#job#Cwd(), - \ 'in_mode': 'lsp', - \ 'out_mode': 'lsp', - \ 'out_cb': { j, d -> timer_start(0, function('s:OnMessage', [instance, d])) }, - \ 'err_cb': { j, d -> timer_start(0, function('s:OnErr', [instance, d])) }, - \ 'exit_cb': { j, d -> timer_start(0, function('s:OnExit', [instance, d])) }, - \ }) - let instance.id = exists('*jobpid') ? jobpid(instance.job) : job_info(instance.job).process - let capabilities = {'workspace': {'workspaceFolders': v:true}, 'copilot': {}} - for name in keys(instance.methods) - if name =~# '^copilot/' - let capabilities.copilot[matchstr(name, '/\zs.*')] = v:true - endif - endfor - let request = instance.Request('initialize', {'capabilities': capabilities}, function('s:GetCapabilitiesResult'), function('s:GetCapabilitiesError'), instance) - endif - let s:instances[instance.id] = instance - return instance -endfunction - -function! copilot#agent#Cancel(request) abort - if type(a:request) == type({}) && has_key(a:request, 'Cancel') - call a:request.Cancel() - endif -endfunction - -function! s:Callback(request, type, callback, timer) abort - call remove(a:request.waiting, a:timer) - if has_key(a:request, a:type) - call a:callback(a:request[a:type]) - endif -endfunction - -function! copilot#agent#Result(request, callback) abort - if has_key(a:request, 'resolve') - call add(a:request.resolve, a:callback) - elseif has_key(a:request, 'result') - let a:request.waiting[timer_start(0, function('s:Callback', [a:request, 'result', a:callback]))] = 1 - endif -endfunction - -function! copilot#agent#Error(request, callback) abort - if has_key(a:request, 'reject') - call add(a:request.reject, a:callback) - elseif has_key(a:request, 'error') - let a:request.waiting[timer_start(0, function('s:Callback', [a:request, 'error', a:callback]))] = 1 - endif -endfunction - -function! s:CloseBuffer(bufnr) abort - for instance in values(s:instances) - try - if has_key(instance, 'job') && has_key(instance.open_buffers, a:bufnr) - let buffer = remove(instance.open_buffers, a:bufnr) - call instance.Notify('textDocument/didClose', {'textDocument': {'uri': buffer.uri}}) - endif - catch - call copilot#logger#Exception() - endtry - endfor -endfunction - -augroup copilot_agent - autocmd! - if !has('nvim') - autocmd BufUnload * call s:CloseBuffer(+expand('')) - endif -augroup END diff --git a/sources_non_forked/copilot.vim/autoload/copilot/client.vim b/sources_non_forked/copilot.vim/autoload/copilot/client.vim new file mode 100644 index 00000000..c811062e --- /dev/null +++ b/sources_non_forked/copilot.vim/autoload/copilot/client.vim @@ -0,0 +1,764 @@ +scriptencoding utf-8 + +let s:plugin_version = copilot#version#String() + +let s:error_canceled = {'code': -32800, 'message': 'Canceled'} +let s:error_exit = {'code': -32097, 'message': 'Process exited'} +let s:error_connection_inactive = {'code': -32096, 'message': 'Connection inactive'} + +let s:root = expand(':h:h:h') + +if !exists('s:instances') + let s:instances = {} +endif + +" allow sourcing this file to reload the Lua file too +if has('nvim') + lua package.loaded._copilot = nil +endif + +function! s:Warn(msg) abort + if !empty(get(g:, 'copilot_no_startup_warnings')) + return + endif + echohl WarningMsg + echomsg 'Copilot: ' . a:msg + echohl NONE +endfunction + +function! s:VimClose() dict abort + if !has_key(self, 'job') + return + endif + let job = self.job + if has_key(self, 'kill') + call job_stop(job, 'kill') + call copilot#logger#Warn('Process forcefully terminated') + return + endif + let self.kill = v:true + let self.shutdown = self.Request('shutdown', {}, function(self.Notify, ['exit'])) + call timer_start(2000, { _ -> job_stop(job, 'kill') }) + call copilot#logger#Debug('Process shutdown initiated') +endfunction + +function! s:LogSend(request, line) abort + return '--> ' . a:line +endfunction + +function! s:RejectRequest(request, error) abort + if a:request.status !=# 'running' + return + endif + let a:request.waiting = {} + call remove(a:request, 'resolve') + let reject = remove(a:request, 'reject') + let a:request.status = 'error' + let a:request.error = deepcopy(a:error) + for Cb in reject + let a:request.waiting[timer_start(0, function('s:Callback', [a:request, 'error', Cb]))] = 1 + endfor + if index([s:error_canceled.code, s:error_connection_inactive.code], a:error.code) != -1 + return + endif + let msg = 'Method ' . a:request.method . ' errored with E' . a:error.code . ': ' . json_encode(a:error.message) + if empty(reject) + call copilot#logger#Error(msg) + else + call copilot#logger#Debug(msg) + endif +endfunction + +function! s:AfterInitialized(fn, ...) dict abort + call add(self.after_initialized, function(a:fn, a:000)) +endfunction + +function! s:Send(instance, request) abort + if !has_key(a:instance, 'job') + return v:false + endif + try + call ch_sendexpr(a:instance.job, a:request) + return v:true + catch /^Vim\%((\a\+)\)\=:E906:/ + let a:instance.kill = v:true + let job = remove(a:instance, 'job') + call job_stop(job) + call timer_start(2000, { _ -> job_stop(job, 'kill') }) + call copilot#logger#Warn('Terminating process after failed write') + return v:false + catch /^Vim\%((\a\+)\)\=:E631:/ + return v:false + endtry +endfunction + +function! s:VimNotify(method, params) dict abort + let request = {'method': a:method, 'params': a:params} + call self.AfterInitialized(function('s:Send', [self, request])) +endfunction + +function! s:RequestWait() dict abort + while self.status ==# 'running' + sleep 1m + endwhile + while !empty(get(self, 'waiting', {})) + sleep 1m + endwhile + return self +endfunction + +function! s:RequestAwait() dict abort + call self.Wait() + if has_key(self, 'result') + return self.result + endif + throw 'Copilot:E' . self.error.code . ': ' . self.error.message +endfunction + +function! s:RequestClient() dict abort + return get(s:instances, self.client_id, v:null) +endfunction + +if !exists('s:id') + let s:id = 0 +endif +if !exists('s:progress_token_id') + let s:progress_token_id = 0 +endif + +function! s:SetUpRequest(instance, id, method, params, progress, ...) abort + let request = { + \ 'client_id': a:instance.id, + \ 'id': a:id, + \ 'method': a:method, + \ 'params': a:params, + \ 'Client': function('s:RequestClient'), + \ 'Wait': function('s:RequestWait'), + \ 'Await': function('s:RequestAwait'), + \ 'Cancel': function('s:RequestCancel'), + \ 'resolve': [], + \ 'reject': [], + \ 'progress': a:progress, + \ 'status': 'running'} + let args = a:000[2:-1] + if len(args) + if !empty(a:1) + call add(request.resolve, { v -> call(a:1, [v] + args)}) + endif + if !empty(a:2) + call add(request.reject, { v -> call(a:2, [v] + args)}) + endif + return request + endif + if a:0 && !empty(a:1) + call add(request.resolve, a:1) + endif + if a:0 > 1 && !empty(a:2) + call add(request.reject, a:2) + endif + return request +endfunction + +function! s:UrlEncode(str) abort + return substitute(iconv(a:str, 'latin1', 'utf-8'),'[^A-Za-z0-9._~!$&''()*+,;=:@/-]','\="%".printf("%02X",char2nr(submatch(0)))','g') +endfunction + +let s:slash = exists('+shellslash') ? '\' : '/' +function! s:UriFromBufnr(bufnr) abort + let absolute = tr(bufname(a:bufnr), s:slash, '/') + if absolute !~# '^\a\+:\|^/\|^$' && getbufvar(a:bufnr, 'buftype') =~# '^\%(nowrite\)\=$' + let absolute = substitute(tr(getcwd(), s:slash, '/'), '/\=$', '/', '') . absolute + endif + return s:UriFromPath(absolute) +endfunction + +function! s:UriFromPath(absolute) abort + let absolute = a:absolute + if has('win32') && absolute =~# '^\a://\@!' + return 'file:///' . strpart(absolute, 0, 2) . s:UrlEncode(strpart(absolute, 2)) + elseif absolute =~# '^/' + return 'file://' . s:UrlEncode(absolute) + elseif absolute =~# '^\a[[:alnum:].+-]*:\|^$' + return absolute + else + return '' + endif +endfunction + +function! s:BufferText(bufnr) abort + return join(getbufline(a:bufnr, 1, '$'), "\n") . "\n" +endfunction + +let s:valid_request_key = '^\%(id\|method\|params\)$' +function! s:SendRequest(instance, request, ...) abort + if !has_key(a:instance, 'job') || get(a:instance, 'shutdown', a:request) isnot# a:request + return s:RejectRequest(a:request, s:error_connection_inactive) + endif + let json = filter(copy(a:request), 'v:key =~# s:valid_request_key') + if empty(s:Send(a:instance, json)) && has_key(a:request, 'id') && has_key(a:instance.requests, a:request.id) + call s:RejectRequest(remove(a:instance.requests, a:request.id), {'code': -32099, 'message': 'Write failed'}) + endif +endfunction + +function! s:RegisterWorkspaceFolderForBuffer(instance, buf) abort + let root = getbufvar(a:buf, 'workspace_folder') + if type(root) != v:t_string + return + endif + let root = s:UriFromPath(substitute(root, '[\/]$', '', '')) + if empty(root) || has_key(a:instance.workspaceFolders, root) + return + endif + let a:instance.workspaceFolders[root] = v:true + call a:instance.Notify('workspace/didChangeWorkspaceFolders', {'event': {'added': [{'uri': root, 'name': fnamemodify(root, ':t')}], 'removed': []}}) +endfunction + +function! s:PreprocessParams(instance, params) abort + let bufnr = v:null + for doc in filter([get(a:params, 'textDocument', {})], 'type(get(v:val, "uri", "")) == v:t_number') + let bufnr = doc.uri + call s:RegisterWorkspaceFolderForBuffer(a:instance, bufnr) + call extend(doc, a:instance.Attach(bufnr)) + endfor + let progress_tokens = [] + for key in keys(a:params) + if key =~# 'Token$' && type(a:params[key]) == v:t_func + let s:progress_token_id += 1 + let a:instance.progress[s:progress_token_id] = a:params[key] + call add(progress_tokens, s:progress_token_id) + let a:params[key] = s:progress_token_id + endif + endfor + return [bufnr, progress_tokens] +endfunction + +function! s:VimAttach(bufnr) dict abort + if !bufloaded(a:bufnr) + return {'uri': '', 'version': 0} + endif + let bufnr = a:bufnr + let doc = { + \ 'uri': s:UriFromBufnr(bufnr), + \ 'version': getbufvar(bufnr, 'changedtick', 0), + \ 'languageId': getbufvar(bufnr, '&filetype'), + \ } + if has_key(self.open_buffers, bufnr) && ( + \ self.open_buffers[bufnr].uri !=# doc.uri || + \ self.open_buffers[bufnr].languageId !=# doc.languageId) + call self.Notify('textDocument/didClose', {'textDocument': {'uri': self.open_buffers[bufnr].uri}}) + call remove(self.open_buffers, bufnr) + endif + if !has_key(self.open_buffers, bufnr) + call self.Notify('textDocument/didOpen', {'textDocument': extend({'text': s:BufferText(bufnr)}, doc)}) + let self.open_buffers[bufnr] = doc + else + call self.Notify('textDocument/didChange', { + \ 'textDocument': {'uri': doc.uri, 'version': doc.version}, + \ 'contentChanges': [{'text': s:BufferText(bufnr)}]}) + let self.open_buffers[bufnr].version = doc.version + endif + return doc +endfunction + +function! s:VimIsAttached(bufnr) dict abort + return bufloaded(a:bufnr) && has_key(self.open_buffers, a:bufnr) ? v:true : v:false +endfunction + +function! s:VimRequest(method, params, ...) dict abort + let s:id += 1 + let params = deepcopy(a:params) + let [_, progress] = s:PreprocessParams(self, params) + let request = call('s:SetUpRequest', [self, s:id, a:method, params, progress] + a:000) + call self.AfterInitialized(function('s:SendRequest', [self, request])) + let self.requests[s:id] = request + return request +endfunction + +function! s:Call(method, params, ...) dict abort + let request = call(self.Request, [a:method, a:params] + a:000) + if a:0 + return request + endif + return request.Await() +endfunction + +function! s:Cancel(request) dict abort + if has_key(self.requests, get(a:request, 'id', '')) + call self.Notify('$/cancelRequest', {'id': a:request.id}) + call s:RejectRequest(remove(self.requests, a:request.id), s:error_canceled) + endif +endfunction + +function! s:RequestCancel() dict abort + let instance = self.Client() + if !empty(instance) + call instance.Cancel(self) + elseif get(self, 'status', '') ==# 'running' + call s:RejectRequest(self, s:error_canceled) + endif + return self +endfunction + +function! s:DispatchMessage(instance, method, handler, id, params, ...) abort + try + let response = {'result': call(a:handler, [a:params, a:instance])} + if response.result is# 0 + let response.result = v:null + endif + catch + call copilot#logger#Exception('lsp.request.' . a:method) + let response = {'error': {'code': -32000, 'message': v:exception}} + endtry + if a:id isnot# v:null + call s:Send(a:instance, extend({'id': a:id}, response)) + endif + if !has_key(s:notifications, a:method) + return response + endif +endfunction + +function! s:OnMessage(instance, body, ...) abort + if !has_key(a:body, 'method') + return s:OnResponse(a:instance, a:body) + endif + let request = a:body + let id = get(request, 'id', v:null) + let params = get(request, 'params', v:null) + if has_key(a:instance.methods, request.method) + return s:DispatchMessage(a:instance, request.method, a:instance.methods[request.method], id, params) + elseif id isnot# v:null + call s:Send(a:instance, {"id": id, "error": {"code": -32700, "message": "Method not found: " . request.method}}) + call copilot#logger#Debug('Unexpected request ' . request.method . ' called with ' . json_encode(params)) + elseif request.method !~# '^\$/' + call copilot#logger#Debug('Unexpected notification ' . request.method . ' called with ' . json_encode(params)) + endif +endfunction + +function! s:OnResponse(instance, response, ...) abort + let response = a:response + let id = get(a:response, 'id', v:null) + if !has_key(a:instance.requests, id) + return + endif + let request = remove(a:instance.requests, id) + for progress_token in request.progress + if has_key(a:instance.progress, progress_token) + call remove(a:instance.progress, progress_token) + endif + endfor + if request.status !=# 'running' + return + endif + if has_key(response, 'result') + let request.waiting = {} + let resolve = remove(request, 'resolve') + call remove(request, 'reject') + let request.status = 'success' + let request.result = response.result + for Cb in resolve + let request.waiting[timer_start(0, function('s:Callback', [request, 'result', Cb]))] = 1 + endfor + else + call s:RejectRequest(request, response.error) + endif +endfunction + +function! s:OnErr(instance, ch, line, ...) abort + if !has_key(a:instance, 'serverInfo') + call copilot#logger#Bare('<-! ' . a:line) + endif +endfunction + +function! s:OnExit(instance, code, ...) abort + let a:instance.exit_status = a:code + if has_key(a:instance, 'job') + call remove(a:instance, 'job') + endif + if has_key(a:instance, 'client_id') + call remove(a:instance, 'client_id') + endif + let message = 'Process exited with status ' . a:code + if a:code >= 18 && a:code < 100 + let message = 'Node.js too old. ' . + \ (get(a:instance.node, 0, 'node') ==# 'node' ? 'Upgrade' : 'Change g:copilot_node_command') . + \ ' to ' . a:code . '.x or newer' + endif + if !has_key(a:instance, 'serverInfo') && !has_key(a:instance, 'startup_error') + let a:instance.startup_error = message + endif + for id in sort(keys(a:instance.requests), { a, b -> +a > +b }) + call s:RejectRequest(remove(a:instance.requests, id), s:error_exit) + endfor + if has_key(a:instance, 'after_initialized') + let a:instance.AfterInitialized = function('copilot#util#Defer') + for Fn in remove(a:instance, 'after_initialized') + call copilot#util#Defer(Fn) + endfor + endif + call copilot#util#Defer({ -> get(s:instances, a:instance.id) is# a:instance ? remove(s:instances, a:instance.id) : {} }) + if a:code == 0 + call copilot#logger#Info(message) + else + call copilot#logger#Warn(message) + if !has_key(a:instance, 'kill') + call copilot#util#Defer(function('s:Warn'), message) + endif + endif +endfunction + +function! copilot#client#LspInit(id, initialize_result) abort + if !has_key(s:instances, a:id) + return + endif + call s:PostInit(a:initialize_result, s:instances[a:id]) +endfunction + +function! copilot#client#LspExit(id, code, signal) abort + if !has_key(s:instances, a:id) + return + endif + let instance = remove(s:instances, a:id) + call s:OnExit(instance, a:code) +endfunction + +function! copilot#client#LspResponse(id, opts, ...) abort + if !has_key(s:instances, a:id) + return + endif + call s:OnResponse(s:instances[a:id], a:opts) +endfunction + +function! s:NvimAttach(bufnr) dict abort + if !bufloaded(a:bufnr) + return {'uri': '', 'version': 0} + endif + call luaeval('pcall(vim.lsp.buf_attach_client, _A[1], _A[2])', [a:bufnr, self.id]) + return luaeval('{uri = vim.uri_from_bufnr(_A), version = vim.lsp.util.buf_versions[_A]}', a:bufnr) +endfunction + +function! s:NvimIsAttached(bufnr) dict abort + return bufloaded(a:bufnr) ? luaeval('vim.lsp.buf_is_attached(_A[1], _A[2])', [a:bufnr, self.id]) : v:false +endfunction + +function! s:NvimRequest(method, params, ...) dict abort + let params = deepcopy(a:params) + let [bufnr, progress] = s:PreprocessParams(self, params) + let request = call('s:SetUpRequest', [self, v:null, a:method, params, progress] + a:000) + call self.AfterInitialized(function('s:NvimDoRequest', [self, request, bufnr])) + return request +endfunction + +function! s:NvimDoRequest(client, request, bufnr) abort + let request = a:request + if has_key(a:client, 'client_id') && !has_key(a:client, 'kill') + let request.id = eval("v:lua.require'_copilot'.lsp_request(a:client.id, a:request.method, a:request.params, a:bufnr)") + endif + if request.id isnot# v:null + let a:client.requests[request.id] = request + else + if has_key(a:client, 'client_id') + call copilot#client#LspExit(a:client.client_id, -1, -1) + endif + call copilot#util#Defer(function('s:RejectRequest'), request, s:error_connection_inactive) + endif + return request +endfunction + +function! s:NvimClose() dict abort + if !has_key(self, 'client_id') + return + endif + let self.kill = v:true + return luaeval('vim.lsp.get_client_by_id(_A).stop()', self.client_id) +endfunction + +function! s:NvimNotify(method, params) dict abort + call self.AfterInitialized(function('s:NvimDoNotify', [self.client_id, a:method, a:params])) +endfunction + +function! s:NvimDoNotify(client_id, method, params) abort + return eval("v:lua.require'_copilot'.rpc_notify(a:client_id, a:method, a:params)") +endfunction + +function! copilot#client#LspHandle(id, request) abort + if !has_key(s:instances, a:id) + return + endif + return s:OnMessage(s:instances[a:id], a:request) +endfunction + +let s:script_name = 'dist/language-server.js' +function! s:Command() abort + if !has('nvim-0.7') && v:version < 900 + return [[], [], 'Vim version too old'] + endif + let script = get(g:, 'copilot_command', '') + if type(script) == type('') + let script = [expand(script)] + endif + if empty(script) || !filereadable(script[0]) + let script = [s:root . '/' . s:script_name] + if !filereadable(script[0]) + return [[], [], 'Could not find ' . s:script_name . ' (bad install?)'] + endif + elseif script[0] !~# '\.js$' + return [[], script + ['--stdio'], ''] + endif + let node = get(g:, 'copilot_node_command', '') + if empty(node) + let node = ['node'] + elseif type(node) == type('') + let node = [expand(node)] + endif + if !executable(get(node, 0, '')) + if get(node, 0, '') ==# 'node' + return [[], [], 'Node.js not found in PATH'] + else + return [[], [], 'Node.js executable `' . get(node, 0, '') . "' not found"] + endif + endif + return [node, script + ['--stdio'], ''] +endfunction + +function! s:UrlDecode(str) abort + return substitute(a:str, '%\(\x\x\)', '\=iconv(nr2char("0x".submatch(1)), "utf-8", "latin1")', 'g') +endfunction + +function! copilot#client#EditorInfo() abort + if !exists('s:editor_version') + if has('nvim') + let s:editor_version = matchstr(execute('version'), 'NVIM v\zs[^[:space:]]\+') + else + let s:editor_version = (v:version / 100) . '.' . (v:version % 100) . (exists('v:versionlong') ? printf('.%04d', v:versionlong % 10000) : '') + endif + endif + return {'name': has('nvim') ? 'Neovim': 'Vim', 'version': s:editor_version} +endfunction + +function! copilot#client#EditorPluginInfo() abort + return {'name': 'copilot.vim', 'version': s:plugin_version} +endfunction + +function! copilot#client#Settings() abort + let settings = { + \ 'http': { + \ 'proxy': get(g:, 'copilot_proxy', v:null), + \ 'proxyStrictSSL': get(g:, 'copilot_proxy_strict_ssl', v:null)}, + \ 'github-enterprise': {'uri': get(g:, 'copilot_auth_provider_url', v:null)}, + \ } + if type(settings.http.proxy) ==# v:t_string && settings.http.proxy =~# '^[^/]\+$' + let settings.http.proxy = 'http://' . settings.http.proxy + endif + if type(get(g:, 'copilot_settings')) == v:t_dict + call extend(settings, g:copilot_settings) + endif + return settings +endfunction + +function! s:PostInit(result, instance) abort + let a:instance.serverInfo = get(a:result, 'serverInfo', {}) + if !has_key(a:instance, 'node_version') && has_key(a:result.serverInfo, 'nodeVersion') + let a:instance.node_version = a:result.serverInfo.nodeVersion + endif + let a:instance.AfterInitialized = function('copilot#util#Defer') + for Fn in remove(a:instance, 'after_initialized') + call copilot#util#Defer(Fn) + endfor +endfunction + +function! s:InitializeResult(result, instance) abort + call s:Send(a:instance, {'method': 'initialized', 'params': {}}) + call s:PostInit(a:result, a:instance) +endfunction + +function! s:InitializeError(error, instance) abort + if !has_key(a:instance, 'startup_error') + let a:instance.startup_error = 'Unexpected error E' . a:error.code . ' initializing language server: ' . a:error.message + call a:instance.Close() + endif +endfunction + +function! s:StartupError() dict abort + while (has_key(self, 'job') || has_key(self, 'client_id')) && !has_key(self, 'startup_error') && !has_key(self, 'serverInfo') + sleep 10m + endwhile + if has_key(self, 'serverInfo') + return '' + else + return get(self, 'startup_error', 'Something unexpected went wrong spawning the language server') + endif +endfunction + +function! s:StatusNotification(params, instance) abort + let a:instance.status = a:params +endfunction + +function! s:Nop(...) abort + return v:null +endfunction + +function! s:False(...) abort + return v:false +endfunction + +function! s:Progress(params, instance) abort + if has_key(a:instance.progress, a:params.token) + call a:instance.progress[a:params.token](a:params.value) + endif +endfunction + +let s:notifications = { + \ '$/progress': function('s:Progress'), + \ 'featureFlagsNotification': function('s:Nop'), + \ 'statusNotification': function('s:StatusNotification'), + \ 'window/logMessage': function('copilot#handlers#window_logMessage'), + \ } + +let s:vim_handlers = { + \ 'window/showMessageRequest': function('copilot#handlers#window_showMessageRequest'), + \ 'window/showDocument': function('copilot#handlers#window_showDocument'), + \ } + +let s:vim_capabilities = { + \ 'workspace': {'workspaceFolders': v:true}, + \ 'window': {'showDocument': {'support': v:true}}, + \ } + +function! copilot#client#New(...) abort + let opts = a:0 ? a:1 : {} + let instance = {'requests': {}, + \ 'progress': {}, + \ 'workspaceFolders': {}, + \ 'after_initialized': [], + \ 'status': {'status': 'Starting', 'message': ''}, + \ 'AfterInitialized': function('s:AfterInitialized'), + \ 'Close': function('s:Nop'), + \ 'Notify': function('s:False'), + \ 'Request': function('s:VimRequest'), + \ 'Attach': function('s:Nop'), + \ 'IsAttached': function('s:False'), + \ 'Call': function('s:Call'), + \ 'Cancel': function('s:Cancel'), + \ 'StartupError': function('s:StartupError'), + \ } + let instance.methods = copy(s:notifications) + let [node, argv, command_error] = s:Command() + if !empty(command_error) + let instance.id = -1 + let instance.startup_error = command_error + call copilot#logger#Error(command_error) + return instance + endif + let instance.node = node + let command = node + argv + let opts = {} + let opts.initializationOptions = { + \ 'editorInfo': copilot#client#EditorInfo(), + \ 'editorPluginInfo': copilot#client#EditorPluginInfo(), + \ } + let opts.workspaceFolders = [] + let settings = extend(copilot#client#Settings(), get(opts, 'editorConfiguration', {})) + if type(get(g:, 'copilot_workspace_folders')) == v:t_list + for folder in g:copilot_workspace_folders + if type(folder) == v:t_string && !empty(folder) && folder !~# '\*\*\|^/$' + for path in glob(folder . '/', 0, 1) + let uri = s:UriFromPath(substitute(path, '[\/]*$', '', '')) + call add(opts.workspaceFolders, {'uri': uri, 'name': fnamemodify(uri, ':t')}) + endfor + elseif type(folder) == v:t_dict && has_key(v:t_dict, 'uri') && !empty(folder.uri) && has_key(folder, 'name') + call add(opts.workspaceFolders, folder) + endif + endfor + endif + for folder in opts.workspaceFolders + let instance.workspaceFolders[folder.uri] = v:true + endfor + if has('nvim') + call extend(instance, { + \ 'Close': function('s:NvimClose'), + \ 'Notify': function('s:NvimNotify'), + \ 'Request': function('s:NvimRequest'), + \ 'Attach': function('s:NvimAttach'), + \ 'IsAttached': function('s:NvimIsAttached'), + \ }) + let instance.client_id = eval("v:lua.require'_copilot'.lsp_start_client(command, keys(instance.methods), opts, settings)") + let instance.id = instance.client_id + else + call extend(instance, { + \ 'Close': function('s:VimClose'), + \ 'Notify': function('s:VimNotify'), + \ 'Attach': function('s:VimAttach'), + \ 'IsAttached': function('s:VimIsAttached'), + \ }) + let state = {'headers': {}, 'mode': 'headers', 'buffer': ''} + let instance.open_buffers = {} + let instance.methods = extend(s:vim_handlers, instance.methods) + let instance.job = job_start(command, { + \ 'cwd': copilot#job#Cwd(), + \ 'noblock': 1, + \ 'stoponexit': '', + \ 'in_mode': 'lsp', + \ 'out_mode': 'lsp', + \ 'out_cb': { j, d -> copilot#util#Defer(function('s:OnMessage'), instance, d) }, + \ 'err_cb': function('s:OnErr', [instance]), + \ 'exit_cb': { j, d -> copilot#util#Defer(function('s:OnExit'), instance, d) }, + \ }) + let instance.id = job_info(instance.job).process + let opts.capabilities = s:vim_capabilities + let opts.processId = getpid() + let request = instance.Request('initialize', opts, function('s:InitializeResult'), function('s:InitializeError'), instance) + call call(remove(instance.after_initialized, 0), []) + call instance.Notify('workspace/didChangeConfiguration', {'settings': settings}) + endif + let s:instances[instance.id] = instance + return instance +endfunction + +function! copilot#client#Cancel(request) abort + if type(a:request) == type({}) && has_key(a:request, 'Cancel') + call a:request.Cancel() + endif +endfunction + +function! s:Callback(request, type, callback, timer) abort + call remove(a:request.waiting, a:timer) + if has_key(a:request, a:type) + call a:callback(a:request[a:type]) + endif +endfunction + +function! copilot#client#Result(request, callback) abort + if has_key(a:request, 'resolve') + call add(a:request.resolve, a:callback) + elseif has_key(a:request, 'result') + let a:request.waiting[timer_start(0, function('s:Callback', [a:request, 'result', a:callback]))] = 1 + endif +endfunction + +function! copilot#client#Error(request, callback) abort + if has_key(a:request, 'reject') + call add(a:request.reject, a:callback) + elseif has_key(a:request, 'error') + let a:request.waiting[timer_start(0, function('s:Callback', [a:request, 'error', a:callback]))] = 1 + endif +endfunction + +function! s:CloseBuffer(bufnr) abort + for instance in values(s:instances) + try + if has_key(instance, 'job') && has_key(instance.open_buffers, a:bufnr) + let buffer = remove(instance.open_buffers, a:bufnr) + call instance.Notify('textDocument/didClose', {'textDocument': {'uri': buffer.uri}}) + endif + catch + call copilot#logger#Exception() + endtry + endfor +endfunction + +augroup copilot_close + autocmd! + if !has('nvim') + autocmd BufUnload * call s:CloseBuffer(+expand('')) + endif +augroup END diff --git a/sources_non_forked/copilot.vim/autoload/copilot/doc.vim b/sources_non_forked/copilot.vim/autoload/copilot/doc.vim deleted file mode 100644 index e442e530..00000000 --- a/sources_non_forked/copilot.vim/autoload/copilot/doc.vim +++ /dev/null @@ -1,116 +0,0 @@ -if exists('g:autoloaded_copilot_prompt') - finish -endif -let g:autoloaded_copilot_prompt = 1 - -scriptencoding utf-8 - -let s:slash = exists('+shellslash') ? '\' : '/' - -function copilot#doc#UTF16Width(str) abort - return strchars(substitute(a:str, "\\%#=2[^\u0001-\uffff]", " ", 'g')) -endfunction - -if exists('*utf16idx') - - function! copilot#doc#UTF16ToByteIdx(str, utf16_idx) abort - return byteidx(a:str, a:utf16_idx, 1) - endfunction - -elseif has('nvim') - - function! copilot#doc#UTF16ToByteIdx(str, utf16_idx) abort - try - return v:lua.vim.str_byteindex(a:str, a:utf16_idx, 1) - catch /^Vim(return):E5108:/ - return -1 - endtry - endfunction - -else - - function! copilot#doc#UTF16ToByteIdx(str, utf16_idx) abort - if copilot#doc#UTF16Width(a:str) < a:utf16_idx - return -1 - endif - let end_offset = len(a:str) - while copilot#doc#UTF16Width(strpart(a:str, 0, end_offset)) > a:utf16_idx && end_offset > 0 - let end_offset -= 1 - endwhile - return end_offset - endfunction - -endif - - -let s:language_normalization_map = { - \ "bash": "shellscript", - \ "bst": "bibtex", - \ "cs": "csharp", - \ "cuda": "cuda-cpp", - \ "dosbatch": "bat", - \ "dosini": "ini", - \ "gitcommit": "git-commit", - \ "gitrebase": "git-rebase", - \ "make": "makefile", - \ "objc": "objective-c", - \ "objcpp": "objective-cpp", - \ "ps1": "powershell", - \ "raku": "perl6", - \ "sh": "shellscript", - \ "text": "plaintext", - \ } -function copilot#doc#LanguageForFileType(filetype) abort - let filetype = substitute(a:filetype, '\..*', '', '') - return get(s:language_normalization_map, empty(filetype) ? "text" : filetype, filetype) -endfunction - -function! s:RelativePath(absolute) abort - if exists('b:copilot_relative_path') - return b:copilot_relative_path - elseif exists('b:copilot_root') - let root = b:copilot_root - elseif len(get(b:, 'projectionist', {})) - let root = sort(keys(b:projectionist), { a, b -> a < b })[0] - else - let root = getcwd() - endif - let root = tr(root, s:slash, '/') . '/' - if strpart(tr(a:absolute, 'A-Z', 'a-z'), 0, len(root)) ==# tr(root, 'A-Z', 'a-z') - return strpart(a:absolute, len(root)) - else - return fnamemodify(a:absolute, ':t') - endif -endfunction - -function! copilot#doc#Get() abort - let absolute = tr(@%, s:slash, '/') - if absolute !~# '^\a\+:\|^/\|^$' && &buftype =~# '^\%(nowrite\)\=$' - let absolute = substitute(tr(getcwd(), s:slash, '/'), '/\=$', '/', '') . absolute - endif - let doc = { - \ 'uri': bufnr(''), - \ 'version': getbufvar('', 'changedtick'), - \ 'relativePath': s:RelativePath(absolute), - \ 'insertSpaces': &expandtab ? v:true : v:false, - \ 'tabSize': shiftwidth(), - \ 'indentSize': shiftwidth(), - \ } - let line = getline('.') - let col_byte = col('.') - (mode() =~# '^[iR]' || empty(line)) - let col_utf16 = copilot#doc#UTF16Width(strpart(line, 0, col_byte)) - let doc.position = {'line': line('.') - 1, 'character': col_utf16} - return doc -endfunction - -function! copilot#doc#Params(...) abort - let extra = a:0 ? a:1 : {} - let params = extend({'doc': extend(copilot#doc#Get(), get(extra, 'doc', {}))}, extra, 'keep') - let params.textDocument = { - \ 'uri': params.doc.uri, - \ 'version': params.doc.version, - \ 'relativePath': params.doc.relativePath, - \ } - let params.position = params.doc.position - return params -endfunction diff --git a/sources_non_forked/copilot.vim/autoload/copilot/handlers.vim b/sources_non_forked/copilot.vim/autoload/copilot/handlers.vim new file mode 100644 index 00000000..a73186fe --- /dev/null +++ b/sources_non_forked/copilot.vim/autoload/copilot/handlers.vim @@ -0,0 +1,31 @@ +function! copilot#handlers#window_logMessage(params, ...) abort + call copilot#logger#Raw(get(a:params, 'type', 6), get(a:params, 'message', '')) +endfunction + +function! copilot#handlers#window_showMessageRequest(params, ...) abort + let choice = inputlist([a:params.message . "\n\nRequest Actions:"] + + \ map(copy(get(a:params, 'actions', [])), { i, v -> (i + 1) . '. ' . v.title})) + return choice > 0 ? get(a:params.actions, choice - 1, v:null) : v:null +endfunction + +function! s:BrowserCallback(into, code) abort + let a:into.code = a:code +endfunction + +function! copilot#handlers#window_showDocument(params, ...) abort + echo a:params.uri + if empty(get(a:params, 'external')) + return {'success': v:false} + endif + let browser = copilot#Browser() + if empty(browser) + return {'success': v:false} + endif + let status = {} + call copilot#job#Stream(browser + [a:params.uri], v:null, v:null, function('s:BrowserCallback', [status])) + let time = reltime() + while empty(status) && reltimefloat(reltime(time)) < 1 + sleep 10m + endwhile + return {'success': get(status, 'code') ? v:false : v:true} +endfunction diff --git a/sources_non_forked/copilot.vim/autoload/copilot/job.vim b/sources_non_forked/copilot.vim/autoload/copilot/job.vim index 212e8e62..39904a8d 100644 --- a/sources_non_forked/copilot.vim/autoload/copilot/job.vim +++ b/sources_non_forked/copilot.vim/autoload/copilot/job.vim @@ -1,11 +1,6 @@ -if exists('g:autoloaded_copilot_job') - finish -endif -let g:autoloaded_copilot_job = 1 - scriptencoding utf-8 -function copilot#job#Nop(...) abort +function! copilot#job#Nop(...) abort endfunction function! s:Jobs(job_or_jobs) abort diff --git a/sources_non_forked/copilot.vim/autoload/copilot/logger.vim b/sources_non_forked/copilot.vim/autoload/copilot/logger.vim index 105e3f9b..923a1c11 100644 --- a/sources_non_forked/copilot.vim/autoload/copilot/logger.vim +++ b/sources_non_forked/copilot.vim/autoload/copilot/logger.vim @@ -1,8 +1,3 @@ -if exists('g:autoloaded_copilot_log') - finish -endif -let g:autoloaded_copilot_log = 1 - if !exists('s:log_file') let s:log_file = tempname() . '-copilot.log' try @@ -11,35 +6,59 @@ if !exists('s:log_file') endtry endif -function! copilot#logger#File() abort - return s:log_file +let s:logs = [] + +function! copilot#logger#BufReadCmd() abort + try + setlocal modifiable noreadonly + silent call deletebufline('', 1, '$') + if !empty(s:logs) + call setline(1, s:logs) + endif + finally + setlocal buftype=nofile bufhidden=wipe nobuflisted nomodified nomodifiable + endtry endfunction +let s:level_prefixes = ['', '[ERROR] ', '[WARN] ', '[INFO] ', '[DEBUG] ', '[DEBUG] '] + function! copilot#logger#Raw(level, message) abort - if $COPILOT_AGENT_VERBOSE !~# '^\%(1\|true\)$' && a:level < 1 - return - endif let lines = type(a:message) == v:t_list ? copy(a:message) : split(a:message, "\n", 1) + let lines[0] = strftime('[%Y-%m-%d %H:%M:%S] ') . get(s:level_prefixes, a:level, '[UNKNOWN] ') . get(lines, 0, '') try if !filewritable(s:log_file) return endif call map(lines, { k, L -> type(L) == v:t_func ? call(L, []) : L }) - call writefile(lines, s:log_file, 'a') + call extend(s:logs, lines) + let overflow = len(s:logs) - get(g:, 'copilot_log_history', 10000) + if overflow > 0 + call remove(s:logs, 0, overflow - 1) + endif + let bufnr = bufnr('copilot:///log') + if bufnr > 0 && bufloaded(bufnr) + call setbufvar(bufnr, '&modifiable', 1) + call setbufline(bufnr, 1, s:logs) + call setbufvar(bufnr, '&modifiable', 0) + for winid in win_findbuf(bufnr) + if has('nvim') && winid != win_getid() + call nvim_win_set_cursor(winid, [len(s:logs), 0]) + endif + endfor + endif catch endtry endfunction -function! copilot#logger#Trace(...) abort - call copilot#logger#Raw(-1, a:000) -endfunction - function! copilot#logger#Debug(...) abort - call copilot#logger#Raw(0, a:000) + if empty(get(g:, 'copilot_debug')) + return + endif + call copilot#logger#Raw(4, a:000) endfunction function! copilot#logger#Info(...) abort - call copilot#logger#Raw(1, a:000) + call copilot#logger#Raw(3, a:000) endfunction function! copilot#logger#Warn(...) abort @@ -47,26 +66,40 @@ function! copilot#logger#Warn(...) abort endfunction function! copilot#logger#Error(...) abort - call copilot#logger#Raw(3, a:000) + call copilot#logger#Raw(1, a:000) endfunction -function! copilot#logger#Exception() abort +function! copilot#logger#Bare(...) abort + call copilot#logger#Raw(0, a:000) +endfunction + +function! copilot#logger#Exception(...) abort if !empty(v:exception) && v:exception !=# 'Vim:Interrupt' call copilot#logger#Error('Exception: ' . v:exception . ' @ ' . v:throwpoint) - let agent = copilot#RunningAgent() - if !empty(agent) + let client = copilot#RunningClient() + if !empty(client) + let [_, type, code, message; __] = matchlist(v:exception, '^\%(\(^[[:alnum:]_#]\+\)\%((\a\+)\)\=\%(\(:E-\=\d\+\)\)\=:\s*\)\=\(.*\)$') let stacklines = [] - for frame in split(substitute(substitute(v:throwpoint, ', \S\+ \(\d\+\)$', '[\1]', ''), '^function ', '', ''), '\.\@\d\+_', '', ''), 'lineno': +fn_line[2]}) + elseif frame =~# ' Autocmds for "\*"$' + call add(stacklines, {'function': frame}) + elseif frame =~# ' Autocmds for ".*"$' + call add(stacklines, {'function': substitute(frame, ' for ".*"$', ' for "[redacted]"', '')}) else - call add(stacklines, substitute(frame, '^\d\+_', '', '')) + call add(stacklines, {'function': '[redacted]'}) endif endfor - call agent.Request('telemetry/exception', { - \ 'origin': 'copilot.vim', - \ 'stacktrace': join([v:exception] + stacklines, "\n") - \ }) + return client.Request('telemetry/exception', { + \ 'transaction': a:0 ? a:1 : '', + \ 'platform': 'other', + \ 'exception_detail': [{ + \ 'type': type . code, + \ 'value': message, + \ 'stacktrace': stacklines}] + \ }, v:null, function('copilot#util#Nop')) endif endif endfunction diff --git a/sources_non_forked/copilot.vim/autoload/copilot/panel.vim b/sources_non_forked/copilot.vim/autoload/copilot/panel.vim index 072ef948..4e25237e 100644 --- a/sources_non_forked/copilot.vim/autoload/copilot/panel.vim +++ b/sources_non_forked/copilot.vim/autoload/copilot/panel.vim @@ -1,8 +1,3 @@ -if exists('g:autoloaded_copilot_panel') - finish -endif -let g:autoloaded_copilot_panel = 1 - scriptencoding utf-8 if !exists('s:panel_id') @@ -11,29 +6,35 @@ endif let s:separator = repeat('─', 72) -function! s:Solutions(state) abort - return sort(values(get(a:state, 'solutions', {})), { a, b -> a.score < b.score }) -endfunction - -function! s:Render(panel_id) abort - let bufnr = bufnr('^' . a:panel_id . '$') - let state = getbufvar(bufnr, 'copilot_panel') - if !bufloaded(bufnr) || type(state) != v:t_dict +function! s:Render(state) abort + let bufnr = bufnr('^' . a:state.panel . '$') + let state = a:state + if !bufloaded(bufnr) return endif - let sorted = s:Solutions(state) - if !empty(get(state, 'status', '')) - let lines = ['Error: ' . state.status] + let sorted = a:state.items + if !empty(get(a:state, 'error')) + let lines = ['Error: ' . a:state.error.message] + let sorted = [] + elseif get(a:state, 'percentage') == 100 + let lines = ['Synthesized ' . (len(sorted) == 1 ? '1 completion' : len(sorted) . ' completions')] else - let target = get(state, 'count_target', '?') - let received = has_key(state, 'status') ? target : len(sorted) - let lines = ['Synthesiz' . (has_key(state, 'status') ? 'ed ' : 'ing ') . received . '/' . target . ' solutions (Duplicates hidden)'] + let lines = [substitute('Synthesizing ' . matchstr(get(a:state, 'message', ''), '\d\+\%(/\d\+\)\=') . ' completions', ' \+', ' ', 'g')] endif if len(sorted) - call add(lines, 'Press on a solution to accept') + call add(lines, 'Press on a completion to accept') endif - for solution in sorted - let lines += [s:separator] + split(solution.displayText, "\n", 1) + let leads = {} + for item in sorted + let insert = split(item.insertText, "\r\n\\=\\|\n", 1) + let insert[0] = strpart(a:state.line, 0, copilot#util#UTF16ToByteIdx(a:state.line, item.range.start.character)) . insert[0] + let lines += [s:separator] + insert + if !has_key(leads, string(item.range.start)) + let match = insert[0 : a:state.position.line - item.range.start.line] + let match[-1] = strpart(match[-1], 0, copilot#util#UTF16ToByteIdx(match[-1], a:state.position.character)) + call map(match, { k, v -> escape(v, '][^$.*\~') }) + let leads[string(item.range.start)] = join(match, '\n') + endif endfor try call setbufvar(bufnr, '&modifiable', 1) @@ -41,64 +42,61 @@ function! s:Render(panel_id) abort call setbufline(bufnr, 1, lines) finally call setbufvar(bufnr, '&modifiable', 0) - call setbufvar(bufnr, '&readonly', 1) endtry + call clearmatches() + call matchadd('CopilotSuggestion', '\C^' . s:separator . '\n\zs\%(' . join(sort(values(leads), { a, b -> len(b) - len(a) }), '\|') . '\)', 10, 4) endfunction -function! copilot#panel#Solution(params, ...) abort - let state = getbufvar('^' . a:params.panelId . '$', 'copilot_panel') - if !bufloaded(a:params.panelId) || type(state) != v:t_dict - return - endif - let state.solutions[a:params.solutionId] = a:params - call s:Render(a:params.panelId) +function! s:PartialResult(state, value) abort + let items = type(a:value) == v:t_list ? a:value : a:value.items + call extend(a:state.items, items) + call s:Render(a:state) endfunction -function! copilot#panel#SolutionsDone(params, ...) abort - let state = getbufvar('^' . a:params.panelId . '$', 'copilot_panel') - if !bufloaded(a:params.panelId) || type(state) != v:t_dict - call copilot#logger#Debug('SolutionsDone: ' . a:params.panelId) - return +function! s:WorkDone(state, value) abort + if has_key(a:value, 'message') + let a:state.message = a:value.message + endif + if has_key(a:value, 'percentage') + let a:state.percentage = a:value.percentage + call s:Render(a:state) endif - let state.status = get(a:params, 'message', '') - call s:Render(a:params.panelId) endfunction function! copilot#panel#Accept(...) abort let state = get(b:, 'copilot_panel', {}) - let solutions = s:Solutions(state) - if empty(solutions) + if empty(state.items) return '' endif if !has_key(state, 'bufnr') || !bufloaded(get(state, 'bufnr', -1)) return "echoerr 'Buffer was closed'" endif let at = a:0 ? a:1 : line('.') - let solution_index = 0 + let index = 0 for lnum in range(1, at) if getline(lnum) ==# s:separator - let solution_index += 1 + let index += 1 endif endfor - if solution_index > 0 && solution_index <= len(solutions) - let solution = solutions[solution_index - 1] - let lnum = solution.range.start.line + 1 + if index > 0 && index <= len(state.items) + let item = state.items[index - 1] + let lnum = item.range.start.line + 1 if getbufline(state.bufnr, lnum) !=# [state.line] - return 'echoerr "Buffer has changed since synthesizing solution"' + return 'echoerr "Buffer has changed since synthesizing completion"' endif - let lines = split(solution.displayText, "\n", 1) - let old_first = getline(solution.range.start.line + 1) - let lines[0] = strpart(old_first, 0, copilot#doc#UTF16ToByteIdx(old_first, solution.range.start.character)) . lines[0] - let old_last = getline(solution.range.end.line + 1) - let lines[-1] .= strpart(old_last, copilot#doc#UTF16ToByteIdx(old_last, solution.range.start.character)) - call setbufline(state.bufnr, solution.range.start.line + 1, lines[0]) - call appendbufline(state.bufnr, solution.range.start.line + 1, lines[1:-1]) - call copilot#Request('notifyAccepted', {'uuid': solution.solutionId}) + let lines = split(item.insertText, "\n", 1) + let old_first = getbufline(state.bufnr, item.range.start.line + 1)[0] + let lines[0] = strpart(old_first, 0, copilot#util#UTF16ToByteIdx(old_first, item.range.start.character)) . lines[0] + let old_last = getbufline(state.bufnr, item.range.end.line + 1)[0] + let lines[-1] .= strpart(old_last, copilot#util#UTF16ToByteIdx(old_last, item.range.end.character)) + call deletebufline(state.bufnr, item.range.start.line + 1, item.range.end.line + 1) + call appendbufline(state.bufnr, item.range.start.line, lines) + call copilot#Request('workspace/executeCommand', item.command) bwipeout let win = bufwinnr(state.bufnr) if win > 0 exe win . 'wincmd w' - exe solution.range.start.line + len(lines) + exe item.range.start.line + len(lines) if state.was_insert startinsert! else @@ -112,49 +110,58 @@ endfunction function! s:Initialize(state) abort let &l:filetype = 'copilot' . (empty(a:state.filetype) ? '' : '.' . a:state.filetype) let &l:tabstop = a:state.tabstop - call clearmatches() - call matchadd('CopilotSuggestion', '\C^' . s:separator . '\n\zs' . escape(a:state.line, '][^$.*\~'), 10, 4) nmap