'use strict' ; import * as fs from 'fs' ; import * as path from 'path' ; import * as which from 'which' ; import * as vscode from 'vscode' ; import * as cp from 'child_process' ; import { LoggingService } from '../services/logging-service' ; import { FORMATTERS , EXTENSION_ID , promptForMissingTool } from '../lib/tools' ; export class FortranFormattingProvider implements vscode . DocumentFormattingEditProvider { constructor ( private logger ) { } public provideDocumentFormattingEdits ( document , options , token ) { const formatterName = this . getFormatter ( ) ; if ( formatterName === 'fprettify' ) { this . doFormatFprettify ( document ) ; } else if ( formatterName === 'findent' ) { this . doFormatFindent ( document ) ; } else { this . logger . logError ( 'Cannot format document with formatter set to Disabled' ) ; } return ; } param document private doFormatFprettify ( document ) { if ( document . languageId !== 'FortranFreeForm' ) { this . logger . logError ( `fprettify can only format FortranFreeForm, change
                            to findent for FortranFixedForm formatting` ) ; return ; } const formatterName = 'fprettify' ; const formatterPath = this . getFormatterPath ( ) ; const formatter = path . join ( formatterPath , formatterName ) ; if ( ! which . sync ( formatter , { nothrow : true } ) ) { this . logger . logWarning ( `Formatter: ${ formatterName } not detected in your system.
                                Attempting to install now.` ) ; const msg = `Installing ${ formatterName } through pip with --user option` ; promptForMissingTool ( formatterName , msg , 'Python' , [ 'Install' ] , this . logger ) ; } const args = [ document . fileName , ... this . getFormatterArgs ( ) ] ; const process = cp . spawn ( formatter , args ) ; process . stdout . on ( 'data' , data => { this . logger . logInfo ( `formatter stdout: ${ data }` ) ; } ) ; process . stderr . on ( 'data' , data => { this . logger . logError ( `formatter stderr: ${ data }` ) ; } ) ; process . on ( 'close' , ( code ) => { if ( code !== 0 ) this . logger . logInfo ( `formatter exited with code: ${ code }` ) ; } ) ; process . on ( 'error' , code => { this . logger . logInfo ( `formatter exited with code: ${ code }` ) ; } ) ; } param document private doFormatFindent ( document ) { const formatterName = 'findent' ; const formatterPath = this . getFormatterPath ( ) ; let formatter = path . join ( formatterPath , formatterName ) ; if ( ! which . sync ( formatter , { nothrow : true } ) ) { this . logger . logWarning ( `Formatter: ${ formatterName } not detected in your system.
                                    Attempting to install now.` ) ; const msg = `Installing ${ formatterName } through pip with --user option` ; promptForMissingTool ( formatterName , msg , 'Python' , [ 'Install' ] , this . logger ) ; } const out = document . uri . path + '.findent.tmp' ; const args = [ '< ' + document . fileName + ' >' , out , ... this . getFormatterArgs ( ) ] . join ( ' ' ) ; formatter = formatter + ' ' + args ; cp . execSync ( formatter , { stdio : 'inherit' } ) ; fs . copyFileSync ( out , document . fileName ) ; fs . unlinkSync ( out ) ; } returns { string } private getFormatter ( ) { const config = vscode . workspace . getConfiguration ( EXTENSION_ID ) ; const formatter = config . get ( 'formatting.formatter' , 'Disabled' ) ; if ( ! FORMATTERS . includes ( formatter ) ) { this . logger . logError ( `Unsupported formatter: ${ formatter }` ) ; } return formatter ; } returns { string [ ] } private getFormatterArgs ( ) { const config = vscode . workspace . getConfiguration ( EXTENSION_ID ) ; const args = config . get ( 'formatting.args' , [ ] ) ; return args ; } returns { string } private getFormatterPath ( ) { const config = vscode . workspace . getConfiguration ( EXTENSION_ID ) ; const formatterPath = config . get ( 'formatting.path' , '' ) ; if ( formatterPath !== '' ) { this . logger . logInfo ( `Formatter located in: ${ formatterPath }` ) ; } return formatterPath ; } }