rbcurse 1.5.0 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. data/Makefile +21 -0
  2. data/Manifest.txt +6 -0
  3. data/README.markdown +6 -4
  4. data/TODO +372 -0
  5. data/TODO2.txt +121 -0
  6. data/VERSION +1 -1
  7. data/examples/README.txt +67 -0
  8. data/examples/abasiclist.rb +33 -0
  9. data/examples/alpmenu.rb +42 -0
  10. data/examples/app.rb +859 -0
  11. data/examples/app.sample +17 -0
  12. data/examples/appdirtree.rb +74 -0
  13. data/examples/appemail.rb +191 -0
  14. data/examples/appemaillb.rb +308 -0
  15. data/examples/appgcompose.rb +315 -0
  16. data/examples/atree.rb +64 -0
  17. data/examples/common/file.rb +40 -0
  18. data/examples/common/rmail.rb +257 -0
  19. data/examples/data.txt +683 -0
  20. data/examples/data/README.markdown +9 -0
  21. data/examples/data/brew.txt +38 -0
  22. data/examples/data/color.2 +37 -0
  23. data/examples/data/gemlist.txt +60 -0
  24. data/examples/data/lotr.txt +12 -0
  25. data/examples/data/ports.txt +136 -0
  26. data/examples/data/tasks.txt +27 -0
  27. data/examples/data/todocsv.csv +28 -0
  28. data/examples/data/unix1.txt +21 -0
  29. data/examples/data/unix2.txt +11 -0
  30. data/examples/dbdemo.rb +495 -0
  31. data/examples/deprecated/appgmail.rb +952 -0
  32. data/examples/deprecated/splitp.rb +56 -0
  33. data/examples/deprecated/testscrolllb.rb +86 -0
  34. data/examples/deprecated/testscrollp.rb +88 -0
  35. data/examples/deprecated/testscrollta.rb +80 -0
  36. data/examples/deprecated/testscrolltable.rb +165 -0
  37. data/examples/deprecated/testsplit.rb +87 -0
  38. data/examples/deprecated/testsplit2.rb +123 -0
  39. data/examples/deprecated/testsplit3.rb +215 -0
  40. data/examples/deprecated/testsplit3_1.rb +244 -0
  41. data/examples/deprecated/testsplit3a.rb +215 -0
  42. data/examples/deprecated/testsplit3b.rb +237 -0
  43. data/examples/deprecated/testsplitta.rb +148 -0
  44. data/examples/deprecated/testsplittv.rb +142 -0
  45. data/examples/deprecated/testsplittvv.rb +144 -0
  46. data/examples/deprecated/testtpane.rb +215 -0
  47. data/examples/deprecated/testtpane2.rb +145 -0
  48. data/examples/deprecated/testtpanetable.rb +203 -0
  49. data/examples/dirtree.rb +88 -0
  50. data/examples/experimental/resultsetdemo.rb +280 -0
  51. data/examples/experimental/testmform.rb +35 -0
  52. data/examples/experimental/testscroller.rb +117 -0
  53. data/examples/experimental/teststackflow.rb +111 -0
  54. data/examples/menu1.rb +112 -0
  55. data/examples/multispl.rb +86 -0
  56. data/examples/newmessagebox.rb +131 -0
  57. data/examples/newtabbedwindow.rb +100 -0
  58. data/examples/newtesttabp.rb +121 -0
  59. data/examples/qdfilechooser.rb +68 -0
  60. data/examples/rfe.rb +1239 -0
  61. data/examples/rfe_renderer.rb +121 -0
  62. data/examples/sqlc.rb +454 -0
  63. data/examples/sqlm.rb +437 -0
  64. data/examples/sqlt.rb +408 -0
  65. data/examples/status.txt +68 -0
  66. data/examples/table1.rb +24 -0
  67. data/examples/term2.rb +84 -0
  68. data/examples/test1.rb +239 -0
  69. data/examples/test2.rb +674 -0
  70. data/examples/testapp.rb +44 -0
  71. data/examples/testapp2.rb +58 -0
  72. data/examples/testchars.rb +137 -0
  73. data/examples/testcombo.rb +91 -0
  74. data/examples/testkeypress.rb +66 -0
  75. data/examples/testlistbox.rb +113 -0
  76. data/examples/testmenu.rb +101 -0
  77. data/examples/testmulticomp.rb +70 -0
  78. data/examples/testmulticontainer.rb +94 -0
  79. data/examples/testmultispl.rb +199 -0
  80. data/examples/testree.rb +106 -0
  81. data/examples/testtable.rb +264 -0
  82. data/examples/testtabp.rb +107 -0
  83. data/examples/testtodo.rb +584 -0
  84. data/examples/testvimsplit.rb +112 -0
  85. data/examples/testwsshortcuts.rb +64 -0
  86. data/examples/testwsshortcuts2.rb +126 -0
  87. data/examples/todo.db +0 -0
  88. data/examples/todo.yml +191 -0
  89. data/examples/viewtodo.rb +574 -0
  90. data/lib/rbcurse/deprecated/README.markdown +12 -0
  91. data/lib/rbcurse/deprecated/rpad.rb +375 -0
  92. data/lib/rbcurse/deprecated/rscrollpane.rb +512 -0
  93. data/lib/rbcurse/deprecated/rsplitpane.rb +894 -0
  94. data/lib/rbcurse/deprecated/rsplitpane2.rb +1009 -0
  95. data/lib/rbcurse/deprecated/rviewport.rb +204 -0
  96. data/lib/rbcurse/deprecated/widgets/mapper.rb +130 -0
  97. data/lib/rbcurse/deprecated/widgets/rmessagebox.rb +348 -0
  98. data/lib/rbcurse/deprecated/widgets/rtabbedpane.rb +1158 -0
  99. data/lib/rbcurse/deprecated/widgets/rtabbedwindow.rb +167 -0
  100. data/lib/rbcurse/deprecated/widgets/scrollable.rb +301 -0
  101. data/lib/rbcurse/deprecated/widgets/stdscrwindow.rb +309 -0
  102. data/lib/ver/keyboard2.rb +170 -0
  103. data/test/test_rbcurse.rb +0 -0
  104. metadata +131 -9
