@@ -3,10 +3,13 @@ package server
3
3
import (
4
4
"context"
5
5
"fmt"
6
+ "reflect"
6
7
7
8
"github.com/google/go-jsonnet"
9
+ "github.com/google/go-jsonnet/formatter"
8
10
"github.com/jdbaldry/go-language-server-protocol/jsonrpc2"
9
11
"github.com/jdbaldry/go-language-server-protocol/lsp/protocol"
12
+ "github.com/mitchellh/mapstructure"
10
13
)
11
14
12
15
func (s * server ) DidChangeConfiguration (ctx context.Context , params * protocol.DidChangeConfigurationParams ) error {
@@ -24,6 +27,13 @@ func (s *server) DidChangeConfiguration(ctx context.Context, params *protocol.Di
24
27
}
25
28
s .extVars = newVars
26
29
30
+ case "formatting" :
31
+ newFmtOpts , err := s .parseFormattingOpts (sv )
32
+ if err != nil {
33
+ return fmt .Errorf ("%w: formatting options parsing failed: %v" , jsonrpc2 .ErrInvalidParams , err )
34
+ }
35
+ s .fmtOpts = newFmtOpts
36
+
27
37
default :
28
38
return fmt .Errorf ("%w: unsupported settings key: %q" , jsonrpc2 .ErrInvalidParams , sk )
29
39
}
@@ -48,9 +58,76 @@ func (s *server) parseExtVars(unparsed interface{}) (map[string]string, error) {
48
58
return extVars , nil
49
59
}
50
60
61
+ func (s * server ) parseFormattingOpts (unparsed interface {}) (formatter.Options , error ) {
62
+ newOpts , ok := unparsed .(map [string ]interface {})
63
+ if ! ok {
64
+ return formatter.Options {}, fmt .Errorf ("unsupported settings value for formatting. expected json object. got: %T" , unparsed )
65
+ }
66
+
67
+ opts := formatter .DefaultOptions ()
68
+ config := mapstructure.DecoderConfig {
69
+ Result : & opts ,
70
+ DecodeHook : mapstructure .ComposeDecodeHookFunc (
71
+ stringStyleDecodeFunc ,
72
+ commentStyleDecodeFunc ,
73
+ ),
74
+ }
75
+ decoder , err := mapstructure .NewDecoder (& config )
76
+ if err != nil {
77
+ return formatter.Options {}, fmt .Errorf ("decoder construction failed: %v" , err )
78
+ }
79
+
80
+ if err := decoder .Decode (newOpts ); err != nil {
81
+ return formatter.Options {}, fmt .Errorf ("map decode failed: %v" , err )
82
+ }
83
+ return opts , nil
84
+ }
85
+
51
86
func resetExtVars (vm * jsonnet.VM , vars map [string ]string ) {
52
87
vm .ExtReset ()
53
88
for vk , vv := range vars {
54
89
vm .ExtVar (vk , vv )
55
90
}
56
91
}
92
+
93
+ func stringStyleDecodeFunc (from , to reflect.Type , unparsed interface {}) (interface {}, error ) {
94
+ if to != reflect .TypeOf (formatter .StringStyleDouble ) {
95
+ return unparsed , nil
96
+ }
97
+ if from .Kind () != reflect .String {
98
+ return nil , fmt .Errorf ("expected string, got: %v" , from .Kind ())
99
+ }
100
+
101
+ // will not panic because of the kind == string check above
102
+ switch str := unparsed .(string ); str {
103
+ case "double" :
104
+ return formatter .StringStyleDouble , nil
105
+ case "single" :
106
+ return formatter .StringStyleSingle , nil
107
+ case "leave" :
108
+ return formatter .StringStyleLeave , nil
109
+ default :
110
+ return nil , fmt .Errorf ("expected one of 'double', 'single', 'leave', got: %q" , str )
111
+ }
112
+ }
113
+
114
+ func commentStyleDecodeFunc (from , to reflect.Type , unparsed interface {}) (interface {}, error ) {
115
+ if to != reflect .TypeOf (formatter .CommentStyleHash ) {
116
+ return unparsed , nil
117
+ }
118
+ if from .Kind () != reflect .String {
119
+ return nil , fmt .Errorf ("expected string, got: %v" , from .Kind ())
120
+ }
121
+
122
+ // will not panic because of the kind == string check above
123
+ switch str := unparsed .(string ); str {
124
+ case "hash" :
125
+ return formatter .CommentStyleHash , nil
126
+ case "slash" :
127
+ return formatter .CommentStyleSlash , nil
128
+ case "leave" :
129
+ return formatter .CommentStyleLeave , nil
130
+ default :
131
+ return nil , fmt .Errorf ("expected one of 'hash', 'slash', 'leave', got: %q" , str )
132
+ }
133
+ }
0 commit comments