Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ A JSON listing prints a default set of keys per row, enough to pick an
item and act on its `uuid`; notes, the parent uuids and Things' own
bookkeeping are left out. `--fields` names the keys you want instead, in
that order: `things anytime -j --fields uuid,title,projectTitle,deadline`.
`--fields all` prints every key, as `--json` did by default in v0.10.0 and
`-f` is the short form. `--fields all` prints every key, as `--json` did by default in v0.10.0 and
earlier, and `things show <uuid> -j` prints one item's full record. It
works on the task listings, `search` and `projects`, and needs `--json`. An
unknown name fails with the list of valid ones. See the
Expand Down
7 changes: 7 additions & 0 deletions cmd/things/fields_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ func TestRunListingFields(t *testing.T) {
"list with filter": {[]string{"-j", "list", "--project", "Chores", "--fields", "title"}, []string{"title"}},
"search": {[]string{"-j", "search", "milk", "--fields", "uuid, title,uuid"}, []string{"uuid", "title"}},
"projects": {[]string{"-j", "projects", "--fields", "openCount,title"}, []string{"openCount", "title"}},

"short, bare view": {[]string{"today", "-j", "-f", "uuid,title"}, []string{"uuid", "title"}},
"short, named view": {[]string{"-j", "anytime", "-f", "uuid,projectTitle"}, []string{"uuid", "projectTitle"}},
"short, list": {[]string{"list", "anytime", "-a", "Home", "-j", "-f", "uuid"}, []string{"uuid"}},
"short, search": {[]string{"-j", "search", "milk", "-f", "uuid, title,uuid"}, []string{"uuid", "title"}},
"short, projects": {[]string{"-j", "projects", "-f", "openCount,title"}, []string{"openCount", "title"}},
"short, joined value": {[]string{"-j", "projects", "-fopenCount,title"}, []string{"openCount", "title"}},
}
for name, c := range cases {
t.Run(name, func(t *testing.T) {
Expand Down
6 changes: 3 additions & 3 deletions cmd/things/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type ListCmd struct {
From string `help:"Only tasks scheduled on or after YYYY-MM-DD (or RFC3339). On 'deadlines', filters by deadline; on 'upcoming', an undated task is matched by its deadline."`
To string `help:"Only tasks scheduled on or before YYYY-MM-DD (or RFC3339). On 'deadlines', filters by deadline; on 'upcoming', an undated task is matched by its deadline."`

Fields *string `help:"${fields_help}" placeholder:"KEYS"`
Fields *string `short:"f" help:"${fields_help}" placeholder:"KEYS"`
}

func (c *ListCmd) Run(kctx *kong.Context, d *Deps) error {
Expand Down Expand Up @@ -249,7 +249,7 @@ type ProjectsCmd struct {
Completed bool `help:"Include completed projects." default:"false"`
OpenOnly bool `help:"Leave out the projects closed but not yet logged, which are listed by default as Things still shows them: under the app's default Daily logging, the ones closed today. Ignored with --completed. --open-only=false overrides open_only in the config file."`

Fields *string `help:"${fields_help}" placeholder:"KEYS"`
Fields *string `short:"f" help:"${fields_help}" placeholder:"KEYS"`
}

func (c *ProjectsCmd) Run(d *Deps) error {
Expand Down Expand Up @@ -343,7 +343,7 @@ func printItem(d *Deps, database *db.DB, task *model.Task) error {
type SearchCmd struct {
Query string `arg:"" required:"" help:"Search query."`

Fields *string `help:"${fields_help}" placeholder:"KEYS"`
Fields *string `short:"f" help:"${fields_help}" placeholder:"KEYS"`
}

func (c *SearchCmd) Run(d *Deps) error {
Expand Down
4 changes: 3 additions & 1 deletion docs/content/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@ A JSON listing prints a default set of keys for each row: the ones needed
to pick an item and act on it. Notes, the parent uuids and Things' own
bookkeeping are left out, since notes alone can be half of a full listing.
`--fields` names the keys you want instead, in the order you want them, and
`--fields all` prints every key:
`--fields all` prints every key. `-f` is the short form of `--fields` on
the task listings, `search` and `projects`:

```sh
things anytime -a "Personal Projects" -j --fields uuid,title,projectTitle,deadline,tags
things projects -j --fields uuid,title,openCount
things today -j -f uuid,title
things anytime -j --fields all
things show <uuid> -j # one item's full record, notes and checklist included
```
Expand Down
8 changes: 4 additions & 4 deletions internal/skill/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Every command that reads or writes Things accepts `--json` / `-j`; `version`, `c
- `logbook` is everything closed, not just everything finished: cancelled items sit beside completed ones, as they do in the app's Logbook. Split them on `"status"` — `"completed"` or `"cancelled"`; plain output prints `[x]` and `[~]`. Filter with `jq '.[] | select(.status=="completed")'` when you mean finished rather than closed.
- `things projects` also reports `taskCount` and `openCount`. `taskCount` is every untrashed task in the project; `openCount` is the ones still open. The difference is the ones that are no longer open, which means completed or cancelled. Tasks filed under a project heading count towards both; the heading rows themselves never do, and neither do trashed tasks or checklist items. Both numbers are Things' own bookkeeping, read straight from the database rather than recounted by the CLI.
- **A `-j` listing prints a default set of keys, not the full record.** Task rows carry `uuid`, `title`, `type`, `status`, `start`, `startBucket`, `startDate`, `reminderTime`, `deadline`, `stopDate`, `projectTitle`, `projectTrashed`, `areaTitle`, `headingTitle`, `tags`, `repeating` and `checklistProgress`; `things projects` rows carry `uuid`, `title`, `status`, `start`, `startDate`, `deadline`, `areaTitle`, `tags`, `taskCount` and `openCount` (each left out when the row has no value, as before). `notes`, the parent uuids (`projectUUID`, `areaUUID`, `headingUUID`), `creationDate`, `index`, `todayIndex`, `trashed`, and `startBucket` on a `things projects` row, are not in a listing unless you ask: read one item's notes with `things show <uuid> -j`, or pass `--fields all` for every key of every row. **This changed:** before, `-j` printed every key. This applies to the task listings, `search` and `projects`; `show` is always the full record.
- **Pick keys with `--fields`.** `things anytime -a "Area" -j --fields uuid,title,projectTitle,deadline,tags` prints only those keys of each row, in that order; `--fields all` prints the full record and takes no other names. Names are the JSON keys exactly as printed (`projectTitle`, not `project`); a row leaves out a key the full record would leave out. An unknown name, or an empty list, fails before anything is read with `{"error": "unknown field", "kind": "task", "unknown": [...], "valid": [...]}` (no `unknown` for an empty list), so read `valid` and retry. It needs `--json`.
- **Pick keys with `--fields`.** `things anytime -a "Area" -j --fields uuid,title,projectTitle,deadline,tags` prints only those keys of each row, in that order; `--fields all` prints the full record and takes no other names. Names are the JSON keys exactly as printed (`projectTitle`, not `project`); a row leaves out a key the full record would leave out. An unknown name, or an empty list, fails before anything is read with `{"error": "unknown field", "kind": "task", "unknown": [...], "valid": [...]}` (no `unknown` for an empty list), so read `valid` and retry. `-f` is the short form; prefer the long `--fields` in scripts. It needs `--json`.
- Human output is styled and column-aligned; colour auto-disables when piping or under `NO_COLOR`. `--color=always|never` overrides. JSON is unaffected.

**A failure under `--json` prints one JSON object to stdout and exits non-zero.** Branch on the exit status and read the failure off stdout — not stderr. On success the read commands print their result there. Of the write commands, `add`, `project add`, `edit`, `project edit`, `complete` and `cancel` print the item (rule 3), `tag add` reports what it created and what it skipped, and the rest print nothing. `error` is a stable token; `message` is the human text.
Expand Down Expand Up @@ -178,7 +178,7 @@ The user may have a TOML file at `~/.config/things-cli/config.toml` (or `$XDG_CO
Global flags, valid on every command: `-j/--json`, `--color=auto|always|never`, `--db PATH`, `--config PATH`, `--no-verify`, `--verify-timeout DURATION` (how long a write's read-back waits, default `5s`; must be above zero — use `--no-verify` to skip it), `--no-hints`, `-v/--version`.

```
things list [view] [--project P] [--area A] [--tag T] [--on D | --from D --to D] [--open-only] [--fields KEYS]
things list [view] [--project P] [--area A] [--tag T] [--on D | --from D --to D] [--open-only] [-f|--fields KEYS]
# views: today, inbox, upcoming, anytime, someday, repeating, logbook, trash, deadlines
# shortcut: `things today`, `things inbox`, etc.
# bare `things` is today — but --project/--area/--tag alone list every open
Expand Down Expand Up @@ -295,15 +295,15 @@ things list [view] [--project P] [--area A] [--tag T] [--on D | --from D --to D]
# page does, and lists that project's row instead.

things show <task> [--agent] # detail; --agent prints a Markdown brief (see below)
things projects [-a|--area A] [--completed] [--open-only] [--fields KEYS]
things projects [-a|--area A] [--completed] [--open-only] [-f|--fields KEYS]
# open projects plus those closed and not yet logged (as the app's list
# still shows them; "status" tells them apart), unless --open-only;
# --completed lists every closed project too.
# carries start/startDate/deadline like a task (startBucket via --fields),
# plus taskCount/openCount in JSON
things areas
things tags
things search <query> [--fields KEYS] # titles and notes, matched literally; a lookup, not a view
things search <query> [-f|--fields KEYS] # titles and notes, matched literally; a lookup, not a view
# skips trashed rows and tasks of a project in the trash, as the app does

things tag add <name>... # create tags; existing names are skipped
Expand Down
Loading