-
Notifications
You must be signed in to change notification settings - Fork 14.1k
Add pager support for rustc --explain EXXXX
#42732
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
Changes from 1 commit
3146e55
1beeb5a
08b6beb
7b0a7fd
0e18a9c
e1a9144
06de114
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -84,10 +84,11 @@ use std::cmp::max; | |
| use std::cmp::Ordering::Equal; | ||
| use std::default::Default; | ||
| use std::env; | ||
| use std::ffi::OsString; | ||
| use std::io::{self, Read, Write}; | ||
| use std::iter::repeat; | ||
| use std::path::PathBuf; | ||
| use std::process; | ||
| use std::process::{self, Command, Stdio}; | ||
| use std::rc::Rc; | ||
| use std::str; | ||
| use std::sync::{Arc, Mutex}; | ||
|
|
@@ -354,27 +355,66 @@ fn handle_explain(code: &str, | |
| match descriptions.find_description(&normalised) { | ||
| Some(ref description) => { | ||
| let mut is_in_code_block = false; | ||
| let mut text = String::new(); | ||
|
|
||
| // Slice off the leading newline and print. | ||
| for line in description[1..].lines() { | ||
| let indent_level = line.find(|c: char| !c.is_whitespace()) | ||
| .unwrap_or_else(|| line.len()); | ||
| let dedented_line = &line[indent_level..]; | ||
| if dedented_line.starts_with("```") { | ||
| is_in_code_block = !is_in_code_block; | ||
| println!("{}", &line[..(indent_level+3)]); | ||
| text.push_str(&line[..(indent_level+3)]); | ||
| text.push('\n'); | ||
| } else if is_in_code_block && dedented_line.starts_with("# ") { | ||
| continue; | ||
| } else { | ||
| println!("{}", line); | ||
| text.push_str(line); | ||
| text.push('\n'); | ||
| } | ||
| } | ||
|
|
||
| show_content_with_pager(&text); | ||
| } | ||
| None => { | ||
| early_error(output, &format!("no extended information for {}", code)); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| fn show_content_with_pager(content: &String) { | ||
| let pager_name = env::var_os("PAGER").unwrap_or(if cfg!(windows) { | ||
| OsString::from("more.com") | ||
|
||
| } else { | ||
| OsString::from("less") | ||
| }); | ||
|
|
||
| let mut fallback_to_println = false; | ||
|
|
||
| match Command::new(pager_name).stdin(Stdio::piped()).spawn() { | ||
| Ok(mut pager) => { | ||
| if let Some(mut pipe) = pager.stdin.as_mut() { | ||
| if pipe.write_all(content.as_bytes()).is_err() { | ||
| fallback_to_println = true; | ||
| } | ||
| } | ||
|
|
||
| if pager.wait().is_err() { | ||
| fallback_to_println = true; | ||
| } | ||
| } | ||
| Err(_) => { | ||
| fallback_to_println = true; | ||
| } | ||
| } | ||
|
|
||
| // If pager fails for whatever reason, we should still print the content | ||
|
||
| // to standard output | ||
| if fallback_to_println { | ||
| println!("{}", content); | ||
|
||
| } | ||
| } | ||
|
|
||
| impl<'a> CompilerCalls<'a> for RustcDefaultCalls { | ||
| fn early_callback(&mut self, | ||
| matches: &getopts::Matches, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@carols10cents maybe this can be prettier. Suggestions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO It's ok to do that
push(). Though you are doing it here and in like375, so you are adding a carriage return regardless of theifstatement, I would just put a single one between lines376-377instead, but that is totally a nitpick.