7 Commits

Author SHA1 Message Date
81d326c5c8 Filter out empty whitespace when considering new tags. 2018-04-16 04:29:19 -05:00
72c332fa45 Add start as an alias for add. 2018-04-09 09:53:00 -05:00
4a878026d8 Bump library version to compile under Nim 0.18 2018-04-02 14:44:26 -05:00
ee733957c6 Add current command. Reformat output of notes. 2017-09-19 10:37:28 -05:00
d75f5607c2 Fix edge case when no marks exist yet. 2017-05-16 12:32:59 -05:00
15708cebdf Add explicit dependency on isaac >= 0.1.2
Something depends on isaac 0.1.0, but that version doesn't compile on Nim 0.16
and above. Until the transitive dependancy is updated, ask for at least 0.1.2.
2017-02-21 11:18:12 -06:00
78a35b6478 Added list tags command. 2017-02-09 10:57:51 -06:00
4 changed files with 57 additions and 23 deletions

8
private/ptkutil.nim Normal file
View File

@ -0,0 +1,8 @@
template first*(a: openarray): auto = a[0]
template last*(a: openarray): auto = a[len(a)-1]
proc flatten*[T](a: seq[seq[T]]): seq[T] =
result = @[]
for subseq in a:
result.add(subseq)

65
ptk.nim
View File

