diff --git a/.gitignore b/.gitignore index 3481463..c91ba74 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ nimcache/ ptk +*.sw? diff --git a/ptk.nim b/ptk.nim index e8fbbe0..f08e030 100644 --- a/ptk.nim +++ b/ptk.nim @@ -4,12 +4,15 @@ ## Simple time keeping CLI import algorithm, docopt, json, langutils, logging, os, sequtils, strutils, - tempfile, times, uuids + tempfile, terminal, times, timeutils, uuids +import ptkutil type Mark* = tuple[id: UUID, time: TimeInfo, summary: string, notes: string] Timeline* = tuple[name: string, marks: seq[Mark]] +const STOP_MSG = "STOP" + let NO_MARK: Mark = ( id: parseUUID("00000000-0000-0000-0000-000000000000"), time: getLocalTime(getTime()), @@ -28,7 +31,6 @@ proc exitErr(msg: string): void = fatal "ptk: " & msg quit(QuitFailure) - proc parseTime(timeStr: string): TimeInfo = for fmt in TIME_FORMATS: try: return parse(timeStr, fmt) @@ -73,25 +75,80 @@ proc saveTimeline(timeline: Timeline, location: string): void = except: raise newException(IOError, "unable to save changes to " & location) finally: close(timelineFile) +proc flexFormat(i: TimeInterval): string = + let fmt = + if i > 1.days: "d'd' H'h' m'm'" + elif i >= 1.hours: "H'h' m'm'" + elif i >= 1.minutes: "m'm' s's'" + else: "s's'" + + return i.format(fmt) + +proc writeMarks(marks: seq[Mark], includeNotes = false): void = + let now = getLocalTime(getTime()) + + let timeFormat = + if now - marks.first.time > 1.years: "yyyy-MM-dd HH:mm" + elif now - marks.first.time > 7.days: "MMM dd HH:mm" + elif now - marks.first.time > 1.days: "ddd HH:mm" + else: "HH:mm" + + var intervals: seq[TimeInterval] = @[] + for i in 0.. longestPrefix: longestPrefix = prefix.len + + for i in 0.. 0: + writeLine(stdout, spaces(longestPrefix) & mark.notes) + writeLine(stdout, "") + proc formatMark(mark: Mark, nextMark = NO_MARK, timeFormat = ISO_TIME_FORMAT, includeNotes = false): string = let nextTime = if nextMark == NO_MARK: getLocalTime(getTime()) - else: mark.time + else: nextMark.time + let duration = (nextTime - mark.time).flexFormat # TODO: pick up here calculating the time between marks - let prefix = ($mark.id)[0..<8] & " " & mark.time.format(timeFormat) & " " + let prefix = ($mark.id)[0..<8] & " " & mark.time.format(timeFormat) & " (" & duration & ") -- " + let prefixLen = len(($mark.id)[0..<8] & " " & mark.time.format(timeFormat) & " (" & duration & ") -- ") + result = prefix & mark.summary if includeNotes and len(mark.notes.strip()) > 0: - let wrappedNotes = wordWrap(s = mark.notes, maxLineWidth = 80 - len(prefix)) + let wrappedNotes = wordWrap(s = mark.notes, maxLineWidth = 80 - prefixLen) for line in splitLines(wrappedNotes): - result &= "\x0D\x0A" & spaces(len(prefix)) & line + result &= "\x0D\x0A" & spaces(prefixLen) & line result &= "\x0D\x0A" -proc findMarkById(timeline: Timeline, id: string): auto = +proc findById(marks: seq[Mark], id: string): auto = var idx = 0 - for mark in timeline.marks: + for mark in marks: if startsWith($mark.id, id): return (mark, idx) inc(idx) @@ -103,7 +160,7 @@ proc doInit(timelineLocation: string): void = let name = stdin.readLine() let timeline = %* - { "name": if name.len > 0: name else: "New Timeline", + { "name": if name.strip.len > 0: name.strip else: "New Timeline", "marks": [] } #"createdAt": getLocalTime().format("yyyy-MM-dd'T'HH:mm:ss") } @@ -152,29 +209,40 @@ Usage: ptk init [options] ptk add [options] ptk add [options] - ptk list [options] [] [] ptk ammend [options] [] + ptk stop [options] + ptk continue ptk delete + ptk list [options] + ptk sum-time --ids ... + ptk sum-time [options] [] [] ptk (-V | --version) ptk (-h | --help) Options: - -f --file Use the given time keeper file. + -f --file Use the given timeline file. -c --config Use as configuration for the CLI. -t --time