Class: TTY2::Reader::Line
- Inherits:
-
Object
- Object
- TTY2::Reader::Line
- Defined in:
- lib/tty2/reader/line.rb
Constant Summary collapse
- ANSI_MATCHER =
/(\[)?\033(\[)?[;?\d]*[\dA-Za-z](\])?/
- 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.
-
#prompt_size ⇒ Object
readonly
The prompt size.
-
#separator ⇒ Regexp
readonly
The word separator pattern for splitting the text.
-
#text ⇒ Object
readonly
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
Insert char(s) at cursor position.
-
#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.
-
#prompt_display_width ⇒ Integer
Prompt display width.
-
#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.
-
#subtext(before: true) ⇒ String
Find a subtext under the cursor.
-
#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 a separator.
-
#word_boundary? ⇒ Boolean
private
Check if cursor is at a word boundary.
-
#word_end_pos(from: @cursor) ⇒ Integer
Find word end position.
-
#word_start_pos(from: @cursor, before: true) ⇒ Integer
Find word start position.
-
#word_to_complete(before: true) ⇒ String
Find a word up to a cursor position.
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
54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/tty2/reader/line.rb', line 54 def initialize(text = "", prompt: "", separator: nil) @text = text.dup @prompt = prompt.dup @prompt_size = prompt_display_width 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
30 31 32 |
# File 'lib/tty2/reader/line.rb', line 30 def cursor @cursor end |
#mode ⇒ Object (readonly)
The line mode
34 35 36 |
# File 'lib/tty2/reader/line.rb', line 34 def mode @mode end |
#prompt ⇒ Object (readonly)
The prompt displayed before input
38 39 40 |
# File 'lib/tty2/reader/line.rb', line 38 def prompt @prompt end |
#prompt_size ⇒ Object (readonly)
The prompt size
42 43 44 |
# File 'lib/tty2/reader/line.rb', line 42 def prompt_size @prompt_size end |
#separator ⇒ Regexp (readonly)
The word separator pattern for splitting the text
49 50 51 |
# File 'lib/tty2/reader/line.rb', line 49 def separator @separator end |
#text ⇒ Object (readonly)
The editable text
26 27 28 |
# File 'lib/tty2/reader/line.rb', line 26 def text @text end |
Class Method Details
.sanitize(text) ⇒ String
Strip ANSI characters from the text
20 21 22 |
# File 'lib/tty2/reader/line.rb', line 20 def self.sanitize(text) text.dup.gsub(ANSI_MATCHER, "") end |
Instance Method Details
#<<(char) ⇒ Object
Add char and move cursor
320 321 322 323 |
# File 'lib/tty2/reader/line.rb', line 320 def <<(char) @text << char @cursor += 1 end |
#[](i) ⇒ Object
Read character
211 212 213 |
# File 'lib/tty2/reader/line.rb', line 211 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.
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/tty2/reader/line.rb', line 178 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 if i > @text.length - 1 @text = before_text + after_text + chars else @text = before_text + chars + after_text end @cursor = i + chars.length end |
#delete(n = 1) ⇒ Object
Remove char from the line at current position
328 329 330 |
# File 'lib/tty2/reader/line.rb', line 328 def delete(n = 1) @text.slice!(@cursor, n) end |
#edit_mode ⇒ Boolean
Enable edit mode
95 96 97 |
# File 'lib/tty2/reader/line.rb', line 95 def edit_mode @mode = :edit end |
#editing? ⇒ Boolean
Check if line is in edit mode
86 87 88 |
# File 'lib/tty2/reader/line.rb', line 86 def editing? @mode == :edit end |
#end? ⇒ Boolean
Check if cursor reached end of the line
131 132 133 |
# File 'lib/tty2/reader/line.rb', line 131 def end? @cursor == @text.length end |
#insert(chars) ⇒ Object
Insert char(s) at cursor position
313 314 315 |
# File 'lib/tty2/reader/line.rb', line 313 def insert(chars) self[@cursor] = chars end |
#left(n = 1) ⇒ Object
Move line position to the left by n chars
138 139 140 |
# File 'lib/tty2/reader/line.rb', line 138 def left(n = 1) @cursor = [0, @cursor - n].max end |
#move_to_end ⇒ Object
Move cursor to end position
159 160 161 |
# File 'lib/tty2/reader/line.rb', line 159 def move_to_end @cursor = @text.length # put cursor outside of text end |
#move_to_start ⇒ Object
Move cursor to beginning position
152 153 154 |
# File 'lib/tty2/reader/line.rb', line 152 def move_to_start @cursor = 0 end |
#prompt_display_width ⇒ Integer
Prompt display width
72 73 74 75 76 77 78 79 |
# File 'lib/tty2/reader/line.rb', line 72 def prompt_display_width lines = self.class.sanitize(@prompt).split(/\r?\n/) return 0 if lines.empty? # return the length of each line + screen width for every line # past the first which accounts for multi-line prompts lines.join.length + ((lines.length - 1) * TTY::Screen.width) end |
#remove(n = 1) ⇒ Object
Remove char from the line in front of the cursor
338 339 340 341 |
# File 'lib/tty2/reader/line.rb', line 338 def remove(n = 1) left(n) @text.slice!(@cursor, n) end |
#replace(text) ⇒ Object
Replace current line with new text
304 305 306 307 308 |
# File 'lib/tty2/reader/line.rb', line 304 def replace(text) @text = text @cursor = @text.length # put cursor outside of text replace_mode end |
#replace_mode ⇒ Boolean
Enable replace mode
113 114 115 |
# File 'lib/tty2/reader/line.rb', line 113 def replace_mode @mode = :replace end |
#replacing? ⇒ Boolean
Check if line is in replace mode
104 105 106 |
# File 'lib/tty2/reader/line.rb', line 104 def replacing? @mode == :replace end |
#right(n = 1) ⇒ Object
Move line position to the right by n chars
145 146 147 |
# File 'lib/tty2/reader/line.rb', line 145 def right(n = 1) @cursor = [@text.length, @cursor + n].min end |
#size ⇒ Object Also known as: length
Full line size with prompt
361 362 363 |
# File 'lib/tty2/reader/line.rb', line 361 def size prompt_size + text_size end |
#start? ⇒ Boolean
Check if cursor reached beginning of the line
122 123 124 |
# File 'lib/tty2/reader/line.rb', line 122 def start? @cursor.zero? end |
#subtext(before: true) ⇒ String
Find a subtext under the cursor
236 237 238 239 240 |
# File 'lib/tty2/reader/line.rb', line 236 def subtext(before: true) before ? @text[0..@cursor] : @text[@cursor..-1] end |
#text_size ⇒ Object
Text size
354 355 356 |
# File 'lib/tty2/reader/line.rb', line 354 def text_size self.class.sanitize(@text).size end |
#to_s ⇒ Object Also known as: inspect
Full line with prompt as string
346 347 348 |
# File 'lib/tty2/reader/line.rb', line 346 def to_s "#{@prompt}#{@text}" end |
#word(before: true) ⇒ String
Find a word under the cursor based on a separator
223 224 225 226 |
# File 'lib/tty2/reader/line.rb', line 223 def word(before: true) start_pos = word_start_pos(before: before) @text[start_pos..word_end_pos(from: start_pos)] 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
295 296 297 |
# File 'lib/tty2/reader/line.rb', line 295 def word_boundary? @text[@cursor] =~ separator end |
#word_end_pos(from: @cursor) ⇒ Integer
Find word end position
284 285 286 287 288 |
# File 'lib/tty2/reader/line.rb', line 284 def word_end_pos(from: @cursor) end_pos = @text.index(separator, from) || text_size end_pos -= 1 unless @text.empty? end_pos end |
#word_start_pos(from: @cursor, before: true) ⇒ Integer
Find word start position
265 266 267 268 269 270 271 272 273 274 |
# File 'lib/tty2/reader/line.rb', line 265 def word_start_pos(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 start_pos = @text.rindex(separator, from) || 0 start_pos += 1 unless start_pos.zero? start_pos end |
#word_to_complete(before: true) ⇒ String
Find a word up to a cursor position
250 251 252 |
# File 'lib/tty2/reader/line.rb', line 250 def word_to_complete(before: true) @text[word_start_pos(before: before)...@cursor] end |