Skip to content

Commit e807d55

Browse files
committed
Added progress reporting support
1 parent c76120c commit e807d55

File tree

3 files changed

+179
-1
lines changed

3 files changed

+179
-1
lines changed

Diff for: handler/builder.go

+46
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package handler
22

33
import (
44
"bytes"
5+
"context"
56
"encoding/json"
67
"log"
78
"strings"
@@ -10,6 +11,7 @@ import (
1011
"github.com/arduino/arduino-cli/arduino/libraries"
1112
"github.com/arduino/arduino-cli/executils"
1213
"github.com/arduino/go-paths-helper"
14+
"github.com/bcmi-labs/arduino-language-server/lsp"
1315
"github.com/bcmi-labs/arduino-language-server/streams"
1416
"github.com/pkg/errors"
1517
)
@@ -50,9 +52,53 @@ func (handler *InoHandler) rebuildEnvironmentLoop() {
5052
}
5153

5254
// Regenerate preprocessed sketch!
55+
done := make(chan bool)
56+
go func() {
57+
{
58+
// Request a new progress token
59+
req := &lsp.WorkDoneProgressCreateParams{Token: "arduinoLanguageServerRebuild"}
60+
var resp lsp.WorkDoneProgressCreateResult
61+
if err := handler.StdioConn.Call(context.Background(), "window/workDoneProgress/create", req, &resp, nil); err != nil {
62+
log.Printf(" !!! could not create report progress: %s", err)
63+
<-done
64+
return
65+
}
66+
}
67+
68+
req := &lsp.ProgressParams{Token: "arduinoLanguageServerRebuild"}
69+
req.Value = lsp.WorkDoneProgressBegin{
70+
Title: "Building sketch",
71+
}
72+
if err := handler.StdioConn.Notify(context.Background(), "$/progress", req, nil); err != nil {
73+
log.Printf(" !!! could not report progress: %s", err)
74+
}
75+
count := 0
76+
dots := []string{".", "..", "..."}
77+
for {
78+
select {
79+
case <-time.After(time.Millisecond * 400):
80+
msg := "compiling" + dots[count%3]
81+
count++
82+
req.Value = lsp.WorkDoneProgressReport{Message: &msg}
83+
if err := handler.StdioConn.Notify(context.Background(), "$/progress", req, nil); err != nil {
84+
log.Printf(" !!! could not report progress: %s", err)
85+
}
86+
case <-done:
87+
msg := "done"
88+
req.Value = lsp.WorkDoneProgressEnd{Message: &msg}
89+
if err := handler.StdioConn.Notify(context.Background(), "$/progress", req, nil); err != nil {
90+
log.Printf(" !!! could not report progress: %s", err)
91+
}
92+
return
93+
}
94+
}
95+
}()
96+
5397
handler.synchronizer.DataMux.Lock()
5498
handler.initializeWorkbench(nil)
5599
handler.synchronizer.DataMux.Unlock()
100+
done <- true
101+
close(done)
56102
}
57103
}
58104

Diff for: lsp/protocol_test.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ func TestDocumentSymbolParse(t *testing.T) {
6666
}
6767

6868
func TestVariousMessages(t *testing.T) {
69+
x := &ProgressParams{
70+
Token: "token",
71+
Value: WorkDoneProgressBegin{
72+
Title: "some work",
73+
},
74+
}
75+
data, err := json.Marshal(&x)
76+
require.NoError(t, err)
77+
require.JSONEq(t, `{"token":"token", "value":{"kind":"begin","title":"some work"}}`, string(data))
78+
6979
msg := `{
7080
"capabilities":{
7181
"codeActionProvider":{
@@ -107,6 +117,6 @@ func TestVariousMessages(t *testing.T) {
107117
},
108118
"serverInfo":{"name":"clangd","version":"clangd version 11.0.0 (https://github.com/llvm/llvm-project 176249bd6732a8044d457092ed932768724a6f06)"}}`
109119
var init InitializeResult
110-
err := json.Unmarshal([]byte(msg), &init)
120+
err = json.Unmarshal([]byte(msg), &init)
111121
require.NoError(t, err)
112122
}

Diff for: lsp/service.go

+122
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/base64"
66
"encoding/binary"
77
"encoding/json"
8+
"errors"
89
"strings"
910
)
1011