@@ -0,0 +1,309 @@
1
+ require 'rbcurse/core/system/ncurses'
2
+ module RubyCurses
3
+ #
4
+ # an attempt to make a window based on stdscr for bottom line printing so the entire
5
+ # application can have one pointer, regardless of whether through App
6
+ # or otherwise. This still provides the full getchar operation, copied from
7
+ # Window class which is the main purpose of this. So as to provide ask, agree and say.
8
+ #
9
+ # We should be able to pass this window to bottomline and have one global bottomline
10
+ # created once (by window class ?)
11
+ #
12
+ # FFI: 2011-09-9 The change to FFI has affected this a lot since I do not get window
13
+ # methods in rbcurse for stdscr whereas suprisingly if i run the samples, i get them
14
+ # all.
15
+ #
16
+ # NOTE:
17
+ # WARNING: Pls do not use this class. This was just experimentation. Using stdscr
18
+ # mucks up the display and overwrites objects on the screen. I will remove this class
19
+ # at some time.
20
+ #
21
+ class StdscrWindow
22
+ attr_reader :width, :height, :top, :left
23
+
24
+ def initialize
25
+
26
+ #@window_pointer = FFI::NCurses.initscr
27
+ @window_pointer = Ncurses.initscr # FFIWINDOW
28
+ $log.debug "STDSCR window pointer is #{@window_pointer.class}"
29
+ #$log.debug "STDSCR window pointer mehtods #{@window_pointer.public_methods}"
30
+ $error_message_row ||= Ncurses.LINES-1
31
+ $error_message_col ||= 1
32
+ init_vars
33
+
34
+
35
+ end
36
+ def init_vars
37
+ #Ncurses::keypad(@window_pointer, true)
38
+ Ncurses.keypad(@window_pointer.pointer, true)
39
+ @stack = []
40
+ end
41
+ ##
42
+
43
+ # Ncurses
44
+
45
+
46
+ # taken from Window
47
+ def method_missing(name, *args)
48
+ name = name.to_s
49
+ if (name[0,2] == "mv")
50
+ test_name = name.dup
51
+ test_name[2,0] = "w" # insert "w" after"mv"
52
+ if (@window_pointer.respond_to?(test_name)) # FFIPOINTER
53
+ return @window_pointer.send(test_name,*args)
54
+ end
55
+
56
+ if (FFI::NCurses.respond_to?(test_name))
57
+ return FFI::NCurses.send(test_name, @window_pointer, *args)
58
+ end
59
+ end
60
+ test_name = "w" + name
61
+ # FFI responds but the pointer does not !!! bottomline 1045
62
+ if (@window_pointer.respond_to?(test_name)) # FFIPOINTER
63
+ return @window_pointer.send(test_name,*args)
64
+ end
65
+ if (FFI::NCurses.respond_to?(test_name))
66
+ return FFI::NCurses.send(test_name, @window_pointer, *args)
67
+ end
68
+ # what if it does not respond, can go into loop and give stack overflow
69
+ FFI::NCurses.send(name, @window_pointer, *args)
70
+ end
71
+ def respond_to?(name)
72
+ name = name.to_s
73
+ if (name[0,2] == "mv" && FFI::NCurses.respond_to?("mvw" + name[2..-1]))
74
+ return true
75
+ end
76
+ FFI::NCurses.respond_to?("w" + name) || FFI::NCurses.respond_to?(name)
77
+ end
78
+ #@window.send(meth, *args)
79
+
80
+ # FFI WARNING XXX I think these methods one window_pointer will fail
81
+ # since somehow stdscr is not getting these methods here.
82
+ def print(string, width = width)
83
+ return unless visible?
84
+ @window_pointer.waddnstr(string.to_s, width)
85
+ end
86
+
87
+ def print_yx(string, y = 0, x = 0)
88
+ @window_pointer.mvwaddnstr(y, x, string, width)
89
+ end
90
+
91
+ def print_empty_line
92
+ return unless visible?
93
+ @window_pointer.printw(' ' * width)
94
+ end
95
+
96
+ def print_line(string)
97
+ print(string.ljust(width))
98
+ end
99
+
100
+ def puts(*strings)
101
+ print(strings.join("\n") << "\n")
102
+ end
103
+
104
+ # FFI 2011-09-9 commented off so it goes to method missing
105
+ def XXXrefresh
106
+ @window_pointer.refresh
107
+ end
108
+
109
+
110
+ def color=(color)
111
+ @color = color
112
+ @window_pointer.color_set(color, nil)
113
+ end
114
+
115
+ def highlight_line(color, y, x, max)
116
+ @window_pointer.mvchgat(y, x, max, FFI::NCurses::A_NORMAL, color, nil)
117
+ end
118
+
119
+ def ungetch(ch)
120
+ FFI::NCurses.ungetch(ch)
121
+ end
122
+
123
+ # this used to work fine in ncursesruby
124
+ # but somehow in ffi, stdscr does not have most methods, i am unable to figure
125
+ # this out. C-c will crash this.
126
+ def getch
127
+ c = @window_pointer.getch # FFI NW stdscr must get key not some window
128
+ #raise "Ncurses.stdscr does not have getch" if !Ncurses.stdscr.respond_to? :getch
129
+ #$log.debug " XXXX before calling getch"
130
+ #c = Ncurses.stdscr.getch # FFIW if you use the FFIWINDOW
131
+ #c = FFI::NCurses.getch # FFI 2011-09-9 # without FFIWINDOW
132
+ #$log.debug " XXXX after calling getch #{c}"
133
+ #if c == FFI::NCurses::KEY_RESIZE
134
+ return c
135
+ rescue Interrupt => ex
136
+ 3 # is C-c
137
+ end
138
+
139
+ # returns control, alt, alt+ctrl, alt+control+shift, F1 .. etc
140
+ # ALT combinations also send a 27 before the actual key
141
+ # Please test with above combinations before using on your terminal
142
+ # added by rkumar 2008-12-12 23:07
143
+ def getchar
144
+ FFI::NCurses.raw # FFI required so that getch does not crash on C-c
145
+ while 1
146
+ ch = getch
147
+ #$log.debug "window getchar() GOT: #{ch}" if ch != -1
148
+ if ch == -1
149
+ # the returns escape 27 if no key followed it, so its SLOW if you want only esc
150
+ if @stack.first == 27
151
+ #$log.debug " -1 stack sizze #{@stack.size}: #{@stack.inspect}, ch #{ch}"
152
+ case @stack.size
153
+ when 1
154
+ @stack.clear
155
+ return 27
156
+ when 2 # basically a ALT-O, this will be really slow since it waits for -1
157
+ ch = 128 + @stack.last
158
+ @stack.clear
159
+ return ch
160
+ when 3
161
+ $log.debug " SHOULD NOT COME HERE getchar()"
162
+ end
163
+ end
164
+ @stack.clear
165
+ next
166
+ end
167
+ # this is the ALT combination
168
+ if @stack.first == 27
169
+ # experimental. 2 escapes in quick succession to make exit faster
170
+ if ch == 27
171
+ @stack.clear
172
+ return ch
173
+ end
174
+ # possible F1..F3 on xterm-color
175
+ if ch == 79 or ch == 91
176
+ #$log.debug " got 27, #{ch}, waiting for one more"
177
+ @stack << ch
178
+ next
179
+ end
180
+ #$log.debug "stack SIZE #{@stack.size}, #{@stack.inspect}, ch: #{ch}"
181
+ if @stack == [27,79]
182
+ # xterm-color
183
+ case ch
184
+ when 80
185
+ ch = KEY_F1
186
+ when 81
187
+ ch = KEY_F2
188
+ when 82
189
+ ch = KEY_F3
190
+ when 83
191
+ ch = KEY_F4
192
+ end
193
+ @stack.clear
194
+ return ch
195
+ elsif @stack == [27, 91]
196
+ if ch == 90
197
+ @stack.clear
198
+ return KEY_BTAB # backtab
199
+ end
200
+ end
201
+ # the usual Meta combos. (alt)
202
+ ch = 128 + ch
203
+ @stack.clear
204
+ return ch
205
+ end
206
+ # append a 27 to stack, actually one can use a flag too
207
+ if ch == 27
208
+ @stack << 27
209
+ next
210
+ end
211
+ return ch
212
+ end
213
+ end
214
+
215
+ def clear
216
+ # return unless visible?
217
+ move 0, 0
218
+ puts *Array.new(height){ ' ' * (width - 1) }
219
+ end
220
+
221
+
222
+ def visible?
223
+ @visible
224
+ end
225
+ ##
226
+ # added by rk 2008-11-29 19:01
227
+ # I usually use this, not the others ones here
228
+ # @param r - row
229
+ # @param c - col
230
+ # @param string - text to print
231
+ # @param color - color pair
232
+ # @ param att - ncurses attribute: normal, bold, reverse, blink,
233
+ # underline
234
+ def printstring(r,c,string, color, att = FFI::NCurses::A_NORMAL)
235
+ prv_printstring(r,c,string, color, att )
236
+ end
237
+
238
+ ## name changed from printstring to prv_prinstring
239
+ def prv_printstring(r,c,string, color, att = FFI::NCurses::A_NORMAL)
240
+
241
+ #$log.debug " #{@name} inside window printstring r #{r} c #{c} #{string} "
242
+ att = FFI::NCurses::A_NORMAL if att.nil?
243
+ case att.to_s.downcase
244
+ when 'normal'
245
+ att = FFI::NCurses::A_NORMAL
246
+ when 'underline'
247
+ att = FFI::NCurses::A_UNDERLINE
248
+ when 'bold'
249
+ att = FFI::NCurses::A_BOLD
250
+ when 'blink'
251
+ att = FFI::NCurses::A_BLINK # unlikely to work
252
+ when 'reverse'
253
+ att = FFI::NCurses::A_REVERSE
254
+ end
255
+
256
+ attron(Ncurses.COLOR_PAIR(color) | att)
257
+ # we should not print beyond window coordinates
258
+ # trying out on 2009-01-03 19:29
259
+ width = Ncurses.COLS
260
+ # the next line won't ensure we don't write outside some bounds like table
261
+ #string = string[0..(width-c)] if c + string.length > width
262
+ #$log.debug "PRINT len:#{string.length}, #{Ncurses.COLS}, #{r}, #{c} w: #{@window} "
263
+ mvprintw(r, c, "%s", string);
264
+ attroff(Ncurses.COLOR_PAIR(color) | att)
265
+ end
266
+ # added by rk 2008-11-29 19:01
267
+ # Since these methods write directly to window they are not advised
268
+ # since clearing previous message we don't know how much to clear.
269
+ # Best to map error_message to a label.
270
+ # 2010-09-13 00:22 WE should not use these any longer.
271
+ # Application should create a label and map a Variable named
272
+ # $errormessage to it. We should only update the Variable
273
+ # CLEANUP DEPRECATED
274
+ def print_error_message text=$error_message
275
+ raise "DEPRECATED CLEANUP use global method of same name"
276
+ r = $error_message_row || Ncurses.LINES-1
277
+ c = $error_message_col || (Ncurses.COLS-text.length)/2
278
+
279
+ $log.debug "got ERROR MESSAGE #{text} row #{r} "
280
+ clear_error r, $datacolor
281
+ printstring r, c, text, color = $promptcolor
282
+ $error_message_clear_pending = true
283
+ end
284
+ # added by rk 2008-11-29 19:01
285
+ # CLEANUP DEPRECATED
286
+ def print_status_message text=$status_message
287
+ raise "DEPRECATED CLEANUP use global method of same name"
288
+ r = $status_message_row || Ncurses.LINES-1
289
+ clear_error r, $datacolor
290
+ # print it in centre
291
+ printstring r, (Ncurses.COLS-text.length)/2, text, color = $promptcolor
292
+ end
293
+ # Clear error message printed
294
+ # I am not only clearing if something was printed. This is since
295
+ # certain small forms like TabbedForm top form throw an error on printstring.
296
+ #
297
+ #raise "DEPRECATED CLEANUP use global method of same name"
298
+ def clear_error r = $error_message_row, color = $datacolor
299
+ return unless $error_message_clear_pending
300
+ c = $error_message_col || (Ncurses.COLS-text.length)/2
301
+ sz = $error_message_size || Ncurses.COLS
302
+ printstring(r, c, "%-*s" % [sz, " "], color)
303
+ $error_message_clear_pending = false
304
+ end
305
+ ##
306
+ def get_window; @window_pointer; end
307
+ def to_s; @name || self; end
308
+ end
309
+ end
@@ -0,0 +1,170 @@
1
+ # Usage:
2
+ # VER::Keyboard2.focus = self
3
+ # or whatever class you have created.
4
+ # DEPENDENCIES:
5
+ # press(key) - a method that takes an int key and processes it
6
+ # stopping? returns true of false. if false, this prgram returns control
7
+ # window - gives window of caller, responding to getch
8
+ # 2008-11-24 12:41
9
+ # this differs from original in that i try to return an int so it can just replace
10
+ # existing loops without any modification
11
+ # I thus return an int not a string
12
+ module VER
13
+ module Keyboard2 # avoid initialize
14
+ ESC = 27 # keycode
15
+ @polling = false
16
+
17
+ module_function
18
+
19
+ def focus=(receiver)
20
+ @stack = []
21
+ @focus = receiver
22
+ poll unless @polling
23
+ end
24
+
25
+ def poll
26
+ @polling = true
27
+
28
+ while char = @focus.window.getch
29
+ break if @focus.stopping? # XXX
30
+ #break if VER.stopping?
31
+ $log.debug("char: #{char} stakc: #{@stack.inspect}") if char != Ncurses::ERR
32
+ if char == Ncurses::ERR # timeout or signal
33
+ #@focus.press('esc') if @stack == [ESC]
34
+ @focus.press(ESC) if @stack == [ESC]
35
+ @stack.clear
36
+ elsif ready = resolve(char)
37
+ $log.debug("char: #{char} ready: #{ready}")
38
+ @stack.clear
39
+ @focus.press(ready)
40
+ end
41
+ end
42
+
43
+ ensure
44
+ @polling = false
45
+ end
46
+
47
+ def resolve(char)
48
+ $log.debug("char: #{char} resolve") if char == ESC
49
+ @stack << char
50
+
51
+ if @stack.first == ESC
52
+ MOD_KEYS[@stack] || SPECIAL_KEYS[@stack]
53
+ elsif (char >= 0 and char < 27) or char == 32 or char == 127
54
+ char
55
+ else
56
+ #NCURSES_KEYS[char] || CONTROL_KEYS[char] || PRINTABLE_KEYS[char]
57
+ NCURSES_KEYS[char] || PRINTABLE_KEYS[char]
58
+ end
59
+ end
60
+
61
+ # TODO: make this section sane
62
+
63
+ ASCII = (0..255).map{|c| c.chr }
64
+ CONTROL = ASCII.grep(/[[:cntrl:]]/)
65
+ PRINTABLE = ASCII.grep(/[[:print:]]/)
66
+
67
+ SPECIAL_KEYS = {
68
+ [27, 79, 50, 81] => 'F14',
69
+ [27, 79, 50, 82] => 'F15',
70
+ [27, 79, 70] => 'end',
71
+ [27, 79, 70] => 'end',
72
+ [27, 79, 72] => 'home',
73
+ # [27, 79, 80] => 'F1',
74
+ [27, 79, 80] => Ncurses::KEY_F1,
75
+ [27, 79, 81] => 'F2',
76
+ [27, 79, 82] => 'F3',
77
+ [27, 79, 83] => 'F4',
78
+ [27, 91, 49, 126] => 'end',
79
+ [27, 91, 49, 126] => 'home',
80
+ [27, 91, 49, 49, 126] => Ncurses::KEY_F1,
81
+ [27, 91, 49, 50, 126] => 'F2',
82
+ [27, 91, 49, 51, 126] => 'F3',
83
+ [27, 91, 49, 52, 126] => 'F4',
84
+ [27, 91, 49, 52, 126] => 'F4',
85
+ [27, 91, 49, 53, 126] => 'F5',
86
+ [27, 91, 49, 55, 126] => 'F6',
87
+ [27, 91, 49, 56, 59, 50, 126] => 'F19',
88
+ [27, 91, 49, 56, 59, 51, 126] => 'F7',
89
+ [27, 91, 49, 59, 51, 65] => 'ppage',
90
+ [27, 91, 49, 59, 51, 66] => 'npage',
91
+ [27, 91, 49, 59, 53, 65] => 'ppage',
92
+ [27, 91, 49, 59, 53, 66] => 'npage',
93
+ [27, 91, 49, 59, 53, 70] => 'M-<',
94
+ [27, 91, 49, 59, 53, 72] => 'M->',
95
+ [27, 91, 50, 54, 126] => 'F14',
96
+ [27, 91, 50, 56, 126] => 'F15',
97
+ [27, 91, 51, 59, 51, 126] => 'del',
98
+ [27, 91, 52, 126] => 'end',
99
+ [27, 91, 55, 126] => 'home',
100
+ [27, 91, 55, 126] => 'home',
101
+ [27, 91, 56, 126] => 'end',
102
+ [27, 91, 56, 126] => 'end',
103
+ [27, 91, 65] => 'up',
104
+ [27, 91, 66] => 'down',
105
+ [27, 91, 67] => 'right',
106
+ [27, 91, 68] => 'left',
107
+ [27, 91, 70] => 'end',
108
+ [27, 91, 72] => 'end',
109
+ [27, 91, 72] => 'home',
110
+ [27, 91, 91, 65] => Ncurses::KEY_F1,
111
+ [27, 91, 91, 66] => 'F2',
112
+ [27, 91, 91, 67] => 'F3',
113
+ [27, 91, 91, 68] => 'F4',
114
+ [27, 91, 91, 69] => 'F5',
115
+ }
116
+
117
+ CONTROL_KEYS = {
118
+ 0 => 'C-space',
119
+ 1 => 'C-a',
120
+ 2 => 'C-b',
121
+ 3 => 'C-c',
122
+ 4 => 'C-d',
123
+ 5 => 'C-e',
124
+ 6 => 'C-f',
125
+ 7 => 'C-g',
126
+ 8 => 'C-h',
127
+ 9 => 'tab',
128
+ 10 => 'return', # C-j
129
+ 11 => 'C-k',
130
+ 12 => 'C-l',
131
+ 13 => 'return', # C-m
132
+ 14 => 'C-n',
133
+ 15 => 'C-o',
134
+ 16 => 'C-p',
135
+ 17 => 'C-q',
136
+ 18 => 'C-r',
137
+ 19 => 'C-s',
138
+ 20 => 'C-t',
139
+ 21 => 'C-u',
140
+ 22 => 'C-v',
141
+ 23 => 'C-w',
142
+ 24 => 'C-x',
143
+ 25 => 'C-y',
144
+ 26 => 'C-z', # FIXME: is usually suspend in shell job control
145
+ # 27 => 'esc',
146
+ 32 => 'space',
147
+ 127 => 'backspace',
148
+ }
149
+
150
+ PRINTABLE_KEYS = {}
151
+ MOD_KEYS = {}
152
+
153
+ PRINTABLE.each do |key|
154
+ code = key.unpack('c')[0] # using unpack to be compatible with 1.9
155
+ # PRINTABLE_KEYS[code] = key
156
+ # MOD_KEYS[[ESC, code]] = "M-#{key}" unless key == '[' # don't map esc
157
+ PRINTABLE_KEYS[code] = code
158
+ MOD_KEYS[[ESC, code]] = 128 + code unless key == '[' # don't map esc
159
+ end
160
+
161
+ NCURSES_KEYS = {}
162
+ Ncurses.constants.grep(/^KEY_/).each do |const|
163
+ value = Ncurses.const_get(const)
164
+ key = const[/^KEY_(.*)/, 1]
165
+ key = key =~ /^F/ ? key : key.downcase # function keys
166
+ #NCURSES_KEYS[value] = key
167
+ NCURSES_KEYS[value] = value
168
+ end
169
+ end
170
+ end