Skip to content

Commit

Permalink
Use pager for docs and make pagers more configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
twpayne committed May 24, 2021
1 parent 6c952eb commit b6ab19e
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 28 deletions.
50 changes: 26 additions & 24 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type Config struct {
Data map[string]interface{} `mapstructure:"data"`
Template templateConfig `mapstructure:"template"`
UseBuiltinGit *autoBool `mapstructure:"useBuiltinGit"`
Pager string `mapstructure:"pager"`

// Global configuration, not settable in the config file.
cpuProfile chezmoi.AbsPath
Expand Down Expand Up @@ -96,6 +97,7 @@ type Config struct {
Add addCmdConfig `mapstructure:"add"`
CD cdCmdConfig `mapstructure:"cd"`
Diff diffCmdConfig `mapstructure:"diff"`
Docs docsCmdConfig `mapstructure:"docs"`
Edit editCmdConfig `mapstructure:"edit"`
Git gitCmdConfig `mapstructure:"git"`
Merge mergeCmdConfig `mapstructure:"merge"`
Expand Down Expand Up @@ -200,14 +202,14 @@ func newConfig(options ...configOption) (*Config, error) {
fileSystem: vfs.OSFS,
homeDir: userHomeDir,
Umask: chezmoi.Umask,
Pager: os.Getenv("PAGER"),
Add: addCmdConfig{
exclude: chezmoi.NewEntryTypeSet(chezmoi.EntryTypesNone),
include: chezmoi.NewEntryTypeSet(chezmoi.EntryTypesAll),
recursive: true,
},
Diff: diffCmdConfig{
Exclude: chezmoi.NewEntryTypeSet(chezmoi.EntryTypesNone),
Pager: os.Getenv("PAGER"),
include: chezmoi.NewEntryTypeSet(chezmoi.EntryTypesAll),
},
Edit: editCmdConfig{
Expand Down Expand Up @@ -753,29 +755,7 @@ func (c *Config) diffFile(path chezmoi.RelPath, fromData []byte, fromMode fs.Fil
if err := unifiedEncoder.Encode(diffPatch); err != nil {
return err
}
return c.diffPager(sb.String())
}

func (c *Config) diffPager(output string) error {
if c.noPager || c.Diff.Pager == "" {
return c.writeOutputString(output)
}

// If the pager command contains any spaces, assume that it is a full
// shell command to be executed via the user's shell. Otherwise, execute
// it directly.
var pagerCmd *exec.Cmd
if strings.IndexFunc(c.Diff.Pager, unicode.IsSpace) != -1 {
shell, _ := shell.CurrentUserShell()
pagerCmd = exec.Command(shell, "-c", c.Diff.Pager)
} else {
//nolint:gosec
pagerCmd = exec.Command(c.Diff.Pager)
}
pagerCmd.Stdin = bytes.NewBufferString(output)
pagerCmd.Stdout = c.stdout
pagerCmd.Stderr = c.stderr
return pagerCmd.Run()
return c.pageOutputString(sb.String(), c.Diff.Pager)
}

func (c *Config) doPurge(purgeOptions *purgeOptions) error {
Expand Down Expand Up @@ -1099,6 +1079,28 @@ func (c *Config) persistentPostRunRootE(cmd *cobra.Command, args []string) error
return nil
}

func (c *Config) pageOutputString(output, cmdPager string) error {
pager := firstNonEmptyString(cmdPager, c.Pager)
if c.noPager || pager == "" {
return c.writeOutputString(output)
}

// If the pager command contains any spaces, assume that it is a full
// shell command to be executed via the user's shell. Otherwise, execute
// it directly.
var pagerCmd *exec.Cmd
if strings.IndexFunc(pager, unicode.IsSpace) != -1 {
shell, _ := shell.CurrentUserShell()
pagerCmd = exec.Command(shell, "-c", pager)
} else {
pagerCmd = exec.Command(pager)
}
pagerCmd.Stdin = bytes.NewBufferString(output)
pagerCmd.Stdout = c.stdout
pagerCmd.Stderr = c.stderr
return pagerCmd.Run()
}

func (c *Config) persistentPreRunRootE(cmd *cobra.Command, args []string) error {
if c.cpuProfile != "" {
f, err := os.Create(string(c.cpuProfile))
Expand Down
5 changes: 3 additions & 2 deletions cmd/diffcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import (

type diffCmdConfig struct {
Exclude *chezmoi.EntryTypeSet `mapstructure:"exclude"`
Pager string `mapstructure:"pager"`
include *chezmoi.EntryTypeSet
recursive bool
Pager string `mapstructure:"pager"`
}

func (c *Config) newDiffCmd() *cobra.Command {
Expand All @@ -31,6 +31,7 @@ func (c *Config) newDiffCmd() *cobra.Command {
flags.VarP(c.Diff.Exclude, "exclude", "x", "exclude entry types")
flags.VarP(c.Diff.include, "include", "i", "include entry types")
flags.BoolVarP(&c.Diff.recursive, "recursive", "r", c.Diff.recursive, "recursive")
flags.StringVar(&c.Diff.Pager, "pager", c.Diff.Pager, "pager")

return diffCmd
}
Expand All @@ -50,5 +51,5 @@ func (c *Config) runDiffCmd(cmd *cobra.Command, args []string) error {
}); err != nil {
return err
}
return c.diffPager(sb.String())
return c.pageOutputString(sb.String(), c.Diff.Pager)
}
9 changes: 8 additions & 1 deletion cmd/docscmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import (
"github.com/twpayne/chezmoi/v2/docs"
)

type docsCmdConfig struct {
Pager string `mapstructure:"pager"`
}

func (c *Config) newDocsCmd() *cobra.Command {
docsCmd := &cobra.Command{
Use: "docs [regexp]",
Expand All @@ -27,6 +31,9 @@ func (c *Config) newDocsCmd() *cobra.Command {
},
}

flags := docsCmd.Flags()
flags.StringVar(&c.Docs.Pager, "pager", c.Docs.Pager, "pager")

return docsCmd
}

Expand Down Expand Up @@ -96,5 +103,5 @@ func (c *Config) runDocsCmd(cmd *cobra.Command, args []string) error {
return err
}

return c.writeOutput(renderedData)
return c.pageOutputString(string(renderedData), c.Docs.Pager)
}
8 changes: 8 additions & 0 deletions completions/chezmoi-completion.bash

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion docs/REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ The following configuration variables are available:
| | `format` | string | `json` | Format for data output, either `json` or `yaml` |
| | `remove` | bool | `false` | Remove targets |
| | `sourceDir` | string | `~/.local/share/chezmoi` | Source directory |
| | `pager` | string | `$PAGER` | Default pager |
| | `umask` | int | *from system* | Umask |
| | `useBuiltinGit` | string | `auto` | Use builtin git if `git` command is not found in $PATH |
| `add` | `templateSymlinks` | bool | `false` | Template symlinks to source and home dirs |
Expand All @@ -287,7 +288,8 @@ The following configuration variables are available:
| `cd` | `args` | []string | *none* | Extra args to shell in `cd` command |
| | `command` | string | *none* | Shell to run in `cd` command |
| `diff` | `exclude` | []string | *none* | Entry types to exclude from diff |
| | `pager` | string | `$PAGER` / `less` | Pager |
| | `pager` | string | *none* | Diff-specific pager |
| `docs` | `pager` | string | *none* | Docs-specific pager |
| `edit` | `args` | []string | *none* | Extra args to edit command |
| | `command` | string | `$EDITOR` / `$VISUAL` | Edit command |
| `secret` | `command` | string | *none* | Generic secret command |
Expand Down Expand Up @@ -775,6 +777,10 @@ Print the difference between the target state and the destination state for
If a `diff.pager` command is set in the configuration file then the output will
be piped into it.

#### `--pager` *pager*

Pager to use for output.

#### `diff` examples

```console
Expand All @@ -787,6 +793,10 @@ $ chezmoi diff ~/.bashrc
Print the documentation page matching the regular expression *regexp*. Matching
is case insensitive. If no pattern is given, print `REFERENCE.md`.

#### `--pager` *pager*

Pager to use for output.

#### `docs` examples

```console
Expand Down

0 comments on commit b6ab19e

Please sign in to comment.