Skip to content

Commit bcab722

Browse files
committed
Improvements related to wallet-cli pagination mode
1 parent 0293882 commit bcab722

3 files changed

Lines changed: 36 additions & 7 deletions

File tree

wallet/wallet-cli-lib/src/console.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use std::{collections::VecDeque, path::PathBuf};
1717

1818
use crossterm::tty::IsTty;
19+
1920
use wallet_cli_commands::WalletCliCommandError;
2021
use wallet_rpc_lib::types::NodeInterface;
2122

wallet/wallet-cli-lib/src/repl/interactive/log.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ impl InteractiveLogger {
6767
// Increase the buffer to prevent dropped log output.
6868
// Do not use very large buffers here, as this will increase
6969
// the amount of allocated memory (even if the buffer is not used).
70-
let external_printer = reedline::ExternalPrinter::new(1024);
70+
// Note that it shouldn't be too small either, because InteractiveLogger is also used
71+
// to collect logs when displaying paginated output; 8k should be enough to collect
72+
// relatively verbose debug logs for several minutes.
73+
let external_printer = reedline::ExternalPrinter::new(8192);
7174

7275
let print_directly = Arc::new(Mutex::new(true));
7376

wallet/wallet-cli-lib/src/repl/interactive/mod.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ pub fn run<N: NodeInterface>(
159159
&mut console,
160160
&mut prompt,
161161
&mut line_editor,
162-
logger.printer(),
162+
&logger,
163163
vi_mode,
164164
true,
165165
) {
@@ -192,7 +192,7 @@ pub fn run<N: NodeInterface>(
192192
&mut console,
193193
&mut prompt,
194194
&mut line_editor,
195-
logger.printer(),
195+
&logger,
196196
vi_mode,
197197
exit_on_error,
198198
) {
@@ -216,7 +216,7 @@ fn handle_response<N: NodeInterface>(
216216
console: &mut impl ConsoleOutput,
217217
prompt: &mut wallet_prompt::WalletPrompt,
218218
line_editor: &mut Reedline,
219-
printer: &reedline::ExternalPrinter<String>,
219+
logger: &log::InteractiveLogger,
220220
vi_mode: bool,
221221
exit_on_error: bool,
222222
) -> CommandResponse<N> {
@@ -225,7 +225,8 @@ fn handle_response<N: NodeInterface>(
225225
console.print_line(&text);
226226
}
227227
Ok(Some(ConsoleCommand::PaginatedPrint { header, body })) => {
228-
paginate_output(header, body, line_editor, console).expect("Should not fail normally");
228+
paginate_output(header, body, line_editor, console, logger)
229+
.expect("Should not fail normally");
229230
}
230231
Ok(Some(ConsoleCommand::SetStatus {
231232
status,
@@ -246,7 +247,8 @@ fn handle_response<N: NodeInterface>(
246247
Ok(Some(ConsoleCommand::Exit)) => return CommandResponse::Exit,
247248

248249
Ok(Some(ConsoleCommand::ChoiceMenu(choice))) => {
249-
let line_editor_helper = create_line_editor(printer.clone(), vec![], None, vi_mode);
250+
let line_editor_helper =
251+
create_line_editor(logger.printer().clone(), vec![], None, vi_mode);
250252
let cmd = handle_choice_menu(choice.as_ref(), line_editor_helper);
251253
if let Some(cmd) = cmd {
252254
return CommandResponse::Command(Box::new(cmd));
@@ -317,9 +319,31 @@ fn paginate_output(
317319
body: String,
318320
line_editor: &mut Reedline,
319321
console: &mut impl ConsoleOutput,
322+
logger: &log::InteractiveLogger,
320323
) -> std::io::Result<()> {
321324
let mut current_index = 0;
322325

326+
// Disable the direct logging, because:
327+
// a) we don't want any log output to appear in the paginated output;
328+
// b) the log output will appear broken in the raw mode anyway (which we switch the terminal
329+
// into inside `read_command`).
330+
// Note: the logs will be collected inside `reedline::ExternalPrinter` and printed
331+
// by `Readline::read_line` later.
332+
logger.set_print_directly(false);
333+
// Enter the alternate screen, to preserve the existing contents of the terminal.
334+
// Note: this call will basically send a certain ANSI code to the specified stream and then
335+
// flush the stream. It shouldn't matter whether we use stdout or stderr here.
336+
crossterm::execute!(std::io::stdout(), crossterm::terminal::EnterAlternateScreen)?;
337+
// Undo all of the above on function exit.
338+
let _cleanup = OnceDestructor::new(|| {
339+
// Note: we can't do anything about the possible error here. Panicking is probably
340+
// better than ignoring it, because the UI will likely be broken anyway
341+
// (though it's not clear under which conditions such an error can occur).
342+
crossterm::execute!(std::io::stdout(), crossterm::terminal::LeaveAlternateScreen)
343+
.expect("failure when leaving alternate terminal screen");
344+
logger.set_print_directly(true);
345+
});
346+
323347
let (mut page_rows, mut offsets) = compute_page_line_offsets(&body);
324348
let mut last_batch = offsets.len() - 1;
325349

@@ -398,7 +422,8 @@ fn read_command(
398422
// TODO: maybe enable raw mode only once per pagination
399423
crossterm::terminal::enable_raw_mode()?;
400424
let _cleanup = OnceDestructor::new(|| {
401-
crossterm::terminal::disable_raw_mode().expect("Should not fail normally")
425+
// Same as in `paginate_output`, we can't do much about the possible error, so we just panic.
426+
crossterm::terminal::disable_raw_mode().expect("failure when disabling raw terminal mode")
402427
});
403428

404429
loop {

0 commit comments

Comments
 (0)