From 5fe1f62633fb71f6e2450acc77605d1102a24e6e Mon Sep 17 00:00:00 2001 From: shugo Date: Sat, 6 Feb 2010 14:26:07 +0000 Subject: ext/curses/view2.rb: replaced with Hugh Sasse's version. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/curses/view2.rb | 228 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 131 insertions(+), 97 deletions(-) (limited to 'ext/curses/view2.rb') diff --git a/ext/curses/view2.rb b/ext/curses/view2.rb index 18d9619216..037771a226 100644 --- a/ext/curses/view2.rb +++ b/ext/curses/view2.rb @@ -2,114 +2,148 @@ require "curses" -if ARGV.size != 1 then - printf("usage: view file\n"); - exit -end -begin - fp = open(ARGV[0], "r") -rescue - raise "cannot open file: #{ARGV[1]}" -end -# signal(SIGINT, finish) - -Curses.init_screen -Curses.nonl -Curses.cbreak -Curses.noecho - -$screen = Curses.stdscr - -$screen.scrollok(true) -#$screen.keypad(true) - -# slurp the file -$data_lines = [] -fp.each_line { |l| - $data_lines.push(l.chop) -} -fp.close - -$top = 0 -$data_lines[0..$screen.maxy-1].each_with_index{|line, idx| - $screen.setpos(idx, 0) - $screen.addstr(line) -} -$screen.setpos(0,0) -$screen.refresh - -def scroll_up - if( $top > 0 ) - $screen.scrl(-1) - $top -= 1 - str = $data_lines[$top] - if( str ) - $screen.setpos(0, 0) - $screen.addstr(str) - end - return true - else - return false +# A curses based file viewer +class FileViewer + + # Create a new fileviewer, and view the file. + def initialize(filename) + @data_lines = [] + @screen = nil + @top = nil + init_curses + load_file(filename) + interact end -end -def scroll_down - if( $top + $screen.maxy < $data_lines.length ) - $screen.scrl(1) - $top += 1 - str = $data_lines[$top + $screen.maxy - 1] - if( str ) - $screen.setpos($screen.maxy - 1, 0) - $screen.addstr(str) + # Perform the curses setup + def init_curses + # signal(SIGINT, finish) + + Curses.init_screen + Curses.nonl + Curses.cbreak + Curses.noecho + + @screen = Curses.stdscr + + @screen.scrollok(true) + #$screen.keypad(true) + end + + # Load the file into memory, and put + # the first part on the curses display. + def load_file(filename) + fp = open(filename, "r") do |fp| + # slurp the file + fp.each_line { |l| + @data_lines.push(l.chop) + } end - return true - else - return false + @top = 0 + @data_lines[0..@screen.maxy-1].each_with_index{|line, idx| + @screen.setpos(idx, 0) + @screen.addstr(line) + } + @screen.setpos(0,0) + @screen.refresh + rescue + raise "cannot open file '#{filename}' for reading" end -end -while true - result = true - c = Curses.getch - case c - when Curses::KEY_DOWN, Curses::KEY_CTRL_N - result = scroll_down - when Curses::KEY_UP, Curses::KEY_CTRL_P - result = scroll_up - when Curses::KEY_NPAGE, ?\s # white space - for i in 0..($screen.maxy - 2) - if( ! scroll_down ) - if( i == 0 ) - result = false - end - break + + # Scroll the display up by one line + def scroll_up + if( @top > 0 ) + @screen.scrl(-1) + @top -= 1 + str = @data_lines[@top] + if( str ) + @screen.setpos(0, 0) + @screen.addstr(str) end + return true + else + return false end - when Curses::KEY_PPAGE - for i in 0..($screen.maxy - 2) - if( ! scroll_up ) - if( i == 0 ) - result = false - end - break + end + + # Scroll the display down by one line + def scroll_down + if( @top + @screen.maxy < @data_lines.length ) + @screen.scrl(1) + @top += 1 + str = @data_lines[@top + @screen.maxy - 1] + if( str ) + @screen.setpos(@screen.maxy - 1, 0) + @screen.addstr(str) end + return true + else + return false end - when Curses::KEY_LEFT, Curses::KEY_CTRL_T - while( scroll_up ) - end - when Curses::KEY_RIGHT, Curses::KEY_CTRL_B - while( scroll_down ) + end + + # Allow the user to interact with the display. + # This uses EMACS-like keybindings, and also + # vi-like keybindings as well, except that left + # and right move to the beginning and end of the + # file, respectively. + def interact + while true + result = true + c = Curses.getch + case c + when Curses::KEY_DOWN, Curses::KEY_CTRL_N, ?j + result = scroll_down + when Curses::KEY_UP, Curses::KEY_CTRL_P, ?k + result = scroll_up + when Curses::KEY_NPAGE, ?\s # white space + for i in 0..(@screen.maxy - 2) + if( ! scroll_down ) + if( i == 0 ) + result = false + end + break + end + end + when Curses::KEY_PPAGE + for i in 0..(@screen.maxy - 2) + if( ! scroll_up ) + if( i == 0 ) + result = false + end + break + end + end + when Curses::KEY_LEFT, Curses::KEY_CTRL_T, ?h + while( scroll_up ) + end + when Curses::KEY_RIGHT, Curses::KEY_CTRL_B, ?l + while( scroll_down ) + end + when ?q + break + else + @screen.setpos(0,0) + @screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ") + end + if( !result ) + Curses.beep + end + @screen.setpos(0,0) end - when ?q - break - else - $screen.setpos(0,0) - $screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ") + Curses.close_screen end - if( !result ) - Curses.beep +end + + +# If we are being run as a main program... +if __FILE__ == $0 + if ARGV.size != 1 then + printf("usage: #{$0} file\n"); + exit end - $screen.setpos(0,0) + + viewer = FileViewer.new(ARGV[0]) end -Curses.close_screen -- cgit v1.2.3