From a9333c2866ad604ef5b8523af7fb1fce10057833 Mon Sep 17 00:00:00 2001 From: Horacio Sanson Date: Thu, 30 Aug 2018 11:39:03 +0900 Subject: [PATCH] Fix #1822 - support go-langserver lsp. --- README.md | 2 +- ale_linters/go/golangserver.vim | 28 +++++++++++ autoload/ale/go.vim | 27 ++++++++++ doc/ale-go.txt | 22 +++++++- doc/ale.txt | 3 +- .../go_paths/go1/prj1/file.go | 0 .../go_paths/go2/prj2/file.go | 0 .../test_golangserver_command_callback.vader | 50 +++++++++++++++++++ 8 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 ale_linters/go/golangserver.vim create mode 100644 autoload/ale/go.vim create mode 100644 test/command_callback/go_paths/go1/prj1/file.go create mode 100644 test/command_callback/go_paths/go2/prj2/file.go create mode 100644 test/command_callback/test_golangserver_command_callback.vader diff --git a/README.md b/README.md index a7b3a22a..f2f74411 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ formatting. | FusionScript | [fusion-lint](https://github.com/RyanSquared/fusionscript) | | Git Commit Messages | [gitlint](https://github.com/jorisroovers/gitlint) | | GLSL | [glslang](https://github.com/KhronosGroup/glslang), [glslls](https://github.com/svenstaro/glsl-language-server) | -| Go | [gofmt](https://golang.org/cmd/gofmt/), [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports), [go vet](https://golang.org/cmd/vet/) !!, [golint](https://godoc.org/github.com/golang/lint), [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) !!, [gometalinter](https://github.com/alecthomas/gometalinter) !!, [go build](https://golang.org/cmd/go/) !!, [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) !!, [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) !! | +| Go | [gofmt](https://golang.org/cmd/gofmt/), [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports), [go vet](https://golang.org/cmd/vet/) !!, [golint](https://godoc.org/github.com/golang/lint), [gotype](https://godoc.org/golang.org/x/tools/cmd/gotype) !!, [gometalinter](https://github.com/alecthomas/gometalinter) !!, [go build](https://golang.org/cmd/go/) !!, [gosimple](https://github.com/dominikh/go-tools/tree/master/cmd/gosimple) !!, [staticcheck](https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck) !!, [golangserver](https://github.com/sourcegraph/go-langserver) | | GraphQL | [eslint](http://eslint.org/), [gqlint](https://github.com/happylinks/gqlint), [prettier](https://github.com/prettier/prettier) | | Hack | [hack](http://hacklang.org/), [hackfmt](https://github.com/facebook/hhvm/tree/master/hphp/hack/hackfmt), [hhast](https://github.com/hhvm/hhast) (disabled by default; see `:help ale-integration-hack`) | | Haml | [haml-lint](https://github.com/brigade/haml-lint) | diff --git a/ale_linters/go/golangserver.vim b/ale_linters/go/golangserver.vim new file mode 100644 index 00000000..c80b096d --- /dev/null +++ b/ale_linters/go/golangserver.vim @@ -0,0 +1,28 @@ +" Author: Horacio Sanson +" Description: Support for go-langserver https://github.com/sourcegraph/go-langserver + +call ale#Set('go_langserver_executable', 'go-langserver') +call ale#Set('go_langserver_options', '') + +function! ale_linters#go#golangserver#GetCommand(buffer) abort + let l:executable = [ale#Escape(ale#Var(a:buffer, 'go_langserver_executable'))] + let l:options = ale#Var(a:buffer, 'go_langserver_options') + let l:options = substitute(l:options, '-gocodecompletion', '', 'g') + let l:options = filter(split(l:options, ' '), 'empty(v:val) != 1') + + if(ale#Var(a:buffer, 'completion_enabled') == 1) + call add(l:options, '-gocodecompletion') + endif + + let l:options = uniq(sort(l:options)) + + return join(extend(l:executable, l:options), ' ') +endfunction + +call ale#linter#Define('go', { +\ 'name': 'golangserver', +\ 'lsp': 'stdio', +\ 'executable_callback': ale#VarFunc('go_langserver_executable'), +\ 'command_callback': 'ale_linters#go#golangserver#GetCommand', +\ 'project_root_callback': 'ale#go#FindProjectRoot', +\}) diff --git a/autoload/ale/go.vim b/autoload/ale/go.vim new file mode 100644 index 00000000..a166480a --- /dev/null +++ b/autoload/ale/go.vim @@ -0,0 +1,27 @@ +" Author: Horacio Sanson https://github.com/hsanson +" Description: Functions for integrating with Go tools + +" Find the nearest dir listed in GOPATH and assume it the root of the go +" project. +function! ale#go#FindProjectRoot(buffer) abort + let l:sep = has('win32') ? ';' : ':' + + let l:filename = ale#path#Simplify(expand('#' . a:buffer . ':p')) + + for l:name in split($GOPATH, l:sep) + let l:path_dir = ale#path#Simplify(l:name) + + " Use the directory from GOPATH if the current filename starts with it. + if l:filename[: len(l:path_dir) - 1] is? l:path_dir + return l:path_dir + endif + endfor + + let l:default_go_path = ale#path#Simplify(expand('~/go')) + + if isdirectory(l:default_go_path) + return l:default_go_path + endif + + return '' +endfunction diff --git a/doc/ale-go.txt b/doc/ale-go.txt index baf403b7..c97f599e 100644 --- a/doc/ale-go.txt +++ b/doc/ale-go.txt @@ -7,7 +7,7 @@ Integration Information The `gometalinter` linter is disabled by default. ALE enables `gofmt`, `golint` and `go vet` by default. It also supports `staticcheck`, `go -build` and `gosimple`. +build`, `gosimple`, and `golangserver`. To enable `gometalinter`, update |g:ale_linters| as appropriate: > @@ -114,5 +114,25 @@ g:ale_go_staticcheck_lint_package *g:ale_go_staticcheck_lint_package* current file. +=============================================================================== +golangserver *ale-go-golangserver* + +g:ale_go_langserver_executable *g:ale_go_langserver_executable* + *b:ale_go_langserver_executable* + Type: |String| + Default: `'go-langserver'` + + Location of the go-langserver binary file. + +g:ale_go_langserver_options *g:ale_go_langserver_options* + *b:ale_go_langserver_options* + Type: |String| + Default: `''` + + Additional options passed to the go-langserver command. Note that the + `-gocodecompletion` option is ignored because it is handled automatically + by the |g:ale_completion_enabled| variable. + + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale.txt b/doc/ale.txt index 4334510f..da7abcf1 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -95,6 +95,7 @@ CONTENTS *ale-contents* govet...............................|ale-go-govet| gometalinter........................|ale-go-gometalinter| staticcheck.........................|ale-go-staticcheck| + golangserver........................|ale-go-golangserver| graphql...............................|ale-graphql-options| eslint..............................|ale-graphql-eslint| gqlint..............................|ale-graphql-gqlint| @@ -384,7 +385,7 @@ Notes: * FusionScript: `fusion-lint` * Git Commit Messages: `gitlint` * GLSL: glslang, `glslls` -* Go: `gofmt`, `goimports`, `go vet`!!, `golint`, `gotype`!!, `gometalinter`!!, `go build`!!, `gosimple`!!, `staticcheck`!! +* Go: `gofmt`, `goimports`, `go vet`!!, `golint`, `gotype`!!, `gometalinter`!!, `go build`!!, `gosimple`!!, `staticcheck`!!, `golangserver` * GraphQL: `eslint`, `gqlint`, `prettier` * Hack: `hack`, `hackfmt`, `hhast` * Haml: `haml-lint` diff --git a/test/command_callback/go_paths/go1/prj1/file.go b/test/command_callback/go_paths/go1/prj1/file.go new file mode 100644 index 00000000..e69de29b diff --git a/test/command_callback/go_paths/go2/prj2/file.go b/test/command_callback/go_paths/go2/prj2/file.go new file mode 100644 index 00000000..e69de29b diff --git a/test/command_callback/test_golangserver_command_callback.vader b/test/command_callback/test_golangserver_command_callback.vader new file mode 100644 index 00000000..a5893cee --- /dev/null +++ b/test/command_callback/test_golangserver_command_callback.vader @@ -0,0 +1,50 @@ +Before: + Save $GOPATH + call ale#assert#SetUpLinterTest('go', 'golangserver') + let sep = has('win32') ? ';' : ':' + let $GOPATH=ale#path#Simplify(g:dir . '/go_paths/go1') + \ . sep + \ . ale#path#Simplify(g:dir . '/go_paths/go2') + +After: + Restore + call ale#assert#TearDownLinterTest() + +Execute(should set correct defaults): + AssertLinter 'go-langserver', ale#Escape('go-langserver') + +Execute(should configure go-langserver callback executable): + let b:ale_go_langserver_executable = 'boo' + AssertLinter 'boo', ale#Escape('boo') + unlet b:ale_go_langserver_executable + +Execute(should set go-langserver options): + call ale#test#SetFilename('go_paths/go1/prj1/file.go') + let b:ale_completion_enabled = 1 + let b:ale_go_langserver_options = '' + AssertEqual ale_linters#go#golangserver#GetCommand(bufnr('%')), ale#Escape('go-langserver') . ' -gocodecompletion' + + let b:ale_go_langserver_options = '-trace' + AssertEqual ale_linters#go#golangserver#GetCommand(bufnr('%')), ale#Escape('go-langserver') . ' -gocodecompletion -trace' + +Execute(should ignore go-langserver -gocodecompletion option): + call ale#test#SetFilename('go_paths/go1/prj1/file.go') + + let b:ale_go_langserver_options = '-trace -gocodecompletion' + let b:ale_completion_enabled = 1 + AssertEqual ale_linters#go#golangserver#GetCommand(bufnr('%')), ale#Escape('go-langserver') . ' -gocodecompletion -trace' + + let b:ale_completion_enabled = 0 + AssertEqual ale_linters#go#golangserver#GetCommand(bufnr('%')), ale#Escape('go-langserver') . ' -trace' + +Execute(should set go-langserver for go app1): + call ale#test#SetFilename('go_paths/go1/prj1/file.go') + AssertLSPLanguage 'go' + AssertLSPOptions {} + AssertLSPProject ale#path#Simplify(g:dir . '/go_paths/go1') + +Execute(should set go-langserver for go app2): + call ale#test#SetFilename('go_paths/go2/prj1/file.go') + AssertLSPLanguage 'go' + AssertLSPOptions {} + AssertLSPProject ale#path#Simplify(g:dir . '/go_paths/go2')