@@ -20,7 +20,6 @@ import (
2020 "context"
2121 "encoding/json"
2222 "fmt"
23- "github.com/cloudwego/abcoder/lang/register"
2423 "os"
2524 "os/exec"
2625 "path/filepath"
@@ -33,6 +32,7 @@ import (
3332 "github.com/cloudwego/abcoder/lang/log"
3433 "github.com/cloudwego/abcoder/lang/lsp"
3534 "github.com/cloudwego/abcoder/lang/python"
35+ "github.com/cloudwego/abcoder/lang/register"
3636 "github.com/cloudwego/abcoder/lang/rust"
3737 "github.com/cloudwego/abcoder/lang/uniast"
3838)
@@ -138,40 +138,63 @@ func checkRepoPath(repoPath string, language uniast.Language) (openfile string,
138138}
139139
140140func checkLSP (language uniast.Language , lspPath string , args ParseOptions ) (l uniast.Language , s string , err error ) {
141- switch language {
142- case uniast .Rust :
143- l , s = rust .GetDefaultLSP ()
144- case uniast .Cxx :
145- l , s = cxx .GetDefaultLSP ()
146- case uniast .Python :
147- l , s = python .GetDefaultLSP ()
148- case uniast .Java :
149- l , s = java .GetDefaultLSP (args .LspOptions )
150- case uniast .Golang :
151- l = uniast .Golang
152- s = ""
153- if _ , err := exec .LookPath ("go" ); err != nil {
154- if _ , err := os .Stat (lspPath ); os .IsNotExist (err ) {
155- log .Error ("Go compiler not found, please make it excutable!\n " , lspPath )
156- return uniast .Unknown , "" , err
141+ if lspPath != "" {
142+ // designated LSP
143+ l = language
144+ s = lspPath
145+ } else {
146+ // default LSP
147+ switch language {
148+ case uniast .Rust :
149+ l , s = rust .GetDefaultLSP ()
150+ case uniast .Cxx :
151+ l , s = cxx .GetDefaultLSP ()
152+ case uniast .Python :
153+ l , s = python .GetDefaultLSP ()
154+ case uniast .Java :
155+ l , s = java .GetDefaultLSP (args .LspOptions )
156+ case uniast .Golang :
157+ if _ , err := exec .LookPath ("go" ); err != nil {
158+ if _ , err := os .Stat (lspPath ); os .IsNotExist (err ) {
159+ log .Error ("Go compiler not found, please make it excutable!\n " , lspPath )
160+ return uniast .Unknown , "" , err
161+ }
157162 }
163+ return uniast .Golang , "" , nil
164+ default :
165+ return uniast .Unknown , "" , fmt .Errorf ("unsupported language: %s" , language )
158166 }
159- return
160- default :
161- return uniast .Unknown , "" , fmt .Errorf ("unsupported language: %s" , language )
162167 }
163- // check if lsp excutable
164- if lspPath != "" {
165- if _ , err := exec .LookPath (lspPath ); err != nil {
166- if _ , err := os .Stat (lspPath ); os .IsNotExist (err ) {
167- log .Error ("Language server %s not found, please make it excutable!\n " , lspPath )
168- return uniast .Unknown , "" , err
169- }
168+
169+ // lsp already installed
170+ if absLspPath , err := exec .LookPath (s ); err == nil {
171+ return l , absLspPath , nil
172+ }
173+
174+ // install the lsp.
175+ log .Error ("Language server %s not found. Trying to auto install.\n " , s )
176+ s , err = installLanguageServer (language )
177+ if err == nil {
178+ if absLspPath , err := exec .LookPath (s ); err == nil {
179+ log .Error ("Auto installation ok. lspPath=%s." , absLspPath )
180+ return l , absLspPath , nil
170181 }
171- s = lspPath
172182 }
173183
174- return
184+ // install failed or broken (lsp not in PATH)
185+ log .Info ("Failed to install language server %s: %+w.\n " , s , err )
186+ return uniast .Unknown , "" , err
187+ }
188+
189+ func installLanguageServer (language uniast.Language ) (string , error ) {
190+ switch language {
191+ case uniast .Cxx :
192+ return cxx .InstallLanguageServer ()
193+ case uniast .Python :
194+ return python .InstallLanguageServer ()
195+ default :
196+ return "" , fmt .Errorf ("auto installation not supported for language: %s" , language )
197+ }
175198}
176199
177200func collectSymbol (ctx context.Context , cli * lsp.LSPClient , repoPath string , opts collect.CollectOption ) (repo * uniast.Repository , err error ) {
0 commit comments