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

config: set $LESS and $LESSCHARSET even if $PAGER is set #3657

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

martinvonz
Copy link
Owner

Our current default for ui.pager is this:

ui.pager = { command = ["less", "-FRX"], env = { LESSCHARSET = "utf-8" } }

If the user has $PAGER set, we take that value and replace the above table by a scalar set to the value from the environment variable. That means that anyone who has set $PAGER to just less will lose both the -FRX and the charset, making e.g. colored output from jj result in escaped ANSI codes rendered by less. The lack of those options might not matter for other tools they use so they might not have realized that they wanted those options.

This patch attempts to improve the situation by changing the default ui.pager to pass -FRX via $LESS, and by setting the value from $PAGER in ui.pager.command, so the rest of the config is left alone.

The default config will still be ignored if you set the scalar ui.pager to e.g. less, since that overrides the table.

Closes #2926

Checklist

If applicable:

  • I have updated CHANGELOG.md
  • I have updated the documentation (README.md, docs/, demos/)
  • I have updated the config schema (cli/src/config-schema.json)
  • I have added tests to cover my changes

Comment on lines +330 to +336
config::Value::new(
None,
config::ValueKind::Array(vec![config::Value::new(
None,
config::ValueKind::String(value),
)]),
),
Copy link
Owner Author

Choose a reason for hiding this comment

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

This is pretty ugly. Is there a more convenient API in the config crate?

Copy link
Collaborator

Choose a reason for hiding this comment

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

.set_override("ui.pager.command", vec![value]) appears to work.
https://docs.rs/config/0.13.4/config/enum.ValueKind.html#impl-From%3CVec%3CT%3E%3E-for-ValueKind

Copy link
Collaborator

@ilyagr ilyagr May 10, 2024

Choose a reason for hiding this comment

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

Actually, I'm not sure this is correct if PAGER contains a command with arguments, e.g. PAGER="less -FRX".

I'm not sure whether that is considered a kosher value for PAGER, but it usually worked for most programs, I think. Something did make me switch to using PAGER=less and LESS=... for the options, though.

Copy link
Collaborator

@ilyagr ilyagr May 10, 2024

Choose a reason for hiding this comment

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

It's possible this is still worth doing even if it doesn't work for PAGER="less -FRX", I'm unsure how common that is.

Or, we could allow ui.pager.command to be a string (perhaps in a future PR).

Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually, I'm not sure this is correct if PAGER contains a command with arguments, e.g. PAGER="less -FRX"?

Good point. PAGER needs to be parsed as if it were executed by the shell. It might be simpler to just special case PAGER=less.

Copy link
Owner Author

Choose a reason for hiding this comment

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

I'll wait a bit to hear from others if we actually want this PR before I spend more time on it.

cli/src/config/misc.toml Outdated Show resolved Hide resolved
This lets you configure e.g. some environment variables to pass to a
pager that will only be used if they're not already set in the user's
environment.

Thanks to @ilyagr for the suggestion.
Our current default for `ui.pager` is this:

```toml
ui.pager = { command = ["less"], env_default = { LESS = "-FRX", LESSCHARSET = "utf-8" } }
```

If the user has `$PAGER` set, we take that value and replace the above
table by a scalar set to the value from the environment variable. That
means that anyone who has set `$PAGER` to just `less` will lose both
the `-FRX` and the charset, making e.g. colored output from `jj`
result in escaped ANSI codes rendered by `less`. The lack of those
options might not matter for other tools they use so they might not
have realized that they wanted those options.

This patch attempts to improve the situation by setting the value from
`$PAGER` in `ui.pager.command` so the rest of the config is left
alone.

The default config will still be ignored if you set the scalar
`ui.pager` to e.g. `less`, since that overrides the table.

Closes #2926
Comment on lines +330 to +336
config::Value::new(
None,
config::ValueKind::Array(vec![config::Value::new(
None,
config::ValueKind::String(value),
)]),
),
Copy link
Collaborator

Choose a reason for hiding this comment

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

.set_override("ui.pager.command", vec![value]) appears to work.
https://docs.rs/config/0.13.4/config/enum.ValueKind.html#impl-From%3CVec%3CT%3E%3E-for-ValueKind

@@ -13,7 +13,7 @@ allow-filesets = false
always-allow-large-revsets = false
diff-instructions = true
paginate = "auto"
pager = { command = ["less", "-FRX"], env = { LESSCHARSET = "utf-8" } }
pager = { command = ["less"], env_default = { LESS="-FRX", LESSCHARSET = "utf-8" } }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Isn't it better to override the LESS variable as before?

I don't remember exactly, but some default-installed ~/.bashrc might set LESS=... If it didn't contain -R, jj's default would break.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Firstly, I think you don't need the - in LESS.

I'm not sure about Yuya's point. I have LESS set to FRX --mouse --wheel-lines=2, and I wouldn't like it overridden entirely. Perhaps we could print a warning after less quits if FRX was not in LESS and it was set? Perhaps we could prepend FRX to the variable?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I also think that, while it might make sense to add -R to LESS, forcibly adding -F (and possibly also -X) might be wrong if the user explicitly did not include them. For example, let's say we launch jj from a file manager like Midnight Commander or ranger. The user might then be relying on less not quitting after one screen to see the output at all. If we forcibly add -F, that would break this use-case. Forcibly adding -X might break it too, but I'm less sure.

So, in my opinion, if we want to hack around weird default values for LESS, we could do the analogue of LESS="R $LESS", but probably no more than that.

@@ -533,21 +533,18 @@ mod tests {

#[test]
fn test_command_args() {
let config_text = r#"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Optional: I'd call this config_toml.

env,
command,
} => {
for (k, v) in env_default {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Optional: Perhaps k.=v would work here? Or k~=v? Or (k=v)?

@@ -590,10 +610,24 @@ with_env = { env = { KEY1 = "value1", KEY2 = "value2" }, command = ["emacs", "-n
assert_eq!(name, "emacs");
assert_eq!(args, ["-nw"].as_ref());

let command_args: CommandNameAndArgs = config.get("with_env_default").unwrap();
Copy link
Collaborator

@ilyagr ilyagr May 10, 2024

Choose a reason for hiding this comment

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

Optional: I was going to suggest adding a test with https://doc.rust-lang.org/std/env/fn.set_var.html here, but I'm not so sure after reading the safety warning there. cargo-nextest is, in principle, multithreaded.

You could also set up a test that sets some variable that very likely exists, like PATH or CARGO. I guess to make the test reliable, you could check if that variable is set first, and skip the test if it isn't.

@@ -13,7 +13,7 @@ allow-filesets = false
always-allow-large-revsets = false
diff-instructions = true
paginate = "auto"
pager = { command = ["less", "-FRX"], env = { LESSCHARSET = "utf-8" } }
pager = { command = ["less"], env_default = { LESS="-FRX", LESSCHARSET = "utf-8" } }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Firstly, I think you don't need the - in LESS.

I'm not sure about Yuya's point. I have LESS set to FRX --mouse --wheel-lines=2, and I wouldn't like it overridden entirely. Perhaps we could print a warning after less quits if FRX was not in LESS and it was set? Perhaps we could prepend FRX to the variable?

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.

FR: selectively enable/disable pagination
3 participants