@@ -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,66 @@ 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 ) ] ) ;
370
+ text. push ( '\n' ) ;
367
371
} else if is_in_code_block && dedented_line. starts_with ( "# " ) {
368
372
continue ;
369
373
} else {
370
- println ! ( "{}" , line) ;
374
+ text. push_str ( line) ;
375
+ text. push ( '\n' ) ;
371
376
}
372
377
}
378
+
379
+ show_content_with_pager ( & text) ;
373
380
}
374
381
None => {
375
382
early_error ( output, & format ! ( "no extended information for {}" , code) ) ;
376
383
}
377
384
}
378
385
}
379
386
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
+
380
420
impl < ' a > CompilerCalls < ' a > for RustcDefaultCalls {
381
421
fn early_callback ( & mut self ,
382
422
matches : & getopts:: Matches ,
0 commit comments