Skip to content

Commit 532cf82

Browse files
committed
feat: Adding support for formatting
1 parent 0c464b6 commit 532cf82

File tree

4 files changed

+100
-14
lines changed

4 files changed

+100
-14
lines changed

internal/lsp/initialize.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ func NewInitializeResponse(id int) InitializeResponse {
2525
},
2626
Result: protocol.InitializeResult{
2727
Capabilities: protocol.ServerCapabilities{
28-
TextDocumentSync: 1,
29-
HoverProvider: true,
30-
DefinitionProvider: true,
31-
CompletionProvider: &protocol.CompletionOptions{},
28+
TextDocumentSync: 1,
29+
HoverProvider: true,
30+
DefinitionProvider: true,
31+
CompletionProvider: &protocol.CompletionOptions{},
32+
DocumentFormattingProvider: true,
3233
},
3334
ServerInfo: &protocol.ServerInfo{
3435
Name: name,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package lsp
2+
3+
import "go.lsp.dev/protocol"
4+
5+
type FormatRequest struct {
6+
Request
7+
Params protocol.DocumentFormattingParams `json:"params"`
8+
}
9+
10+
type FormatResponse struct {
11+
Response
12+
Result []protocol.TextEdit `json:"result"`
13+
}

internal/tg/state.go

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,22 +95,22 @@ func (s *State) Hover(l logger.Logger, id int, docURI protocol.DocumentURI, posi
9595
)
9696

9797
if word == "" {
98-
return buildEmptyHoverResponse(id)
98+
return newEmptyHoverResponse(id)
9999
}
100100

101101
//nolint:gocritic
102102
switch context {
103103
case hover.HoverContextLocal:
104104
if store.Cfg == nil {
105-
return buildEmptyHoverResponse(id)
105+
return newEmptyHoverResponse(id)
106106
}
107107

108108
if _, ok := store.Cfg.Locals[word]; !ok {
109-
return buildEmptyHoverResponse(id)
109+
return newEmptyHoverResponse(id)
110110
}
111111

112112
if store.CfgAsCty.IsNull() {
113-
return buildEmptyHoverResponse(id)
113+
return newEmptyHoverResponse(id)
114114
}
115115

116116
locals := store.CfgAsCty.GetAttr("locals")
@@ -134,10 +134,10 @@ func (s *State) Hover(l logger.Logger, id int, docURI protocol.DocumentURI, posi
134134
}
135135
}
136136

137-
return buildEmptyHoverResponse(id)
137+
return newEmptyHoverResponse(id)
138138
}
139139

140-
func buildEmptyHoverResponse(id int) lsp.HoverResponse {
140+
func newEmptyHoverResponse(id int) lsp.HoverResponse {
141141
return lsp.HoverResponse{
142142
Response: lsp.Response{
143143
RPC: lsp.RPCVersion,
@@ -168,7 +168,7 @@ func (s *State) Definition(l logger.Logger, id int, docURI protocol.DocumentURI,
168168
)
169169

170170
if target == "" {
171-
return buildEmptyDefinitionResponse(id, docURI, position)
171+
return newEmptyDefinitionResponse(id, docURI, position)
172172
}
173173

174174
//nolint:gocritic
@@ -180,7 +180,7 @@ func (s *State) Definition(l logger.Logger, id int, docURI protocol.DocumentURI,
180180
)
181181

182182
if store.Cfg == nil {
183-
return buildEmptyDefinitionResponse(id, docURI, position)
183+
return newEmptyDefinitionResponse(id, docURI, position)
184184
}
185185

186186
l.Debug(
@@ -225,10 +225,10 @@ func (s *State) Definition(l logger.Logger, id int, docURI protocol.DocumentURI,
225225
}
226226
}
227227

228-
return buildEmptyDefinitionResponse(id, docURI, position)
228+
return newEmptyDefinitionResponse(id, docURI, position)
229229
}
230230

231-
func buildEmptyDefinitionResponse(id int, docURI protocol.DocumentURI, position protocol.Position) lsp.DefinitionResponse {
231+
func newEmptyDefinitionResponse(id int, docURI protocol.DocumentURI, position protocol.Position) lsp.DefinitionResponse {
232232
return lsp.DefinitionResponse{
233233
Response: lsp.Response{
234234
RPC: lsp.RPCVersion,
@@ -257,3 +257,56 @@ func (s *State) TextDocumentCompletion(l logger.Logger, id int, docURI protocol.
257257

258258
return response
259259
}
260+
261+
func (s *State) TextDocumentFormatting(l logger.Logger, id int, docURI protocol.DocumentURI) lsp.FormatResponse {
262+
store := s.Configs[docURI.Filename()]
263+
264+
l.Debug(
265+
"Formatting requested",
266+
"uri", docURI,
267+
)
268+
269+
if store.Cfg == nil {
270+
return newEmptyFormatResponse(id)
271+
}
272+
273+
formatted := hclwrite.Format([]byte(store.Document))
274+
275+
return lsp.FormatResponse{
276+
Response: lsp.Response{
277+
RPC: lsp.RPCVersion,
278+
ID: &id,
279+
},
280+
Result: []protocol.TextEdit{
281+
{
282+
Range: protocol.Range{
283+
Start: protocol.Position{
284+
Line: 0,
285+
Character: 0,
286+
},
287+
End: getEndOfDocument(store.Document),
288+
},
289+
NewText: string(formatted),
290+
},
291+
},
292+
}
293+
}
294+
295+
func newEmptyFormatResponse(id int) lsp.FormatResponse {
296+
return lsp.FormatResponse{
297+
Response: lsp.Response{
298+
RPC: lsp.RPCVersion,
299+
ID: &id,
300+
},
301+
Result: []protocol.TextEdit{},
302+
}
303+
}
304+
305+
func getEndOfDocument(doc string) protocol.Position {
306+
lines := strings.Split(doc, "\n")
307+
308+
return protocol.Position{
309+
Line: uint32(len(lines) - 1),
310+
Character: uint32(len(lines[len(lines)-1])),
311+
}
312+
}

main.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,25 @@ func handleMessage(l logger.Logger, writer io.Writer, state tg.State, method str
203203
"Response", response,
204204
)
205205

206+
writeResponse(l, writer, response)
207+
208+
case protocol.MethodTextDocumentFormatting:
209+
var request lsp.FormatRequest
210+
if err := json.Unmarshal(contents, &request); err != nil {
211+
l.Error(
212+
"Failed to parse format request",
213+
"error",
214+
err,
215+
)
216+
}
217+
218+
l.Debug(
219+
"Formatting",
220+
"URI", request.Params.TextDocument.URI,
221+
)
222+
223+
response := state.TextDocumentFormatting(l, request.ID, request.Params.TextDocument.URI)
224+
206225
writeResponse(l, writer, response)
207226
}
208227
}

0 commit comments

Comments
 (0)