Class: Yatte::Buffer
- Inherits:
-
Object
- Object
- Yatte::Buffer
- Defined in:
- lib/yatte/buffer.rb
Constant Summary collapse
- INDENT_STEP =
" "- OPENING_BRACKETS =
"({["- CLOSING_BRACKETS =
")}]"- BRACKET_PAIRS_REVERSE =
{")" => "(", "]" => "[", "}" => "{"}.freeze
Instance Attribute Summary collapse
-
#lines ⇒ Object
readonly
Returns the value of attribute lines.
-
#undo_stack ⇒ Object
Returns the value of attribute undo_stack.
Instance Method Summary collapse
- #dedent_closing_bracket(row) ⇒ Object
- #delete_char(row, col) ⇒ Object
- #delete_range(start_row, start_col, end_row, end_col) ⇒ Object
- #dirty? ⇒ Boolean
- #extract_range(start_row, start_col, end_row, end_col) ⇒ Object
- #find(query, start_row, start_col) ⇒ Object
-
#initialize(lines = nil) ⇒ Buffer
constructor
A new instance of Buffer.
- #insert_char(row, col, char) ⇒ Object
- #insert_newline(row, col) ⇒ Object
- #insert_text(row, col, text) ⇒ Object
- #leading_whitespace(row) ⇒ Object
- #line_at(row) ⇒ Object
- #line_count ⇒ Object
- #line_length(row) ⇒ Object
- #mark_clean ⇒ Object
- #replace_at(row, col, old_text, new_text) ⇒ Object
- #rfind(query, start_row, start_col) ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(lines = nil) ⇒ Buffer
Returns a new instance of Buffer.
13 14 15 16 17 |
# File 'lib/yatte/buffer.rb', line 13 def initialize(lines = nil) @lines = lines ? lines.map { |l| +l.to_s } : [+""] @dirty = false @undo_stack = nil end |
Instance Attribute Details
#lines ⇒ Object (readonly)
Returns the value of attribute lines.
10 11 12 |
# File 'lib/yatte/buffer.rb', line 10 def lines @lines end |
#undo_stack ⇒ Object
Returns the value of attribute undo_stack.
11 12 13 |
# File 'lib/yatte/buffer.rb', line 11 def undo_stack @undo_stack end |
Instance Method Details
#dedent_closing_bracket(row) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/yatte/buffer.rb', line 70 def dedent_closing_bracket(row) line = @lines[row] stripped = line.lstrip return unless stripped.length == 1 && CLOSING_BRACKETS.include?(stripped) # Find matching indent level by scanning backward for the opening bracket open_bracket = BRACKET_PAIRS_REVERSE[stripped] depth = 0 (row - 1).downto(0) do |r| @lines[r].each_char do |ch| if ch == stripped depth += 1 elsif ch == open_bracket if depth == 0 target_indent = @lines[r][/\A\s*/] @lines[row] = +(target_indent + stripped) @dirty = true return target_indent.length else depth -= 1 end end end end nil end |
#delete_char(row, col) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/yatte/buffer.rb', line 40 def delete_char(row, col) if col > 0 @lines[row].slice!(col - 1) @dirty = true [row, col - 1] elsif row > 0 new_col = @lines[row - 1].length @lines[row - 1] << @lines[row] @lines.delete_at(row) @dirty = true [row - 1, new_col] else [row, col] end end |
#delete_range(start_row, start_col, end_row, end_col) ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/yatte/buffer.rb', line 112 def delete_range(start_row, start_col, end_row, end_col) if start_row == end_row @lines[start_row].slice!(start_col...end_col) else tail = @lines[end_row][end_col..] || "" @lines[start_row] = +(@lines[start_row][0...start_col] || "") @lines[start_row] << tail @lines.slice!(start_row + 1..end_row) end @dirty = true [start_row, start_col] end |
#dirty? ⇒ Boolean
196 197 198 |
# File 'lib/yatte/buffer.rb', line 196 def dirty? @dirty end |
#extract_range(start_row, start_col, end_row, end_col) ⇒ Object
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/yatte/buffer.rb', line 101 def extract_range(start_row, start_col, end_row, end_col) if start_row == end_row @lines[start_row][start_col...end_col] || "" else parts = [+@lines[start_row][start_col..] || ""] (start_row + 1...end_row).each { |r| parts << @lines[r] } parts << (@lines[end_row][0...end_col] || "") parts.join("\n") end end |
#find(query, start_row, start_col) ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/yatte/buffer.rb', line 162 def find(query, start_row, start_col) (start_row...@lines.length).each do |row| col = @lines[row].index(query, (row == start_row) ? start_col : 0) return [row, col] if col end (0...start_row).each do |row| col = @lines[row].index(query) return [row, col] if col end nil end |
#insert_char(row, col, char) ⇒ Object
35 36 37 38 |
# File 'lib/yatte/buffer.rb', line 35 def insert_char(row, col, char) @lines[row].insert(col, char) @dirty = true end |
#insert_newline(row, col) ⇒ Object
56 57 58 59 60 61 62 63 |
# File 'lib/yatte/buffer.rb', line 56 def insert_newline(row, col) tail = @lines[row].slice!(col..) indent = auto_indent(row) new_line = +(indent + (tail || "")) @lines.insert(row + 1, new_line) @dirty = true [row + 1, indent.length] end |
#insert_text(row, col, text) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/yatte/buffer.rb', line 125 def insert_text(row, col, text) text_lines = text.split("\n", -1) if text_lines.length == 1 @lines[row].insert(col, text_lines[0]) @dirty = true return [row, col + text_lines[0].length] end tail = @lines[row][col..] || "" @lines[row] = +(@lines[row][0...col] || "") @lines[row] << text_lines[0] (1...text_lines.length).each do |i| @lines.insert(row + i, +text_lines[i]) end last_row = row + text_lines.length - 1 last_col = @lines[last_row].length @lines[last_row] << tail @dirty = true [last_row, last_col] end |
#leading_whitespace(row) ⇒ Object
65 66 67 68 |
# File 'lib/yatte/buffer.rb', line 65 def leading_whitespace(row) return "" if row < 0 || row >= @lines.length @lines[row][/\A\s*/] end |
#line_at(row) ⇒ Object
29 30 31 32 33 |
# File 'lib/yatte/buffer.rb', line 29 def line_at(row) return +"" if row < 0 || row >= @lines.length @lines[row] end |
#line_count ⇒ Object
19 20 21 |
# File 'lib/yatte/buffer.rb', line 19 def line_count @lines.length end |
#line_length(row) ⇒ Object
23 24 25 26 27 |
# File 'lib/yatte/buffer.rb', line 23 def line_length(row) return 0 if row < 0 || row >= @lines.length @lines[row].length end |
#mark_clean ⇒ Object
200 201 202 |
# File 'lib/yatte/buffer.rb', line 200 def mark_clean @dirty = false end |
#replace_at(row, col, old_text, new_text) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/yatte/buffer.rb', line 149 def replace_at(row, col, old_text, new_text) old_lines = old_text.split("\n", -1) end_row = row + old_lines.length - 1 end_col = if old_lines.length == 1 col + old_text.length else old_lines.last.length end delete_range(row, col, end_row, end_col) insert_text(row, col, new_text) end |
#rfind(query, start_row, start_col) ⇒ Object
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/yatte/buffer.rb', line 176 def rfind(query, start_row, start_col) search_col = [start_col - 1, 0].max if start_col > 0 col = @lines[start_row].rindex(query, search_col) return [start_row, col] if col && col < start_col end (start_row - 1).downto(0) do |row| col = @lines[row].rindex(query) return [row, col] if col end (@lines.length - 1).downto(start_row + 1) do |row| col = @lines[row].rindex(query) return [row, col] if col end nil end |
#to_s ⇒ Object
97 98 99 |
# File 'lib/yatte/buffer.rb', line 97 def to_s @lines.join("\n") + "\n" end |