Skip to content

Commit

Permalink
Language server initialisation adjustments (#580)
Browse files Browse the repository at this point in the history
* Drop InitializationOption from config

this is unused and behaves differently in different clients, see #578

Signed-off-by: Charlie Egan <charlie@styra.com>

* Run LS in workspaceless mode when no root URI set

This disables features that make use of the Root URI, namely on
the linting of more than one file, use of config file, and
linting of unopened files.

This is only used when a language server is started with no
client root URI.

Signed-off-by: Charlie Egan <charlie@styra.com>

---------

Signed-off-by: Charlie Egan <charlie@styra.com>
  • Loading branch information
charlieegan3 authored Feb 26, 2024
1 parent 3205762 commit 21a0dc4
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 21 deletions.
17 changes: 8 additions & 9 deletions internal/lsp/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,14 @@ type FileEvent struct {
}

type InitializeParams struct {
ProcessID int `json:"processId"`
ClientInfo Client `json:"clientInfo"`
Locale string `json:"locale"`
RootPath string `json:"rootPath"`
RootURI string `json:"rootUri"`
Capabilities ClientCapabilities `json:"capabilities"`
InitializationOption string `json:"initializationOptions"`
Trace string `json:"trace"`
WorkspaceFolders []WorkspaceFolder `json:"workspaceFolders"`
ProcessID int `json:"processId"`
ClientInfo Client `json:"clientInfo"`
Locale string `json:"locale"`
RootPath string `json:"rootPath"`
RootURI string `json:"rootUri"`
Capabilities ClientCapabilities `json:"capabilities"`
Trace string `json:"trace"`
WorkspaceFolders []WorkspaceFolder `json:"workspaceFolders"`
}

type WorkspaceFolder struct {
Expand Down
49 changes: 37 additions & 12 deletions internal/lsp/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ type LanguageServer struct {

clientRootURI string
clientIdentifier clients.Identifier

// workspaceMode is set to true when the ls is initialized with
// a clientRootURI.
workspaceMode bool
}

// fileDiagnosticRequiredEvent is sent to the diagnosticRequestFile channel when
Expand Down Expand Up @@ -396,6 +400,14 @@ func (l *LanguageServer) handleWorkspaceDiagnostic(
Items: make([]WorkspaceFullDocumentDiagnosticReport, 0),
}

// if we're not in workspace mode, we can't show anything here
// since we don't have the URI of the workspace from initialize
if !l.workspaceMode {
l.logOutboundMessage("workspace/diagnostic", workspaceReport)

return workspaceReport, nil
}

workspaceReport.Items = append(workspaceReport.Items, WorkspaceFullDocumentDiagnosticReport{
URI: l.clientRootURI,
Kind: "full",
Expand Down Expand Up @@ -461,10 +473,31 @@ func (l *LanguageServer) handleInitialize(
},
}

if l.clientRootURI != "" {
l.log("running in workspace mode")
l.workspaceMode = true

err = l.loadWorkspaceContents()
if err != nil {
return nil, fmt.Errorf("failed to load workspace contents: %w", err)
}

// attempt to load the config as it is found on disk
file, err := config.FindConfig(strings.TrimPrefix(l.clientRootURI, "file://"))
if err == nil {
l.reloadConfig(file, false)
}
}

l.logOutboundMessage("initialize", result)

return result, nil
}

func (l *LanguageServer) loadWorkspaceContents() error {
workspaceRootPath := uri.ToPath(l.clientIdentifier, l.clientRootURI)

// load the rego source files into the cache
err = filepath.WalkDir(workspaceRootPath, func(path string, d os.DirEntry, err error) error {
err := filepath.WalkDir(workspaceRootPath, func(path string, d os.DirEntry, err error) error {
if err != nil {
return fmt.Errorf("failed to walk workspace dir %q: %w", d.Name(), err)
}
Expand All @@ -489,18 +522,10 @@ func (l *LanguageServer) handleInitialize(
return nil
})
if err != nil {
return nil, fmt.Errorf("failed to walk workspace dir %q: %w", workspaceRootPath, err)
return fmt.Errorf("failed to walk workspace dir %q: %w", workspaceRootPath, err)
}

// attempt to load the config as it is found on disk
file, err := config.FindConfig(strings.TrimPrefix(l.clientRootURI, "file://"))
if err == nil {
l.reloadConfig(file, false)
}

l.logOutboundMessage("initialize", result)

return result, nil
return nil
}

func (l *LanguageServer) reloadConfig(configReader io.Reader, runWorkspaceDiagnostics bool) {
Expand Down

0 comments on commit 21a0dc4

Please sign in to comment.