From ed0b036220705e259ab574861016d1c53fdf6de8 Mon Sep 17 00:00:00 2001 From: Braden Kelley Date: Tue, 25 Jun 2024 01:18:28 -0700 Subject: [PATCH] fix(biome): find root when using biome.jsonc (#4774) Since biome supports either `biome.json` or `biome.jsonc` config files, we need to look for both when searching for the LSP project root. We can also look for a package.json or .git folder to use. This uses mostly the same logic as deno. --- autoload/ale/handlers/biome.vim | 33 ++++++++++++++++++++-- doc/ale-typescript.txt | 16 +++++++++++ test/linter/test_biome.vader | 19 +++++++++++++ test/linter/test_typescript_deno_lsp.vader | 2 ++ test/test-files/biome/json/biome.json | 0 test/test-files/biome/json/src/test.ts | 0 test/test-files/biome/jsonc/biome.jsonc | 0 test/test-files/biome/jsonc/src/test.ts | 0 8 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 test/test-files/biome/json/biome.json create mode 100644 test/test-files/biome/json/src/test.ts create mode 100644 test/test-files/biome/jsonc/biome.jsonc create mode 100644 test/test-files/biome/jsonc/src/test.ts diff --git a/autoload/ale/handlers/biome.vim b/autoload/ale/handlers/biome.vim index a12bfe83..47384e56 100644 --- a/autoload/ale/handlers/biome.vim +++ b/autoload/ale/handlers/biome.vim @@ -5,6 +5,7 @@ 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, 'biome', [ @@ -30,7 +31,35 @@ function! ale#handlers#biome#GetLanguage(buffer) abort endfunction function! ale#handlers#biome#GetProjectRoot(buffer) abort - let l:biome_file = ale#path#FindNearestFile(a:buffer, 'biome.json') + let l:project_root = ale#Var(a:buffer, 'biome_lsp_project_root') - return !empty(l:biome_file) ? fnamemodify(l:biome_file, ':h') : '' + 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/doc/ale-typescript.txt b/doc/ale-typescript.txt index 967287a2..f22b6586 100644 --- a/doc/ale-typescript.txt +++ b/doc/ale-typescript.txt @@ -35,6 +35,22 @@ g:ale_biome_fixer_apply_unsafe *g:ale_biome_fixer_apply_unsafe* 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/test/linter/test_biome.vader b/test/linter/test_biome.vader index c2cd9407..2e5e7aac 100644 --- a/test/linter/test_biome.vader +++ b/test/linter/test_biome.vader @@ -1,7 +1,9 @@ Before: Save g:ale_biome_options + Save g:ale_biome_lsp_project_root let g:ale_biome_options = '' + let g:ale_biome_lsp_project_root = '' call ale#assert#SetUpLinterTest('typescript', 'biome') call ale#test#SetFilename('test.ts') @@ -33,3 +35,20 @@ Execute(Uses the filetype as the language): call ale#test#SetFilename('test.jsx') set filetype=javascriptreact AssertLSPLanguage 'javascriptreact' + +Execute(Should find project root containing biome.json): + call ale#test#SetFilename('../test-files/biome/json/src/test.ts') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/biome/json') + +Execute(Should find project root containing biome.jsonc): + call ale#test#SetFilename('../test-files/biome/jsonc/src/test.ts') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/biome/jsonc') + +Execute(Should use user-specified project root): + let g:ale_biome_lsp_project_root = '/' + + call ale#test#SetFilename('../test-files/biome/jsonc/src/test.ts') + + AssertLSPProject '/' diff --git a/test/linter/test_typescript_deno_lsp.vader b/test/linter/test_typescript_deno_lsp.vader index 8bae1ae2..c77b2a10 100644 --- a/test/linter/test_typescript_deno_lsp.vader +++ b/test/linter/test_typescript_deno_lsp.vader @@ -1,10 +1,12 @@ Before: Save g:ale_deno_import_map + Save g:ale_deno_importMap Save g:ale_deno_unstable Save g:ale_deno_executable Save g:ale_deno_lsp_project_root let g:ale_deno_import_map = 'import_map.json' + let g:ale_deno_importMap = '' let g:ale_deno_unstable = 0 let g:ale_deno_executable = 'deno' let g:ale_deno_lsp_project_root = '' diff --git a/test/test-files/biome/json/biome.json b/test/test-files/biome/json/biome.json new file mode 100644 index 00000000..e69de29b diff --git a/test/test-files/biome/json/src/test.ts b/test/test-files/biome/json/src/test.ts new file mode 100644 index 00000000..e69de29b diff --git a/test/test-files/biome/jsonc/biome.jsonc b/test/test-files/biome/jsonc/biome.jsonc new file mode 100644 index 00000000..e69de29b diff --git a/test/test-files/biome/jsonc/src/test.ts b/test/test-files/biome/jsonc/src/test.ts new file mode 100644 index 00000000..e69de29b