diff --git a/pit.nimble b/pit.nimble index f8fdd8f..80284d2 100644 --- a/pit.nimble +++ b/pit.nimble @@ -1,6 +1,6 @@ # Package -version = "4.31.0" +version = "4.31.1" author = "Jonathan Bernard" description = "Personal issue tracker." license = "MIT" diff --git a/src/pit.nim b/src/pit.nim index 637bfa7..6d3860e 100644 --- a/src/pit.nim +++ b/src/pit.nim @@ -172,8 +172,6 @@ when isMainModule: var exclTagsOption = none(seq[string]) let filter = initFilter() - var filterOption = none(IssueFilter) - if args["--properties"] or args["--context"]: @@ -207,43 +205,37 @@ when isMainModule: # Initialize filter with properties (if given) if propertiesOption.isSome: filter.properties = propertiesOption.get - filterOption = some(filter) # Add property exclusions (if given) if exclPropsOption.isSome: filter.exclProperties = exclPropsOption.get - filterOption = some(filter) # If they supplied text matches, add that to the filter. if args["--match"]: filter.summaryMatch = some(re("(?i)" & $args["--match"])) - filterOption = some(filter) if args["--match-all"]: filter.fullMatch = some(re("(?i)" & $args["--match-all"])) - filterOption = some(filter) # If no "context" property is given, use the default (if we have one) if ctx.defaultContext.isSome and not filter.properties.hasKey("context"): stderr.writeLine("Limiting to default context: " & ctx.defaultContext.get) filter.properties["context"] = ctx.defaultContext.get - filterOption = some(filter) if tagsOption.isSome: filter.hasTags = tagsOption.get - filterOption = some(filter) if exclTagsOption.isSome: filter.exclTags = exclTagsOption.get - filterOption = some(filter) if args["--today"]: filter.inclStates.add(@[Current, TodoToday, Pending]) - filterOption = some(filter) if args["--future"]: filter.inclStates.add(@[Pending, Todo]) - filterOption = some(filter) + + if args["--show-hidden"]: + filter.exclHidden = false # Finally, if the "context" is "all", don't filter on context if filter.properties.hasKey("context") and @@ -433,7 +425,7 @@ when isMainModule: for state in statesOption.get: ctx.loadIssues(state) else: ctx.loadAllIssues() - if filterOption.isSome: ctx.filterIssues(filterOption.get) + ctx.filterIssues(filter) for state, issueList in ctx.issues: for issue in issueList: @@ -449,27 +441,27 @@ when isMainModule: stdout.writeLine formatIssue(issue) # List projects - elif listProjects: ctx.listProjects(filterOption) + elif listProjects: ctx.listProjects(some(filter)) # List milestones - elif listMilestones: ctx.listMilestones(filterOption) + elif listMilestones: ctx.listMilestones(some(filter)) # List all issues else: trace "listing all issues" let showBoth = args["--today"] == args["--future"] ctx.list( - filter = filterOption, + filter = some(filter), states = statesOption, showToday = showBoth or args["--today"], showFuture = showBoth or args["--future"], - showHidden = args["--show-hidden"], verbose = ctx.verbose) elif args["show"]: if args["project-board"]: - ctx.showProjectBoard(filterOption) + if not args["--show-done"]: filter.exclStates.add(Done) + ctx.showProjectBoard(some(filter)) discard elif args["dupes"]: diff --git a/src/pit/cliconstants.nim b/src/pit/cliconstants.nim index 49d4422..2c28e8f 100644 --- a/src/pit/cliconstants.nim +++ b/src/pit/cliconstants.nim @@ -1,4 +1,4 @@ -const PIT_VERSION* = "4.31.0" +const PIT_VERSION* = "4.31.1" const USAGE* = """Usage: pit ( new | add) [] [options] @@ -18,7 +18,7 @@ const USAGE* = """Usage: pit add-binary-property [options] pit get-binary-property [options] pit show dupes [options] - pit show project-board [options] + pit show project-board [--show-done] [options] pit show [options] pit sync [...] [options] pit help [options] @@ -239,4 +239,4 @@ Issue Properties: If present, expected to be a comma-delimited list of text tags. The -g option is a short-hand for '-p tags:'. -""" \ No newline at end of file +""" diff --git a/src/pit/formatting.nim b/src/pit/formatting.nim index 0f440b5..c649bbc 100644 --- a/src/pit/formatting.nim +++ b/src/pit/formatting.nim @@ -173,7 +173,6 @@ proc list*( states: Option[seq[IssueState]], showToday = false, showFuture = false, - showHidden = false, verbose: bool) = if states.isSome: @@ -219,10 +218,7 @@ proc list*( for s in [Current, TodoToday, Pending]: if ctx.issues.hasKey(s) and ctx.issues[s].len > 0: - let visibleIssues = ctx.issues[s].filterIt( - showHidden or - not (it.hasProp("hide-until") and - it.getDateTime("hide-until") > getTime().local)) + let visibleIssues = ctx.issues[s] if isatty(stdout): stdout.write ctx.formatSection(visibleIssues, s, indent, verbose) @@ -242,10 +238,7 @@ proc list*( for s in futureCategories: if ctx.issues.hasKey(s) and ctx.issues[s].len > 0: - let visibleIssues = ctx.issues[s].filterIt( - showHidden or - not (it.hasProp("hide-until") and - it.getDateTime("hide-until") > getTime().local)) + let visibleIssues = ctx.issues[s] if isatty(stdout): stdout.write ctx.formatSection(visibleIssues, s, indent, verbose) diff --git a/src/pit/libpit.nim b/src/pit/libpit.nim index 8c9f990..433c623 100644 --- a/src/pit/libpit.nim +++ b/src/pit/libpit.nim @@ -30,6 +30,7 @@ type exclStates*: seq[IssueState] hasTags*: seq[string] exclTags*: seq[string] + exclHidden*: bool properties*: TableRef[string, string] exclProperties*: TableRef[string, seq[string]] @@ -151,6 +152,7 @@ proc initFilter*(): IssueFilter = summaryMatch: none(Regex), inclStates: @[], exclStates: @[], + exclHidden: true, hasTags: @[], exclTags: @[], properties: newTable[string, string](), @@ -184,6 +186,10 @@ proc stateFilter*(states: seq[IssueState]): IssueFilter = result = initFilter() result.inclStates = states +proc showHiddenFilter*(): IssueFilter = + result = initFilter() + result.exclHidden = false + proc groupBy*(issues: seq[Issue], propertyKey: string): TableRef[string, seq[Issue]] = result = newTable[string, seq[Issue]]() for i in issues: @@ -416,6 +422,12 @@ proc nextRecurrence*(tasksDir: string, rec: Recurrence, defaultIssue: Issue): Is proc filter*(issues: seq[Issue], filter: IssueFilter): seq[Issue] = var f: seq[Issue] = issues + if filter.exclHidden: + let now = getTime().local + f = f --> filter( + not it.hasProp("hide-until") or + it.getDateTime("hide-until") <= now) + for k,v in filter.properties: f = f --> filter(it.hasProp(k) and it[k] == v) diff --git a/src/pit/projects.nim b/src/pit/projects.nim index c6ea050..9261e71 100644 --- a/src/pit/projects.nim +++ b/src/pit/projects.nim @@ -4,6 +4,10 @@ from std/sequtils import repeat, toSeq import cliutils, uuids, zero_functional import ./[formatting, libpit] +const NO_PROJECT* = "" +const NO_MILESTONE* = "" +const NO_CONTEXT* = "" + type ProjectCfg* = ref object of RootObj name: string @@ -62,15 +66,18 @@ proc buildDb*(ctx: CliContext, cfg: ProjectsConfiguration): ProjectsDatabase = # Now populate the database with issues for (state, issues) in pairs(ctx.issues): for issue in issues: - if not issue.hasProp("project") or - not issue.hasProp("milestone"): - continue - let projectName = issue["project"] - let milestone = issue["milestone"] + let projectName = + if issue.hasProp("project"): issue["project"] + else: NO_PROJECT + + let milestone = + if issue.hasProp("milestone"): issue["milestone"] + else: NO_MILESTONE + let context = if issue.hasProp("context"): issue["context"] - else: "" + else: NO_CONTEXT # Make sure we have entries for this context and project if not result.hasKey(context): result[context] = @[] @@ -128,15 +135,18 @@ proc listProjects*(ctx: CliContext, filter = none[IssueFilter]()) = for (state, issues) in pairs(ctx.issues): for issue in issues: - if issue.hasProp("project"): - let context = - if issue.hasProp("context"): issue["context"] - else: "" + let context = + if issue.hasProp("context"): issue["context"] + else: NO_CONTEXT - if not projectsByContext.hasKey(context): - projectsByContext[context] = newCountTable[string]() + let projectName = + if issue.hasProp("project"): issue["project"] + else: NO_PROJECT - projectsByContext[context].inc(issue["project"]) + if not projectsByContext.hasKey(context): + projectsByContext[context] = newCountTable[string]() + + projectsByContext[context].inc(projectName) for (context, projects) in pairs(projectsByContext):