import * as vscode from 'vscode' ; import * as path from 'path' ; import * as fs from 'fs' ; import * as chokidar from 'chokidar' ; import { Extension } from '../extension' ; export class Manager { extension : Extension ; bibWatcher : chokidar . FSWatcher ; watched : string [ ] ; constructor ( extension ) { this . extension = extension ; this . watched = [ ] ; } findBib ( ) { const bibRegex = /^bibliography:\s* \[(.*)\]/m ; const activeText = vscode . window . activeTextEditor ! . document . getText ( ) ; let bibresult = activeText . match ( bibRegex ) ; let foundFiles = [ ] ; if ( bibresult ) { const bibFiles = bibresult [ 1 ] . split ( ',' ) . map ( item => item . trim ( ) ) ; for ( let i in bibFiles ) { let bibFile = this . stripQuotes ( bibFiles [ i ] ) ; bibFile = this . resolveBibFile ( bibFile ) ; this . extension . log ( `Looking for .bib file: ${ bibFile }` ) ; this . addBibToWatcher ( bibFile ) ; foundFiles . push ( bibFile ) ; } } const configuration = vscode . workspace . getConfiguration ( 'PandocCiter' ) ; if ( configuration . get ( 'RootFile' ) !== "" ) { let curInput = path . join ( configuration . get ( 'RootFile' ) ) ; if ( ! path . isAbsolute ( curInput ) ) { curInput = path . join ( vscode . workspace . rootPath , configuration . get ( 'RootFile' ) ) ; } var rootText = fs . readFileSync ( curInput , 'utf8' ) ; bibresult = rootText . match ( bibRegex ) ; if ( bibresult ) { const bibFiles = bibresult [ 1 ] . split ( ',' ) . map ( item => item . trim ( ) ) ; for ( let i in bibFiles ) { let bibFile = path . join ( path . dirname ( curInput ) , bibFiles [ i ] ) ; bibFile = this . resolveBibFile ( bibFile ) ; this . extension . log ( `Looking for .bib file: ${ bibFile }` ) ; this . addBibToWatcher ( bibFile ) ; foundFiles . push ( bibFile ) ; } } } if ( configuration . get ( 'UseDefaultBib' ) && ( configuration . get ( 'DefaultBib' ) !== "" ) ) { let bibFile = path . join ( configuration . get ( 'DefaultBib' ) ) ; bibFile = this . resolveBibFile ( bibFile , true ) ; this . extension . log ( `Looking for .bib file: ${ bibFile }` ) ; this . addBibToWatcher ( bibFile ) ; foundFiles . push ( bibFile ) ; } let watched_but_not_found = this . watched . filter ( e => ! foundFiles . includes ( e ) ) ; if ( configuration . get ( 'ForgetUnusedBib' ) ) { if ( watched_but_not_found . length > 0 ) { this . forgetUnusedFiles ( watched_but_not_found ) ; } } return ; } stripQuotes ( inputString ) { if ( inputString [ 0 ] === inputString [ inputString . length - 1 ] && "\"'" . includes ( inputString [ 0 ] ) ) { return inputString . slice ( 1 , - 1 ) ; } else { return inputString ; } } resolveBibFile ( bibFile , useWorkspaceFolder ? ) { if ( path . isAbsolute ( bibFile ) ) { return bibFile ; } else if ( useWorkspaceFolder ) { return path . resolve ( vscode . workspace . rootPath , bibFile ) ; } else { return path . resolve ( path . dirname ( vscode . window . activeTextEditor ! . document . fileName ) , bibFile ) ; } } addBibToWatcher ( bibPath ) { if ( path . extname ( bibPath ) === '' ) { bibPath += '.bib' ; } if ( ! fs . existsSync ( bibPath ) && fs . existsSync ( bibPath + '.bib' ) ) { bibPath += '.bib' ; } if ( fs . existsSync ( bibPath ) ) { this . extension . log ( `Found .bib file ${ bibPath }` ) ; if ( this . bibWatcher === undefined ) { this . extension . log ( `Creating file watcher for .bib files.` ) ; this . bibWatcher = chokidar . watch ( bibPath , { awaitWriteFinish : true } ) ; this . bibWatcher . on ( 'change' , ( filePath ) => { this . extension . log ( `Bib file watcher - responding to change in ${ filePath }` ) ; this . extension . completer . citation . parseBibFile ( filePath ) ; } ) ; this . bibWatcher . on ( 'unlink' , ( filePath ) => { this . extension . log ( `Bib file watcher: ${ filePath } deleted.` ) ; this . extension . completer . citation . forgetParsedBibItems ( filePath ) ; this . bibWatcher . unwatch ( filePath ) ; this . watched . splice ( this . watched . indexOf ( filePath ) , 1 ) ; } ) ; this . extension . completer . citation . parseBibFile ( bibPath ) ; } else if ( this . watched . indexOf ( bibPath ) < 0 ) { this . extension . log ( `Adding .bib file ${ bibPath } to bib file watcher.` ) ; this . bibWatcher . add ( bibPath ) ; this . watched . push ( bibPath ) ; this . extension . completer . citation . parseBibFile ( bibPath ) ; } else { this . extension . log ( `.bib file ${ bibPath } is already being watched.` ) ; } } } forgetUnusedFiles ( filesToForget ) { for ( let i in filesToForget ) { let filePath = filesToForget [ i ] ; this . extension . log ( `Forget unused bib file: ${ filePath }` ) ; this . extension . completer . citation . forgetParsedBibItems ( filePath ) ; this . bibWatcher . unwatch ( filePath ) ; this . watched . splice ( this . watched . indexOf ( filePath ) , 1 ) ; } return ; } }