Compare commits

..

3 Commits
4.4.3 ... 4.6.0

4 changed files with 56 additions and 19 deletions

View File

@ -12,4 +12,4 @@ bin = @["pit", "pit_api"]
# Dependencies
requires @[ "nim >= 0.19.0", "cliutils 0.6.1", "docopt 0.6.8", "jester 0.4.1",
"langutils >= 0.4.0", "timeutils 0.3.0", "uuids 0.1.10" ]
"langutils >= 0.4.0", "timeutils 0.4.0", "uuids 0.1.10" ]

View File

@ -5,7 +5,7 @@ import cliutils, docopt, json, logging, options, os, ospaths, sequtils,
tables, terminal, times, timeutils, unicode, uuids
from nre import re
import strutils except capitalize, toUpper, toLower
import strutils except capitalize, strip, toUpper, toLower
import pitpkg/private/libpit
export libpit
@ -76,11 +76,21 @@ proc formatSectionIssue(ctx: CliContext, issue: Issue, width: int, indent = "",
var showDetails = not issue.details.isNilOrWhitespace and verbose
# Wrap and write the summary.
var wrappedSummary = (" ".repeat(5) & issue.summary).wordWrap(width - 2).indent(2 + indent.len)
wrappedSummary = wrappedSummary[(6 + indent.len)..^1]
var prefixLen = 0
var summaryIndentLen = indent.len + 7
if issue.hasProp("delegated-to"): prefixLen += issue["delegated-to"].len + 2 # space for the ':' and ' '
# Wrap and write the summary.
var wrappedSummary = ("+".repeat(prefixLen) & issue.summary).wordWrap(width - summaryIndentLen).indent(summaryIndentLen)
wrappedSummary = wrappedSummary[(prefixLen + summaryIndentLen)..^1]
result = (indent & ($issue.id)[0..<6]).withColor(fgBlack, true) & " "
if issue.hasProp("delegated-to"):
result &= (issue["delegated-to"] & ": ").withColor(fgGreen)
result = (indent & ($issue.id)[0..<6]).withColor(fgBlack, true)
result &= wrappedSummary.withColor(fgWhite)
if issue.tags.len > 0:
@ -92,9 +102,9 @@ proc formatSectionIssue(ctx: CliContext, issue: Issue, width: int, indent = "",
if issue.hasProp("pending"):
let startIdx = "Pending: ".len
var pendingText = issue["pending"].wordWrap(width - startIdx - 2)
var pendingText = issue["pending"].wordWrap(width - startIdx - summaryIndentLen)
.indent(startIdx)
pendingText = ("Pending: " & pendingText[startIdx..^1]).indent(indent.len + 2)
pendingText = ("Pending: " & pendingText[startIdx..^1]).indent(summaryIndentLen)
result &= "\n" & pendingText.withColor(fgCyan)
if showDetails:
@ -106,16 +116,9 @@ proc formatSectionIssueList(ctx: CliContext, issues: seq[Issue], width: int,
indent: string, verbose: bool): string =
result = ""
var topPadded = true
for i in issues:
var issueText = ctx.formatSectionIssue(i, width, indent, verbose)
if issueText.splitLines.len > 1:
if topPadded: result &= issueText & "\n\n"
else: result &= "\n" & issueText & "\n\n"
topPadded = true
else:
result &= issueText & "\n"
topPadded = false
proc formatSection(ctx: CliContext, issues: seq[Issue], state: IssueState,
indent = "", verbose = false): string =
@ -241,7 +244,10 @@ Usage:
pit list [<listable>] [options]
pit ( start | done | pending | todo-today | todo | suspend ) <id>... [options]
pit edit <ref>...
pit tag <id>... [options]
pit untag <id>... [options]
pit reorder <state>
pit delegate <id> <delegated-to>
pit ( delete | rm ) <id>...
Options:
@ -353,6 +359,29 @@ Options:
else: edit(ctx.tasksDir.loadIssueById(editRef))
elif args["tag"]:
if not args["--tags"]: raise newException(Exception, "no tags given")
let newTags = ($args["--tags"]).split(",").mapIt(it.strip)
for id in @(args["<id>"]):
var issue = ctx.tasksDir.loadIssueById(id)
issue.tags = deduplicate(issue.tags & newTags)
issue.store()
elif args["untag"]:
let tagsToRemove: seq[string] =
if args["--tags"]: ($args["--tags"]).split(",").mapIt(it.strip)
else: @[]
for id in @(args["<id>"]):
var issue = ctx.tasksDir.loadIssueById(id)
if tagsToRemove.len > 0:
issue.tags = issue.tags.filter(
proc (tag: string): bool = not tagsToRemove.anyIt(it == tag))
else: issue.tags = @[]
issue.store()
elif args["start"] or args["todo-today"] or args["done"] or
args["pending"] or args["todo"] or args["suspend"]:
@ -382,6 +411,13 @@ Options:
elif targetState == Done or targetState == Pending:
discard execShellCmd("ptk stop")
elif args["delegate"]:
let issue = ctx.tasksDir.loadIssueById($(args["<id>"]))
issue["delegated-to"] = $args["<delegated-to>"]
issue.store()
elif args["delete"] or args["rm"]:
for id in @(args["<id>"]):

View File

@ -146,7 +146,8 @@ proc toStorageFormat*(issue: Issue, withComments = false): string =
if withComments: lines.add("# Summary (one line):")
lines.add(issue.summary)
if withComments: lines.add("# Properties (\"key:value\" per line):")
for key, val in issue.properties: lines.add(key & ": " & val)
for key, val in issue.properties:
if not val.isNilOrWhitespace: lines.add(key & ": " & val)
if issue.tags.len > 0: lines.add("tags: " & issue.tags.join(","))
if not isNilOrWhitespace(issue.details) or withComments:
if withComments: lines.add("# Details go below the \"--------\"")
@ -178,7 +179,7 @@ proc store*(tasksDir: string, issue: Issue, state: IssueState, withComments = fa
else:
issue.filepath = stateDir / filename
issue.store()
issue.store(withComments)
proc storeOrder*(issues: seq[Issue], path: string) =
var orderLines = newSeq[string]()

View File

@ -1 +1 @@
const PIT_VERSION* = "4.4.3"
const PIT_VERSION* = "4.6.0"