diff --git a/README.md b/README.md index 8e0bbd0..be70149 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,9 @@ timesheet week [DATE] Show raw events for current week or week of DATE timesheet month [DATE] Show raw events for current month or month of DATE timesheet TASK Show raw events + archive Show archive tasks + archive TASK Add task to archive + unarch TASK Remove task from archive refresh Refresh worksheet file after manual edit (no command) Show running task and timer @@ -53,13 +56,12 @@ $ worktimer.scm report --- REPORT - Overall: 00:03:45 uberproject: 00:03:45 website: 00:03:45 programming: 00:02:34 design: 00:01:11 - + --- LAST STOPPED TASK uberproject/website/programming: [2014-04-18 09:47:04] - [2014-04-18 09:49:38] - 00:02:34 @@ -82,7 +84,7 @@ Overall: 00:03:45 uberproject: 00:03:45 website: 00:03:45 - + --- LAST STOPPED TASK uberproject/website/programming: [2014-04-18 09:47:04] - [2014-04-18 09:49:38] - 00:02:34 @@ -118,6 +120,11 @@ `timesheet`. Эта команда показывает выполнявшиеся задачи в таком виде, в котором они сохраняются на диск. Параметры команды такие-же, как у команды `report`. +Задачи (или подзадачи) можно отправлять в архив командой `archive [TASK]`. После этого +они перестают отображаться в отчете и в списке задач. Посмотреть список +архивированных задач можно командой `archive` без параметров. Деархивировать +задачу можно командой `unarch [TASK]`. + # Автодополнение для zsh Для включения автодополнения в zsh скопируйте файл `zsh-completion/_timer` в @@ -134,5 +141,3 @@ Автодополнение в bash включается так: $ . bash-completion/timer - -[![Join the chat at https://gitter.im/punzik/worktimer](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/punzik/worktimer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) diff --git a/README.org b/README.org index 6831bf6..a6e7819 100644 --- a/README.org +++ b/README.org @@ -27,6 +27,9 @@ timesheet week [DATE] Show raw events for current week or week of DATE timesheet month [DATE] Show raw events for current month or month of DATE timesheet TASK Show raw events + archive Show archive tasks + archive TASK Add task to archive + unarch TASK Remove task from archive refresh Refresh worksheet file after manual edit (no command) Show running task and timer #+end_src @@ -75,7 +78,7 @@ website: 00:03:45 programming: 00:02:34 design: 00:01:11 - + --- LAST STOPPED TASK uberproject/website/programming: [2014-04-18 09:47:04] - [2014-04-18 09:49:38] - 00:02:34 #+end_src @@ -100,7 +103,7 @@ Overall: 00:03:45 uberproject: 00:03:45 website: 00:03:45 - + --- LAST STOPPED TASK uberproject/website/programming: [2014-04-18 09:47:04] - [2014-04-18 09:49:38] - 00:02:34 #+end_src @@ -139,6 +142,11 @@ =timesheet=. Эта команда показывает выполнявшиеся задачи в таком виде, в котором они сохраняются на диск. Параметры команды такие-же, как у команды =report=. +Задачи (или подзадачи) можно отправлять в архив командой =archive [TASK]=. После этого +они перестают отображаться в отчете и в списке задач. Посмотреть список +архивированных задач можно командой =archive= без параметров. Деархивировать +задачу можно командой =unarch [TASK]=. + ** Автодополнение для zsh Для включения автодополнения в zsh скопируйте файл =zsh-completion/_timer= в =~/.zsh-completion/=, и добавте в файл =~/.zshrc= строки diff --git a/bash-completion/timer b/bash-completion/timer index 3761489..e90632e 100644 --- a/bash-completion/timer +++ b/bash-completion/timer @@ -1,16 +1,16 @@ _timer() { local uncomplete=${COMP_WORDS[COMP_CWORD]} - + case "$COMP_CWORD" in 1) # Commands - COMPREPLY=( $(compgen -W "start stop report deadline refresh timesheet help" -- $uncomplete) ) + COMPREPLY=( $(compgen -W "start stop report deadline archive unarch refresh timesheet help" -- $uncomplete) ) ;; 2) # Command argument 1 case "${COMP_WORDS[1]}" in - start) + start|archive) local tasklist=$(timer tasklist) COMPREPLY=( $(compgen -W "$tasklist" -- $uncomplete)) ;; @@ -22,6 +22,10 @@ _timer() local deadlist=$(timer deadlist) COMPREPLY=( $(compgen -W "set clear all $deadlist" -- $uncomplete)) ;; + unarch) + local archlist=$(timer archlist) + COMPREPLY=( $(compgen -W "$archlist" -- $uncomplete)) + ;; esac ;; 3) diff --git a/worktimer.scm b/worktimer.scm index 87bcdf5..038ad21 100755 --- a/worktimer.scm +++ b/worktimer.scm @@ -44,7 +44,7 @@ ;;; ========================= COMMON HELPER FUNCTIONS ========================== ;;; Find substring separated by ch-start and ch-end. -;;; (substring/find str ch-start ch-end [begin end]) +;;; (substring/find str ch-start ch-end [begin end]) ;;; If ch-start is #f, select substring from beginning of string. ;;; If ch-end is #f, select substring from ch-start to end string. (define (substring/find str ch-start ch-end . args) @@ -137,6 +137,16 @@ (loop (cdr a) (cdr b)) (string< (car a) (car b)))))))) +;;; Path prefixes with prefix? +(define (path-prefix? path prefix) + (let loop ((path path) + (prefix prefix)) + (if (null? prefix) #t + (if (null? path) #f + (if (string=? (car path) (car prefix)) + (loop (cdr path) (cdr prefix)) + #f))))) + ;;; Compare dates (define (datetime-utc a)) @@ -256,7 +266,7 @@ (let fold-path ((path (caar recs)) (spath "") (tasklist tasklist)) - (if (null? path) tasklist + (if (null? path) tasklist (let ((spath (string-append spath (if (zero? (string-length spath)) "" "/") @@ -273,6 +283,13 @@ (apply append (cons records more))) stringstring a))) + archives)) + ;;; Print timesheet -(define (print-timesheet timesheet deadlines) +(define (print-timesheet timesheet deadlines archives) (unless (null? deadlines) (format #t "--- DEADLINES\n") (print-deadlines deadlines)) + (unless (null? deadlines) + (format #t "--- ARCHIVE\n") + (print-archives archives)) (unless (null? timesheet) (format #t "--- TIMESHEET\n") (print-timerecords timesheet))) @@ -427,7 +470,7 @@ (set-car! (cdr tree) (add-duration (cadr tree) duration)) ;; Search next leaf corresponding to path item - (if (null? path) + (if (or (null? path)) project-tree (let ((item (find (lambda (i) (string= (car i) (car path))) @@ -449,7 +492,7 @@ (set-cdr! (cddr tree) (cons add-items (cdddr tree))) project-tree)))))) ;; END tree-add-duration! - + (let loop ((projects (list "Overall" (make-time 'time-duration 0 0) #f)) (timesheet timesheet)) (if (null? timesheet) @@ -459,8 +502,8 @@ (start (cadr task)) (duration (cadddr task))) (loop (tree-add-duration! projects path - (if duration duration - (date-difference (current-date) start))) + (if duration duration + (date-difference (current-date) start))) (cdr timesheet)))))) ;;; Add deadlines to report tree @@ -509,7 +552,7 @@ ;; no deadline (else "")))) - + (for-each (lambda (l) (walk l (+ level 2))) @@ -565,14 +608,21 @@ (if (string-ci= (car path) (car rep-path)) (loop (cdr path) (cdr rep-path)) #f)))))))))) - (values + (values (filter filter-lambda sheet) description))))) +;;; Remove archived tasks from sheet +(define (not-archived sheet archives) + (filter (lambda (x) + (not (path-in-archive? + (car x) + archives))) sheet)) + ;;; ================================ COMMANDS ================================== ;;; Start new task. Returns new sheet with started task or #f if nothing started. -(define (cmd-start-task sheet deadlines . params) +(define (cmd-start-task sheet deadlines archives . params) (let* ((last (last-task sheet)) (path (if (null? params) (if last (car last) #f) @@ -582,33 +632,35 @@ (begin (format (current-error-port) "Not specified task path. No tasks in the sheet.\n") - (values #f #f)) + (values #f #f #f)) (begin (stop-task last) (let-values (((sheet task) (new-task sheet path))) (format #t "--- NEW TASK RUN\n") (print-timerecord task) - (values sheet deadlines)))))) + (values sheet deadlines archives)))))) ;;; Stop a running task. Returns new sheet or #f if nothing to stop. -(define (cmd-stop-task sheet deadlines . params) +(define (cmd-stop-task sheet deadlines archives . params) (let ((last (last-task sheet))) (if (stop-task last) (begin (format #t "--- STOP TASK\n") (print-timerecord last) - (values sheet deadlines)) + (values sheet deadlines archives)) (begin (format (current-error-port) "Nothing to stop\n") - (values #f #f))))) + (values #f #f #f))))) ;;; Print report -(define (cmd-report sheet deadlines . params) +(define (cmd-report sheet deadlines archives . params) (format #t "--- REPORT") (let ((qualis (nth-maybe 0 params)) (range (nth-maybe 1 params))) (let-values (((sheet description) - (filter-sheet sheet qualis range))) + (filter-sheet + (not-archived sheet archives) + qualis range))) (when (not (null? description)) (display ". ") (display description)) @@ -622,27 +674,38 @@ (format #t "\n--- ~a TASK\n" (if (caddr last) "LAST STOPPED" "RUNNING")) (print-timerecord last (current-date)))) - (values #f #f)) + (values #f #f #f)) ;;; Print all tasks -(define (cmd-tasklist sheet deadlines . unused) - (format #t "~{~a ~}\n" (record-path-list sheet deadlines)) - (values #f #f)) +(define (cmd-tasklist sheet deadlines archives . unused) + (format #t "~{~a ~}\n" (record-path-list + (not-archived sheet archives) + deadlines)) + (values #f #f #f)) ;;; Print deadlines -(define (cmd-deadlist sheet deadlines . unused) +(define (cmd-deadlist sheet deadlines archives . unused) (format #t "~{~a ~}\n" (record-name-list deadlines)) - (values #f #f)) + (values #f #f #f)) + +;;; Print archive +(define (cmd-archlist sheet deadlines archives . unused) + (format #t "~{~a ~}\n" + (remove-dup + (sort + (map (lambda (x) (path->string x)) archives) + stringstring (car last))))) - (values #f #f)) + (values #f #f #f)) ;;; Deadlines -(define (cmd-deadline sheet deadlines . args) +(define (cmd-deadline sheet deadlines archives . args) (let ((deadlines (let* ((arg0 (if (null? args) #f (car args))) (arg1 (if (and arg0 (not (null? (cdr args)))) (cadr args) #f)) @@ -692,7 +755,7 @@ ((equal? arg0 "all") (print-deadlines deadlines) #f) - + ;; Show deadline for task (else (let ((task (if arg0 @@ -712,28 +775,54 @@ deadlines)) #f))))) (if deadlines - (values sheet deadlines) - (values #f #f)))) + (values sheet deadlines archives) + (values #f #f #f)))) ;;; Events -(define (cmd-timesheet sheet deadlines . params) +(define (cmd-timesheet sheet deadlines archives . params) (format #t "--- TIMESHEET") (let ((qualis (nth-maybe 0 params)) (range (nth-maybe 1 params))) (let-values (((sheet description) - (filter-sheet sheet qualis range))) + (filter-sheet + (not-archived sheet archives) + qualis range))) (when (not (null? description)) (display ". ") (display description)) (newline) (print-timerecords sheet))) - (values #f #f)) + (values #f #f #f)) + +;;; Archive +(define (cmd-archive sheet deadlines archives . params) + (let ((task-str (nth-maybe 0 params))) + (if (null? task-str) + (begin + (format #t "--- ARCHIVE\n") + (print-archives archives) + (values #f #f #f)) + (values sheet + deadlines + (cons (path-split task-str) archives))))) + +;;; Unarchive +(define (cmd-unarch sheet deadlines archives . params) + (let ((task-str (nth-maybe 0 params))) + (if (null? task-str) + (values #f #f #f) + (let ((task (path-split task-str))) + (values sheet + deadlines + (fold (lambda (p a) + (if (equal? p task) a + (cons p a))) '() archives)))))) ;;; ================================ MAIN FUNCTION ================================== (define (main cmdl) (let ((command (cdr cmdl))) - (let-values (((sheet deadlines) (read-timesheet ts-file))) + (let-values (((sheet deadlines archives) (read-timesheet ts-file))) (if (null? command) ;; Show running task @@ -758,27 +847,30 @@ (date/time->string deadtime)) ")")) "")))) - + (format #t "NO TASKS\n"))) ;; Else run command (let ((param (cdr command)) (command (car command))) (let-values - (((sheet' deadlines') + (((sheet' deadlines' archives') (apply (cond ((string= command "start") cmd-start-task) ((string= command "stop") cmd-stop-task) ((string= command "report") cmd-report) - ((string= command "refresh") (lambda (s d . p) (values s d))) + ((string= command "refresh") (lambda (s d a . p) (values s d a))) ((string= command "deadline") cmd-deadline) ((string= command "timesheet") cmd-timesheet) + ((string= command "archive") cmd-archive) + ((string= command "unarch") cmd-unarch) ;; Service commands ((string= command "tasklist") cmd-tasklist) ((string= command "deadlist") cmd-deadlist) + ((string= command "archlist") cmd-archlist) ((string= command "lasttask") cmd-lasttask) - + ;; ----------------------- Show usage ------------------------- ;; (else (with-output-to-port (current-error-port) @@ -801,21 +893,24 @@ (format #t " timesheet week [DATE] Show raw events for current week or week of DATE\n") (format #t " timesheet month [DATE] Show raw events for current month or month of DATE\n") (format #t " timesheet TASK Show raw events\n") + (format #t " archive Show archive tasks\n") + (format #t " archive TASK Add task to archive\n") + (format #t " unarch TASK Remove task from archive\n") (format #t " refresh Refresh worksheet file after manual edit\n") (format #t " (no command) Show running task and timer\n\n") (format #t "DATE format: YYYY-mm-dd\n") (format #t "TIME format: HH:MM:SS\n") (newline))) - (lambda (s d . p) (values #f #f)))) - (cons* sheet deadlines param)))) - + (lambda (s d a . p) (values #f #f #f)))) + (cons* sheet deadlines archives param)))) + ;; ----------------------- Save new sheet ------------------------- ;; (when (and (list? sheet') (not (null? sheet'))) (with-output-to-file ts-file (lambda () - (print-timesheet sheet' deadlines')))))))))) + (print-timesheet sheet' deadlines' archives')))))))))) ;;; JUST DO IT! (main (command-line)) diff --git a/zsh-completion/_timer b/zsh-completion/_timer index 0f83fea..6f72a83 100644 --- a/zsh-completion/_timer +++ b/zsh-completion/_timer @@ -3,23 +3,23 @@ _timer() { typeset -A opt_args - + _arguments \ '1: :->command' \ '2: :->arg1' \ '3: :->arg2' \ '4: :->arg3' - + case "$state" in (command) # Commands - _arguments '1:commands:(start stop report deadline refresh timesheet help)' + _arguments '1:commands:(start stop report deadline archive unarch refresh timesheet help)' ;; (arg1) # Command argument 1 case $words[2] in - (start) + (start|archive) compadd $(timer tasklist) ;; (report|timesheet) @@ -28,6 +28,8 @@ _timer() { (deadline) compadd set clear all $(timer deadlist) ;; + (unarch) + compadd $(timer archlist) esac ;; @@ -67,7 +69,7 @@ _timer() { compadd $(date +"%Y-%m-%d") fi ;; - esac + esac } _timer "$@"