From 59dae8a09cd043133882f5211f9fc89ca7160b58 Mon Sep 17 00:00:00 2001 From: Pau Ruiz Safont Date: Sat, 22 May 2021 15:58:37 +0100 Subject: [PATCH] ocaml: prepare for filetype separation The ocaml filetype is currently used for several, different file formats. This causes problems as not all tools support all formats. New filetypes are introduced to support this separation, this needs some changes in ale that are fortunately backwards-compatible. These change add ocamlinterface file support for ocp-indent, merlin, ocamlformat and ocaml-lsp. For ocaml-lsp I took the liberty to add all recognised language ids, even if they are not supported. ols has not been changed as the project has been abandoned since 2019. --- ale_linters/ocamlinterface/merlin.vim | 17 +++++++++++ ale_linters/ocamlinterface/ocamllsp.vim | 13 +++++++++ autoload/ale/fix/registry.vim | 4 +-- autoload/ale/handlers/ocamllsp.vim | 9 +++++- .../linter/test_ocamlinterface_ocamllsp.vader | 29 +++++++++++++++++++ 5 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 ale_linters/ocamlinterface/merlin.vim create mode 100644 ale_linters/ocamlinterface/ocamllsp.vim create mode 100644 test/linter/test_ocamlinterface_ocamllsp.vader diff --git a/ale_linters/ocamlinterface/merlin.vim b/ale_linters/ocamlinterface/merlin.vim new file mode 100644 index 0000000000..799490f71a --- /dev/null +++ b/ale_linters/ocamlinterface/merlin.vim @@ -0,0 +1,17 @@ +" Author: Andrey Popp -- @andreypopp +" Description: Report errors in OCaml code with Merlin + +if !exists('g:merlin') + finish +endif + +function! ale_linters#ocamlinterface#merlin#Handle(buffer, lines) abort + return merlin#ErrorLocList() +endfunction + +call ale#linter#Define('ocamlinterface', { +\ 'name': 'merlin', +\ 'executable': 'ocamlmerlin', +\ 'command': 'true', +\ 'callback': 'ale_linters#ocamlinterface#merlin#Handle', +\}) diff --git a/ale_linters/ocamlinterface/ocamllsp.vim b/ale_linters/ocamlinterface/ocamllsp.vim new file mode 100644 index 0000000000..cd4bea80de --- /dev/null +++ b/ale_linters/ocamlinterface/ocamllsp.vim @@ -0,0 +1,13 @@ +" Author: Risto Stevcev +" Description: The official language server for OCaml + +call ale#Set('ocaml_ocamllsp_use_opam', 1) + +call ale#linter#Define('ocamlinterface', { +\ 'name': 'ocamllsp', +\ 'lsp': 'stdio', +\ 'executable': function('ale#handlers#ocamllsp#GetExecutable'), +\ 'command': function('ale#handlers#ocamllsp#GetCommand'), +\ 'language': function('ale#handlers#ocamllsp#GetLanguage'), +\ 'project_root': function('ale#handlers#ocamllsp#GetProjectRoot'), +\}) diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index efc9ebe022..1cd5b6efcc 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -303,12 +303,12 @@ let s:default_registry = { \ }, \ 'ocamlformat': { \ 'function': 'ale#fixers#ocamlformat#Fix', -\ 'suggested_filetypes': ['ocaml'], +\ 'suggested_filetypes': ['ocaml', 'ocamlinterface'], \ 'description': 'Fix OCaml files with ocamlformat.', \ }, \ 'ocp-indent': { \ 'function': 'ale#fixers#ocp_indent#Fix', -\ 'suggested_filetypes': ['ocaml'], +\ 'suggested_filetypes': ['ocaml', 'ocamlinterface'], \ 'description': 'Fix OCaml files with ocp-indent.', \ }, \ 'refmt': { diff --git a/autoload/ale/handlers/ocamllsp.vim b/autoload/ale/handlers/ocamllsp.vim index 07d9b0cf24..2738ea2b84 100644 --- a/autoload/ale/handlers/ocamllsp.vim +++ b/autoload/ale/handlers/ocamllsp.vim @@ -1,6 +1,13 @@ " Author: Risto Stevcev " Description: Handlers for the official OCaml language server +let s:language_id_of_filetype = { +\ 'menhir': 'ocaml.menhir', +\ 'ocaml': 'ocaml', +\ 'ocamlinterface': 'ocaml.interface', +\ 'ocamllex': 'ocaml.lex' +\} + function! ale#handlers#ocamllsp#GetExecutable(buffer) abort return 'ocamllsp' endfunction @@ -13,7 +20,7 @@ function! ale#handlers#ocamllsp#GetCommand(buffer) abort endfunction function! ale#handlers#ocamllsp#GetLanguage(buffer) abort - return getbufvar(a:buffer, '&filetype') + return s:language_id_of_filetype[getbufvar(a:buffer, '&filetype')] endfunction function! ale#handlers#ocamllsp#GetProjectRoot(buffer) abort diff --git a/test/linter/test_ocamlinterface_ocamllsp.vader b/test/linter/test_ocamlinterface_ocamllsp.vader new file mode 100644 index 0000000000..aa0b2100ac --- /dev/null +++ b/test/linter/test_ocamlinterface_ocamllsp.vader @@ -0,0 +1,29 @@ +Before: + call ale#assert#SetUpLinterTest('ocamlinterface', 'ocamllsp') + + Save &filetype + let &filetype = 'ocamlinterface' + +After: + call ale#assert#TearDownLinterTest() + +Execute(The language string should be correct): + AssertLSPLanguage 'ocaml.interface' + +Execute(The project root should be detected correctly): + AssertLSPProject '' + + call ale#test#SetFilename('../test-files/ocamllsp/file.ml') + + AssertLSPProject ale#path#Simplify(g:dir . '/../test-files/ocamllsp') + +Execute(The executable should be run using opam exec by default): + call ale#test#SetFilename('../test-files/ocamllsp/file.ml') + + AssertLinter 'ocamllsp', 'opam config exec -- ocamllsp' + +Execute(The executable should be run directly if use_opam flag is disabled): + let g:ale_ocaml_ocamllsp_use_opam = 0 + call ale#test#SetFilename('../test-files/ocamllsp/file.ml') + + AssertLinter 'ocamllsp', 'ocamllsp'