diff --git a/ale_linters/terraform/terraform_ls.vim b/ale_linters/terraform/terraform_ls.vim new file mode 100644 index 00000000..ab35126e --- /dev/null +++ b/ale_linters/terraform/terraform_ls.vim @@ -0,0 +1,38 @@ +" Author: Horacio Sanson +" Description: terraform-ls integration for ALE (cf. https://github.com/hashicorp/terraform-ls) + +call ale#Set('terraform_terraform_executable', 'terraform') +call ale#Set('terraform_ls_executable', 'terraform-ls') +call ale#Set('terraform_ls_options', '') + +function! ale_linters#terraform#terraform_ls#GetTerraformExecutable(buffer) abort + let l:terraform_executable = ale#Var(a:buffer, 'terraform_terraform_executable') + + if(ale#path#IsAbsolute(l:terraform_executable)) + return '-tf-exec ' . l:terraform_executable + endif + + return '' +endfunction + +function! ale_linters#terraform#terraform_ls#GetCommand(buffer) abort + return '%e' + \ . ale#Pad('serve') + \ . ale#Pad(ale_linters#terraform#terraform_ls#GetTerraformExecutable(a:buffer)) + \ . ale#Pad(ale#Var(a:buffer, 'terraform_ls_options')) +endfunction + +function! ale_linters#terraform#terraform_ls#GetProjectRoot(buffer) abort + let l:tf_dir = ale#path#FindNearestDirectory(a:buffer, '.terraform') + + return !empty(l:tf_dir) ? fnamemodify(l:tf_dir, ':h:h') : '' +endfunction + +call ale#linter#Define('terraform', { +\ 'name': 'terraform_ls', +\ 'lsp': 'stdio', +\ 'executable': {b -> ale#Var(b, 'terraform_ls_executable')}, +\ 'command': function('ale_linters#terraform#terraform_ls#GetCommand'), +\ 'project_root': function('ale_linters#terraform#terraform_ls#GetProjectRoot'), +\ 'language': 'terraform', +\}) diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index ac99f6ff..d9b5f68f 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -486,7 +486,10 @@ Notes: * Tcl * `nagelfar`!! * Terraform - * `fmt` + * `terraform` + * `terraform-fmt-fixer` + * `terraform-ls` + * `terraform-lsp` * `tflint` * Texinfo * `alex`!! diff --git a/doc/ale-terraform.txt b/doc/ale-terraform.txt index f62db190..175bdf5c 100644 --- a/doc/ale-terraform.txt +++ b/doc/ale-terraform.txt @@ -32,6 +32,28 @@ g:ale_terraform_terraform_executable *g:ale_terraform_terraform_executable* This variable can be changed to use a different executable for terraform. +=============================================================================== +terraform-ls *ale-terraform-terraform-ls* + +Official terraform language server. More stable than *terraform-lsp* but +currently has less features. + +g:ale_terraform_ls_executable *g:ale_terraform_ls_executable* + *b:ale_terraform_ls_executable* + Type: |String| + Default: `'terraform-ls'` + + This variable can be changed to use a different executable for terraform-ls. + + +g:ale_terraform_ls_options *g:ale_terraform_ls_options* + *b:ale_terraform_ls_options* + Type: |String| + Default: `''` + + This variable can be changed to pass custom CLI flags to terraform-ls. + + =============================================================================== terraform-lsp *ale-terraform-terraform-lsp* diff --git a/doc/ale.txt b/doc/ale.txt index e58fed72..84f20686 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -2984,6 +2984,7 @@ documented in additional help files. terraform...............................|ale-terraform-options| terraform-fmt-fixer...................|ale-terraform-fmt-fixer| terraform.............................|ale-terraform-terraform| + terraform-ls..........................|ale-terraform-terraform-ls| terraform-lsp.........................|ale-terraform-terraform-lsp| tflint................................|ale-terraform-tflint| tex.....................................|ale-tex-options| diff --git a/supported-tools.md b/supported-tools.md index 90485281..069432ca 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -495,7 +495,10 @@ formatting. * Tcl * [nagelfar](http://nagelfar.sourceforge.net) :floppy_disk: * Terraform - * [fmt](https://github.com/hashicorp/terraform) + * [terraform](https://github.com/hashicorp/terraform) + * [terraform-fmt-fixer](https://github.com/hashicorp/terraform) + * [terraform-ls](https://github.com/hashicorp/terraform-ls) + * [terraform-lsp](https://github.com/juliosueiras/terraform-lsp) * [tflint](https://github.com/wata727/tflint) * Texinfo * [alex](https://github.com/wooorm/alex) :floppy_disk: diff --git a/test/command_callback/test_terraform_ls_command_callback.vader b/test/command_callback/test_terraform_ls_command_callback.vader new file mode 100644 index 00000000..d559ba8c --- /dev/null +++ b/test/command_callback/test_terraform_ls_command_callback.vader @@ -0,0 +1,61 @@ +Before: + call ale#assert#SetUpLinterTest('terraform', 'terraform_ls') + +After: + if isdirectory(g:dir . '/.terraform') + call delete(g:dir . '/.terraform', 'd') + endif + + unlet! b:ale_terraform_terraform_executable + unlet! b:ale_terraform_ls_executable + unlet! b:ale_terraform_ls_options + + call ale#assert#TearDownLinterTest() + +Execute(Should send correct LSP language): + AssertLSPLanguage 'terraform' + +Execute(Should load default executable): + AssertLinter 'terraform-ls', + \ ale#Escape('terraform-ls') . ' serve' + +Execute(Should configure custom executable): + let b:ale_terraform_ls_executable = 'foo' + AssertLinter 'foo', + \ ale#Escape('foo') . ' serve' + +Execute(Should ignore non-absolute custom terraform executable): + let b:ale_terraform_terraform_executable = 'terraform' + AssertLinter 'terraform-ls', + \ ale#Escape('terraform-ls') . ' serve' + +Execute(Should set absolute custom terraform executable): + let b:ale_terraform_terraform_executable = '/bin/terraform' + AssertLinter 'terraform-ls', + \ ale#Escape('terraform-ls') . ' serve -tf-exec /bin/terraform' + +Execute(Should set custom options): + let b:ale_terraform_ls_options = '--bar' + + AssertLinter 'terraform-ls', + \ ale#Escape('terraform-ls') . ' serve --bar' + +Execute(Should return current directory if it contains .terraform directory): + call mkdir(g:dir . '/.terraform') + AssertLSPProject g:dir + +Execute(Should return nearest directory with .terraform if found in parent directory): + call ale#test#SetFilename('../terraform_files/main.tf') + + let b:parent_dir = ale#path#Simplify(g:dir . '/..') + let b:tf_dir = b:parent_dir . '/.terraform' + + if !isdirectory(b:tf_dir) + call mkdir(b:tf_dir) + endif + + AssertLSPProject b:parent_dir + + call delete(b:tf_dir, 'd') + unlet!b:parent_dir + unlet!b:tf_dir