Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 75 additions & 75 deletions internal/lsp/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,12 @@ func (c *Client) RegisterServerRequestHandler(method string, handler ServerReque
func (c *Client) InitializeLSPClient(ctx context.Context, workspaceDir string) (*protocol.InitializeResult, error) {
initParams := &protocol.InitializeParams{
WorkspaceFoldersInitializeParams: protocol.WorkspaceFoldersInitializeParams{
WorkspaceFolders: []protocol.WorkspaceFolder{
{
URI: protocol.URI("file://" + workspaceDir),
Name: workspaceDir,
},
},
WorkspaceFolders: []protocol.WorkspaceFolder{
{
URI: protocol.URI(string(protocol.URIFromPath(workspaceDir))),
Name: workspaceDir,
},
},
},

XInitializeParams: protocol.XInitializeParams{
Expand All @@ -131,7 +131,7 @@ func (c *Client) InitializeLSPClient(ctx context.Context, workspaceDir string) (
Version: "0.1.0",
},
RootPath: workspaceDir,
RootURI: protocol.DocumentUri("file://" + workspaceDir),
RootURI: protocol.URIFromPath(workspaceDir),
Capabilities: protocol.ClientCapabilities{
Workspace: protocol.WorkspaceClientCapabilities{
Configuration: true,
Expand Down Expand Up @@ -215,7 +215,7 @@ func (c *Client) InitializeLSPClient(ctx context.Context, workspaceDir string) (
}

// LSP sepecific Initialization
path := strings.ToLower(c.Cmd.Path)
path := strings.ToLower(c.Cmd.Path)
switch {
case strings.Contains(path, "typescript-language-server"):
err := initializeTypescriptLanguageServer(ctx, c, workspaceDir)
Expand Down Expand Up @@ -287,13 +287,13 @@ type OpenFileInfo struct {
}

func (c *Client) OpenFile(ctx context.Context, filepath string) error {
uri := fmt.Sprintf("file://%s", filepath)
docURI := protocol.URIFromPath(filepath)

c.openFilesMu.Lock()
if _, exists := c.openFiles[uri]; exists {
c.openFilesMu.Unlock()
return nil // Already open
}
c.openFilesMu.Lock()
if _, exists := c.openFiles[string(docURI)]; exists {
c.openFilesMu.Unlock()
return nil // Already open
}
c.openFilesMu.Unlock()

// Skip files that do not exist or cannot be read
Expand All @@ -302,41 +302,41 @@ func (c *Client) OpenFile(ctx context.Context, filepath string) error {
return fmt.Errorf("error reading file: %w", err)
}

params := protocol.DidOpenTextDocumentParams{
TextDocument: protocol.TextDocumentItem{
URI: protocol.DocumentUri(uri),
LanguageID: DetectLanguageID(uri),
Version: 1,
Text: string(content),
},
}
params := protocol.DidOpenTextDocumentParams{
TextDocument: protocol.TextDocumentItem{
URI: docURI,
LanguageID: DetectLanguageID(filepath),
Version: 1,
Text: string(content),
},
}

if err := c.Notify(ctx, "textDocument/didOpen", params); err != nil {
return err
}

c.openFilesMu.Lock()
c.openFiles[uri] = &OpenFileInfo{
Version: 1,
URI: protocol.DocumentUri(uri),
}
c.openFilesMu.Unlock()
c.openFilesMu.Lock()
c.openFiles[string(docURI)] = &OpenFileInfo{
Version: 1,
URI: docURI,
}
c.openFilesMu.Unlock()

lspLogger.Debug("Opened file: %s", filepath)
lspLogger.Debug("Opened file: %s", filepath)

return nil
}

func (c *Client) NotifyChange(ctx context.Context, filepath string) error {
uri := fmt.Sprintf("file://%s", filepath)
docURI := protocol.URIFromPath(filepath)

content, err := os.ReadFile(filepath)
if err != nil {
return fmt.Errorf("error reading file: %w", err)
}

c.openFilesMu.Lock()
fileInfo, isOpen := c.openFiles[uri]
c.openFilesMu.Lock()
fileInfo, isOpen := c.openFiles[string(docURI)]
if !isOpen {
c.openFilesMu.Unlock()
return fmt.Errorf("cannot notify change for unopened file: %s", filepath)
Expand All @@ -347,71 +347,71 @@ func (c *Client) NotifyChange(ctx context.Context, filepath string) error {
version := fileInfo.Version
c.openFilesMu.Unlock()

params := protocol.DidChangeTextDocumentParams{
TextDocument: protocol.VersionedTextDocumentIdentifier{
TextDocumentIdentifier: protocol.TextDocumentIdentifier{
URI: protocol.DocumentUri(uri),
},
Version: version,
},
ContentChanges: []protocol.TextDocumentContentChangeEvent{
{
Value: protocol.TextDocumentContentChangeWholeDocument{
Text: string(content),
},
},
},
}
params := protocol.DidChangeTextDocumentParams{
TextDocument: protocol.VersionedTextDocumentIdentifier{
TextDocumentIdentifier: protocol.TextDocumentIdentifier{
URI: docURI,
},
Version: version,
},
ContentChanges: []protocol.TextDocumentContentChangeEvent{
{
Value: protocol.TextDocumentContentChangeWholeDocument{
Text: string(content),
},
},
},
}

return c.Notify(ctx, "textDocument/didChange", params)
}

func (c *Client) CloseFile(ctx context.Context, filepath string) error {
uri := fmt.Sprintf("file://%s", filepath)

c.openFilesMu.Lock()
if _, exists := c.openFiles[uri]; !exists {
c.openFilesMu.Unlock()
return nil // Already closed
}
c.openFilesMu.Unlock()

params := protocol.DidCloseTextDocumentParams{
TextDocument: protocol.TextDocumentIdentifier{
URI: protocol.DocumentUri(uri),
},
}
docURI := protocol.URIFromPath(filepath)

c.openFilesMu.Lock()
if _, exists := c.openFiles[string(docURI)]; !exists {
c.openFilesMu.Unlock()
return nil // Already closed
}
c.openFilesMu.Unlock()

params := protocol.DidCloseTextDocumentParams{
TextDocument: protocol.TextDocumentIdentifier{
URI: docURI,
},
}
lspLogger.Debug("Closing file: %s", params.TextDocument.URI.Dir())
if err := c.Notify(ctx, "textDocument/didClose", params); err != nil {
return err
}

c.openFilesMu.Lock()
delete(c.openFiles, uri)
c.openFilesMu.Unlock()
c.openFilesMu.Lock()
delete(c.openFiles, string(docURI))
c.openFilesMu.Unlock()

return nil
}

func (c *Client) IsFileOpen(filepath string) bool {
uri := fmt.Sprintf("file://%s", filepath)
c.openFilesMu.RLock()
defer c.openFilesMu.RUnlock()
_, exists := c.openFiles[uri]
return exists
uri := string(protocol.URIFromPath(filepath))
c.openFilesMu.RLock()
defer c.openFilesMu.RUnlock()
_, exists := c.openFiles[uri]
return exists
}

// CloseAllFiles closes all currently open files
func (c *Client) CloseAllFiles(ctx context.Context) {
c.openFilesMu.Lock()
filesToClose := make([]string, 0, len(c.openFiles))

// First collect all URIs that need to be closed
for uri := range c.openFiles {
// Convert URI back to file path by trimming "file://" prefix
filePath := strings.TrimPrefix(uri, "file://")
filesToClose = append(filesToClose, filePath)
}
// First collect all URIs that need to be closed
for uri := range c.openFiles {
// Convert URI back to file path using protocol utilities
filePath := protocol.DocumentUri(uri).Path()
filesToClose = append(filesToClose, filePath)
}
c.openFilesMu.Unlock()

// Then close them all
Expand Down
2 changes: 1 addition & 1 deletion internal/tools/diagnostics.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func GetDiagnosticsForFile(ctx context.Context, client *lsp.Client, filePath str
time.Sleep(time.Second * 3)

// Convert the file path to URI format
uri := protocol.DocumentUri("file://" + filePath)
uri := protocol.URIFromPath(filePath)

// Request fresh diagnostics
diagParams := protocol.DocumentDiagnosticParams{
Expand Down
2 changes: 1 addition & 1 deletion internal/tools/execute-codelens.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func ExecuteCodeLens(ctx context.Context, client *lsp.Client, filePath string, i

// Get code lenses
docIdentifier := protocol.TextDocumentIdentifier{
URI: protocol.DocumentUri("file://" + filePath),
URI: protocol.URIFromPath(filePath),
}

params := protocol.CodeLensParams{
Expand Down
2 changes: 1 addition & 1 deletion internal/tools/get-codelens.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func GetCodeLens(ctx context.Context, client *lsp.Client, filePath string) (stri

// Create document identifier
docIdentifier := protocol.TextDocumentIdentifier{
URI: protocol.DocumentUri("file://" + filePath),
URI: protocol.URIFromPath(filePath),
}

// Request code lens from LSP
Expand Down
2 changes: 1 addition & 1 deletion internal/tools/hover.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func GetHoverInfo(ctx context.Context, client *lsp.Client, filePath string, line
Line: uint32(line - 1),
Character: uint32(column - 1),
}
uri := protocol.DocumentUri("file://" + filePath)
uri := protocol.URIFromPath(filePath)
params.TextDocument = protocol.TextDocumentIdentifier{
URI: uri,
}
Expand Down
2 changes: 1 addition & 1 deletion internal/tools/lsp-utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func GetFullDefinition(ctx context.Context, client *lsp.Client, startLocation pr

if found {
// Convert URI to filesystem path
filePath, err := url.PathUnescape(strings.TrimPrefix(string(startLocation.URI), "file://"))
filePath, err := url.PathUnescape(protocol.DocumentUri(string(startLocation.URI)).Path())
if err != nil {
return "", protocol.Location{}, fmt.Errorf("failed to unescape URI: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/tools/references.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func FindReferences(ctx context.Context, client *lsp.Client, symbolName string)
for _, uriStr := range uris {
uri := protocol.DocumentUri(uriStr)
fileRefs := refsByFile[uri]
filePath := strings.TrimPrefix(uriStr, "file://")
filePath := protocol.DocumentUri(uriStr).Path()

// Format file header
fileInfo := fmt.Sprintf("---\n\n%s\nReferences in File: %d\n",
Expand Down
2 changes: 1 addition & 1 deletion internal/tools/rename-symbol.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func RenameSymbol(ctx context.Context, client *lsp.Client, filePath string, line
}

// Convert 1-indexed line/column to 0-indexed for LSP protocol
uri := protocol.DocumentUri("file://" + filePath)
uri := protocol.URIFromPath(filePath)
position := protocol.Position{
Line: uint32(line - 1),
Character: uint32(column - 1),
Expand Down
2 changes: 1 addition & 1 deletion internal/tools/utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func ExtractTextFromLocation(loc protocol.Location) (string, error) {
path := strings.TrimPrefix(string(loc.URI), "file://")
path := protocol.DocumentUri(string(loc.URI)).Path()

content, err := os.ReadFile(path)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/watcher/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ func (w *WorkspaceWatcher) WatchWorkspace(ctx context.Context, workspacePath str
return
}

uri := fmt.Sprintf("file://%s", event.Name)
uri := string(protocol.URIFromPath(event.Name))

// Check if this is a file (not a directory) and should be excluded
isFile := false
Expand Down