import * as _ from 'lodash' ; import * as path from 'path' ; import * as vscode from 'vscode' ; import Config from './config' ; import Consts from './consts' ; import Document from './todo/document' ; import ItemFile from './views/items/item' ; import ItemTodo from './views/items/todo' ; import StatusbarTimer from './statusbars/timer' ; import Utils from './utils' ; import ViewEmbedded from './views/embedded' ; import ViewFiles from './views/files' ; const callTodosMethodOptions = { checkValidity : false , filter : _ . identity , method : undefined , args : [ ] , errors : { invalid : 'Only todos can perform this action' , filtered : 'This todo cannot perform this action' } } ; async function callTodosMethod ( options ? ) { options = _ . isString ( options ) ? { method : options } : options ; options = _ . merge ( { } , callTodosMethodOptions , options ) ; const textEditor = vscode . window . activeTextEditor , doc = new Document ( textEditor ) ; if ( ! doc . isSupported ( ) ) return ; const lines = _ . uniq ( _ . flatten ( textEditor . selections . map ( selection => _ . range ( selection . start . line , selection . end . line + 1 ) ) ) ) , todos = _ . filter ( lines . map ( line => doc . getTodoAt ( line , options . checkValidity ) ) ) ; if ( todos . length !== lines . length ) vscode . window . showErrorMessage ( options . errors . invalid ) ; if ( ! todos . length ) return ; const todosFiltered = todos . filter ( options . filter ) ; if ( todosFiltered . length !== todos . length ) vscode . window . showErrorMessage ( options . errors . filtered ) ; if ( ! todosFiltered . length ) return ; todosFiltered . map ( todo => todo [ options . method ] ( ... options . args ) ) ; const edits = _ . filter ( _ . flattenDeep ( todosFiltered . map ( todo => todo [ 'makeEdit' ] ( ) ) ) ) ; if ( ! edits . length ) return ; const selectionsTagIndexes = textEditor . selections . map ( selection => { const line = textEditor . document . lineAt ( selection . start . line ) ; return line . text . indexOf ( Consts . symbols . tag ) ; } ) ; await Utils . editor . edits . apply ( textEditor , edits ) ; textEditor . selections = textEditor . selections . map ( ( selection , index ) => { if ( selectionsTagIndexes [ index ] >= 0 ) return selection ; const line = textEditor . document . lineAt ( selection . start . line ) ; if ( selection . start . character !== line . text . length ) return selection ; const tagIndex = line . text . indexOf ( Consts . symbols . tag ) ; if ( tagIndex < 0 ) return selection ; const position = new vscode . Position ( selection . start . line , tagIndex ) ; return new vscode . Selection ( position , position ) ; } ) ; } async function open ( filePath ? , lineNumber ? ) { filePath = _ . isString ( filePath ) ? filePath : undefined ; lineNumber = _ . isNumber ( lineNumber ) ? lineNumber : undefined ; if ( filePath ) { return Utils . file . open ( filePath , true , lineNumber ) ; } else { const config = Config . get ( ) , { activeTextEditor } = vscode . window , editorPath = activeTextEditor && activeTextEditor . document . uri . fsPath , rootPath = Utils . folder . getRootPath ( editorPath ) ; if ( ! rootPath ) return vscode . window . showErrorMessage ( 'You have to open a project before being able to open its todo file' ) ; const projectPath = ( ( await Utils . folder . getWrapperPathOf ( rootPath , editorPath || rootPath , config . file . name ) ) || rootPath ) as string , todo = Utils . todo . get ( projectPath ) ; if ( ! _ . isUndefined ( todo ) ) { return Utils . file . open ( todo . path , true , lineNumber ) ; } else { const defaultPath = path . join ( projectPath , config . file . name ) ; await Utils . file . make ( defaultPath , config . file . defaultContent ) ; return Utils . file . open ( defaultPath ) ; } } } async function openEmbedded ( ) { await Utils . embedded . initProvider ( ) ; const config = Config . get ( ) , todos = await Utils . embedded . provider . get ( undefined , config . embedded . file . groupByRoot , config . embedded . file . groupByType , config . embedded . file . groupByFile ) , content = Utils . embedded . provider . renderTodos ( todos ) ; if ( ! content ) return vscode . window . showInformationMessage ( 'No embedded todos found' ) ; Utils . editor . open ( content ) ; } function toggleBox ( ) { return callTodosMethod ( 'toggleBox' ) ; } function toggleDone ( ) { return callTodosMethod ( 'toggleDone' ) ; } function toggleCancelled ( ) { return callTodosMethod ( 'toggleCancelled' ) ; } function toggleStart ( ) { return callTodosMethod ( { checkValidity : true , filter : todo => todo . isBox ( ) , method : 'toggleStart' , errors : { invalid : 'Only todos can be started' , filtered : 'Only not done/cancelled todos can be started' } } ) ; } function toggleTimer ( ) { Consts . timer = ! Consts . timer ; StatusbarTimer . updateVisibility ( ) ; StatusbarTimer . updateTimer ( ) ; vscode . window . showInformationMessage ( `Timer ${ Consts . timer ? 'enabled' : 'disabled' }` ) ; } function archive ( ) { const textEditor = vscode . window . activeTextEditor , doc = new Document ( textEditor ) ; if ( ! doc . isSupported ( ) ) return ; Utils . archive . run ( doc ) ; } function viewOpenFile ( file ) { Utils . file . open ( file . resourceUri . fsPath , true , 0 ) ; } function viewRevealTodo ( todo ) { if ( todo . obj . todo ) { const startIndex = todo . obj . rawLine . indexOf ( todo . obj . todo ) , endIndex = startIndex + todo . obj . todo . length ; Utils . file . open ( todo . obj . filePath , true , todo . obj . lineNr , startIndex , endIndex ) ; } else { Utils . file . open ( todo . obj . filePath , true , todo . obj . lineNr ) ; } } function viewFilesOpen ( ) { open ( ) ; } function viewFilesCollapse ( ) { ViewFiles . expanded = false ; vscode . commands . executeCommand ( 'setContext' , 'todo-files-expanded' , false ) ; ViewFiles . refresh ( true ) ; } function viewFilesExpand ( ) { ViewFiles . expanded = true ; vscode . commands . executeCommand ( 'setContext' , 'todo-files-expanded' , true ) ; ViewFiles . refresh ( true ) ; } function viewEmbeddedCollapse ( ) { ViewEmbedded . expanded = false ; vscode . commands . executeCommand ( 'setContext' , 'todo-embedded-expanded' , false ) ; ViewEmbedded . refresh ( true ) ; } function viewEmbeddedExpand ( ) { ViewEmbedded . expanded = true ; vscode . commands . executeCommand ( 'setContext' , 'todo-embedded-expanded' , true ) ; ViewEmbedded . refresh ( true ) ; } async function viewEmbeddedFilter ( ) { const filter = await vscode . window . showInputBox ( { placeHolder : 'Filter string...' } ) ; if ( ! filter || ViewEmbedded . filter === filter ) return ; ViewEmbedded . filter = filter ; vscode . commands . executeCommand ( 'setContext' , 'todo-embedded-filtered' , true ) ; ViewEmbedded . refresh ( ) ; } const embeddedFilter = viewEmbeddedFilter ; function viewEmbeddedClearFilter ( ) { ViewEmbedded . filter = false ; vscode . commands . executeCommand ( 'setContext' , 'todo-embedded-filtered' , false ) ; ViewEmbedded . refresh ( ) ; } const embeddedClearFilter = viewEmbeddedClearFilter ; function viewEmbeddedToggleAllFiles ( force = ! ViewEmbedded . all ) { ViewEmbedded . all = force ; vscode . commands . executeCommand ( 'setContext' , 'todo-embedded-all' , force ) ; ViewEmbedded . refresh ( ) ; } function viewEmbeddedShowAllFiles ( ) { viewEmbeddedToggleAllFiles ( true ) ; } function viewEmbeddedShowActiveFile ( ) { viewEmbeddedToggleAllFiles ( false ) ; } export { open , openEmbedded , toggleBox , toggleDone , toggleCancelled , toggleStart , toggleTimer , archive , viewOpenFile , viewRevealTodo , viewFilesOpen , viewFilesCollapse , viewFilesExpand , viewEmbeddedCollapse , viewEmbeddedExpand , viewEmbeddedFilter , embeddedFilter , viewEmbeddedClearFilter , embeddedClearFilter , viewEmbeddedToggleAllFiles , viewEmbeddedShowAllFiles , viewEmbeddedShowActiveFile } ; export { toggleBox as editorToggleBox , toggleDone as editorToggleDone , toggleCancelled as editorToggleCancelled , toggleStart as editorToggleStart , archive as editorArchive } ;