Advertisement
dravster

Scroller.pl "A scrolling window for terse output"

Aug 25th, 2013
286
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 3.15 KB | None | 0 0
  1. #! /usr/bin/perl
  2. #
  3. # A script born out of a discussion thread:
  4. # http://unix.stackexchange.com/questions/88159/only-output-most-recent-10-or-n-lines-of-a-lengthy-command-output
  5. #
  6. # scroller.pl <offset> <size> <headerfile>
  7. # Create a scroll window of <size> lines long at row <offset>, displaying a <headerfile> before this
  8. # window.
  9. #
  10. # <offset>, <size> and <headerfile> are all optional.
  11. # <offset> and <size> can be set to '-' to make it use the whole window size.
  12. #
  13. # The scroll window displays everything passed on STDIN.
  14. #
  15. # Examples:
  16. #
  17. #    tar -zcvf mybackup.tgz / | scroller.pl                 # scroll the tar in the whole term screen
  18. #    tar -zcvf mybackup.tgz / | scroller.pl 5 18            # scroll at line 5 an 18 line scroll window
  19. #    tar -zcvf mybackup.tgz / | scroller.pl - - headerfile  # print a header file and scroll below it
  20.  
  21. use strict;
  22. use warnings;
  23. use Curses;
  24. use Text::Wrap;
  25.  
  26. # exit curses mode nicely on Ctrl-C
  27. $SIG{INT} = sub { endwin; exit(0); };  
  28.  
  29. my $fsize = 0;
  30. my $a = 0;
  31. my $s;
  32.  
  33. # read in a file if set on argv[2]
  34. my $file = $ARGV[2];
  35. if(defined $file) {
  36.     local($/) = undef;
  37.     open(TMP, "<$file") or die "Failed to open file: $file\n";
  38.     $file = <TMP>;
  39.     close(TMP);
  40.  
  41.     # work out the number of lines
  42.     $fsize = map $_, $file =~ /\n/gs;
  43.     $fsize++;
  44. }
  45.  
  46. # initialize curses
  47. initscr();
  48.  
  49. # create and output the file window if a file was provided
  50. if($file) {
  51.     $s = newwin($fsize, COLS(), 0, 1) if($file);
  52.     if(!defined $s) { endwin; die "Failed to create file window!" }
  53.     $s->addstr(0,0,$file);
  54.     $s->refresh();
  55.  
  56. # else set where to wrap (used when no file is provided to stop scroll buffer spamming)
  57. } else {
  58.     $Text::Wrap::columns = COLS()-1;
  59. }
  60.  
  61.  
  62. # use the first argument for the offset (what line to start the scrolling window at)
  63. # or calc the size of the offset taking into consideration the potential "header file"
  64. my $offset;
  65. if($ARGV[0] && $ARGV[0] ne '-') {
  66.     $offset = $ARGV[0];
  67.  
  68.     if($offset <= $fsize) {
  69.         endwin;
  70.         die "Offset is smaller than the length of the file provided";
  71.     }  
  72. } else {
  73.     $offset = ($fsize ? $fsize : 1);
  74. }  
  75.  
  76. # Use the 2nd argument for the length of the scroll window, or calculate it
  77. # how many rows long is this window?
  78. my $rows;
  79. if ($ARGV[1] and $ARGV[1] ne '-') {
  80.     $rows = $ARGV[1]+1;
  81. } else {
  82.     $rows = LINES() - $offset;
  83. }  
  84.  
  85. # create the window and set scrolling to true
  86. my $w = newwin($rows, COLS(), $offset, 1);
  87. if(!defined $w) { endwin; die "Failed to create window!" }
  88. $w->scrollok(1);
  89.  
  90. # process the input
  91. while(<STDIN>) {
  92.     my $line = $_;
  93.  
  94.     $a++ if($a < $rows-1);
  95.  
  96.     # if a file is defined, the window above will stop the scroll buffer of the terminal getting
  97.     # filled with long lines, just add the string and refresh
  98.     if($file) {
  99.         $w->addstr($a, 0, $line);
  100.         $w->refresh();
  101.  
  102.     # else we have to split the lines and add each line individually
  103.     } else {
  104.         foreach( split(/\n/, wrap('', '', $line)) ) {
  105.             $w->addstr($a, 0, "$_\n");
  106.             $w->refresh();
  107.         }
  108.     }
  109. }
  110.  
  111. # all done send the endwin sequence
  112. endwin;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement