ok/jj
1
0
Fork 0
forked from mirrors/jj

built-in pager: write a message to the user if pager failed to start

The message is printed at the end, any text sent to the pager before
then is lost. See
https://github.com/martinvonz/jj/pull/4197#discussion_r1701799135
for a discussion about why that seems OK.
This commit is contained in:
Ilya Grigoriev 2024-08-02 01:05:30 -07:00
parent 9ec617534c
commit 37ccfd5acc
2 changed files with 45 additions and 7 deletions

View file

@ -69,6 +69,7 @@ git2 = { workspace = true }
gix = { workspace = true } gix = { workspace = true }
hex = { workspace = true } hex = { workspace = true }
indexmap = { workspace = true } indexmap = { workspace = true }
indoc = { workspace = true }
itertools = { workspace = true } itertools = { workspace = true }
jj-lib = { workspace = true } jj-lib = { workspace = true }
maplit = { workspace = true } maplit = { workspace = true }
@ -102,7 +103,6 @@ anyhow = { workspace = true }
assert_cmd = { workspace = true } assert_cmd = { workspace = true }
assert_matches = { workspace = true } assert_matches = { workspace = true }
async-trait = { workspace = true } async-trait = { workspace = true }
indoc = { workspace = true }
insta = { workspace = true } insta = { workspace = true }
test-case = { workspace = true } test-case = { workspace = true }
testutils = { workspace = true } testutils = { workspace = true }

View file

@ -18,7 +18,8 @@ use std::str::FromStr;
use std::thread::JoinHandle; use std::thread::JoinHandle;
use std::{env, fmt, io, mem}; use std::{env, fmt, io, mem};
use minus::Pager as MinusPager; use indoc::indoc;
use minus::{MinusError, Pager as MinusPager};
use tracing::instrument; use tracing::instrument;
use crate::command_error::{config_error_with_message, CommandError}; use crate::command_error::{config_error_with_message, CommandError};
@ -46,7 +47,7 @@ enum UiOutput {
/// A builtin pager /// A builtin pager
pub struct BuiltinPager { pub struct BuiltinPager {
pager: MinusPager, pager: MinusPager,
dynamic_pager_thread: JoinHandle<()>, dynamic_pager_thread: JoinHandle<Result<(), MinusError>>,
} }
impl Write for &BuiltinPager { impl Write for &BuiltinPager {
@ -69,9 +70,9 @@ impl Default for BuiltinPager {
} }
impl BuiltinPager { impl BuiltinPager {
pub fn finalize(self) { pub fn finalize(self) -> Result<(), MinusError> {
let dynamic_pager_thread = self.dynamic_pager_thread; let dynamic_pager_thread = self.dynamic_pager_thread;
dynamic_pager_thread.join().unwrap(); dynamic_pager_thread.join().unwrap()
} }
pub fn new() -> Self { pub fn new() -> Self {
@ -87,7 +88,7 @@ impl BuiltinPager {
pager, pager,
dynamic_pager_thread: std::thread::spawn(move || { dynamic_pager_thread: std::thread::spawn(move || {
// This thread handles the actual paging. // This thread handles the actual paging.
minus::dynamic_paging(pager_handle).unwrap(); minus::dynamic_paging(pager_handle)
}), }),
} }
} }
@ -130,7 +131,44 @@ impl UiOutput {
} }
} }
UiOutput::BuiltinPaged { pager } => { UiOutput::BuiltinPaged { pager } => {
pager.finalize(); if let Err(minus_error) = pager.finalize() {
writeln!(
ui.warning_default(),
"Built-in pager failed to start: {minus_error}",
)
.ok();
writeln!(ui.warning_default(), "The output of this command is lost.").ok();
if matches!(
minus_error,
MinusError::Setup(minus::error::SetupError::InvalidTerminal)
) {
if cfg!(windows) {
writeln!(
ui.hint_default(),
indoc! {r#"
jj's builtin pager is likely incompatible with this terminal
This is known to happen with `mintty`, the default Git Bash terminal on Windows.
Possible workarounds:
- Use `jj --no-pager`
- Configure a different pager, see https://martinvonz.github.io/jj/latest/windows/#pagination for Git Bash on Windows
- Use a different terminal (e.g. Windows Terminal or the Command Prompt)
- Use `winpty jj ...`; `winpty` comes with Git Bash or Cygwin."#
}
).ok();
} else {
writeln!(
ui.hint_default(),
"Try `jj --no-pager`. You can also try `TERM=xterm` or setting up \
a different pager."
)
.ok();
}
}
// We do not cause a panic or another error so that the exit
// code of the command is preserved.
}
} }
} }
} }