github.com/jd-ly/tools@v0.5.7/internal/lsp/fake/client.go (about)

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package fake
     6  
     7  import (
     8  	"context"
     9  	"fmt"
    10  
    11  	"github.com/jd-ly/tools/internal/lsp/protocol"
    12  )
    13  
    14  // ClientHooks are called to handle the corresponding client LSP method.
    15  type ClientHooks struct {
    16  	OnLogMessage             func(context.Context, *protocol.LogMessageParams) error
    17  	OnDiagnostics            func(context.Context, *protocol.PublishDiagnosticsParams) error
    18  	OnWorkDoneProgressCreate func(context.Context, *protocol.WorkDoneProgressCreateParams) error
    19  	OnProgress               func(context.Context, *protocol.ProgressParams) error
    20  	OnShowMessage            func(context.Context, *protocol.ShowMessageParams) error
    21  	OnShowMessageRequest     func(context.Context, *protocol.ShowMessageRequestParams) error
    22  	OnRegistration           func(context.Context, *protocol.RegistrationParams) error
    23  	OnUnregistration         func(context.Context, *protocol.UnregistrationParams) error
    24  }
    25  
    26  // Client is an adapter that converts an *Editor into an LSP Client. It mosly
    27  // delegates functionality to hooks that can be configured by tests.
    28  type Client struct {
    29  	editor *Editor
    30  	hooks  ClientHooks
    31  }
    32  
    33  func (c *Client) ShowMessage(ctx context.Context, params *protocol.ShowMessageParams) error {
    34  	if c.hooks.OnShowMessage != nil {
    35  		return c.hooks.OnShowMessage(ctx, params)
    36  	}
    37  	return nil
    38  }
    39  
    40  func (c *Client) ShowMessageRequest(ctx context.Context, params *protocol.ShowMessageRequestParams) (*protocol.MessageActionItem, error) {
    41  	if c.hooks.OnShowMessageRequest != nil {
    42  		if err := c.hooks.OnShowMessageRequest(ctx, params); err != nil {
    43  			return nil, err
    44  		}
    45  	}
    46  	if len(params.Actions) == 0 || len(params.Actions) > 1 {
    47  		return nil, fmt.Errorf("fake editor cannot handle multiple action items")
    48  	}
    49  	return &params.Actions[0], nil
    50  }
    51  
    52  func (c *Client) LogMessage(ctx context.Context, params *protocol.LogMessageParams) error {
    53  	if c.hooks.OnLogMessage != nil {
    54  		return c.hooks.OnLogMessage(ctx, params)
    55  	}
    56  	return nil
    57  }
    58  
    59  func (c *Client) Event(ctx context.Context, event *interface{}) error {
    60  	return nil
    61  }
    62  
    63  func (c *Client) PublishDiagnostics(ctx context.Context, params *protocol.PublishDiagnosticsParams) error {
    64  	if c.hooks.OnDiagnostics != nil {
    65  		return c.hooks.OnDiagnostics(ctx, params)
    66  	}
    67  	return nil
    68  }
    69  
    70  func (c *Client) WorkspaceFolders(context.Context) ([]protocol.WorkspaceFolder, error) {
    71  	return []protocol.WorkspaceFolder{}, nil
    72  }
    73  
    74  func (c *Client) Configuration(_ context.Context, p *protocol.ParamConfiguration) ([]interface{}, error) {
    75  	results := make([]interface{}, len(p.Items))
    76  	for i, item := range p.Items {
    77  		if item.Section != "gopls" {
    78  			continue
    79  		}
    80  		results[i] = c.editor.configuration()
    81  	}
    82  	return results, nil
    83  }
    84  
    85  func (c *Client) RegisterCapability(ctx context.Context, params *protocol.RegistrationParams) error {
    86  	if c.hooks.OnRegistration != nil {
    87  		return c.hooks.OnRegistration(ctx, params)
    88  	}
    89  	return nil
    90  }
    91  
    92  func (c *Client) UnregisterCapability(ctx context.Context, params *protocol.UnregistrationParams) error {
    93  	if c.hooks.OnUnregistration != nil {
    94  		return c.hooks.OnUnregistration(ctx, params)
    95  	}
    96  	return nil
    97  }
    98  
    99  func (c *Client) Progress(ctx context.Context, params *protocol.ProgressParams) error {
   100  	if c.hooks.OnProgress != nil {
   101  		return c.hooks.OnProgress(ctx, params)
   102  	}
   103  	return nil
   104  }
   105  
   106  func (c *Client) WorkDoneProgressCreate(ctx context.Context, params *protocol.WorkDoneProgressCreateParams) error {
   107  	if c.hooks.OnWorkDoneProgressCreate != nil {
   108  		return c.hooks.OnWorkDoneProgressCreate(ctx, params)
   109  	}
   110  	return nil
   111  }
   112  
   113  // ApplyEdit applies edits sent from the server. Note that as of writing gopls
   114  // doesn't use this feature, so it is untested.
   115  func (c *Client) ApplyEdit(ctx context.Context, params *protocol.ApplyWorkspaceEditParams) (*protocol.ApplyWorkspaceEditResponse, error) {
   116  	if len(params.Edit.Changes) != 0 {
   117  		return &protocol.ApplyWorkspaceEditResponse{FailureReason: "Edit.Changes is unsupported"}, nil
   118  	}
   119  	for _, change := range params.Edit.DocumentChanges {
   120  		path := c.editor.sandbox.Workdir.URIToPath(change.TextDocument.URI)
   121  		edits := convertEdits(change.Edits)
   122  		if err := c.editor.EditBuffer(ctx, path, edits); err != nil {
   123  			return nil, err
   124  		}
   125  	}
   126  	return &protocol.ApplyWorkspaceEditResponse{Applied: true}, nil
   127  }