Class: TTY::Reader::Line
- Inherits:
-
Object
- Object
- TTY::Reader::Line
- Defined in:
- lib/greenhat/tty/custom_line.rb,
lib/greenhat/tty/line.rb
Overview
Shim Helper
Constant Summary collapse
- DEFAULT_WORD_BREAK_CHARACTERS =
The word break characters list used by shell
" \t\n\"\\'`@$><=|&{("
Instance Attribute Summary collapse
-
#cursor ⇒ Object
readonly
The current cursor position witin the text.
-
#mode ⇒ Object
readonly
The line mode.
-
#prompt ⇒ Object
readonly
The prompt displayed before input.
-
#separator ⇒ Regexp
readonly
The word separator pattern for splitting the text.
-
#text ⇒ Object
The editable text.
Class Method Summary collapse
-
.sanitize(text) ⇒ String
Strip ANSI characters from the text.
Instance Method Summary collapse
-
#<<(char) ⇒ Object
Add char and move cursor.
-
#[](i) ⇒ Object
Read character.
-
#[]=(i, chars) ⇒ Object
Insert characters inside a line.
-
#delete(n = 1) ⇒ Object
Remove char from the line at current position.
-
#edit_mode ⇒ Boolean
Enable edit mode.
-
#editing? ⇒ Boolean
Check if line is in edit mode.
-
#end? ⇒ Boolean
Check if cursor reached end of the line.
-
#initialize(text = '', prompt: '', separator: nil) {|_self| ... } ⇒ Line
constructor
private
Create a Line instance.
-
#insert(chars) ⇒ Object
No Tabs.
-
#left(n = 1) ⇒ Object
Move line position to the left by n chars.
-
#move_to_end ⇒ Object
Move cursor to end position.
-
#move_to_start ⇒ Object
Move cursor to beginning position.
- #move_word_left ⇒ Object
- #move_word_right ⇒ Object
-
#prompt_size ⇒ Object
Prompt size.
-
#range(from: @cursor, before: true) ⇒ Range
Find a range of characters under the cursor based on the word separator.
-
#remove(n = 1) ⇒ Object
Remove char from the line in front of the cursor.
-
#replace(text) ⇒ Object
Replace current line with new text.
-
#replace_mode ⇒ Boolean
Enable replace mode.
-
#replacing? ⇒ Boolean
Check if line is in replace mode.
-
#right(n = 1) ⇒ Object
Move line position to the right by n chars.
-
#size ⇒ Object
(also: #length)
Full line size with prompt.
-
#start? ⇒ Boolean
Check if cursor reached beginning of the line.
-
#text_size ⇒ Object
Text size.
-
#to_s ⇒ Object
(also: #inspect)
Full line with prompt as string.
-
#word(before: true) ⇒ String
Find a word under the cursor based on the word separator.
-
#word_boundary? ⇒ Boolean
private
Check if cursor is at a word boundary.
Constructor Details
#initialize(text = '', prompt: '', separator: nil) {|_self| ... } ⇒ Line
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Create a Line instance
52 53 54 55 56 57 58 59 60 61 |
# File 'lib/greenhat/tty/line.rb', line 52 def initialize(text = '', prompt: '', separator: nil) @text = text.dup @prompt = prompt.dup break_chars = DEFAULT_WORD_BREAK_CHARACTERS.chars @separator = separator || Regexp.union(break_chars) @cursor = [0, @text.length].max @mode = :edit yield self if block_given? end |
Instance Attribute Details
#cursor ⇒ Object (readonly)
The current cursor position witin the text
32 33 34 |
# File 'lib/greenhat/tty/line.rb', line 32 def cursor @cursor end |
#mode ⇒ Object (readonly)
The line mode
36 37 38 |
# File 'lib/greenhat/tty/line.rb', line 36 def mode @mode end |
#prompt ⇒ Object (readonly)
The prompt displayed before input
40 41 42 |
# File 'lib/greenhat/tty/line.rb', line 40 def prompt @prompt end |
#separator ⇒ Regexp (readonly)
The word separator pattern for splitting the text
47 48 49 |
# File 'lib/greenhat/tty/line.rb', line 47 def separator @separator end |
#text ⇒ Object
The editable text
28 29 30 |
# File 'lib/greenhat/tty/line.rb', line 28 def text @text end |
Class Method Details
.sanitize(text) ⇒ String
Strip ANSI characters from the text
22 23 24 |
# File 'lib/greenhat/tty/line.rb', line 22 def self.sanitize(text) text.dup.gsub(ANSI_MATCHER, '') end |
Instance Method Details
#<<(char) ⇒ Object
Add char and move cursor
267 268 269 270 |
# File 'lib/greenhat/tty/line.rb', line 267 def <<(char) @text << char @cursor += 1 end |
#[](i) ⇒ Object
Read character
193 194 195 |
# File 'lib/greenhat/tty/line.rb', line 193 def [](i) @text[i] end |
#[]=(i, chars) ⇒ Object
Insert characters inside a line. When the lines exceeds maximum length, an extra space is added to accomodate index.
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/greenhat/tty/line.rb', line 160 def []=(i, chars) edit_mode if i.is_a?(Range) @text[i] = chars @cursor += chars.length return end if i <= 0 before_text = '' after_text = @text.dup elsif i > @text.length - 1 # insert outside of line input before_text = @text.dup after_text = "\s" * (i - @text.length) @cursor += after_text.length else before_text = @text[0..i - 1].dup after_text = @text[i..-1].dup end @text = if i > @text.length - 1 before_text + after_text + chars else before_text + chars + after_text end @cursor = i + chars.length end |
#delete(n = 1) ⇒ Object
Remove char from the line at current position
275 276 277 |
# File 'lib/greenhat/tty/line.rb', line 275 def delete(n = 1) @text.slice!(@cursor, n) end |
#edit_mode ⇒ Boolean
Enable edit mode
77 78 79 |
# File 'lib/greenhat/tty/line.rb', line 77 def edit_mode @mode = :edit end |
#editing? ⇒ Boolean
Check if line is in edit mode
68 69 70 |
# File 'lib/greenhat/tty/line.rb', line 68 def editing? @mode == :edit end |
#end? ⇒ Boolean
Check if cursor reached end of the line
113 114 115 |
# File 'lib/greenhat/tty/line.rb', line 113 def end? @cursor == @text.length end |
#insert(chars) ⇒ Object
No Tabs
260 261 262 |
# File 'lib/greenhat/tty/line.rb', line 260 def insert(chars) self[@cursor] = chars end |
#left(n = 1) ⇒ Object
Move line position to the left by n chars
120 121 122 |
# File 'lib/greenhat/tty/line.rb', line 120 def left(n = 1) @cursor = [0, @cursor - n].max end |
#move_to_end ⇒ Object
Move cursor to end position
141 142 143 |
# File 'lib/greenhat/tty/line.rb', line 141 def move_to_end @cursor = @text.length # put cursor outside of text end |
#move_to_start ⇒ Object
Move cursor to beginning position
134 135 136 |
# File 'lib/greenhat/tty/line.rb', line 134 def move_to_start @cursor = 0 end |
#move_word_left ⇒ Object
5 6 7 8 9 10 11 12 13 14 |
# File 'lib/greenhat/tty/custom_line.rb', line 5 def move_word_left loop do # Don't go past beginning break if @cursor.zero? left 1 break if self[@cursor].blank? end end |
#move_word_right ⇒ Object
16 17 18 19 20 21 |
# File 'lib/greenhat/tty/custom_line.rb', line 16 def move_word_right loop do right 1 break if self[@cursor].blank? end end |
#prompt_size ⇒ Object
Prompt size
301 302 303 304 305 306 |
# File 'lib/greenhat/tty/line.rb', line 301 def prompt_size p = self.class.sanitize(@prompt).split(/\r?\n/) # return the length of each line + screen width for every line past the first # which accounts for multi-line prompts p.join.length + ((p.length - 1) * TTY::Screen.width) end |
#range(from: @cursor, before: true) ⇒ Range
Find a range of characters under the cursor based on the word separator
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/greenhat/tty/line.rb', line 220 def range(from: @cursor, before: true) # move back or forward by one character when at a word boundary if word_boundary? from = before ? from - 1 : from + 1 end # find start position start_pos = @text.rindex(separator, from) || 0 start_pos += 1 unless start_pos.zero? # find end position end_pos = @text.index(separator, start_pos) || text_size end_pos -= 1 unless @text.empty? start_pos..end_pos end |
#remove(n = 1) ⇒ Object
Remove char from the line in front of the cursor
285 286 287 288 |
# File 'lib/greenhat/tty/line.rb', line 285 def remove(n = 1) left(n) @text.slice!(@cursor, n) end |
#replace(text) ⇒ Object
Replace current line with new text
251 252 253 254 255 |
# File 'lib/greenhat/tty/line.rb', line 251 def replace(text) @text = text @cursor = @text.length # put cursor outside of text replace_mode end |
#replace_mode ⇒ Boolean
Enable replace mode
95 96 97 |
# File 'lib/greenhat/tty/line.rb', line 95 def replace_mode @mode = :replace end |
#replacing? ⇒ Boolean
Check if line is in replace mode
86 87 88 |
# File 'lib/greenhat/tty/line.rb', line 86 def replacing? @mode == :replace end |
#right(n = 1) ⇒ Object
Move line position to the right by n chars
127 128 129 |
# File 'lib/greenhat/tty/line.rb', line 127 def right(n = 1) @cursor = [@text.length, @cursor + n].min end |
#size ⇒ Object Also known as: length
Full line size with prompt
318 319 320 |
# File 'lib/greenhat/tty/line.rb', line 318 def size prompt_size + text_size end |
#start? ⇒ Boolean
Check if cursor reached beginning of the line
104 105 106 |
# File 'lib/greenhat/tty/line.rb', line 104 def start? @cursor.zero? end |
#text_size ⇒ Object
Text size
311 312 313 |
# File 'lib/greenhat/tty/line.rb', line 311 def text_size self.class.sanitize(@text).size end |
#to_s ⇒ Object Also known as: inspect
Full line with prompt as string
293 294 295 |
# File 'lib/greenhat/tty/line.rb', line 293 def to_s "#{@prompt}#{@text}" end |
#word(before: true) ⇒ String
Find a word under the cursor based on the word separator
205 206 207 |
# File 'lib/greenhat/tty/line.rb', line 205 def word(before: true) @text[range(before: before)] end |
#word_boundary? ⇒ Boolean
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Check if cursor is at a word boundary
242 243 244 |
# File 'lib/greenhat/tty/line.rb', line 242 def word_boundary? @text[@cursor] =~ separator end |