WIP Support basic list options.
This commit is contained in:
parent
063a869b51
commit
d86da67284
80
src/pit.nim
80
src/pit.nim
@ -13,6 +13,7 @@ type
|
|||||||
tasksDir*: string
|
tasksDir*: string
|
||||||
contexts*: TableRef[string, string]
|
contexts*: TableRef[string, string]
|
||||||
issues*: TableRef[IssueState, seq[Issue]]
|
issues*: TableRef[IssueState, seq[Issue]]
|
||||||
|
termWidth*: int
|
||||||
cfg*: CombinedConfig
|
cfg*: CombinedConfig
|
||||||
|
|
||||||
proc initContext(args: Table[string, Value]): CliContext =
|
proc initContext(args: Table[string, Value]): CliContext =
|
||||||
@ -46,7 +47,8 @@ proc initContext(args: Table[string, Value]): CliContext =
|
|||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
tasksDir: cfg.getVal("tasks-dir", ""),
|
tasksDir: cfg.getVal("tasks-dir", ""),
|
||||||
contexts: newTable[string,string](),
|
contexts: newTable[string,string](),
|
||||||
issues: newTable[IssueState, seq[Issue]]())
|
issues: newTable[IssueState, seq[Issue]](),
|
||||||
|
termWidth: parseInt(cfg.getVal("term-width", "80")))
|
||||||
|
|
||||||
if cfgJson.hasKey("contexts"):
|
if cfgJson.hasKey("contexts"):
|
||||||
for k, v in cfgJson["contexts"]:
|
for k, v in cfgJson["contexts"]:
|
||||||
@ -75,7 +77,8 @@ proc formatIssue(ctx: CliContext, issue: Issue, state: IssueState,
|
|||||||
|
|
||||||
if state == Pending and issue.properties.hasKey("pending"):
|
if state == Pending and issue.properties.hasKey("pending"):
|
||||||
let startIdx = "Pending: ".len
|
let startIdx = "Pending: ".len
|
||||||
var pendingText = issue["pending"].wordWrap(width - startIdx - 2).indent(startIdx)
|
var pendingText = issue["pending"].wordWrap(width - startIdx - 2)
|
||||||
|
.indent(startIdx)
|
||||||
pendingText = ("Pending: " & pendingText[startIdx..^1]).indent(indent.len + 2)
|
pendingText = ("Pending: " & pendingText[startIdx..^1]).indent(indent.len + 2)
|
||||||
lines.add(pendingText)
|
lines.add(pendingText)
|
||||||
|
|
||||||
@ -84,16 +87,15 @@ proc formatIssue(ctx: CliContext, issue: Issue, state: IssueState,
|
|||||||
return lines.join("\n")
|
return lines.join("\n")
|
||||||
|
|
||||||
proc formatSection(ctx: CliContext, issues: seq[Issue], state: IssueState,
|
proc formatSection(ctx: CliContext, issues: seq[Issue], state: IssueState,
|
||||||
width = 80, indent = " "): string =
|
indent = ""): string =
|
||||||
let innerWidth = width - (indent.len * 2)
|
let innerWidth = ctx.termWidth - (indent.len * 2)
|
||||||
var lines: seq[string] = @[]
|
var lines: seq[string] = @[]
|
||||||
|
|
||||||
lines.add(indent & ".".repeat(innerWidth))
|
lines.add(indent & ".".repeat(innerWidth))
|
||||||
lines.add(state.displayName.center(width))
|
lines.add(state.displayName.center(ctx.termWidth))
|
||||||
lines.add("")
|
lines.add("")
|
||||||
|
|
||||||
var topPadded = true
|
var topPadded = true
|
||||||
var showDetails = false
|
|
||||||
|
|
||||||
let issuesByContext = issues.groupBy("context")
|
let issuesByContext = issues.groupBy("context")
|
||||||
|
|
||||||
@ -116,16 +118,23 @@ proc formatSection(ctx: CliContext, issues: seq[Issue], state: IssueState,
|
|||||||
lines.add("")
|
lines.add("")
|
||||||
return lines.join("\n")
|
return lines.join("\n")
|
||||||
|
|
||||||
proc loadIssues(ctx: CliContext, state: IssueState): seq[Issue] =
|
proc loadIssues(ctx: CliContext, state: IssueState) =
|
||||||
result = loadIssues(joinPath(ctx.tasksDir, $state))
|
ctx.issues[state] = loadIssues(joinPath(ctx.tasksDir, $state))
|
||||||
|
|
||||||
proc loadAllIssues(ctx: CliContext) =
|
proc loadAllIssues(ctx: CliContext) =
|
||||||
for state in IssueState:
|
for state in IssueState: ctx.loadIssues(state)
|
||||||
ctx.issues[state] = loadIssues(ctx, state)
|
|
||||||
|
|
||||||
proc sameDay(a, b: DateTime): bool =
|
proc sameDay(a, b: DateTime): bool =
|
||||||
result = a.year == b.year and a.yearday == b.yearday
|
result = a.year == b.year and a.yearday == b.yearday
|
||||||
|
|
||||||
|
proc formatHeader(ctx: CliContext, header: string): string =
|
||||||
|
var lines: seq[string] = @[]
|
||||||
|
lines.add('_'.repeat(ctx.termWidth))
|
||||||
|
lines.add(header.center(ctx.termWidth))
|
||||||
|
lines.add('~'.repeat(ctx.termWidth))
|
||||||
|
lines.add("")
|
||||||
|
return lines.join("\n")
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -146,9 +155,11 @@ Options:
|
|||||||
-C, --config <cfgFile> Location of the config file (defaults to $HOME/.pitrc)
|
-C, --config <cfgFile> Location of the config file (defaults to $HOME/.pitrc)
|
||||||
-h, --help Print this usage information.
|
-h, --help Print this usage information.
|
||||||
-T, --today Limit to today's issues.
|
-T, --today Limit to today's issues.
|
||||||
|
-F, --future Limit to future issues.
|
||||||
-E, --echo-args Echo arguments (for debug purposes).
|
-E, --echo-args Echo arguments (for debug purposes).
|
||||||
--tasks-dir Path to the tasks directory (defaults to the value
|
--tasks-dir Path to the tasks directory (defaults to the value
|
||||||
configured in the .pitrc file)
|
configured in the .pitrc file)
|
||||||
|
--term-width Manually set the terminal width to use.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logging.addHandler(newConsoleLogger())
|
logging.addHandler(newConsoleLogger())
|
||||||
@ -169,33 +180,40 @@ Options:
|
|||||||
## Actual command runners
|
## Actual command runners
|
||||||
if args["list"]:
|
if args["list"]:
|
||||||
|
|
||||||
ctx.loadAllIssues()
|
# Specific state request
|
||||||
|
if args["<state>"]:
|
||||||
|
let state = parseEnum[IssueState]($args["<state>"])
|
||||||
|
ctx.loadIssues(state)
|
||||||
|
echo ctx.formatSection(ctx.issues[state], state)
|
||||||
|
|
||||||
let fullWidth = 80
|
else:
|
||||||
let innerWidth = fullWidth - 4
|
|
||||||
|
|
||||||
# Today's items
|
let showBoth = args["--today"] == args["--future"]
|
||||||
echo '_'.repeat(fullWidth)
|
let indent = if showBoth: " " else: ""
|
||||||
echo "Today".center(fullWidth)
|
ctx.loadAllIssues()
|
||||||
echo '~'.repeat(fullWidth)
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
for s in [Current, TodoToday]:
|
# Today's items
|
||||||
echo ctx.formatSection(ctx.issues[s], s)
|
if args["--today"] or showBoth:
|
||||||
|
if showBoth: echo ctx.formatHeader("Today")
|
||||||
|
|
||||||
echo ctx.formatSection(
|
for s in [Current, TodoToday]:
|
||||||
ctx.issues[Done].filterIt(
|
if ctx.issues.hasKey(s) and ctx.issues[s].len > 0:
|
||||||
it.properties.hasKey("completed") and
|
echo ctx.formatSection(ctx.issues[s], s, indent)
|
||||||
sameDay(now, it.getDateTime("completed"))), Done)
|
|
||||||
|
|
||||||
# Future items
|
if ctx.issues.hasKey(Done):
|
||||||
echo '_'.repeat(fullWidth)
|
let doneIssues = ctx.issues[Done].filterIt(
|
||||||
echo "Future".center(fullWidth)
|
it.properties.hasKey("completed") and
|
||||||
echo '~'.repeat(fullWidth)
|
sameDay(now, it.getDateTime("completed")))
|
||||||
echo ""
|
if doneIssues.len > 0:
|
||||||
|
echo ctx.formatSection(doneIssues, Done, indent)
|
||||||
|
|
||||||
for s in [Pending, Todo]:
|
# Future items
|
||||||
echo ctx.formatSection(ctx.issues[s], s)
|
if args["--future"] or showBoth:
|
||||||
|
if showBoth: echo ctx.formatHeader("Future")
|
||||||
|
|
||||||
|
for s in [Pending, Todo]:
|
||||||
|
if ctx.issues.hasKey(s) and ctx.issues[s].len > 0:
|
||||||
|
echo ctx.formatSection(ctx.issues[s], s, indent)
|
||||||
|
|
||||||
except:
|
except:
|
||||||
fatal "pit: " & getCurrentExceptionMsg()
|
fatal "pit: " & getCurrentExceptionMsg()
|
||||||
|
@ -17,6 +17,8 @@ type
|
|||||||
Todo = "todo"
|
Todo = "todo"
|
||||||
|
|
||||||
const ISO8601Format* = "yyyy:MM:dd'T'HH:mm:sszzz"
|
const ISO8601Format* = "yyyy:MM:dd'T'HH:mm:sszzz"
|
||||||
|
const DONE_FOLDER_FORMAT* = "yyyy-MM"
|
||||||
|
|
||||||
let ISSUE_FILE_PATTERN = re"[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}\.txt"
|
let ISSUE_FILE_PATTERN = re"[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}\.txt"
|
||||||
|
|
||||||
proc displayName*(s: IssueState): string =
|
proc displayName*(s: IssueState): string =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user