From 9b362634f7210657d94870b017e969bdcdda8de0 Mon Sep 17 00:00:00 2001 From: Mohammed Chelouti <70812484+motato1@users.noreply.github.com> Date: Tue, 29 Dec 2020 21:46:02 +0100 Subject: [PATCH] feat: Add Deno lsp support --- ale_linters/typescript/deno.vim | 25 ++++++++ autoload/ale/handlers/deno.vim | 43 +++++++++++++ .../test_typescript_deno_lsp.vader | 61 +++++++++++++++++++ test/typescript/test.ts | 0 test/typescript/tsconfig.json | 0 5 files changed, 129 insertions(+) create mode 100644 ale_linters/typescript/deno.vim create mode 100644 test/command_callback/test_typescript_deno_lsp.vader create mode 100644 test/typescript/test.ts create mode 100644 test/typescript/tsconfig.json diff --git a/ale_linters/typescript/deno.vim b/ale_linters/typescript/deno.vim new file mode 100644 index 00000000..051cb208 --- /dev/null +++ b/ale_linters/typescript/deno.vim @@ -0,0 +1,25 @@ +" Author: Mohammed Chelouti - https://github.com/motato1 +" Description: Deno lsp linter for TypeScript files. + +call ale#linter#Define('typescript', { +\ 'name': 'deno', +\ 'lsp': 'stdio', +\ 'executable': function('ale#handlers#deno#GetExecutable'), +\ 'command': '%e lsp', +\ 'project_root': function('ale#handlers#deno#GetProjectRoot'), +\ 'initialization_options': function('ale_linters#typescript#deno#GetInitializationOptions'), +\}) + +function! ale_linters#typescript#deno#GetInitializationOptions(buffer) abort + let l:options = { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false, + \ } + + if ale#Var(a:buffer, 'deno_unstable') + let l:options.unstable = v:true + endif + + return l:options +endfunction diff --git a/autoload/ale/handlers/deno.vim b/autoload/ale/handlers/deno.vim index 636c25da..4bf4546a 100644 --- a/autoload/ale/handlers/deno.vim +++ b/autoload/ale/handlers/deno.vim @@ -3,7 +3,50 @@ call ale#Set('deno_executable', 'deno') call ale#Set('deno_unstable', 0) +call ale#Set('deno_lsp_project_root', '') function! ale#handlers#deno#GetExecutable(buffer) abort return ale#Var(a:buffer, 'deno_executable') endfunction + +" Find project root for Deno's language server. +" +" Deno projects do not require a project or configuration file at the project root. +" This means the root directory has to be guessed, +" unless it is explicitly specified by the user. +" +" The project root is determined by ... +" 1. using a user-specified value from deno_lsp_project_root +" 2. looking for common top-level files/dirs +" 3. using the buffer's directory +function! ale#handlers#deno#GetProjectRoot(buffer) abort + let l:project_root = ale#Var(a:buffer, 'deno_lsp_project_root') + + if !empty(l:project_root) + return l:project_root + endif + + let l:possible_project_roots = [ + \ 'tsconfig.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/test/command_callback/test_typescript_deno_lsp.vader b/test/command_callback/test_typescript_deno_lsp.vader new file mode 100644 index 00000000..b6e4db0e --- /dev/null +++ b/test/command_callback/test_typescript_deno_lsp.vader @@ -0,0 +1,61 @@ +Before: + let g:ale_deno_unstable = 0 + let g:ale_deno_executable = 'deno' + let g:ale_deno_project_root = '' + + runtime autoload/ale/handlers/deno.vim + call ale#assert#SetUpLinterTest('typescript', 'deno') + +After: + call ale#assert#TearDownLinterTest() + +Execute(Should set deno lsp for TypeScript projects using stable Deno API): + AssertLSPLanguage 'typescript' + AssertLSPConfig {} + AssertLSPProject ale#path#Simplify(g:dir . '/../..') + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false + \} + +Execute(Should set deno lsp using unstable Deno API if enabled by user): + let g:ale_deno_unstable = 1 + AssertLSPLanguage 'typescript' + AssertLSPConfig {} + AssertLSPProject ale#path#Simplify(g:dir . '/../..') + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:true + \} + +Execute(Should find project root containing tsconfig.json): + call ale#test#SetFilename('../typescript/test.ts') + AssertLSPLanguage 'typescript' + AssertLSPConfig {} + AssertLSPProject ale#path#Simplify(g:dir . '/../typescript') + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false + \} + +Execute(Should use user-specified project root): + let g:ale_deno_lsp_project_root = '/' + + call ale#test#SetFilename('../typescript/test.ts') + AssertLSPLanguage 'typescript' + AssertLSPConfig {} + AssertLSPProject '/' + AssertLSPOptions { + \ 'enable': v:true, + \ 'lint': v:true, + \ 'unstable': v:false + \} + + +Execute(Check Deno LSP command): + AssertLinter 'deno', [ + \ ale#Escape('deno') . ' lsp', + \] diff --git a/test/typescript/test.ts b/test/typescript/test.ts new file mode 100644 index 00000000..e69de29b diff --git a/test/typescript/tsconfig.json b/test/typescript/tsconfig.json new file mode 100644 index 00000000..e69de29b