@@ -19,6 +19,8 @@ import { RenderNode, WebviewContent, WebviewMessage } from "./webview/WebviewMes
19
19
import { WorkspaceContext } from "../WorkspaceContext" ;
20
20
import { DocCDocumentationRequest , DocCDocumentationResponse } from "../sourcekit-lsp/extensions" ;
21
21
import { LSPErrorCodes , ResponseError } from "vscode-languageclient" ;
22
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
23
+ import throttle = require( "lodash.throttle" ) ;
22
24
23
25
export enum PreviewEditorConstant {
24
26
VIEW_TYPE = "swift.previewDocumentationEditor" ,
@@ -178,73 +180,77 @@ export class DocumentationPreviewEditor implements vscode.Disposable {
178
180
}
179
181
}
180
182
181
- private async convertDocumentation ( textEditor : vscode . TextEditor ) : Promise < void > {
182
- const document = textEditor . document ;
183
- if (
184
- document . uri . scheme !== "file" ||
185
- ! [ "markdown" , "tutorial" , "swift" ] . includes ( document . languageId )
186
- ) {
187
- this . postMessage ( {
188
- type : "update-content" ,
189
- content : {
190
- type : "error" ,
191
- errorMessage : PreviewEditorConstant . UNSUPPORTED_EDITOR_ERROR_MESSAGE ,
192
- } ,
193
- } ) ;
194
- return ;
195
- }
183
+ private convertDocumentation = throttle (
184
+ async ( textEditor : vscode . TextEditor ) : Promise < void > => {
185
+ const document = textEditor . document ;
186
+ if (
187
+ document . uri . scheme !== "file" ||
188
+ ! [ "markdown" , "tutorial" , "swift" ] . includes ( document . languageId )
189
+ ) {
190
+ this . postMessage ( {
191
+ type : "update-content" ,
192
+ content : {
193
+ type : "error" ,
194
+ errorMessage : PreviewEditorConstant . UNSUPPORTED_EDITOR_ERROR_MESSAGE ,
195
+ } ,
196
+ } ) ;
197
+ return ;
198
+ }
196
199
197
- try {
198
- const response = await this . context . languageClientManager . useLanguageClient (
199
- async ( client ) : Promise < DocCDocumentationResponse > => {
200
- return await client . sendRequest ( DocCDocumentationRequest . type , {
201
- textDocument : {
202
- uri : document . uri . toString ( ) ,
203
- } ,
204
- position : textEditor . selection . start ,
205
- } ) ;
206
- }
207
- ) ;
208
- this . postMessage ( {
209
- type : "update-content" ,
210
- content : {
211
- type : "render-node" ,
212
- renderNode : this . parseRenderNode ( response . renderNode ) ,
213
- } ,
214
- } ) ;
215
- } catch ( error ) {
216
- // Update the preview editor to reflect what error occurred
217
- let livePreviewErrorMessage = "An internal error occurred" ;
218
- const baseLogErrorMessage = `SourceKit-LSP request "${ DocCDocumentationRequest . method } " failed: ` ;
219
- if ( error instanceof ResponseError ) {
220
- if ( error . code === LSPErrorCodes . RequestCancelled ) {
221
- // We can safely ignore cancellations
222
- return undefined ;
200
+ try {
201
+ const response = await this . context . languageClientManager . useLanguageClient (
202
+ async ( client ) : Promise < DocCDocumentationResponse > => {
203
+ return await client . sendRequest ( DocCDocumentationRequest . type , {
204
+ textDocument : {
205
+ uri : document . uri . toString ( ) ,
206
+ } ,
207
+ position : textEditor . selection . start ,
208
+ } ) ;
209
+ }
210
+ ) ;
211
+ this . postMessage ( {
212
+ type : "update-content" ,
213
+ content : {
214
+ type : "render-node" ,
215
+ renderNode : this . parseRenderNode ( response . renderNode ) ,
216
+ } ,
217
+ } ) ;
218
+ } catch ( error ) {
219
+ // Update the preview editor to reflect what error occurred
220
+ let livePreviewErrorMessage = "An internal error occurred" ;
221
+ const baseLogErrorMessage = `SourceKit-LSP request "${ DocCDocumentationRequest . method } " failed: ` ;
222
+ if ( error instanceof ResponseError ) {
223
+ if ( error . code === LSPErrorCodes . RequestCancelled ) {
224
+ // We can safely ignore cancellations
225
+ return undefined ;
226
+ }
227
+ switch ( error . code ) {
228
+ case LSPErrorCodes . RequestFailed :
229
+ // RequestFailed response errors can be shown to the user
230
+ livePreviewErrorMessage = error . message ;
231
+ break ;
232
+ default :
233
+ // We should log additional info for other response errors
234
+ this . context . outputChannel . log (
235
+ baseLogErrorMessage + JSON . stringify ( error . toJson ( ) , undefined , 2 )
236
+ ) ;
237
+ break ;
238
+ }
239
+ } else {
240
+ this . context . outputChannel . log ( baseLogErrorMessage + `${ error } ` ) ;
223
241
}
224
- switch ( error . code ) {
225
- case LSPErrorCodes . RequestFailed :
226
- // RequestFailed response errors can be shown to the user
227
- livePreviewErrorMessage = error . message ;
228
- break ;
229
- default :
230
- // We should log additional info for other response errors
231
- this . context . outputChannel . log (
232
- baseLogErrorMessage + JSON . stringify ( error . toJson ( ) , undefined , 2 )
233
- ) ;
234
- break ;
235
- }
236
- } else {
237
- this . context . outputChannel . log ( baseLogErrorMessage + `${ error } ` ) ;
242
+ this . postMessage ( {
243
+ type : "update-content" ,
244
+ content : {
245
+ type : "error" ,
246
+ errorMessage : livePreviewErrorMessage ,
247
+ } ,
248
+ } ) ;
238
249
}
239
- this . postMessage ( {
240
- type : "update-content" ,
241
- content : {
242
- type : "error" ,
243
- errorMessage : livePreviewErrorMessage ,
244
- } ,
245
- } ) ;
246
- }
247
- }
250
+ } ,
251
+ 100 /* 10 times per second */ ,
252
+ { trailing : true }
253
+ ) ;
248
254
249
255
private parseRenderNode ( content : string ) : RenderNode {
250
256
const renderNode : RenderNode = JSON . parse ( content ) ;
0 commit comments