@@ -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