lib/textbringer/window.rb in textbringer-0.1.6 vs lib/textbringer/window.rb in textbringer-0.1.7
- old
+ new
@@ -3,47 +3,53 @@
require "curses"
require "unicode/display_width"
require "fiddle/import"
module Textbringer
- begin
- # These features should be provided by curses.gem.
- module PDCurses
+ # These features should be provided by curses.gem.
+ module PDCurses
+ KEY_OFFSET = 0xec00
+ ALT_0 = KEY_OFFSET + 0x97
+ ALT_9 = KEY_OFFSET + 0xa0
+ ALT_A = KEY_OFFSET + 0xa1
+ ALT_Z = KEY_OFFSET + 0xba
+ ALT_NUMBER_BASE = ALT_0 - ?0.ord
+ ALT_ALPHA_BASE = ALT_A - ?a.ord
+
+ KEY_MODIFIER_SHIFT = 1
+ KEY_MODIFIER_CONTROL = 2
+ KEY_MODIFIER_ALT = 4
+ KEY_MODIFIER_NUMLOCK = 8
+
+ @dll_loaded = false
+
+ class << self
+ attr_writer :dll_loaded
+
+ def dll_loaded?
+ @dll_loaded
+ end
+ end
+
+ begin
extend Fiddle::Importer
dlload "pdcurses.dll"
extern "unsigned long PDC_get_key_modifiers(void)"
extern "int PDC_save_key_modifiers(unsigned char)"
extern "int PDC_return_key_modifiers(unsigned char)"
-
- KEY_MODIFIER_SHIFT = 1
- KEY_MODIFIER_CONTROL = 2
- KEY_MODIFIER_ALT = 4
- KEY_MODIFIER_NUMLOCK = 8
+ @dll_loaded = true
+ rescue Fiddle::DLError
end
- rescue
- remove_const :PDCurses
end
class Window
KEY_NAMES = {}
Curses.constants.grep(/\AKEY_/).each do |name|
KEY_NAMES[Curses.const_get(name)] =
name.slice(/\AKEY_(.*)/, 1).downcase.intern
end
- ALT_IS_FUNCTION_KEY =
- /mswin32|mingw32/ =~ RUBY_PLATFORM && /PDCurses/ =~ Curses::VERSION
- if ALT_IS_FUNCTION_KEY
- KEY_OFFSET = 0xec00
- ALT_0 = KEY_OFFSET + 0x97
- ALT_9 = KEY_OFFSET + 0xa0
- ALT_A = KEY_OFFSET + 0xa1
- ALT_Z = KEY_OFFSET + 0xba
- ALT_NUMBER_BASE = ALT_0 - ?0.ord
- ALT_ALPHA_BASE = ALT_A - ?a.ord
- end
-
@@windows = []
@@current = nil
@@echo_area = nil
def self.windows
@@ -265,16 +271,16 @@
end
def read_char
key = get_char
if key.is_a?(Integer)
- if ALT_IS_FUNCTION_KEY
- if ALT_0 <= key && key <= ALT_9
- @key_buffer.push((key - ALT_NUMBER_BASE).chr)
+ if PDCurses.dll_loaded?
+ if PDCurses::ALT_0 <= key && key <= PDCurses::ALT_9
+ @key_buffer.push((key - PDCurses::ALT_NUMBER_BASE).chr)
return "\e"
- elsif ALT_A <= key && key <= ALT_Z
- @key_buffer.push((key - ALT_ALPHA_BASE).chr)
+ elsif PDCurses::ALT_A <= key && key <= PDCurses::ALT_Z
+ @key_buffer.push((key - PDCurses::ALT_ALPHA_BASE).chr)
return "\e"
end
end
KEY_NAMES[key] || key
else
@@ -290,10 +296,13 @@
@window.nodelay = false
end
end
def wait_input(msecs)
+ unless @key_buffer.empty?
+ return @key_buffer.first
+ end
@window.timeout = msecs
begin
c = @window.get_char
if c
Curses.unget_char(c)
@@ -303,10 +312,13 @@
@window.timeout = -1
end
end
def has_input?
+ unless @key_buffer.empty?
+ return true
+ end
@window.nodelay = true
begin
c = @window.get_char
if c
Curses.unget_char(c)
@@ -444,17 +456,23 @@
recenter
end
end
def scroll_up
+ if @bottom_of_window.location == @buffer.point_max
+ raise EditorError, "End of buffer"
+ end
@buffer.point_to_mark(@bottom_of_window)
@buffer.previous_line
@buffer.beginning_of_line
@buffer.mark_to_point(@top_of_window)
end
def scroll_down
+ if @top_of_window.location == @buffer.point_min
+ raise EditorError, "Beginning of buffer"
+ end
@buffer.point_to_mark(@top_of_window)
@buffer.next_line
@buffer.beginning_of_line
@top_of_window.location = 0
end
@@ -605,14 +623,14 @@
end
end
def get_char
if @key_buffer.empty?
- PDCurses.PDC_save_key_modifiers(1) if defined?(PDCurses)
+ PDCurses.PDC_save_key_modifiers(1) if PDCurses.dll_loaded?
begin
need_retry = false
key = @window.get_char
- if defined?(PDCurses)
+ if PDCurses.dll_loaded?
mods = PDCurses.PDC_get_key_modifiers
if key.is_a?(String) && key.ascii_only?
if (mods & PDCurses::KEY_MODIFIER_CONTROL) != 0
key = key == ?? ? "\x7f" : (key.ord & 0x9f).chr
end