@@ -268,39 +268,130 @@ export class JupyterlabFileEditorCodeFormatter extends JupyterlabCodeFormatter {
268
268
}
269
269
270
270
formatAction ( config : any , formatter : string ) {
271
+ return this . formatEditor ( config , { saving : false } , formatter ) ;
272
+ }
273
+
274
+ public async formatEditor (
275
+ config : any ,
276
+ context : Context ,
277
+ formatter ?: string ,
278
+ ) {
271
279
if ( this . working ) {
272
280
return ;
273
281
}
274
- const editorWidget = this . editorTracker . currentWidget ;
275
- this . working = true ;
276
- const editor = editorWidget ! . content . editor ;
277
- const code = editor . model . sharedModel . source ;
278
- this . formatCode (
279
- [ code ] ,
280
- formatter ,
281
- config [ formatter ] ,
282
- false ,
283
- config . cacheFormatters
284
- )
285
- . then ( data => {
286
- if ( data . code [ 0 ] . error ) {
287
- void showErrorMessage (
288
- 'Jupyterlab Code Formatter Error' ,
289
- data . code [ 0 ] . error
282
+ try {
283
+ this . working = true ;
284
+
285
+ const formattersToUse = await this . getFormattersToUse ( config , formatter ) ;
286
+ await this . applyFormatters (
287
+ formattersToUse ,
288
+ config ,
289
+ context
290
+ ) ;
291
+ } catch ( error ) {
292
+ await showErrorMessage ( 'Jupyterlab Code Formatter Error' , error ) ;
293
+ }
294
+ this . working = false ;
295
+ }
296
+
297
+ private getEditorType ( ) {
298
+ if ( ! this . editorTracker . currentWidget ) {
299
+ return null ;
300
+ }
301
+
302
+ const mimeType =
303
+ this . editorTracker . currentWidget . content . model ! . mimeType ;
304
+
305
+ const mimeTypes = new Map ( [
306
+ [ 'text/x-python' , 'python' ] ,
307
+ [ 'application/x-rsrc' , 'r' ] ,
308
+ [ 'application/x-scala' , 'scala' ] ,
309
+ [ 'application/x-rustsrc' , 'rust' ] ,
310
+ [ 'application/x-c++src' , 'cpp' ] , // Not sure that this is right, whatever.
311
+ // Add more MIME types and corresponding programming languages here
312
+ ] ) ;
313
+
314
+ return mimeTypes . get ( mimeType ) ;
315
+ }
316
+
317
+ private getDefaultFormatters ( config : any ) : Array < string > {
318
+ const editorType = this . getEditorType ( ) ;
319
+ if ( editorType ) {
320
+ const defaultFormatter =
321
+ config . preferences . default_formatter [ editorType ] ;
322
+ if ( defaultFormatter instanceof Array ) {
323
+ return defaultFormatter ;
324
+ } else if ( defaultFormatter !== undefined ) {
325
+ return [ defaultFormatter ] ;
326
+ }
327
+ }
328
+ return [ ] ;
329
+ }
330
+
331
+ private async getFormattersToUse ( config : any , formatter ?: string ) {
332
+ const defaultFormatters = this . getDefaultFormatters ( config ) ;
333
+ const formattersToUse =
334
+ formatter !== undefined ? [ formatter ] : defaultFormatters ;
335
+
336
+ if ( formattersToUse . length === 0 ) {
337
+ await showErrorMessage (
338
+ 'Jupyterlab Code Formatter Error' ,
339
+ 'Unable to find default formatters to use, please file an issue on GitHub.'
340
+ ) ;
341
+ }
342
+
343
+ return formattersToUse ;
344
+ }
345
+
346
+ private async applyFormatters (
347
+ formattersToUse : string [ ] ,
348
+ config : any ,
349
+ context : Context
350
+ ) {
351
+ for ( const formatterToUse of formattersToUse ) {
352
+ if ( formatterToUse === 'noop' || formatterToUse === 'skip' ) {
353
+ continue ;
354
+ }
355
+ const showErrors =
356
+ ! ( config . suppressFormatterErrors ?? false ) &&
357
+ ! (
358
+ ( config . suppressFormatterErrorsIFFAutoFormatOnSave ?? false ) &&
359
+ context . saving
290
360
) ;
291
- this . working = false ;
292
- return ;
293
- }
294
- this . editorTracker . currentWidget ! . content . editor . model . sharedModel . source =
295
- data . code [ 0 ] . code ;
296
- this . working = false ;
297
- } )
298
- . catch ( error => {
299
- this . working = false ;
300
- void showErrorMessage ( 'Jupyterlab Code Formatter Error' , error ) ;
301
- } ) ;
361
+
362
+ const editorWidget = this . editorTracker . currentWidget ;
363
+ this . working = true ;
364
+ const editor = editorWidget ! . content . editor ;
365
+ const code = editor . model . sharedModel . source ;
366
+ this . formatCode (
367
+ [ code ] ,
368
+ formatterToUse ,
369
+ config [ formatterToUse ] ,
370
+ false ,
371
+ config . cacheFormatters
372
+ )
373
+ . then ( data => {
374
+ if ( data . code [ 0 ] . error ) {
375
+ if ( showErrors ) {
376
+ void showErrorMessage (
377
+ 'Jupyterlab Code Formatter Error' ,
378
+ data . code [ 0 ] . error
379
+ ) ;
380
+ }
381
+ this . working = false ;
382
+ return ;
383
+ }
384
+ this . editorTracker . currentWidget ! . content . editor . model . sharedModel . source =
385
+ data . code [ 0 ] . code ;
386
+ this . working = false ;
387
+ } )
388
+ . catch ( error => {
389
+ void showErrorMessage ( 'Jupyterlab Code Formatter Error' , error ) ;
390
+ } ) ;
391
+ }
302
392
}
303
393
394
+
304
395
applicable ( formatter : string , currentWidget : Widget ) {
305
396
const currentEditorWidget = this . editorTracker . currentWidget ;
306
397
// TODO: Handle showing just the correct formatter for the language later
0 commit comments