Class: Reline::ANSI
- Inherits:
-
Object
- Object
- Reline::ANSI
- Defined in:
- lib/reline/ansi.rb
Constant Summary collapse
- RAW_KEYSTROKE_CONFIG =
{ # Console (80x25) [27, 91, 49, 126] => :ed_move_to_beg, # Home [27, 91, 52, 126] => :ed_move_to_end, # End [27, 91, 51, 126] => :key_delete, # Del [27, 91, 65] => :ed_prev_history, # ↑ [27, 91, 66] => :ed_next_history, # ↓ [27, 91, 67] => :ed_next_char, # → [27, 91, 68] => :ed_prev_char, # ← # KDE [27, 91, 72] => :ed_move_to_beg, # Home [27, 91, 70] => :ed_move_to_end, # End # Del is 0x08 [27, 71, 65] => :ed_prev_history, # ↑ [27, 71, 66] => :ed_next_history, # ↓ [27, 71, 67] => :ed_next_char, # → [27, 71, 68] => :ed_prev_char, # ← # urxvt / exoterm [27, 91, 55, 126] => :ed_move_to_beg, # Home [27, 91, 56, 126] => :ed_move_to_end, # End # GNOME [27, 79, 72] => :ed_move_to_beg, # Home [27, 79, 70] => :ed_move_to_end, # End # Del is 0x08 # Arrow keys are the same of KDE # iTerm2 [27, 27, 91, 67] => :em_next_word, # Option+→ [27, 27, 91, 68] => :ed_prev_word, # Option+← [195, 166] => :em_next_word, # Option+f [195, 162] => :ed_prev_word, # Option+b # others [27, 32] => :em_set_mark, # M-<space> [24, 24] => :em_exchange_mark, # C-x C-x TODO also add Windows [27, 91, 49, 59, 53, 67] => :em_next_word, # Ctrl+→ [27, 91, 49, 59, 53, 68] => :ed_prev_word, # Ctrl+← [27, 79, 65] => :ed_prev_history, # ↑ [27, 79, 66] => :ed_next_history, # ↓ [27, 79, 67] => :ed_next_char, # → [27, 79, 68] => :ed_prev_char, # ← }
- @@input =
STDIN
- @@output =
STDOUT
- @@buf =
[]
- @@old_winch_handler =
nil
Class Method Summary collapse
- .clear_screen ⇒ Object
- .cursor_pos ⇒ Object
- .deprep(otio) ⇒ Object
- .empty_buffer? ⇒ Boolean
- .encoding ⇒ Object
- .erase_after_cursor ⇒ Object
- .get_screen_size ⇒ Object
- .getc ⇒ Object
- .in_pasting? ⇒ Boolean
- .input=(val) ⇒ Object
- .move_cursor_column(x) ⇒ Object
- .move_cursor_down(x) ⇒ Object
- .move_cursor_up(x) ⇒ Object
- .output=(val) ⇒ Object
- .prep ⇒ Object
- .retrieve_keybuffer ⇒ Object
- .scroll_down(x) ⇒ Object
- .set_screen_size(rows, columns) ⇒ Object
- .set_winch_handler(&handler) ⇒ Object
- .ungetc(c) ⇒ Object
- .win? ⇒ Boolean
Class Method Details
.clear_screen ⇒ Object
196 197 198 199 |
# File 'lib/reline/ansi.rb', line 196 def self.clear_screen @@output.write "\e[2J" @@output.write "\e[1;1H" end |
.cursor_pos ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/reline/ansi.rb', line 132 def self.cursor_pos begin res = '' m = nil @@input.raw do |stdin| @@output << "\e[6n" @@output.flush loop do c = stdin.getc next if c.nil? res << c m = res.match(/\e\[(?<row>\d+);(?<column>\d+)R/) break if m end (m.pre_match + m.post_match).chars.reverse_each do |ch| stdin.ungetc ch end end column = m[:column].to_i - 1 row = m[:row].to_i - 1 rescue Errno::ENOTTY begin buf = @@output.pread(@@output.pos, 0) row = buf.count("\n") column = buf.rindex("\n") ? (buf.size - buf.rindex("\n")) - 1 : 0 rescue Errno::ESPIPE # Just returns column 1 for ambiguous width because this I/O is not # tty and can't seek. row = 0 column = 1 end end Reline::CursorPos.new(column, row) end |
.deprep(otio) ⇒ Object
213 214 215 216 217 |
# File 'lib/reline/ansi.rb', line 213 def self.deprep(otio) int_handle = Signal.trap('INT', 'IGNORE') Signal.trap('INT', int_handle) Signal.trap('WINCH', @@old_winch_handler) if @@old_winch_handler end |
.empty_buffer? ⇒ Boolean
87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/reline/ansi.rb', line 87 def self.empty_buffer? unless @@buf.empty? return false end rs, = IO.select([@@input], [], [], 0.00001) if rs and rs[0] false else true end end |
.encoding ⇒ Object
4 5 6 |
# File 'lib/reline/ansi.rb', line 4 def self.encoding Encoding.default_external end |
.erase_after_cursor ⇒ Object
187 188 189 |
# File 'lib/reline/ansi.rb', line 187 def self.erase_after_cursor @@output.write "\e[K" end |
.get_screen_size ⇒ Object
115 116 117 118 119 120 121 122 123 |
# File 'lib/reline/ansi.rb', line 115 def self.get_screen_size s = @@input.winsize return s if s[0] > 0 && s[1] > 0 s = [ENV["LINES"].to_i, ENV["COLUMNS"].to_i] return s if s[0] > 0 && s[1] > 0 [24, 80] rescue Errno::ENOTTY [24, 80] end |
.getc ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/reline/ansi.rb', line 70 def self.getc unless @@buf.empty? return @@buf.shift end until c = @@input.raw(intr: true, &:getbyte) sleep 0.1 end (c == 0x16 && @@input.raw(min: 0, tim: 0, &:getbyte)) || c rescue Errno::EIO # Maybe the I/O has been closed. nil end |
.in_pasting? ⇒ Boolean
83 84 85 |
# File 'lib/reline/ansi.rb', line 83 def self.in_pasting? not Reline::IOGate.empty_buffer? end |
.input=(val) ⇒ Object
60 61 62 |
# File 'lib/reline/ansi.rb', line 60 def self.input=(val) @@input = val end |
.move_cursor_column(x) ⇒ Object
167 168 169 |
# File 'lib/reline/ansi.rb', line 167 def self.move_cursor_column(x) @@output.write "\e[#{x + 1}G" end |
.move_cursor_down(x) ⇒ Object
179 180 181 182 183 184 185 |
# File 'lib/reline/ansi.rb', line 179 def self.move_cursor_down(x) if x > 0 @@output.write "\e[#{x}B" if x > 0 elsif x < 0 move_cursor_up(-x) end end |
.move_cursor_up(x) ⇒ Object
171 172 173 174 175 176 177 |
# File 'lib/reline/ansi.rb', line 171 def self.move_cursor_up(x) if x > 0 @@output.write "\e[#{x}A" if x > 0 elsif x < 0 move_cursor_down(-x) end end |
.output=(val) ⇒ Object
65 66 67 |
# File 'lib/reline/ansi.rb', line 65 def self.output=(val) @@output = val end |
.prep ⇒ Object
206 207 208 209 210 211 |
# File 'lib/reline/ansi.rb', line 206 def self.prep retrieve_keybuffer int_handle = Signal.trap('INT', 'IGNORE') Signal.trap('INT', int_handle) nil end |
.retrieve_keybuffer ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/reline/ansi.rb', line 103 def self.retrieve_keybuffer begin result = select([@@input], [], [], 0.001) return if result.nil? str = @@input.read_nonblock(1024) str.bytes.each do |c| @@buf.push(c) end rescue EOFError end end |
.scroll_down(x) ⇒ Object
191 192 193 194 |
# File 'lib/reline/ansi.rb', line 191 def self.scroll_down(x) return if x.zero? @@output.write "\e[#{x}S" end |
.set_screen_size(rows, columns) ⇒ Object
125 126 127 128 129 130 |
# File 'lib/reline/ansi.rb', line 125 def self.set_screen_size(rows, columns) @@input.winsize = [rows, columns] self rescue Errno::ENOTTY self end |
.set_winch_handler(&handler) ⇒ Object
202 203 204 |
# File 'lib/reline/ansi.rb', line 202 def self.set_winch_handler(&handler) @@old_winch_handler = Signal.trap('WINCH', &handler) end |
.ungetc(c) ⇒ Object
99 100 101 |
# File 'lib/reline/ansi.rb', line 99 def self.ungetc(c) @@buf.unshift(c) end |
.win? ⇒ Boolean
8 9 10 |
# File 'lib/reline/ansi.rb', line 8 def self.win? false end |