@@ -60,39 +60,28 @@ module Fsi =
60
60
()
61
61
62
62
module Watcher =
63
+ open Webviews
63
64
let mutable panel : WebviewPanel option = None
64
65
65
- let setContent str =
66
- panel
67
- |> Option.iter ( fun p ->
68
- let str =
69
- sprintf
70
- """
71
- <html>
72
- <head>
73
- <meta>
74
- <style>
75
- table { border-collapse: collapse;}
76
- th {
77
- border-left: 1px solid var(--vscode-editor-foreground);
78
- border-right: 1px solid var(--vscode-editor-foreground);
79
- padding: 5px;
80
- }
81
- td {
82
- border: 1px solid var(--vscode-editor-foreground);
83
- min-width: 100px;
84
- padding: 5px;
85
- }
86
- </style>
87
- </head>
88
- <body>
89
- %s
90
- </body>
91
- </html>
92
- """
93
- str
94
-
95
- p.webview.html <- str)
66
+ let updateContent
67
+ ( context : ExtensionContext )
68
+ ( varsContent : ( string * string ) option )
69
+ ( typesContent : ( string * string ) option )
70
+ ( funcsContent : ( string * string ) option )
71
+ =
72
+ let ( vars , varsScript ) = defaultArg varsContent ( " " , " " )
73
+ let ( types , typesScript ) = defaultArg typesContent ( " " , " " )
74
+ let ( funcs , funcsScript ) = defaultArg funcsContent ( " " , " " )
75
+
76
+ match panel with
77
+ | Some panel ->
78
+ FsWebview.render (
79
+ context,
80
+ panel,
81
+ $" {vars}{types}{funcs}" ,
82
+ scripts = [ varsScript; typesScript; funcsScript ]
83
+ )
84
+ | None -> ()
96
85
97
86
let openPanel () =
98
87
promise {
@@ -113,18 +102,22 @@ module Fsi =
113
102
match panel with
114
103
| Some p -> p.reveal (!! - 2 , true )
115
104
| None ->
116
- let opts =
117
- createObj
118
- [ " enableCommandUris" ==> true
119
- " enableFindWidget" ==> true
120
- " retainContextWhenHidden" ==> true ]
121
-
122
105
let viewOpts =
123
106
createObj
124
107
[ " preserveFocus" ==> true
125
108
" viewColumn" ==> - 2 ]
126
109
127
- let p = window.createWebviewPanel ( " fsiWatcher" , " FSI Watcher" , !! viewOpts, opts)
110
+ let p =
111
+ FsWebview.create (
112
+ " fsiWatcher" ,
113
+ " FSI Watcher" ,
114
+ !! viewOpts,
115
+ enableScripts = true ,
116
+ enableFindWidget = true ,
117
+ enableCommandUris = true ,
118
+ retainContextWhenHidden = true
119
+ )
120
+
128
121
let onClose () = panel <- None
129
122
130
123
p.onDidDispose.Invoke(!! onClose) |> ignore
@@ -140,42 +133,44 @@ module Fsi =
140
133
path.join ( VSCodeExtension.ionidePluginPath (), " watcher" , " funcs.txt" )
141
134
142
135
143
- let handler () =
144
- let mutable varsContent = " "
145
- let mutable typesContent = " "
146
- let mutable funcsContent = " "
147
-
136
+ let handler ( context : ExtensionContext ) =
137
+ let mutable varsContent = None
138
+ let mutable typesContent = None
139
+ let mutable funcsContent = None
148
140
149
141
node.fs.readFile (
150
142
varsUri,
151
143
( fun _ buf ->
152
144
if not ( Utils.isUndefined buf) then
153
145
let cnt = buf.ToString()
154
146
155
- varsContent <-
156
- cnt
157
- |> String.split [| '\n' |]
158
- |> Seq.map ( fun row ->
159
- let x = row.Split([| " ###IONIDESEP###" |], StringSplitOptions.None)
160
-
161
- sprintf
162
- " <tr><td>%s </td><td><code>%s </code></td><td><code>%s </code></td><td>%s </td></tr>"
163
- x.[ 0 ]
164
- x.[ 1 ]
165
- x.[ 2 ]
166
- x.[ 3 ])
167
- |> String.concat " \n "
168
- |> sprintf
169
- """ </br><h3>Declared values</h3></br><table style="width:100%%"><tr><th style="width: 12%%">Name</th><th style="width: 65%%">Value</th><th style="width: 20%%">Type</th><th>Step</th></tr>%s </table>"""
170
-
171
-
172
- setContent (
173
- varsContent
174
- + " \n\n "
175
- + funcsContent
176
- + " \n\n "
177
- + typesContent
178
- ))
147
+ if String.IsNullOrWhiteSpace cnt then
148
+ varsContent <- None
149
+ else
150
+
151
+ let datagridContent =
152
+ cnt
153
+ |> String.split [| '\n' |]
154
+ |> Array.map ( fun row ->
155
+ let x = row.Split([| " ###IONIDESEP###" |], StringSplitOptions.None)
156
+
157
+ box
158
+ {| name = x[ 0 ]
159
+ value = x[ 1 ]
160
+ Type = x[ 2 ]
161
+ step = x[ 3 ] |})
162
+ // ensure column order
163
+ let headers =
164
+ [| " Name" , " name"
165
+ " Value" , " value"
166
+ " Type" , " Type"
167
+ " Step" , " step" |]
168
+
169
+ let grid , script = VsHtml.datagrid ( " vars-content" , datagridContent, headers)
170
+
171
+ varsContent <- Some( html $" <h3>Declared values</h3>{grid}" , script)
172
+
173
+ updateContent context varsContent typesContent funcsContent)
179
174
)
180
175
181
176
node.fs.readFile (
@@ -184,30 +179,33 @@ module Fsi =
184
179
if not ( Utils.isUndefined buf) then
185
180
let cnt = buf.ToString()
186
181
187
- funcsContent <-
188
- cnt
189
- |> String.split [| '\n' |]
190
- |> Seq.map ( fun row ->
191
- let x = row.Split([| " ###IONIDESEP###" |], StringSplitOptions.None)
192
-
193
- sprintf
194
- " <tr><td>%s </td><td><code>%s </code></td><td><code>%s </code></td><td>%s </td></tr>"
195
- x.[ 0 ]
196
- x.[ 1 ]
197
- x.[ 2 ]
198
- x.[ 3 ])
199
- |> String.concat " \n "
200
- |> sprintf
201
- """ </br><h3>Declared functions</h3></br><table style="width:100%%"><tr><th style="width: 12%%">Name</th><th style="width: 65%%">Parameters</th><th style="width: 20%%">Returned type</th><th>Step</th></tr>%s </table>"""
202
-
203
-
204
- setContent (
205
- varsContent
206
- + " \n\n "
207
- + funcsContent
208
- + " \n\n "
209
- + typesContent
210
- ))
182
+ if String.IsNullOrWhiteSpace cnt then
183
+ funcsContent <- None
184
+ else
185
+ let datagridContent =
186
+ cnt
187
+ |> String.split [| '\n' |]
188
+ |> Array.map ( fun row ->
189
+ let x = row.Split([| " ###IONIDESEP###" |], StringSplitOptions.None)
190
+
191
+ box
192
+ {| name = x[ 0 ]
193
+ parameters = x[ 1 ]
194
+ returnType = x[ 2 ]
195
+ step = x[ 3 ] |})
196
+
197
+ let grid , script =
198
+ VsHtml.datagrid (
199
+ " funcs-content" ,
200
+ datagridContent,
201
+ [| " Name" , " name"
202
+ " Parameters" , " parameters"
203
+ " Return Type" , " returnType" |]
204
+ )
205
+
206
+ funcsContent <- Some( html $" <h3>Declared functions</h3>{grid}" , script)
207
+
208
+ updateContent context varsContent typesContent funcsContent)
211
209
)
212
210
213
211
node.fs.readFile (
@@ -216,40 +214,39 @@ module Fsi =
216
214
if not ( Utils.isUndefined buf) then
217
215
let cnt = buf.ToString()
218
216
219
- typesContent <-
220
- if String.IsNullOrWhiteSpace cnt then
221
- " "
222
- else
217
+ if String.IsNullOrWhiteSpace cnt then
218
+ typesContent <- None
219
+ else
220
+ let extractSignature ( str : string ) =
221
+ if str.Contains " #|#" then
222
+ " | " + str.Replace( " #|#" , " </br>| " )
223
+ else
224
+ str
225
+
226
+ let datagridContent =
223
227
cnt
224
228
|> String.split [| '\n' |]
225
- |> Seq .map ( fun row ->
229
+ |> Array .map ( fun row ->
226
230
let x = row.Split([| " ###IONIDESEP###" |], StringSplitOptions.None)
227
231
228
- let signature =
229
- if x.[ 1 ]. Contains " #|#" then
230
- " | " + x.[ 1 ]. Replace( " #|#" , " </br>| " )
231
- else
232
- x.[ 1 ]
233
-
234
- sprintf " <tr><td>%s </td><td><code>%s </code></td><td>%s </td></tr>" x.[ 0 ] signature x.[ 2 ])
235
- |> String.concat " \n "
236
- |> sprintf
237
- """ </br><h3>Declared types</h3></br><table style="width:100%%"><tr><th style="width: 12%%">Name</th><th style="width: 85%%">Signature</th><th>Step</th></tr>%s </table>"""
238
-
239
-
240
- setContent (
241
- varsContent
242
- + " \n\n "
243
- + funcsContent
244
- + " \n\n "
245
- + typesContent
246
- ))
232
+ let signature = extractSignature x[ 1 ]
233
+
234
+ box
235
+ {| Name = x[ 0 ]
236
+ Signature = signature
237
+ Step = x[ 2 ] |})
238
+
239
+ let grid , script = VsHtml.datagrid ( " types-content" , datagridContent)
240
+
241
+ typesContent <- Some( html $" <h3>Declared types</h3>{grid}" , script)
242
+
243
+ updateContent context varsContent typesContent funcsContent)
247
244
)
248
245
249
- let activate dispsables =
250
- fs.watchFile ( varsUri, ( fun st st2 -> handler () ))
251
- fs.watchFile ( typesUri, ( fun st st2 -> handler () ))
252
- fs.watchFile ( funcUri, ( fun st st2 -> handler () ))
246
+ let activate context dispsables =
247
+ fs.watchFile ( varsUri, ( fun st st2 -> handler context ))
248
+ fs.watchFile ( typesUri, ( fun st st2 -> handler context ))
249
+ fs.watchFile ( funcUri, ( fun st st2 -> handler context ))
253
250
254
251
let mutable fsiOutput : Terminal option = None
255
252
let mutable fsiOutputPID : int option = None
@@ -635,7 +632,7 @@ module Fsi =
635
632
}
636
633
637
634
let activate ( context : ExtensionContext ) =
638
- Watcher.activate (!! context.subscriptions)
635
+ Watcher.activate context (!! context.subscriptions)
639
636
SdkScriptsNotify.activate context
640
637
641
638
window.registerTerminalProfileProvider ( " ionide-fsharp.fsi" , provider)
0 commit comments