Skip to content

Commit

Permalink
Improve and extend the built-in help texts and descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
jotaen authored Mar 3, 2024
1 parent 2fd92a6 commit 2b733de
Show file tree
Hide file tree
Showing 22 changed files with 250 additions and 148 deletions.
35 changes: 23 additions & 12 deletions klog/app/cli/bookmarks.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,38 @@ import (
)

type Bookmarks struct {
List BookmarksList `cmd:"" help:"Displays all bookmarks"`
Ls BookmarksList `cmd:"" hidden:"" help:"Alias for 'list'"`
List BookmarksList `cmd:"" help:"Display all bookmarks."`
Ls BookmarksList `cmd:"" hidden:"" help:"Alias for 'list'."`

Set BookmarksSet `cmd:"" help:"Defines a bookmark (or overwrites an existing one)"`
New BookmarksSet `cmd:"" hidden:"" help:"Alias for 'set'"`
Set BookmarksSet `cmd:"" help:"Define a bookmark (or overwrite an existing one)."`
New BookmarksSet `cmd:"" hidden:"" help:"Alias for 'set'."`

Unset BookmarksUnset `cmd:"" help:"Removes a bookmark from the collection"`
Rm BookmarksUnset `cmd:"" hidden:"" help:"Alias for 'unset'"`
Unset BookmarksUnset `cmd:"" help:"Remove a bookmark from the collection. (This only removes the bookmark, not the target file.)"`
Rm BookmarksUnset `cmd:"" hidden:"" help:"Alias for 'unset'."`

Clear BookmarksClear `cmd:"" help:"Clears entire bookmark collection"`
Clear BookmarksClear `cmd:"" help:"Clear entire bookmark collection. (This only removes the bookmarks, not the target files.)"`

Info BookmarksInfo `cmd:"" help:"Prints file information for a bookmark"`
Info BookmarksInfo `cmd:"" help:"Print file information for a bookmark."`
}

func (opt *Bookmarks) Help() string {
return `Bookmarks allow you to interact with often-used files via an alias,
regardless of your current working directory. A bookmark name is always prefixed with an '@'.
return `
Bookmarks allow you to interact with often-used files via an alias, independent of your current working directory.
You can think of a bookmark as some sort of klog-specific symlink, that’s always available when you invoke klog, and that resolves to the designated file.
Use the subcommands below to set up and manage your bookmarks.
E.g.: klog total @work
A bookmark name is denoted by the prefix '@'. For example, if you have a bookmark named '@work', that points to a .klg file, you can use klog like this:
You can specify as many bookmarks as you want. There can even be one “unnamed” bookmark.`
klog total @work
klog start --summary 'Started new project' @work
klog edit @work
You can specify as many bookmarks as you want. There can also be one “unnamed” default bookmark (which internally is identified by the name '@default').
This is useful in case you only have one main file at a time, and allows you to use klog without any input arguments at all. E.g.:
klog total
klog start --summary 'Started new project'
`
}

type BookmarksList struct{}
Expand Down
15 changes: 7 additions & 8 deletions klog/app/cli/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,23 @@ import (
)

type Config struct {
ConfigFilePath bool `name:"file-path" help:"Prints the path to your config file"`
util.NoStyleArgs
}

func (opt *Config) Help() string {
return `You are able to configure some of klog’s behaviour by providing a configuration file in your klog config folder. (Run ` + "`" + `klog config --file-path` + "`" + ` to print the path of that config file.)
return `
You are able to configure some of klog’s behaviour by providing a configuration file.
If you run ` + "`" + `klog config` + "`" + `, you can learn about the supported properties in the file, and which of those you have set.
If you run 'klog config', you can learn about the supported properties in the file, and which of those you have set.
You may use the output of that command as template for setting up your config file, as its format is valid syntax.
You may use the output as template for setting up your config file, as its format is valid syntax.`
The configuration file is named 'config.ini' and resides in your klog config folder.
Run 'klog info config-folder' to learn where your klog config folder is located.
`
}

