diff --git a/README.md b/README.md index e8108733..a7b3a22a 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ formatting. | Rust | cargo !! (see `:help ale-integration-rust` for configuration instructions), [rls](https://github.com/rust-lang-nursery/rls), [rustc](https://www.rust-lang.org/), [rustfmt](https://github.com/rust-lang-nursery/rustfmt) | | SASS | [sass-lint](https://www.npmjs.com/package/sass-lint), [stylelint](https://github.com/stylelint/stylelint) | | SCSS | [prettier](https://github.com/prettier/prettier), [sass-lint](https://www.npmjs.com/package/sass-lint), [scss-lint](https://github.com/brigade/scss-lint), [stylelint](https://github.com/stylelint/stylelint) | -| Scala | [fsc](https://www.scala-lang.org/old/sites/default/files/linuxsoft_archives/docu/files/tools/fsc.html), [scalac](http://scala-lang.org), [scalafmt](https://scalameta.org/scalafmt/), [scalastyle](http://www.scalastyle.org) | +| Scala | [fsc](https://www.scala-lang.org/old/sites/default/files/linuxsoft_archives/docu/files/tools/fsc.html), [sbtserver](https://www.scala-sbt.org/1.x/docs/sbt-server.html), [scalac](http://scala-lang.org), [scalafmt](https://scalameta.org/scalafmt/), [scalastyle](http://www.scalastyle.org)| | Slim | [slim-lint](https://github.com/sds/slim-lint) | | SML | [smlnj](http://www.smlnj.org/) | | Solidity | [solhint](https://github.com/protofire/solhint), [solium](https://github.com/duaraghav8/Solium) | diff --git a/ale_linters/scala/sbtserver.vim b/ale_linters/scala/sbtserver.vim new file mode 100644 index 00000000..d75c38ca --- /dev/null +++ b/ale_linters/scala/sbtserver.vim @@ -0,0 +1,27 @@ +" Author: ophirr33 +" Description: TCP lsp client for sbt Server + +call ale#Set('scala_sbtserver_address', '127.0.0.1:4273') +call ale#Set('scala_sbtserver_project_root', '') + +function! ale_linters#scala#sbtserver#GetProjectRoot(buffer) abort + let l:project_root = ale#Var(a:buffer, 'scala_sbtserver_project_root') + if l:project_root is? '' + let l:project_root = ale#path#FindNearestFile(a:buffer, 'build.sbt') + return !empty(l:project_root) ? fnamemodify(l:project_root, ':h') : '' + endif + return l:project_root +endfunction + +function! ale_linters#scala#sbtserver#GetAddress(buffer) abort + let l:address = ale#Var(a:buffer, 'scala_sbtserver_address') + return l:address +endfunction + +call ale#linter#Define('scala', { +\ 'name': 'sbtserver', +\ 'lsp': 'socket', +\ 'address_callback': 'ale_linters#scala#sbtserver#GetAddress', +\ 'language': 'scala', +\ 'project_root_callback': 'ale_linters#scala#sbtserver#GetProjectRoot', +\}) diff --git a/autoload/ale/linter.vim b/autoload/ale/linter.vim index aad386aa..06bc5e80 100644 --- a/autoload/ale/linter.vim +++ b/autoload/ale/linter.vim @@ -99,7 +99,7 @@ function! ale#linter#PreProcess(filetype, linter) abort endif if index(['', 'socket', 'stdio', 'tsserver'], l:obj.lsp) < 0 - throw '`lsp` must be either `''lsp''` or `''tsserver''` if defined' + throw '`lsp` must be either `''lsp''`, `''stdio''`, `''socket''` or `''tsserver''` if defined' endif if !l:needs_executable diff --git a/doc/ale-scala.txt b/doc/ale-scala.txt index b992d428..ff43cd6c 100644 --- a/doc/ale-scala.txt +++ b/doc/ale-scala.txt @@ -2,6 +2,39 @@ ALE Scala Integration *ale-scala-options* +=============================================================================== +sbtserver *ale-scala-sbtserver* + +`sbtserver` requires a running ^1.1.x sbt shell to connect to. It will attempt +to connect via TCP to the address defined in `g:ale_scala_sbtserver_address`. +As `sbt` defaults to listening via unix sockets, place these settings into +your `~/.sbt/1.0/global.sbt` to ensure that ale will always attempt to connect +to the right socket: + +`serverConnectionType := ConnectionType.Tcp` and `serverPort := 4273` + + +g:ale_scala_sbtserver_address *g:ale_scala_sbtserver_address* + *b:ale_scala_sbtserver_address* + Type: |String| + Default: `'127.0.0.1:4273'` + + By default the address is found by parsing `active.json`, however, reading a + file is a blocking operation which should be avoided in ale. The easy way + around this is to configure sbt to always connect to the same port, which + the instructions above describe. + + +g:ale_scala_sbtserver_project_root *g:ale_scala_sbtserver_project_root* + *b:ale_scala_sbtserver_project_root* + Type: |String| + Default: `''` + + By default the project root is found by searching upwards for `build.sbt`. + If the project root is elsewhere, you can override the project root + directory. + + =============================================================================== scalafmt *ale-scala-scalafmt* diff --git a/doc/ale.txt b/doc/ale.txt index 2c018a10..4334510f 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -249,6 +249,7 @@ CONTENTS *ale-contents* sass..................................|ale-sass-options| stylelint...........................|ale-sass-stylelint| scala.................................|ale-scala-options| + sbtserver...........................|ale-scala-sbtserver| scalafmt............................|ale-scala-scalafmt| scalastyle..........................|ale-scala-scalastyle| scss..................................|ale-scss-options| @@ -430,7 +431,7 @@ Notes: * Rust: `cargo`!!, `rls`, `rustc` (see |ale-integration-rust|), `rustfmt` * SASS: `sass-lint`, `stylelint` * SCSS: `prettier`, `sass-lint`, `scss-lint`, `stylelint` -* Scala: `fsc`, `scalac`, `scalafmt`, `scalastyle` +* Scala: `fsc`, `sbtserver`, `scalac`, `scalafmt`, `scalastyle` * Slim: `slim-lint` * SML: `smlnj` * Solidity: `solhint`, `solium` diff --git a/test/command_callback/test_scala_sbtserver.vader b/test/command_callback/test_scala_sbtserver.vader new file mode 100644 index 00000000..1b708bd9 --- /dev/null +++ b/test/command_callback/test_scala_sbtserver.vader @@ -0,0 +1,19 @@ +" Author: ophirr33 +" Description: Tests for the sbt Server lsp linter + +Before: + call ale#assert#SetUpLinterTest('scala', 'sbtserver') +After: + call ale#assert#TearDownLinterTest() +Execute(should set sbtserver for sbt project with build.sbt): + call ale#test#SetFilename('../scala_fixtures/valid_sbt_project/Main.scala') + AssertLSPLanguage 'scala' + AssertLSPOptions {} + AssertLSPProject ale#path#Simplify(g:dir . 'command_callback/../scala_fixtures/valid_sbt_project') + AssertLSPAddress '127.0.0.1:4273' +Execute(should not set sbtserver for sbt project without build.sbt): + call ale#test#SetFilename('../scala_fixtures/invalid_sbt_project/Main.scala') + AssertLSPLanguage 'scala' + AssertLSPOptions {} + AssertLSPProject '' + AssertLSPAddress '127.0.0.1:4273' diff --git a/test/scala_fixtures/invalid_sbt_project/Main.scala b/test/scala_fixtures/invalid_sbt_project/Main.scala new file mode 100644 index 00000000..e69de29b diff --git a/test/scala_fixtures/valid_sbt_project/Main.scala b/test/scala_fixtures/valid_sbt_project/Main.scala new file mode 100644 index 00000000..e69de29b diff --git a/test/scala_fixtures/valid_sbt_project/build.sbt b/test/scala_fixtures/valid_sbt_project/build.sbt new file mode 100644 index 00000000..e69de29b