import * as path from 'path' ; import * as fs from 'fs' ; import { WorkspaceFolder , Position , Range , TextEditor } from 'vscode' ; import { EOL } from 'os' ; import { CsvEntry } from '../model' ; param s export const removeTrailingSlash = ( s ) : string => s . replace ( /\/$|\\$/ , '' ) ; param s export const removeLeadingSlash = ( s ) : string => s . replace ( /^\/|^\\/ , '' ) ; param s export const removeLeadingAndTrailingSlash = ( s ) : string => removeLeadingSlash ( removeTrailingSlash ( s ) ) ; param dir param base returns export const isProperSubpathOf = ( dir , base ) : boolean => { const relative = path . relative ( base , dir ) ; return ! ! relative && ! relative . startsWith ( '..' ) && ! path . isAbsolute ( relative ) ; } ; param folders export const getWorkspaceFolder = ( folders , activeTextEditor ? ) : string => { if ( ! folders || ! folders [ 0 ] || ! folders [ 0 ] . uri || ! folders [ 0 ] . uri . fsPath ) { const currentFile = activeTextEditor ?. document . fileName ; return currentFile ? path . dirname ( currentFile ) : '' ; } return folders [ 0 ] . uri . fsPath ; } ; param workspaceRoot param filename export const toAbsolutePath = ( workspaceRoot , filename ) : string => { const harmonizedFileName = filename . replace ( /\\/g , '/' ) ; return path . resolve ( workspaceRoot , removeLeadingSlash ( harmonizedFileName ) ) ; } ; param pathToFile param range export const getFileContentForRange = ( pathToFile , range ) : string => { let fileContent = '' ; try { fileContent = fs . readFileSync ( pathToFile , 'utf8' ) ; } catch ( error ) { console . log ( 'Error reading file' , pathToFile , error ) ; } const fileContentLines = fileContent . split ( EOL ) ; return fileContentLines . slice ( range . start . line , range . end . line ) . join ( EOL ) ; } ; param input export const escapeDoubleQuotesForCsv = ( input ) : string => { return input . replace ( /"/g , '""' ) ; } ; param input export const escapeEndOfLineForCsv = ( input ) : string => { return input . replace ( /\n/g , '\\n' ) ; } ; param input export const unescapeEndOfLineFromCsv = ( input ) : string => { return input . replace ( /\\n/g , '\n' ) ; } ; param input export const startLineNumberFromStringDefinition = ( input ) : number => { const matches = input . match ( /^\d+/s ) ; return matches ? Number ( matches [ 0 ] ) : 0 ; } ; param input export const startPositionNumberFromStringDefinition = ( input ) : number => { const matches = input . match ( /(?<=:)\d+/s ) ; return matches ? Number ( matches [ 0 ] ) : 0 ; } ; param input export const endLineNumberFromStringDefinition = ( input ) : number => { const matches = input . match ( /(?<=-)\d+/s ) ; return matches ? Number ( matches [ 0 ] ) : 0 ; } ; param input export const endPositionNumberFromStringDefinition = ( input ) : number => { const matches = input . match ( /(?<=:)\d+/g ) ; return matches && matches [ 1 ] ? Number ( matches [ 1 ] ) : 0 ; } ; param input export const rangeFromStringDefinition = ( input , offset = 0 ) : Range => { const startLine = startLineNumberFromStringDefinition ( input ) - 1 ; const startPosition = startPositionNumberFromStringDefinition ( input ) ; const endLine = endLineNumberFromStringDefinition ( input ) - 1 + offset ; const endPosition = endPositionNumberFromStringDefinition ( input ) ; return new Range ( new Position ( startLine > 0 ? startLine : 0 , startPosition > 0 ? startPosition : 0 ) , new Position ( endLine > 0 ? endLine : 0 , endPosition > 0 ? endPosition : 0 ) ) ; } ; param input export const rangesFromStringDefinition = ( input , offset = 0 ) : Range [ ] => { return splitStringDefinition ( input ) . map ( ( str ) => rangeFromStringDefinition ( str , offset ) ) ; } ; param input export const splitStringDefinition = ( input ) : string [ ] => input . split ( '|' ) . map ( ( str ) => str . trim ( ) ) ; param localA param localB export const sortLineSelections = ( localA , localB ) : number => startLineNumberFromStringDefinition ( localA ) - startLineNumberFromStringDefinition ( localB ) ; param a param b see https export const sortCsvEntryForLines = ( a , b ) : number => { const aSplit = splitStringDefinition ( a . lines ) ; const bSplit = splitStringDefinition ( b . lines ) ; aSplit . sort ( sortLineSelections ) ; bSplit . sort ( sortLineSelections ) ; const lineASplitStart = startLineNumberFromStringDefinition ( aSplit [ 0 ] ) ; const lineASplitEnd = endLineNumberFromStringDefinition ( aSplit [ 0 ] ) ; const lineBSplitStart = startLineNumberFromStringDefinition ( bSplit [ 0 ] ) ; const lineBSplitEnd = endLineNumberFromStringDefinition ( bSplit [ 0 ] ) ; if ( lineASplitStart <= lineBSplitStart && lineASplitEnd >= lineBSplitEnd ) { return - 1 ; } return lineASplitStart - lineBSplitStart ; } ; param reviewFilePath return export const getBackupFilename = ( reviewFilePath ) : string => { const timeStamp = new Date ( ) . toISOString ( ) . replace ( /[:,\.]/g , '-' ) ; return path . join ( path . dirname ( reviewFilePath ) , path . parse ( reviewFilePath ) . name + '-' + timeStamp + '.bak' ) ; } ; param workspaceRoot param filename export const standardizeFilename = ( workspaceRoot , filename ) : string => { return filename . replace ( workspaceRoot , '' ) ; } ;