func (opt *Config) Run(ctx app.Context) app.Error {
opt.NoStyleArgs.Apply(&ctx)
if opt.ConfigFilePath {
ctx.Print(app.Join(ctx.KlogConfigFolder(), app.CONFIG_FILE_NAME).Path() + "\n")
return nil
}
styler, _ := ctx.Serialise()
for i, e := range app.CONFIG_FILE_ENTRIES {
ctx.Print(styler.Props(tf.StyleProps{Color: tf.SUBDUED}).Format(util.Reflower.Reflow(e.Help.Summary, []string{"# "})))
Expand Down
14 changes: 9 additions & 5 deletions klog/app/cli/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,22 @@ import (
)

type Create struct {
ShouldTotal klog.ShouldTotal `name:"should" placeholder:"DURATION" help:"The should-total of the record"`
ShouldTotal klog.ShouldTotal `name:"should" placeholder:"DURATION" help:"The should-total of the record."`
ShouldTotalAlias klog.ShouldTotal `name:"should-total" placeholder:"DURATION" hidden:""` // Alias for “canonical” term
Summary klog.RecordSummary `name:"summary" short:"s" placeholder:"TEXT" help:"Summary text for the new record"`
Summary klog.RecordSummary `name:"summary" short:"s" placeholder:"TEXT" help:"Summary text for the new record."`
util.AtDateArgs
util.NoStyleArgs
util.OutputFileArgs
util.WarnArgs
util.OutputFileArgs
}

func (opt *Create) Help() string {
return `The new record is inserted into the file at the chronologically correct position.
(Assuming that the records are sorted from oldest to latest.)`
return `
You can set a should-total value via '--should' and a record summary via '--summary'.
The new record is inserted into the file at the chronologically correct position.
(Assuming that the records are sorted from oldest to latest.)
`
}

func (opt *Create) Run(ctx app.Context) app.Error {
Expand Down
4 changes: 2 additions & 2 deletions klog/app/cli/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (
)

type Edit struct {
util.OutputFileArgs
util.QuietArgs
util.OutputFileArgs
}

const hint = "You can specify your preferred editor via the $EDITOR environment variable, or the klog config file."
const hint = "You can specify your preferred editor via the $EDITOR environment variable, or via the klog config file."

func (opt *Edit) Help() string {
return hint
Expand Down
75 changes: 50 additions & 25 deletions klog/app/cli/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,76 @@ import (
kc "github.com/jotaen/kong-completion"
)

// Guideline for help texts and descriptions:
// - Command and flag descriptions are phrased in imperative style, and they
// end in a period. Examples:
// - Pretty-print records.
// - Sort output by date.
// - Code and literal values are wrapped in single quotes (')
// - Types of flag values are spelled in UPPER-CASE. The type is explained in
// the flag description. For complex types, there should also be an example.

type Cli struct {
Default Default `hidden:"" cmd:"" default:"withargs" help:""`

// Evaluate Files
Print Print `cmd:"" name:"print" group:"Evaluate Files" help:"Pretty-prints records"`
Total Total `cmd:"" name:"total" group:"Evaluate Files" help:"Evaluates the total time"`
Report Report `cmd:"" name:"report" group:"Evaluate Files" help:"Prints an aggregated calendar report"`
Tags Tags `cmd:"" name:"tags" group:"Evaluate Files" help:"Prints total times aggregated by tags"`
Today Today `cmd:"" name:"today" group:"Evaluate Files" help:"Evaluates the current day"`
Print Print `cmd:"" name:"print" group:"Evaluate Files" help:"Pretty-print records."`
Total Total `cmd:"" name:"total" group:"Evaluate Files" help:"Evaluate the total time."`
Report Report `cmd:"" name:"report" group:"Evaluate Files" help:"Print an aggregated calendar report."`
Tags Tags `cmd:"" name:"tags" group:"Evaluate Files" help:"Print total times aggregated by tags."`
Today Today `cmd:"" name:"today" group:"Evaluate Files" help:"Evaluate the current day."`

// Manipulate Files
Track Track `cmd:"" name:"track" group:"Manipulate Files" help:"Adds a new entry to a record"`
Start Start `cmd:"" name:"start" group:"Manipulate Files" aliases:"in" help:"Starts a new open time range"`
Stop Stop `cmd:"" name:"stop" group:"Manipulate Files" aliases:"out" help:"Closes the open time range"`
Pause Pause `cmd:"" name:"pause" group:"Manipulate Files" help:"Pauses the open time range"`
Switch Switch `cmd:"" name:"switch" group:"Manipulate Files" help:"Closes open range and starts a new one"`
Create Create `cmd:"" name:"create" group:"Manipulate Files" help:"Creates a new, empty record"`
Track Track `cmd:"" name:"track" group:"Manipulate Files" help:"Add a new entry to a record."`
Start Start `cmd:"" name:"start" group:"Manipulate Files" aliases:"in" help:"Start a new open time range."`
Stop Stop `cmd:"" name:"stop" group:"Manipulate Files" aliases:"out" help:"Close the open time range."`
Pause Pause `cmd:"" name:"pause" group:"Manipulate Files" help:"Pause the open time range."`
Switch Switch `cmd:"" name:"switch" group:"Manipulate Files" help:"Close open range and starts a new one."`
Create Create `cmd:"" name:"create" group:"Manipulate Files" help:"Create a new, empty record."`

// Manage Files
Bookmarks Bookmarks `cmd:"" name:"bookmarks" group:"Manage Files" aliases:"bk" help:"Named aliases for often-used files"`
Bookmarks Bookmarks `cmd:"" name:"bookmarks" group:"Manage Files" aliases:"bk" help:"Named aliases for often-used files."`
Bookmark Bookmarks `cmd:"" name:"bookmark" hidden:"" help:"(Alias)"` // Hidden alias for convenience / typo
Edit Edit `cmd:"" name:"edit" group:"Manage Files" help:"Opens a file or bookmark in your editor"`
Goto Goto `cmd:"" name:"goto" group:"Manage Files" help:"Opens the file explorer at a file or bookmark"`
Edit Edit `cmd:"" name:"edit" group:"Manage Files" help:"Open a file or bookmark in your editor."`
Goto Goto `cmd:"" name:"goto" group:"Manage Files" help:"Open the file explorer at a file or bookmark."`

// Misc
Version Version `cmd:"" name:"version" group:"Misc" help:"Prints version info and check for updates"`
Config Config `cmd:"" name:"config" group:"Misc" help:"Prints the current configuration"`
Info Info `cmd:"" name:"info" group:"Misc" help:"Prints information about klog"`
Json Json `cmd:"" name:"json" group:"Misc" help:"Converts records to JSON"`
Completion kc.Completion `cmd:"" name:"completion" group:"Misc" help:"Outputs shell code for enabling tab completion"`
Version Version `cmd:"" name:"version" group:"Misc" help:"Print version info and check for updates."`
Config Config `cmd:"" name:"config" group:"Misc" help:"Print the current configuration."`
Info Info `cmd:"" name:"info" group:"Misc" help:"Print information about klog."`
Json Json `cmd:"" name:"json" group:"Misc" help:"Convert records to JSON."`
Completion kc.Completion `cmd:"" name:"completion" group:"Misc" help:"Output shell code for enabling tab completion."`
}

const DESCRIPTION = "klog: command line app for time tracking with plain-text files.\n" +
"Run with --help to learn usage.\n" +
"Documentation online at " + KLOG_WEBSITE_URL

type Default struct {
Version bool `short:"v" name:"version" help:"Alias for 'klog version'"`
Version bool `short:"v" name:"version" help:"Alias for 'klog version'."`
}

func (opt *Default) Help() string {
return `
klog: command line app for time tracking with plain-text files. See also ` + KLOG_WEBSITE_URL + `
Time-tracking data is stored in files ending in the '.klg' extension.
You can use the subcommands below to evaluate, manipulate and manage your files.
Use the '--help' flag on the subcommands to learn more.
You can specify input data in one of these 3 ways:
- by passing the name of a file or a bookmark,
- by piping data to stdin,
- or by setting up a default bookmark.
Run 'klog bookmarks --help' to learn about bookmark usage.
One general note about flags: for all flags that have values, you can either use a space or an equals sign as delimiter, i.e. both '--flag value' and '--flag=value' are fine.
`
}

func (opt *Default) Run(ctx app.Context) app.Error {
if opt.Version {
versionCmd := Version{}
return versionCmd.Run(ctx)
}
ctx.Print(DESCRIPTION + "\n")
ctx.Print("klog: command line app for time tracking with plain-text files.\n")
ctx.Print("Run 'klog --help' to learn usage.\n")
return nil
}
19 changes: 15 additions & 4 deletions klog/app/cli/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,24 @@ import (
)

type Info struct {
Spec InfoSpec `cmd:"" name:"spec" help:"Prints file format specification"`
License InfoLicense `cmd:"" name:"license" help:"Prints license / copyright information"`
ConfigFolder InfoConfigFolder `cmd:"" name:"config-folder" help:"Prints path of klog config folder"`
Spec InfoSpec `cmd:"" name:"spec" help:"Print the .klg file format specification."`
License InfoLicense `cmd:"" name:"license" help:"Print license / copyright information."`
ConfigFolder InfoConfigFolder `cmd:"" name:"config-folder" help:"Print the path of the klog config folder."`
}

func (opt *Info) Help() string {
return ""
return `
Run 'klog info config-folder' to see the location of your klog config folder.
The location of the config folder depends on your operating system and environment settings.
You can customise the folder’s location via environment variables – run the command to learn which ones klog relies on.
The config folder is used to store two files:
- 'config.ini' (optional) – you can create this file manually to override some of klog’s default behaviour. Run 'klog config' to learn more.
- 'bookmarks.json' (optional) – if you use bookmarks, then klog uses this file as database. You are not supposed to edit this file by hand! Instead, use the 'klog bookmarks' command to manage your bookmarks.
Run 'klog info spec' to read the formal specification of the klog file format.
If you want to review klog’s license and copyright information, run 'klog info license'.
`
}

type InfoConfigFolder struct {
Expand Down
14 changes: 7 additions & 7 deletions klog/app/cli/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@ import (
)

type Json struct {
Pretty bool `name:"pretty" help:"Pretty-print output"`
Pretty bool `name:"pretty" help:"Pretty-print output."`
util.NowArgs
util.FilterArgs
util.SortArgs
util.InputFilesArgs
}

func (opt *Json) Help() string {
return `The output structure contains two properties at the top level: "records" and "errors".
return `
The output structure is a JSON object which contains two properties at the top level: 'records' and 'errors'.
If the file is valid, 'records' is an array containing a JSON object for each record, and 'errors' is 'null'.
If the file has syntax errors, 'records' is 'null', and 'errors' contains an array of error objects.
If the file is valid, "records" is an array containing a JSON object for each record; "errors" is null.
If the file has syntax errors, "records" is null and "errors" contains an array of error objects.
The structure of the "record" and "error" objects is always uniform. You can best explore it by running the command with the --pretty flag.
The structure of the 'record' and 'error' objects is always uniform and should be self-explanatory.
You can best explore it by running the command with the --pretty flag.
`
}

Expand Down
21 changes: 13 additions & 8 deletions klog/app/cli/pause.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,25 @@ import (
)

type Pause struct {
Summary klog.EntrySummary `name:"summary" short:"s" placeholder:"TEXT" help:"Summary text for the pause entry"`
NoAppendTags bool `name:"no-tags" help:"Do not automatically take over (append) tags from open range"`
Extend bool `name:"extend" short:"e" help:"Extend latest pause, instead of adding a new pause entry"`
util.OutputFileArgs
Summary klog.EntrySummary `name:"summary" short:"s" placeholder:"TEXT" help:"Summary text for the pause entry."`
NoAppendTags bool `name:"no-tags" help:"Do not automatically take over (append) tags from open range."`
Extend bool `name:"extend" short:"e" help:"Extend latest pause, instead of adding a new pause entry."`
util.NoStyleArgs
util.WarnArgs
util.OutputFileArgs
}

func (opt *Pause) Help() string {
return `Creates a pause entry for a record with an open time range.
The command is blocking – it keeps updating the pause entry until the process is exited.
(The file will be written into once per minute.)
return `
This command is only available for records that contain an open time range (i.e., an ongoing activity).
The pause is basically a new entry with a negative duration, which is appended to the record.
The command is blocking and keeps updating (incrementing) the duration of the pause entry until the shell process is exited via Ctrl^C.
The file will be written into once per minute.
If you wish to extend an existing pause, you can use the '--extend' flag. In this case it will increment the last pause entry in the record, instead of appending a new entry.
If the open range in the record contains tags, then these will automatically be taken over and appended to the pause entry.
If the open range in the record contains tags in its summary, then these will automatically be taken over and appended to the pause entry.
You can opt out of this behaviour with the '--no-tags' flag.
`
}

Expand Down
10 changes: 8 additions & 2 deletions klog/app/cli/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

type Print struct {
WithTotals bool `name:"with-totals" help:"Amend output with evaluated total times"`
WithTotals bool `name:"with-totals" help:"Amend output with evaluated total times."`
util.FilterArgs
util.SortArgs
util.WarnArgs
Expand All @@ -20,7 +20,13 @@ type Print struct {
}

func (opt *Print) Help() string {
return `The output is syntax-highlighted. Note that the formatting is sanitised/normalised, especially in regards to whitespace.`
return `
Outputs data on the terminal, by default with syntax-highlighting turned on.
Note that the output doesn’t resemble the file byte by byte, but the command may apply some minor clean-ups of the formatting.
If run with filter flags, it only outputs those entries that match the filter clauses.
You can optionally also sort the records, or print out the total times for each record and entry.
`
}

func (opt *Print) Run(ctx app.Context) app.Error {
Expand Down
12 changes: 8 additions & 4 deletions klog/app/cli/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
)

type Report struct {
AggregateBy string `name:"aggregate" placeholder:"KIND" short:"a" help:"Aggregate data by: day (default), week, month, quarter, year" enum:"DAY,day,d,WEEK,week,w,MONTH,month,m,QUARTER,quarter,q,YEAR,year,y," default:"day"`
Fill bool `name:"fill" short:"f" help:"Fill the gaps and show a consecutive stream"`
AggregateBy string `name:"aggregate" placeholder:"KIND" short:"a" help:"How to aggregate the data. KIND can be 'day' (default), 'week', 'month', 'quarter' or 'year'." enum:"DAY,day,d,WEEK,week,w,MONTH,month,m,QUARTER,quarter,q,YEAR,year,y," default:"day"`
Fill bool `name:"fill" short:"f" help:"Fill the gaps and show a consecutive stream."`
util.DiffArgs
util.FilterArgs
util.NowArgs
Expand All @@ -24,9 +24,13 @@ type Report struct {
}

func (opt *Report) Help() string {
return `It aggregates the totals by period, and prints the respective values from oldest to latest.
return `
It aggregates the totals by period, and prints the respective values chronologically (from oldest to latest).
The default aggregation is by day, but you can choose other periods via the '--aggregate' flag.
The default aggregation is by day, but you choose other periods via the --aggregate flag.`
The report skips all days (weeks, months, etc.) if no data is available for them.
If you want a consecutive, chronological stream, you can use the '--fill' flag.
`
}

func (opt *Report) Run(ctx app.Context) app.Error {
Expand Down
Loading

0 comments on commit 2b733de

Please sign in to comment.