@@ -1029,3 +1030,124 @@ type SemanticHighlightingToken struct {
10291030
Length uint16
10301031
Scope uint16
10311032
}
1033+
1034+
type ProgressParams struct {
1035+
Token string `json:"token"`
1036+
Value interface{} `json:"value"`
1037+
}
1038+
1039+
type WorkDoneProgressCreateParams struct {
1040+
Token string `json:"token"`
1041+
}
1042+
1043+
type WorkDoneProgressCreateResult struct{}
1044+
1045+
// MarshalJSON implements json.Marshaler.
1046+
func (v *WorkDoneProgressCreateResult) MarshalJSON() ([]byte, error) {
1047+
return []byte("null"), nil
1048+
}
1049+
1050+
// UnmarshalJSON implements json.Unmarshaler.
1051+
func (v *WorkDoneProgressCreateResult) UnmarshalJSON(data []byte) error {
1052+
if bytes.Equal(data, []byte("null")) {
1053+
return nil
1054+
}
1055+
return errors.New("expected null")
1056+
}
1057+
1058+
type WorkDoneProgressBegin struct {
1059+
Title string `json:"title"`
1060+
Cancellable *bool `json:"cancellable,omitempty"`
1061+
Message *string `json:"message,omitempty"`
1062+
Percentage *int `json:"percentage,omitempty"`
1063+
}
1064+
1065+
// MarshalJSON implements json.Marshaler.
1066+
func (v WorkDoneProgressBegin) MarshalJSON() ([]byte, error) {
1067+
return json.Marshal(struct {
1068+
Title string `json:"title"`
1069+
Cancellable *bool `json:"cancellable,omitempty"`
1070+
Message *string `json:"message,omitempty"`
1071+
Percentage *int `json:"percentage,omitempty"`
1072+
Kind string `json:"kind"`
1073+
}{v.Title, v.Cancellable, v.Message, v.Percentage, "begin"})
1074+
}
1075+
1076+
// UnmarshalJSON implements json.Unmarshaler.
1077+
func (v *WorkDoneProgressBegin) UnmarshalJSON(data []byte) error {
1078+
type ProgressBegin struct {
1079+
WorkDoneProgressBegin
1080+
Kind string `json:"kind"`
1081+
}
1082+
var x ProgressBegin
1083+
if err := json.Unmarshal(data, &x); err != nil {
1084+
return err
1085+
}
1086+
if x.Kind != "begin" {
1087+
return errors.New(`expected kind == "begin"`)
1088+
}
1089+
*v = x.WorkDoneProgressBegin
1090+
return nil
1091+
}
1092+
1093+
type WorkDoneProgressReport struct {
1094+
Cancellable *bool `json:"cancellable,omitempty"`
1095+
Message *string `json:"message,omitempty"`
1096+
Percentage *int `json:"percentage,omitempty"`
1097+
}
1098+
1099+
// MarshalJSON implements json.Marshaler.
1100+
func (v WorkDoneProgressReport) MarshalJSON() ([]byte, error) {
1101+
return json.Marshal(struct {
1102+
Cancellable *bool `json:"cancellable,omitempty"`
1103+
Message *string `json:"message,omitempty"`
1104+
Percentage *int `json:"percentage,omitempty"`
1105+
Kind string `json:"kind"`
1106+
}{v.Cancellable, v.Message, v.Percentage, "report"})
1107+
}
1108+
1109+
// UnmarshalJSON implements json.Unmarshaler.
1110+
func (v *WorkDoneProgressReport) UnmarshalJSON(data []byte) error {
1111+
type ProgressReport struct {
1112+
WorkDoneProgressReport
1113+
Kind string `json:"kind"`
1114+
}
1115+
var x ProgressReport
1116+
if err := json.Unmarshal(data, &x); err != nil {
1117+
return err
1118+
}
1119+
if x.Kind != "report" {
1120+
return errors.New(`expected kind == "report"`)
1121+
}
1122+
*v = x.WorkDoneProgressReport
1123+
return nil
1124+
}
1125+
1126+
type WorkDoneProgressEnd struct {
1127+
Message *string `json:"message,omitempty"`
1128+
}
1129+
1130+
// MarshalJSON implements json.Marshaler.
1131+
func (v WorkDoneProgressEnd) MarshalJSON() ([]byte, error) {
1132+
return json.Marshal(struct {
1133+
Message *string `json:"message,omitempty"`
1134+
Kind string `json:"kind"`
1135+
}{v.Message, "end"})
1136+
}
1137+
1138+
// UnmarshalJSON implements json.Unmarshaler.
1139+
func (v *WorkDoneProgressEnd) UnmarshalJSON(data []byte) error {
1140+
type ProgressEnd struct {
1141+
WorkDoneProgressEnd
1142+
Kind string `json:"kind"`
1143+
}
1144+
var x ProgressEnd
1145+
if err := json.Unmarshal(data, &x); err != nil {
1146+
return err
1147+
}
1148+
if x.Kind != "end" {
1149+
return errors.New(`expected kind == "end"`)
1150+
}
1151+
*v = x.WorkDoneProgressEnd
1152+
return nil
1153+
}

0 commit comments

Comments
 (0)