Skip to content

Commit ccfa9c4

Browse files
committed
use PAGER to view --explain output #32665
1 parent 7acce37 commit ccfa9c4

File tree

1 file changed

+43
-3
lines changed

1 file changed

+43
-3
lines changed

src/librustc_driver/lib.rs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,11 @@ use std::cmp::max;
8383
use std::cmp::Ordering::Equal;
8484
use std::default::Default;
8585
use std::env;
86+
use std::ffi::OsString;
8687
use std::io::{self, Read, Write};
8788
use std::iter::repeat;
8889
use std::path::PathBuf;
89-
use std::process;
90+
use std::process::{self, Command, Stdio};
9091
use std::rc::Rc;
9192
use std::str;
9293
use std::sync::{Arc, Mutex};
@@ -356,27 +357,66 @@ fn handle_explain(code: &str,
356357
match descriptions.find_description(&normalised) {
357358
Some(ref description) => {
358359
let mut is_in_code_block = false;
360+
let mut text = String::new();
361+
359362
// Slice off the leading newline and print.
360363
for line in description[1..].lines() {
361364
let indent_level = line.find(|c: char| !c.is_whitespace())
362365
.unwrap_or_else(|| line.len());
363366
let dedented_line = &line[indent_level..];
364367
if dedented_line.starts_with("```") {
365368
is_in_code_block = !is_in_code_block;
366-
println!("{}", &line[..(indent_level+3)]);
369+
text.push_str(&line[..(indent_level+3)]);
370+
text.push('\n');
367371
} else if is_in_code_block && dedented_line.starts_with("# ") {
368372
continue;
369373
} else {
370-
println!("{}", line);
374+
text.push_str(line);
375+
text.push('\n');
371376
}
372377
}
378+
379+
show_content_with_pager(&text);
373380
}
374381
None => {
375382
early_error(output, &format!("no extended information for {}", code));
376383
}
377384
}
378385
}
379386

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

0 commit comments

Comments
 (0)