Imported File#ftype spec from rubyspecs.
[rbx.git] / lib / readline-native.rb
blob6e9bb00f1330d0b6ba514ce8408a963d90a8b705
1 module Readline
3   module ASCII
4     Home = 1
5     ControlC = 3
6     ControlD = 4
7     End = 5
8     Erase = 8
9     Tab = 9
10     Return = 10
11     Escape = 27
12     Backspace = 127
13   end
15   @history = []
16   @history_idx = 0
18   def self.readline(prompt)
19     str = []
20     idx = 0
22     begin
23       @c_erase, @c_kill, @c_quit, @c_intr = _terminal_raw
25       print prompt
27       while true
28         cur = STDIN.read(1)
30         if cur.nil? then
31           print "\n"
32           return nil
33         end
34         
35         code = cur[0]
36         code = ASCII::Erase if code == @c_erase
38         cur = code.chr
39         
40         if code == ASCII::Return
41           print "\n"
42           break
43         elsif code == ASCII::ControlD
44           print "\n"
45           return nil
46         elsif code == @c_intr
47           puts "", "<Control-C>"
48           raise Interrupt, "User requested termination with Control-C"
49         elsif code == ASCII::Erase
50           if str.size > 0
51             print "\b" * idx
52             idx -= 1
53             str.slice!(idx)
54             print str.join(""), " ", "\b" * (str.size + 1 - idx)
55           end
56         elsif code == ASCII::Escape
57           STDIN.read(1) # eat the [
58           command = STDIN.read(1)
59           input = "\e[" + command
61           if command == "A"
62             # history up
63             if @history_idx > 0
64               if @history_idx == @history.size && str.size > 0
65                 @history << str
66               end
68               @history_idx -= 1
70               print "\b" * idx, " " * str.size, "\b" * str.size
71               str = @history[@history_idx].dup
72               idx = str.size
73               print str.join("")
74             end
75           elsif command == "B"
76             # history down
77             if @history_idx < @history.size
78               @history_idx += 1
80               print "\b" * idx, " " * str.size, "\b" * str.size
81               str = (@history[@history_idx] || []).dup
82               idx = str.size
83               print str.join("")
84             end
85           elsif command == "C"
86             # cursor right
87             if idx < str.size
88               idx += 1
89               print input
90             end
91           elsif command == "D"
92             # cursor left
93             if idx > 0
94               idx -= 1
95               print input
96             end
97           else
98             print input
99           end
100         elsif code == ASCII::Home
101           print "\b" * idx
102           idx = 0
103         elsif code == ASCII::End
104           print "\b" * idx, str.join("")
105           idx = str.size
106         else
107           str.insert(idx, cur)
108           print "\b" * idx, str.join(""), "\b" * (str.size - idx - 1)
109           idx += 1
110         end
111       end
112     ensure
113       _terminal_normal
114     end
116     @history << str
117     @history_idx = @history.size
119     out = str.join("")
120     return out
121   end