diff options
Diffstat (limited to 'sample/curses/view2.rb')
-rw-r--r-- | sample/curses/view2.rb | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/sample/curses/view2.rb b/sample/curses/view2.rb new file mode 100644 index 0000000000..037771a226 --- /dev/null +++ b/sample/curses/view2.rb @@ -0,0 +1,149 @@ +#!/usr/local/bin/ruby + +require "curses" + + +# 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 + + # 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 + @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 + + + # 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 + 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 + 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 + Curses.close_screen + end +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 + + viewer = FileViewer.new(ARGV[0]) +end |