@@ -6,10 +6,7 @@ package lsp
6
6
7
7
import (
8
8
"context"
9
- "fmt"
10
- "go/format"
11
9
"os"
12
- "strings"
13
10
"sync"
14
11
15
12
"golang.org/x/tools/internal/jsonrpc2"
@@ -20,7 +17,7 @@ import (
20
17
// stream is closed.
21
18
func RunServer (ctx context.Context , stream jsonrpc2.Stream , opts ... interface {}) error {
22
19
s := & server {
23
- activeFiles : make ( map [protocol. DocumentURI ] string ),
20
+ view : newView ( ),
24
21
}
25
22
conn , client := protocol .RunServer (ctx , stream , s , opts ... )
26
23
s .client = client
@@ -33,31 +30,7 @@ type server struct {
33
30
initializedMu sync.Mutex
34
31
initialized bool // set once the server has received "initialize" request
35
32
36
- activeFilesMu sync.Mutex
37
- activeFiles map [protocol.DocumentURI ]string // files
38
- }
39
-
40
- func (s * server ) cacheActiveFile (uri protocol.DocumentURI , changes []protocol.TextDocumentContentChangeEvent ) error {
41
- s .activeFilesMu .Lock ()
42
- defer s .activeFilesMu .Unlock ()
43
-
44
- for _ , change := range changes {
45
- if change .RangeLength == 0 {
46
- s .activeFiles [uri ] = change .Text
47
- }
48
- }
49
- return nil
50
- }
51
-
52
- func (s * server ) readActiveFile (uri protocol.DocumentURI ) (string , error ) {
53
- s .activeFilesMu .Lock ()
54
- defer s .activeFilesMu .Unlock ()
55
-
56
- content , ok := s .activeFiles [uri ]
57
- if ! ok {
58
- return "" , fmt .Errorf ("file not found: %s" , uri )
59
- }
60
- return content , nil
33
+ * view
61
34
}
62
35
63
36
func (s * server ) Initialize (ctx context.Context , params * protocol.InitializeParams ) (* protocol.InitializeResult , error ) {
@@ -70,9 +43,11 @@ func (s *server) Initialize(ctx context.Context, params *protocol.InitializePara
70
43
return & protocol.InitializeResult {
71
44
Capabilities : protocol.ServerCapabilities {
72
45
TextDocumentSync : protocol.TextDocumentSyncOptions {
73
- Change : float64 (protocol .Full ), // full contents of file sent on each update
46
+ Change : float64 (protocol .Full ), // full contents of file sent on each update
47
+ OpenClose : true ,
74
48
},
75
- DocumentFormattingProvider : true ,
49
+ DocumentFormattingProvider : true ,
50
+ DocumentRangeFormattingProvider : true ,
76
51
},
77
52
}, nil
78
53
}
@@ -119,12 +94,19 @@ func (s *server) ExecuteCommand(context.Context, *protocol.ExecuteCommandParams)
119
94
return nil , notImplemented ("ExecuteCommand" )
120
95
}
121
96
122
- func (s * server ) DidOpen (context.Context , * protocol.DidOpenTextDocumentParams ) error {
123
- return notImplemented ("DidOpen" )
97
+ func (s * server ) DidOpen (ctx context.Context , params * protocol.DidOpenTextDocumentParams ) error {
98
+ s .cacheActiveFile (params .TextDocument .URI , params .TextDocument .Text )
99
+ return nil
124
100
}
125
101
126
102
func (s * server ) DidChange (ctx context.Context , params * protocol.DidChangeTextDocumentParams ) error {
127
- s .cacheActiveFile (params .TextDocument .URI , params .ContentChanges )
103
+ if len (params .ContentChanges ) < 1 {
104
+ return jsonrpc2 .NewErrorf (jsonrpc2 .CodeInternalError , "no content changes provided" )
105
+ }
106
+ // We expect the full content of file, i.e. a single change with no range.
107
+ if change := params .ContentChanges [0 ]; change .RangeLength == 0 {
108
+ s .cacheActiveFile (params .TextDocument .URI , change .Text )
109
+ }
128
110
return nil
129
111
}
130
112
@@ -140,8 +122,9 @@ func (s *server) DidSave(context.Context, *protocol.DidSaveTextDocumentParams) e
140
122
return notImplemented ("DidSave" )
141
123
}
142
124
143
- func (s * server ) DidClose (context.Context , * protocol.DidCloseTextDocumentParams ) error {
144
- return notImplemented ("DidClose" )
125
+ func (s * server ) DidClose (ctx context.Context , params * protocol.DidCloseTextDocumentParams ) error {
126
+ s .clearActiveFile (params .TextDocument .URI )
127
+ return nil
145
128
}
146
129
147
130
func (s * server ) Completion (context.Context , * protocol.CompletionParams ) (* protocol.CompletionList , error ) {
@@ -213,34 +196,11 @@ func (s *server) ColorPresentation(context.Context, *protocol.ColorPresentationP
213
196
}
214
197
215
198
func (s * server ) Formatting (ctx context.Context , params * protocol.DocumentFormattingParams ) ([]protocol.TextEdit , error ) {
216
- data , err := s .readActiveFile (params .TextDocument .URI )
217
- if err != nil {
218
- return nil , jsonrpc2 .NewErrorf (jsonrpc2 .CodeInternalError , "unable to format %s: %v" , params .TextDocument .URI , err )
219
- }
220
- fmted , err := format .Source ([]byte (data ))
221
- if err != nil {
222
- return nil , jsonrpc2 .NewErrorf (jsonrpc2 .CodeInternalError , "unable to format %s: %v" , params .TextDocument .URI , err )
223
- }
224
- // Get the ending line and column numbers for the original file.
225
- line := strings .Count (data , "\n " )
226
- col := len (data ) - strings .LastIndex (data , "\n " )
227
- if col < 0 {
228
- col = 0
229
- }
230
- // TODO(rstambler): Compute text edits instead of replacing whole file.
231
- return []protocol.TextEdit {
232
- {
233
- Range : protocol.Range {
234
- Start : protocol.Position {0 , 0 },
235
- End : protocol.Position {float64 (line ), float64 (col )},
236
- },
237
- NewText : string (fmted ),
238
- },
239
- }, nil
199
+ return s .format (params .TextDocument .URI , nil )
240
200
}
241
201
242
- func (s * server ) RangeFormatting (context.Context , * protocol.DocumentRangeFormattingParams ) ([]protocol.TextEdit , error ) {
243
- return nil , notImplemented ( "RangeFormatting" )
202
+ func (s * server ) RangeFormatting (ctx context.Context , params * protocol.DocumentRangeFormattingParams ) ([]protocol.TextEdit , error ) {
203
+ return s . format ( params . TextDocument . URI , & params . Range )
244
204
}
245
205
246
206
func (s * server ) OnTypeFormatting (context.Context , * protocol.DocumentOnTypeFormattingParams ) ([]protocol.TextEdit , error ) {
0 commit comments