@@ -84,10 +84,11 @@ use std::cmp::max;
84
84
use std:: cmp:: Ordering :: Equal ;
85
85
use std:: default:: Default ;
86
86
use std:: env;
87
+ use std:: ffi:: OsString ;
87
88
use std:: io:: { self , Read , Write } ;
88
89
use std:: iter:: repeat;
89
90
use std:: path:: PathBuf ;
90
- use std:: process;
91
+ use std:: process:: { self , Command , Stdio } ;
91
92
use std:: rc:: Rc ;
92
93
use std:: str;
93
94
use std:: sync:: { Arc , Mutex } ;
@@ -354,27 +355,66 @@ fn handle_explain(code: &str,
354
355
match descriptions. find_description ( & normalised) {
355
356
Some ( ref description) => {
356
357
let mut is_in_code_block = false ;
358
+ let mut text = String :: new ( ) ;
359
+
357
360
// Slice off the leading newline and print.
358
361
for line in description[ 1 ..] . lines ( ) {
359
362
let indent_level = line. find ( |c : char | !c. is_whitespace ( ) )
360
363
. unwrap_or_else ( || line. len ( ) ) ;
361
364
let dedented_line = & line[ indent_level..] ;
362
365
if dedented_line. starts_with ( "```" ) {
363
366
is_in_code_block = !is_in_code_block;
364
- println ! ( "{}" , & line[ ..( indent_level+3 ) ] ) ;
367
+ text. push_str ( & line[ ..( indent_level+3 ) ] ) ;
368
+ text. push ( '\n' ) ;
365
369
} else if is_in_code_block && dedented_line. starts_with ( "# " ) {
366
370
continue ;
367
371
} else {
368
- println ! ( "{}" , line) ;
372
+ text. push_str ( line) ;
373
+ text. push ( '\n' ) ;
369
374
}
370
375
}
376
+
377
+ show_content_with_pager ( & text) ;
371
378
}
372
379
None => {
373
380
early_error ( output, & format ! ( "no extended information for {}" , code) ) ;
374
381
}
375
382
}
376
383
}
377
384
385
+ fn show_content_with_pager ( content : & String ) {
386
+ let pager_name = env:: var_os ( "PAGER" ) . unwrap_or ( if cfg ! ( windows) {
387
+ OsString :: from ( "more.com" )
388
+ } else {
389
+ OsString :: from ( "less" )
390
+ } ) ;
391
+
392
+ let mut fallback_to_println = false ;
393
+
394
+ match Command :: new ( pager_name) . stdin ( Stdio :: piped ( ) ) . spawn ( ) {
395
+ Ok ( mut pager) => {
396
+ if let Some ( mut pipe) = pager. stdin . as_mut ( ) {
397
+ if pipe. write_all ( content. as_bytes ( ) ) . is_err ( ) {
398
+ fallback_to_println = true ;
399
+ }
400
+ }
401
+
402
+ if pager. wait ( ) . is_err ( ) {
403
+ fallback_to_println = true ;
404
+ }
405
+ }
406
+ Err ( _) => {
407
+ fallback_to_println = true ;
408
+ }
409
+ }
410
+
411
+ // If pager fails for whatever reason, we should still print the content
412
+ // to standard output
413
+ if fallback_to_println {
414
+ println ! ( "{}" , content) ;
415
+ }
416
+ }
417
+
378
418
impl < ' a > CompilerCalls < ' a > for RustcDefaultCalls {
379
419
fn early_callback ( & mut self ,
380
420
matches : & getopts:: Matches ,
0 commit comments