@ -6,7 +6,7 @@
import algorithm, docopt, json, langutils, logging, os, nre, sequtils,
sets, strutils, tempfile, terminal, times, timeutils, uuids
import ptkutil
import private/ptkutil
type
Mark* = tuple[id: UUID, time: TimeInfo, summary: string, notes: string, tags: seq[string]]
@ -154,6 +154,9 @@ proc writeMarks(timeline: Timeline, indices: seq[int], includeNotes = false): vo
if prefix.len > longestPrefix: longestPrefix = prefix.len
let colWidth = 80
let notesPrefixLen = 4
for w in toWrite:
if w.mark.summary == STOP_MSG: continue
@ -174,7 +177,11 @@ proc writeMarks(timeline: Timeline, indices: seq[int], includeNotes = false): vo
writeLine(stdout, "")
if includeNotes and len(w.mark.notes.strip) > 0:
writeLine(stdout, spaces(longestPrefix) & w.mark.notes)
writeLine(stdout, "")
let wrappedNotes = wordWrap(s = w.mark.notes,
maxLineWidth = colWidth)
for line in splitLines(wrappedNotes):
writeLine(stdout, spaces(notesPrefixLen) & line)
writeLine(stdout, "")
proc formatMark(mark: Mark, nextMark = NO_MARK, timeFormat = ISO_TIME_FORMAT, includeNotes = false): string =
@ -190,13 +197,12 @@ proc formatMark(mark: Mark, nextMark = NO_MARK, timeFormat = ISO_TIME_FORMAT, in
# TODO: pick up here calculating the time between marks
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 - prefixLen)
let wrappedNotes = wordWrap(s = mark.notes, maxLineWidth = 80 - prefix.len)
for line in splitLines(wrappedNotes):
result &= "\x0D\x0A" & spaces(prefixLen) & line
result &= "\x0D\x0A" & spaces(prefix.len) & line
result &= "\x0D\x0A"
proc findById(marks: seq[Mark], id: string): int =
@ -338,8 +344,8 @@ when isMainModule:
let doc = """
Usage:
ptk init [options]
ptk add [options]
ptk add [options] <summary>
ptk (add | start) [options]
ptk (add | start) [options] <summary>
ptk resume [options] [<id>]
ptk amend [options] [<id>] [<summary>]
ptk merge <timeline> [<timeline>...]
@ -347,6 +353,8 @@ Usage:
ptk continue
ptk delete <id>
ptk (list | ls) [options]
ptk (list | ls) tags
ptk current
ptk sum-time --ids <ids>...
ptk sum-time [options] [<firstId>] [<lastId>]
ptk (-V | --version)
@ -379,7 +387,7 @@ Options:
let now = getLocalTime(getTime())
# Parse arguments
let args = docopt(doc, version = "ptk 0.8.0")
let args = docopt(doc, version = "ptk 0.11.3")
if args["--echo-args"]: echo $args
@ -464,7 +472,7 @@ Options:
time: if args["--time"]: parseTime($args["--time"]) else: now,
summary: STOP_MSG,
notes: args["--notes"] ?: "",
tags: (args["--tags"] ?: "").split({',', ';'}))
tags: (args["--tags"] ?: "").split({',', ';'}).filterIt(not it.isNilOrWhitespace))
timeline.marks.add(newMark)
@ -499,21 +507,22 @@ Options:
saveTimeline(timeline, timelineLocation)
if args["add"]:
if args["add"] or args["start"]:
var newMark: Mark = (
id: genUUID(),
time: if args["--time"]: parseTime($args["--time"]) else: now,
summary: args["<summary>"] ?: "",
notes: args["--notes"] ?: "",
tags: (args["--tags"] ?: "").split({',', ';'}))
tags: (args["--tags"] ?: "").split({',', ';'}).filterIt(not it.isNilOrWhitespace))
if args["--edit"]: edit(newMark)
let prevLastIdx = timeline.marks.getLastIndex()
timeline.marks.add(newMark)
timeline.writeMarks(
indices = @[prevLastIdx, timeline.marks.len - 1],
indices = if prevLastIdx < 0: @[0]
else: @[prevLastIdx, timeline.marks.len - 1],
includeNotes = args["--verbose"])
saveTimeline(timeline, timelineLocation)
@ -525,7 +534,9 @@ Options:
if args["<id>"]:
markToResumeIdx = timeline.marks.findById($args["<id>"])
if markToResumeIdx == -1: exitErr "Cannot find a mark matching " & $args["<id>"]
else: markToResumeIdx = timeline.marks.getLastIndex()
else:
markToResumeIdx = timeline.marks.getLastIndex()
if markToResumeIdx < 0: exitErr "No mark to resume."
var markToResume = timeline.marks[markToResumeIdx]
var newMark: Mark = (
@ -552,7 +563,9 @@ Options:
if args["<id>"]:
markIdx = timeline.marks.findById($args["<id>"])
if markIdx == -1: exitErr "Cannot find a mark matching " & $args["<id>"]
else: markIdx = timeline.marks.getLastIndex()
else:
markIdx = timeline.marks.getLastIndex()
if markIdx < 0: exitErr "No mark to amend."
var mark = timeline.marks[markIdx]
@ -590,11 +603,27 @@ Options:
if args["list"] or args["ls"]:
var selectedIndices = timeline.filterMarkIndices(args)
if args["tags"]:
timeline.writeMarks(
indices = selectedIndices,
includeNotes = args["--version"])
echo $(timeline.marks.mapIt(it.tags)
.flatten().deduplicate().sorted(system.cmp).join("\n"))
else:
var selectedIndices = timeline.filterMarkIndices(args)
timeline.writeMarks(
indices = selectedIndices,
includeNotes = args["--verbose"])
if args["current"]:
let idx = timeline.marks.len - 1
if timeline.marks[idx].summary == STOP_MSG:
echo "ptk: no current task"
else:
timeline.writeMarks(
indices = @[idx],
includeNotes = true)
if args["sum-time"]:

View File

@ -1,6 +1,6 @@
# Package
version = "0.8.0"
version = "0.11.3"
author = "Jonathan Bernard"
description = "Personal Time Keeper"
license = "MIT"
@ -8,5 +8,5 @@ bin = @["ptk"]
# Dependencies
requires @["nim >= 0.15.0", "docopt >= 0.6.4", "uuids", "langutils", "tempfile", "timeutils >= 0.2.0"]
requires @["nim >= 0.18.0", "docopt >= 0.6.4", "uuids", "langutils", "tempfile", "timeutils >= 0.2.2", "isaac >= 0.1.2"]

View File

@ -1,3 +0,0 @@
template first*(a: openarray): auto = a[0]
template last*(a: openarray): auto = a[len(a)-1]