Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pager #672

Merged
merged 4 commits into from
Nov 29, 2022
Merged

Add pager #672

merged 4 commits into from
Nov 29, 2022

Conversation

chooglen
Copy link
Contributor

@chooglen chooglen commented Oct 24, 2022

Add pager support via the following config variables:

  • ui.pager: the program to use as the pager. Defaults to $PAGER.
  • ui.paginate: whether to paginate output. Supported values are 'auto',
    'always' and 'never'. Defaults to 'auto'.

Support for the --pager (or should it be called --paginate?) flag is WIP.

Checklist

If applicable:

  • I have updated CHANGELOG.md
  • I have updated the documentation (README.md, docs/, demos/)

src/ui.rs Outdated Show resolved Hide resolved
@martinvonz
Copy link
Member

  • e.g. maybe we really like struct Ui

Yes, I think the goal should be to route clap's output through the Ui object. We have previously talked about also avoiding having clap exit the process (by calling try_get_matches_from() instead of get_matches_from()).

  • How we could change the default paging behavior per-command

Yes, that's what Mercurial does. For many commands (e.g. jj squash), it doesn't make sense to spawn a pager because the output is just a few lines at most.

Writes first go to a temporary buffer and the pager is spawned only if
the buffer is nonempty.

Mercurial lets the commands decide when to enable the pager (if it's configured to be used). That should remove the need for a temporary buffer.

src/ui.rs Outdated Show resolved Hide resolved
@Ralith
Copy link
Contributor

Ralith commented Oct 24, 2022

Whether we really need DynWriteLock or if there are simpler alternatives here

We should stream output directly to the pager rather than buffering it up in full first. A file descriptor (or ChildStdin) doesn't require locking to write to, so in that case DynWriteLock will become unnecessary.

@yuja
Copy link
Contributor

yuja commented Oct 25, 2022

A file descriptor (or ChildStdin) doesn't require locking to write to, so in that case DynWriteLock will become unnecessary.

Yep, I lied in the chat, sorry.

If we need line-buffered output (like stdout), I think &ChildStdin can be wrapped per stdout_formatter() call, instead of locking shared buffered writer.

@chooglen chooglen force-pushed the demo/pager branch 2 times, most recently from 1afc334 to 11f689d Compare November 1, 2022 20:05
@chooglen chooglen changed the title Demonstrate pager Add pager Nov 1, 2022
@chooglen
Copy link
Contributor Author

chooglen commented Nov 1, 2022

Ok this is ready for review again :)

src/main.rs Outdated Show resolved Hide resolved
src/ui.rs Outdated Show resolved Hide resolved
src/ui.rs Outdated Show resolved Hide resolved
src/ui.rs Outdated Show resolved Hide resolved
src/ui.rs Outdated Show resolved Hide resolved
src/main.rs Outdated Show resolved Hide resolved
src/ui.rs Outdated Show resolved Hide resolved
src/ui.rs Outdated Show resolved Hide resolved
src/ui.rs Outdated Show resolved Hide resolved
@chooglen chooglen marked this pull request as draft November 2, 2022 00:59
src/ui.rs Outdated Show resolved Hide resolved
@chooglen chooglen force-pushed the demo/pager branch 5 times, most recently from 2dc4f2f to 6ef8312 Compare November 17, 2022 22:05
@chooglen chooglen marked this pull request as ready for review November 17, 2022 23:13
src/ui.rs Show resolved Hide resolved
Copy link
Member

@martinvonz martinvonz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This definitely deserves a mention in the changelog! Probably also worth mentioning in docs/config.md.

src/ui.rs Outdated Show resolved Hide resolved
src/ui.rs Outdated Show resolved Hide resolved
src/ui.rs Outdated Show resolved Hide resolved
src/ui.rs Outdated Show resolved Hide resolved
src/ui.rs Outdated Show resolved Hide resolved
We'll add a variant that isn't a pair. Also add a function to create a
new UiOutput::Terminal, we will create this variant in a few places
because we want to fall back to it.
Teach Ui's writing functions to write to a pager without touching the
process's file descriptors. This is done by introducing UiOutput::Paged,
which spawns a pager that Ui's functions can write to.

The pager program can be chosen via `ui.pager`. (defaults to Defaults to
$PAGER, and 'less' if that is unset (falling back to 'less' also makes
the tests pass).

Currently, commands are paginated if:

- they have "long" output (as defined by jj developers)
- jj is invoked in a terminal

The next commit will allow pagination to be turned off via a CLI option.
More complex pagination toggling (e.g. showing a pager even if the
output doesn't look like a terminal, using a pager for shorter ouput) is
left for a future PR.
@chooglen
Copy link
Contributor Author

In a future PR, I want to be able to paginate jj --help. It's easy to paginate if I add request_pager() call where we handle clap errors, but the tricky part is getting jj --help --no-pager to work right, since --help short-circuits the arg parsing.

Copy link
Member

@martinvonz martinvonz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants