Skip to content

Commit 3146e55

Browse files
committed
use PAGER to view --explain output #32665
1 parent 1d2db7b commit 3146e55

File tree

1 file changed

+43
-3
lines changed

1 file changed

+43
-3
lines changed

src/librustc_driver/lib.rs

+43-3
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,11 @@ use std::cmp::max;
8484
use std::cmp::Ordering::Equal;
8585
use std::default::Default;
8686
use std::env;
87+
use std::ffi::OsString;
8788
use std::io::{self, Read, Write};
8889
use std::iter::repeat;
8990
use std::path::PathBuf;
90-
use std::process;
91+
use std::process::{self, Command, Stdio};
9192
use std::rc::Rc;
9293
use std::str;
9394
use std::sync::{Arc, Mutex};
@@ -354,27 +355,66 @@ fn handle_explain(code: &str,
354355
match descriptions.find_description(&normalised) {
355356
Some(ref description) => {
356357
let mut is_in_code_block = false;
358+
let mut text = String::new();
359+
357360
// Slice off the leading newline and print.
358361
for line in description[1..].lines() {
359362
let indent_level = line.find(|c: char| !c.is_whitespace())
360363
.unwrap_or_else(|| line.len());
361364
let dedented_line = &line[indent_level..];
362365
if dedented_line.starts_with("```") {
363366
is_in_code_block = !is_in_code_block;
364-
println!("{}", &line[..(indent_level+3)]);
367+
text.push_str(&line[..(indent_level+3)]);
368+
text.push('\n');
365369
} else if is_in_code_block && dedented_line.starts_with("# ") {
366370
continue;
367371
} else {
368-
println!("{}", line);
372+
text.push_str(line);
373+
text.push('\n');
369374
}
370375
}
376+
377+
show_content_with_pager(&text);
371378
}
372379
None => {
373380
early_error(output, &format!("no extended information for {}", code));
374381
}
375382
}
376383
}
377384

385+
fn show_content_with_pager(content: &String) {
386+
let pager_name = env::var_os("PAGER").unwrap_or(if cfg!(windows) {
387+
OsString::from("more.com")
388+
} else {
389+
OsString::from("less")
390+
});
391+
392+
let mut fallback_to_println = false;
393+
394+
match Command::new(pager_name).stdin(Stdio::piped()).spawn() {
395+
Ok(mut pager) => {
396+
if let Some(mut pipe) = pager.stdin.as_mut() {
397+
if pipe.write_all(content.as_bytes()).is_err() {
398+
fallback_to_println = true;
399+
}
400+
}
401+
402+
if pager.wait().is_err() {
403+
fallback_to_println = true;
404+
}
405+
}
406+
Err(_) => {
407+
fallback_to_println = true;
408+
}
409+
}
410+
411+
// If pager fails for whatever reason, we should still print the content
412+
// to standard output
413+
if fallback_to_println {
414+
println!("{}", content);
415+
}
416+
}
417+
378418
impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
379419
fn early_callback(&mut self,
380420
matches: &getopts::Matches,

0 commit comments

Comments
 (0)