|
|
|
@ -3,10 +3,10 @@
|
|
|
|
|
##
|
|
|
|
|
## Simple time keeping CLI
|
|
|
|
|
|
|
|
|
|
import algorithm, docopt, json, langutils, logging, os, nre, sequtils,
|
|
|
|
|
sets, strutils, tempfile, terminal, times, uuids
|
|
|
|
|
import algorithm, docopt, json, langutils, logging, os, nre, std/wordwrap,
|
|
|
|
|
sequtils, sets, strutils, tempfile, terminal, times, uuids
|
|
|
|
|
|
|
|
|
|
import timeutils except `-`;
|
|
|
|
|
import timeutils except `-`
|
|
|
|
|
|
|
|
|
|
import private/util
|
|
|
|
|
import private/api
|
|
|
|
@ -98,7 +98,7 @@ proc writeMarks(timeline: Timeline, indices: seq[int], includeNotes = false): vo
|
|
|
|
|
|
|
|
|
|
if includeNotes and len(w.mark.notes.strip) > 0:
|
|
|
|
|
writeLine(stdout, "")
|
|
|
|
|
let wrappedNotes = wordWrap(s = w.mark.notes,
|
|
|
|
|
let wrappedNotes = wrapWords(s = w.mark.notes,
|
|
|
|
|
maxLineWidth = colWidth)
|
|
|
|
|
for line in splitLines(wrappedNotes):
|
|
|
|
|
writeLine(stdout, spaces(notesPrefixLen) & line)
|
|
|
|
@ -152,17 +152,18 @@ proc edit(mark: Mark): Mark =
|
|
|
|
|
discard os.execShellCmd "$EDITOR " & tempFileName & " </dev/tty >/dev/tty"
|
|
|
|
|
|
|
|
|
|
var markPart = Time
|
|
|
|
|
var notes: seq[string] = @[]
|
|
|
|
|
|
|
|
|
|
for line in lines tempFileName:
|
|
|
|
|
if strip(line)[0] == '#': continue
|
|
|
|
|
if strip(line).len > 0 and strip(line)[0] == '#': continue
|
|
|
|
|
elif markPart == Time: result.time = parseTime(line); markPart = Summary
|
|
|
|
|
elif markPart == Summary: result.summary = line; markPart = Tags
|
|
|
|
|
elif markPart == Tags:
|
|
|
|
|
result.tags = line.split({',', ';'});
|
|
|
|
|
result.notes = ""
|
|
|
|
|
markPart = Notes
|
|
|
|
|
else: result.notes &= line & "\x0D\x0A"
|
|
|
|
|
else: notes.add(line)
|
|
|
|
|
|
|
|
|
|
result.notes = notes.join("\n")
|
|
|
|
|
finally: close(tempFile)
|
|
|
|
|
|
|
|
|
|
proc filterMarkIndices(timeline: Timeline, args: Table[string, Value]): seq[int] =
|
|
|
|
@ -171,15 +172,15 @@ proc filterMarkIndices(timeline: Timeline, args: Table[string, Value]): seq[int]
|
|
|
|
|
|
|
|
|
|
let marks = timeline.marks
|
|
|
|
|
let now = getTime().local
|
|
|
|
|
let allIndices = sequtils.toSeq(0..<marks.len).filterIt(marks[it].summary != STOP_MSG).toSet
|
|
|
|
|
let allIndices = sequtils.toSeq(0..<marks.len).filterIt(marks[it].summary != STOP_MSG).toHashSet
|
|
|
|
|
let union = args["--or"]
|
|
|
|
|
|
|
|
|
|
var selected =
|
|
|
|
|
if union: initSet[int]()
|
|
|
|
|
if union: initHashSet[int]()
|
|
|
|
|
else: allIndices
|
|
|
|
|
|
|
|
|
|
template filterMarks(curSet: HashSet[int], pred: untyped): untyped =
|
|
|
|
|
var res: HashSet[int] = initSet[int]()
|
|
|
|
|
var res: HashSet[int] = initHashSet[int]()
|
|
|
|
|
if union:
|
|
|
|
|
for mIdx {.inject.} in allIndices:
|
|
|
|
|
if pred: res.incl(mIdx)
|
|
|
|
@ -310,11 +311,11 @@ Options:
|
|
|
|
|
".ptkrc", $getEnv("PTKRC"), $getEnv("HOME") & "/.ptkrc"]
|
|
|
|
|
|
|
|
|
|
var ptkrcFilename: string =
|
|
|
|
|
foldl(ptkrcLocations, if len(a) > 0: a elif existsFile(b): b else: "")
|
|
|
|
|
foldl(ptkrcLocations, if len(a) > 0: a elif fileExists(b): b else: "")
|
|
|
|
|
|
|
|
|
|
var cfg: JsonNode
|
|
|
|
|
var cfgFile: File
|
|
|
|
|
if not existsFile(ptkrcFilename):
|
|
|
|
|
if not fileExists(ptkrcFilename):
|
|
|
|
|
warn "ptk: could not find .ptkrc file."
|
|
|
|
|
ptkrcFilename = $getEnv("HOME") & "/.ptkrc"
|
|
|
|
|
try:
|
|
|
|
@ -336,7 +337,7 @@ Options:
|
|
|
|
|
"ptk.log.json"]
|
|
|
|
|
|
|
|
|
|
var timelineLocation =
|
|
|
|
|
foldl(timelineLocations, if len(a) > 0: a elif existsFile(b): b else: "")
|
|
|
|
|
foldl(timelineLocations, if len(a) > 0: a elif fileExists(b): b else: "")
|
|
|
|
|
|
|
|
|
|
# Execute commands
|
|
|
|
|
if args["init"]:
|
|
|
|
@ -347,7 +348,7 @@ Options:
|
|
|
|
|
let filesToMerge = args["<timeline>"]
|
|
|
|
|
let timelines = filesToMerge.mapIt(loadTimeline(it))
|
|
|
|
|
|
|
|
|
|
let names = timelines.mapIt(it.name).toSet
|
|
|
|
|
let names = timelines.mapIt(it.name).toHashSet
|
|
|
|
|
let mergedName = sequtils.toSeq(names.items).foldl(a & " + " & b)
|
|
|
|
|
var merged: Timeline = (
|
|
|
|
|
name: mergedName,
|
|
|
|
@ -385,7 +386,7 @@ Options:
|
|
|
|
|
time: if args["--time"]: parseTime($args["--time"]) else: now,
|
|
|
|
|
summary: STOP_MSG,
|
|
|
|
|
notes: args["--notes"] ?: "",
|
|
|
|
|
tags: (args["--tags"] ?: "").split({',', ';'}).filterIt(not it.isNilOrWhitespace))
|
|
|
|
|
tags: (args["--tags"] ?: "").split({',', ';'}).filterIt(not it.isEmptyOrWhitespace))
|
|
|
|
|
|
|
|
|
|
timeline.marks.add(newMark)
|
|
|
|
|
|
|
|
|
@ -427,7 +428,7 @@ Options:
|
|
|
|
|
time: if args["--time"]: parseTime($args["--time"]) else: now,
|
|
|
|
|
summary: args["<summary>"] ?: "",
|
|
|
|
|
notes: args["--notes"] ?: "",
|
|
|
|
|
tags: (args["--tags"] ?: "").split({',', ';'}).filterIt(not it.isNilOrWhitespace))
|
|
|
|
|
tags: (args["--tags"] ?: "").split({',', ';'}).filterIt(not it.isEmptyOrWhitespace))
|
|
|
|
|
|
|
|
|
|
if args["--edit"]: newMark = edit(newMark)
|
|
|
|
|
|
|
|
|
|