Skip to content

Commit

Permalink
feat: add handler for workspace will create files request
Browse files Browse the repository at this point in the history
  • Loading branch information
fr3shw3b committed Jun 25, 2024
1 parent 76fa728 commit df38ff0
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 0 deletions.
1 change: 1 addition & 0 deletions lsp_3_17/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ type Handler struct {
workspaceSymbolResolve WorkspaceSymbolResolveHandlerFunc
workspaceDidChangeConfiguration WorkspaceDidChangeConfigurationHandlerFunc
workspaceDidChangeFolders WorkspaceDidChangeFoldersHandlerFunc
workspaceWillCreateFiles WorkspaceWillCreateFilesHandlerFunc

isInitialized bool
// Provides a mapping of method names to the respective handlers
Expand Down
33 changes: 33 additions & 0 deletions lsp_3_17/handler_workspace_features.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ func WithWorkspaceDidChangeFoldersHandler(handler WorkspaceDidChangeFoldersHandl
}
}

// WithWorkspaceWillCreateFilesHandler sets the handler for the `workspace/willCreateFiles` request.
func WithWorkspaceWillCreateFilesHandler(handler WorkspaceWillCreateFilesHandlerFunc) HandlerOption {
return func(root *Handler) {
root.SetWorkspaceWillCreateFilesHandler(handler)
}
}

// SetWorkspaceSymbolHandler sets the handler for the `workspace/symbol` request.
func (h *Handler) SetWorkspaceSymbolHandler(handler WorkspaceSymbolHandlerFunc) {
h.mu.Lock()
Expand Down Expand Up @@ -66,6 +73,14 @@ func (h *Handler) SetWorkspaceDidChangeFoldersHandler(handler WorkspaceDidChange
h.messageHandlers[MethodWorkspaceDidChangeFolders] = createWorkspaceDidChangeFoldersHandler(h)
}

// SetWorkspaceWillCreateFilesHandler sets the handler for the `workspace/willCreateFiles` request.
func (h *Handler) SetWorkspaceWillCreateFilesHandler(handler WorkspaceWillCreateFilesHandlerFunc) {
h.mu.Lock()
defer h.mu.Unlock()
h.workspaceWillCreateFiles = handler
h.messageHandlers[MethodWorkspaceWillCreateFiles] = createWorkspaceWillCreateFilesHandler(h)
}

func createWorkspaceSymbolHandler(root *Handler) common.Handler {
return common.HandlerFunc(
func(
Expand Down Expand Up @@ -137,3 +152,21 @@ func createWorkspaceDidChangeFoldersHandler(root *Handler) common.Handler {
},
)
}

func createWorkspaceWillCreateFilesHandler(root *Handler) common.Handler {
return common.HandlerFunc(
func(
ctx *common.LSPContext,
) (r any, validMethod bool, validParams bool, err error) {
validMethod = true
if root.workspaceWillCreateFiles != nil {
var params CreateFilesParams
if err = json.Unmarshal(ctx.Params, &params); err == nil {
validParams = true
r, err = root.workspaceWillCreateFiles(ctx, &params)
}
}
return
},
)
}
61 changes: 61 additions & 0 deletions lsp_3_17/handler_workspace_features_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,64 @@ func (s *HandlerTestSuite) Test_calls_workspace_did_change_folders_notification_
s.Require().Equal(didChangeFoldersParams, *receivedParams)
}
}

func (s *HandlerTestSuite) Test_calls_workspace_will_create_files_request_handler() {
logger, err := zap.NewDevelopment()
s.Require().NoError(err)

ctx, cancel := context.WithTimeout(context.Background(), server.DefaultTimeout)
defer cancel()

workspaceEdit := WorkspaceEdit{
Changes: map[string][]TextEdit{
"edit1": []TextEdit{
{
Range: &Range{
Start: Position{
Line: 1,
Character: 1,
},
End: Position{
Line: 1,
Character: 5,
},
},
NewText: "help",
},
},
},
}
serverHandler := NewHandler(
WithWorkspaceWillCreateFilesHandler(
func(ctx *common.LSPContext, params *CreateFilesParams) (*WorkspaceEdit, error) {
return &workspaceEdit, nil
},
),
)
// Emulate the LSP initialisation process.
serverHandler.SetInitialized(true)
srv := server.NewServer(serverHandler, true, nil, nil)

container := createTestConnectionsContainer(srv.NewHandler())

go srv.Serve(container.serverConn, logger)

clientLSPContext := server.NewLSPContext(ctx, container.clientConn, nil)

createFilesParams := &CreateFilesParams{
Files: []FileCreate{
{
URI: "file:///test_doc.go",
},
},
}

returnedEdit := WorkspaceEdit{}
err = clientLSPContext.Call(
MethodWorkspaceWillCreateFiles,
createFilesParams,
&returnedEdit,
)
s.Require().NoError(err)
s.Require().Equal(workspaceEdit, returnedEdit)
}
28 changes: 28 additions & 0 deletions lsp_3_17/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -542,3 +542,31 @@ type WorkspaceFoldersChangeEvent struct {
// The array of removed workspace folders.
Removed []WorkspaceFolder `json:"removed"`
}

// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#workspace_willCreateFiles

const MethodWorkspaceWillCreateFiles = Method("workspace/willCreateFiles")

// WorkspaceWillCreateFilesHandlerFunc is the function signature for the
// `workspace/willCreateFiles` method.
type WorkspaceWillCreateFilesHandlerFunc func(
context *common.LSPContext,
params *CreateFilesParams,
) (*WorkspaceEdit, error)

// CreateFilesParams contains the parameters sent in notifications/requests
// for user-initiated creation of files.
//
// @since 3.16.0
type CreateFilesParams struct {
// An array of all files/folders created in this operation.
Files []FileCreate `json:"files"`
}

// FileCreate represents information on a file/folder creation.
//
// @since 3.16.0
type FileCreate struct {
// A file:// URI for the location of the file/folder being created.
URI string `json:"uri"`
}

0 comments on commit df38ff0

Please sign in to comment.