@@ -83,10 +83,11 @@ use std::cmp::max;
83
83
use std:: cmp:: Ordering :: Equal ;
84
84
use std:: default:: Default ;
85
85
use std:: env;
86
+ use std:: ffi:: OsString ;
86
87
use std:: io:: { self , Read , Write } ;
87
88
use std:: iter:: repeat;
88
89
use std:: path:: PathBuf ;
89
- use std:: process;
90
+ use std:: process:: { self , Command , Stdio } ;
90
91
use std:: rc:: Rc ;
91
92
use std:: str;
92
93
use std:: sync:: { Arc , Mutex } ;
@@ -356,27 +357,65 @@ fn handle_explain(code: &str,
356
357
match descriptions. find_description ( & normalised) {
357
358
Some ( ref description) => {
358
359
let mut is_in_code_block = false ;
360
+ let mut text = String :: new ( ) ;
361
+
359
362
// Slice off the leading newline and print.
360
363
for line in description[ 1 ..] . lines ( ) {
361
364
let indent_level = line. find ( |c : char | !c. is_whitespace ( ) )
362
365
. unwrap_or_else ( || line. len ( ) ) ;
363
366
let dedented_line = & line[ indent_level..] ;
364
367
if dedented_line. starts_with ( "```" ) {
365
368
is_in_code_block = !is_in_code_block;
366
- println ! ( "{}" , & line[ ..( indent_level+3 ) ] ) ;
369
+ text . push_str ( & line[ ..( indent_level+3 ) ] ) ;
367
370
} else if is_in_code_block && dedented_line. starts_with ( "# " ) {
368
371
continue ;
369
372
} else {
370
- println ! ( "{}" , line) ;
373
+ text . push_str ( line) ;
371
374
}
375
+ text. push ( '\n' ) ;
372
376
}
377
+
378
+ show_content_with_pager ( & text) ;
373
379
}
374
380
None => {
375
381
early_error ( output, & format ! ( "no extended information for {}" , code) ) ;
376
382
}
377
383
}
378
384
}
379
385
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
+
380
419
impl < ' a > CompilerCalls < ' a > for RustcDefaultCalls {
381
420
fn early_callback ( & mut self ,
382
421
matches : & getopts:: Matches ,
0 commit comments