@@ -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,65 @@ 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 ) ] ) ;
367370 } else if is_in_code_block && dedented_line. starts_with ( "# " ) {
368371 continue ;
369372 } else {
370- println ! ( "{}" , line) ;
373+ text . push_str ( line) ;
371374 }
375+ text. push ( '\n' ) ;
372376 }
377+
378+ show_content_with_pager ( & text) ;
373379 }
374380 None => {
375381 early_error ( output, & format ! ( "no extended information for {}" , code) ) ;
376382 }
377383 }
378384}
379385
386+ fn show_content_with_pager ( content : & String ) {
387+ let pager_name = env:: var_os ( "PAGER" ) . unwrap_or_else ( || if cfg ! ( windows) {
388+ OsString :: from ( "more.com" )
389+ } else {
390+ OsString :: from ( "less" )
391+ } ) ;
392+
393+ let mut fallback_to_println = false ;
394+
395+ match Command :: new ( pager_name) . stdin ( Stdio :: piped ( ) ) . spawn ( ) {
396+ Ok ( mut pager) => {
397+ if let Some ( mut pipe) = pager. stdin . as_mut ( ) {
398+ if pipe. write_all ( content. as_bytes ( ) ) . is_err ( ) {
399+ fallback_to_println = true ;
400+ }
401+ }
402+
403+ if pager. wait ( ) . is_err ( ) {
404+ fallback_to_println = true ;
405+ }
406+ }
407+ Err ( _) => {
408+ fallback_to_println = true ;
409+ }
410+ }
411+
412+ // If pager fails for whatever reason, we should still print the content
413+ // to standard output
414+ if fallback_to_println {
415+ print ! ( "{}" , content) ;
416+ }
417+ }
418+
380419impl < ' a > CompilerCalls < ' a > for RustcDefaultCalls {
381420 fn early_callback ( & mut self ,
382421 matches : & getopts:: Matches ,
0 commit comments