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
This commit is contained in:
shugo 2010-02-06 14:26:07 +00:00
parent 3b21e88faa
commit 5fe1f62633

View File

@ -2,16 +2,22 @@
require "curses" require "curses"
if ARGV.size != 1 then
printf("usage: view file\n"); # A curses based file viewer
exit class FileViewer
end
begin # Create a new fileviewer, and view the file.
fp = open(ARGV[0], "r") def initialize(filename)
rescue @data_lines = []
raise "cannot open file: #{ARGV[1]}" @screen = nil
@top = nil
init_curses
load_file(filename)
interact
end end
# Perform the curses setup
def init_curses
# signal(SIGINT, finish) # signal(SIGINT, finish)
Curses.init_screen Curses.init_screen
@ -19,34 +25,42 @@ Curses.nonl
Curses.cbreak Curses.cbreak
Curses.noecho Curses.noecho
$screen = Curses.stdscr @screen = Curses.stdscr
$screen.scrollok(true) @screen.scrollok(true)
#$screen.keypad(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 # slurp the file
$data_lines = []
fp.each_line { |l| fp.each_line { |l|
$data_lines.push(l.chop) @data_lines.push(l.chop)
} }
fp.close end
@top = 0
$top = 0 @data_lines[0..@screen.maxy-1].each_with_index{|line, idx|
$data_lines[0..$screen.maxy-1].each_with_index{|line, idx| @screen.setpos(idx, 0)
$screen.setpos(idx, 0) @screen.addstr(line)
$screen.addstr(line)
} }
$screen.setpos(0,0) @screen.setpos(0,0)
$screen.refresh @screen.refresh
rescue
raise "cannot open file '#{filename}' for reading"
end
# Scroll the display up by one line
def scroll_up def scroll_up
if( $top > 0 ) if( @top > 0 )
$screen.scrl(-1) @screen.scrl(-1)
$top -= 1 @top -= 1
str = $data_lines[$top] str = @data_lines[@top]
if( str ) if( str )
$screen.setpos(0, 0) @screen.setpos(0, 0)
$screen.addstr(str) @screen.addstr(str)
end end
return true return true
else else
@ -54,14 +68,15 @@ def scroll_up
end end
end end
# Scroll the display down by one line
def scroll_down def scroll_down
if( $top + $screen.maxy < $data_lines.length ) if( @top + @screen.maxy < @data_lines.length )
$screen.scrl(1) @screen.scrl(1)
$top += 1 @top += 1
str = $data_lines[$top + $screen.maxy - 1] str = @data_lines[@top + @screen.maxy - 1]
if( str ) if( str )
$screen.setpos($screen.maxy - 1, 0) @screen.setpos(@screen.maxy - 1, 0)
$screen.addstr(str) @screen.addstr(str)
end end
return true return true
else else
@ -69,16 +84,22 @@ def scroll_down
end end
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 while true
result = true result = true
c = Curses.getch c = Curses.getch
case c case c
when Curses::KEY_DOWN, Curses::KEY_CTRL_N when Curses::KEY_DOWN, Curses::KEY_CTRL_N, ?j
result = scroll_down result = scroll_down
when Curses::KEY_UP, Curses::KEY_CTRL_P when Curses::KEY_UP, Curses::KEY_CTRL_P, ?k
result = scroll_up result = scroll_up
when Curses::KEY_NPAGE, ?\s # white space when Curses::KEY_NPAGE, ?\s # white space
for i in 0..($screen.maxy - 2) for i in 0..(@screen.maxy - 2)
if( ! scroll_down ) if( ! scroll_down )
if( i == 0 ) if( i == 0 )
result = false result = false
@ -87,7 +108,7 @@ while true
end end
end end
when Curses::KEY_PPAGE when Curses::KEY_PPAGE
for i in 0..($screen.maxy - 2) for i in 0..(@screen.maxy - 2)
if( ! scroll_up ) if( ! scroll_up )
if( i == 0 ) if( i == 0 )
result = false result = false
@ -95,21 +116,34 @@ while true
break break
end end
end end
when Curses::KEY_LEFT, Curses::KEY_CTRL_T when Curses::KEY_LEFT, Curses::KEY_CTRL_T, ?h
while( scroll_up ) while( scroll_up )
end end
when Curses::KEY_RIGHT, Curses::KEY_CTRL_B when Curses::KEY_RIGHT, Curses::KEY_CTRL_B, ?l
while( scroll_down ) while( scroll_down )
end end
when ?q when ?q
break break
else else
$screen.setpos(0,0) @screen.setpos(0,0)
$screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ") @screen.addstr("[unknown key `#{Curses.keyname(c)}'=#{c}] ")
end end
if( !result ) if( !result )
Curses.beep Curses.beep
end end
$screen.setpos(0,0) @screen.setpos(0,0)
end end
Curses.close_screen 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