@@ -268,39 +268,130 @@ export class JupyterlabFileEditorCodeFormatter extends JupyterlabCodeFormatter {
268268 }
269269
270270 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+ ) {
271279 if ( this . working ) {
272280 return ;
273281 }
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
290360 ) ;
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+ }
302392 }
303393
394+
304395 applicable ( formatter : string , currentWidget : Widget ) {
305396 const currentEditorWidget = this . editorTracker . currentWidget ;
306397 // TODO: Handle showing just the correct formatter for the language later
0 commit comments