@@ -83,10 +83,11 @@ use std::cmp::max;
8383use std:: cmp:: Ordering :: Equal ;
8484use std:: default:: Default ;
8585use std:: env;
86+ use std:: ffi:: OsString ;
8687use std:: io:: { self , Read , Write } ;
8788use std:: iter:: repeat;
8889use std:: path:: PathBuf ;
89- use std:: process;
90+ use std:: process:: { self , Command , Stdio } ;
9091use std:: rc:: Rc ;
9192use std:: str;
9293use 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+
380420impl < ' a > CompilerCalls < ' a > for RustcDefaultCalls {
381421 fn early_callback ( & mut self ,
382422 matches : & getopts:: Matches ,
0 commit comments