Class: Diakonos::Buffer
- Defined in:
- lib/diakonos/buffer.rb,
lib/diakonos/buffer/file.rb,
lib/diakonos/buffer/undo.rb,
lib/diakonos/buffer/cursor.rb,
lib/diakonos/buffer/delete.rb,
lib/diakonos/buffer/display.rb,
lib/diakonos/buffer/searching.rb,
lib/diakonos/buffer/selection.rb,
lib/diakonos/buffer/bookmarking.rb,
lib/diakonos/buffer/indentation.rb
Constant Summary collapse
- STOPPED_TYPING =
true- STILL_TYPING =
false- NO_SNAPSHOT =
true- DO_DISPLAY =
true- DONT_DISPLAY =
false- READ_ONLY =
true- READ_WRITE =
false- ROUND_DOWN =
false- ROUND_UP =
true- PAD_END =
true- DONT_PAD_END =
false- START_FROM_BEGINNING =
-1
- DO_PITCH_CURSOR =
true- DONT_PITCH_CURSOR =
false- STRIP_LINE =
true- DONT_STRIP_LINE =
false- USE_INDENT_IGNORE =
true- DONT_USE_INDENT_IGNORE =
false- WORD_REGEXP =
/\w+/- SECONDS_PER_DAY =
60 * 60 * 24
- DO_USE_MD5 =
true- DONT_USE_MD5 =
false- COLUMNS_FOR_DIAGNOSTICS =
width in characters
1- CHARACTER_PAIRS =
{ '(' => { partner: ')', direction: :forward }, '<' => { partner: '>', direction: :forward }, '{' => { partner: '}', direction: :forward }, '[' => { partner: ']', direction: :forward }, ')' => { partner: '(', direction: :backward }, '>' => { partner: '<', direction: :backward }, '}' => { partner: '{', direction: :backward }, ']' => { partner: '[', direction: :backward }, }
- OPPOSITE_DIRECTION =
{ up: :down, down: :up, }
Instance Attribute Summary collapse
-
#changing_selection ⇒ Object
readonly
Returns the value of attribute changing_selection.
-
#desired_column ⇒ Object
writeonly
Sets the attribute desired_column.
-
#language ⇒ Object
readonly
Returns the value of attribute language.
-
#last_col ⇒ Object
readonly
Returns the value of attribute last_col.
-
#last_row ⇒ Object
readonly
Returns the value of attribute last_row.
-
#last_screen_col ⇒ Object
readonly
Returns the value of attribute last_screen_col.
-
#last_screen_x ⇒ Object
readonly
Returns the value of attribute last_screen_x.
-
#last_screen_y ⇒ Object
readonly
Returns the value of attribute last_screen_y.
-
#last_search_regexps ⇒ Object
readonly
Returns the value of attribute last_search_regexps.
-
#left_column ⇒ Object
readonly
Returns the value of attribute left_column.
-
#lines ⇒ Object
Returns the value of attribute lines.
-
#lsp_session ⇒ Object
Returns the value of attribute lsp_session.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#num_matches_found ⇒ Object
readonly
Returns the value of attribute num_matches_found.
-
#original_language ⇒ Object
readonly
Returns the value of attribute original_language.
-
#read_only ⇒ Object
Returns the value of attribute read_only.
-
#selection_mode ⇒ Object
readonly
Returns the value of attribute selection_mode.
-
#tab_size ⇒ Object
readonly
Returns the value of attribute tab_size.
-
#top_line ⇒ Object
readonly
Returns the value of attribute top_line.
Instance Method Summary collapse
- #==(other) ⇒ Object
- #[](arg) ⇒ Object
- #_find_down(regexps, regexp, from_row, from_col, search_area) ⇒ Object
- #_find_up(regexps, regexp, search_area, from_row, from_col) ⇒ Object
- #anchor_selection(row = @last_row, col = @last_col, do_display = DO_DISPLAY) ⇒ Object
- #anchor_unanchored_selection(*args) ⇒ Object
- #carriage_return ⇒ Object
- #clear_matches(do_display = DONT_DISPLAY) ⇒ Object
- #clear_pair_highlight ⇒ Object
- #clear_search_area ⇒ Object
- #close_code ⇒ Object
- #collapse_whitespace ⇒ Object
-
#column_of(x) ⇒ Object
Translates the window column, x, to a buffer-relative column index.
-
#column_to_x(col) ⇒ Object
Returns nil if the column is off-screen.
- #columnize(delimiter = /=>?|:|,/, num_spaces_padding = 1) ⇒ Object
- #comment_out ⇒ Object
- #configure(language = ( $diakonos.get_language_from_shabang( @lines[ 0 ] ) || $diakonos.get_language_from_name( @name ) || LANG_TEXT )) ⇒ Object
- #confirm_finding(regexps, search_area, from_row, from_col, match) ⇒ Object
- #context ⇒ Object
- #copy_selection ⇒ Object
- #current_column ⇒ Object
- #current_line ⇒ Object
- #current_row ⇒ Object
-
#cursor_to(row, col, do_display = DONT_DISPLAY, stopped_typing = STOPPED_TYPING, adjust_row = ADJUST_ROW) ⇒ Object
Returns true iff the cursor changed positions in the buffer.
- #cursor_to_bol ⇒ Object
-
#cursor_to_bov ⇒ Object
Bottom of view.
- #cursor_to_eof ⇒ Object
- #cursor_to_eol ⇒ Object
-
#cursor_to_tov ⇒ Object
Top of view.
-
#delete ⇒ Object
x and y are given window-relative, not buffer-relative.
- #delete_from(char) ⇒ Object
- #delete_from_to(row_from, col_from, row_to, col_to) ⇒ Object
- #delete_line ⇒ Object
- #delete_selection(do_display = DO_DISPLAY) ⇒ Object
- #delete_to(char) ⇒ Object
- #delete_to_and_from(char, inclusive = NOT_INCLUSIVE) ⇒ Object
- #delete_to_eol ⇒ Object
- #diagnostics_for_current_line ⇒ Object
- #diagnostics_for_line(line:) ⇒ Object
- #display ⇒ Object
-
#file_different? ⇒ Boolean
Compares MD5 sums of buffer and actual file on disk.
-
#file_modified? ⇒ Boolean
Check if the file which is being edited has been modified since the last time we checked it.
-
#find(regexps, options = {}) ⇒ Integer
split across newline characters.
- #find_again(last_search_regexps, direction = @last_search_direction) ⇒ Object
- #find_opening_match(line, bos_allowed: true, match_close: true) ⇒ Object
- #forgotten? ⇒ Boolean
- #go_block_inner ⇒ Object
- #go_block_next ⇒ Object
- #go_block_outer ⇒ Object
- #go_block_previous ⇒ Object
- #go_to_char(char, after = ON_CHAR) ⇒ Object
- #go_to_char_previous(char, after = ON_CHAR) ⇒ Object
- #go_to_line(line = nil, column = nil, do_display = DO_DISPLAY) ⇒ Object
- #go_to_next_bookmark ⇒ Object
- #go_to_pair_match ⇒ Object
- #go_to_previous_bookmark ⇒ Object
-
#grep(regexp_source) ⇒ Object
Returns an Array of results, where each result is a String usually containing n‘s due to context.
- #highlight_matches(regexp = @highlight_regexp) ⇒ Object
- #highlight_pair ⇒ Object
-
#in_line(x, y) ⇒ Object
Returns true iff the given column, x, is less than the length of the given line, y.
- #indent(row = @last_row, do_display = DO_DISPLAY) ⇒ Object
- #indentation_level(row, use_indent_ignore = USE_INDENT_IGNORE) ⇒ Object
-
#initialize(options = {}) ⇒ Buffer
constructor
Set name to nil to create a buffer that is not associated with a file.
- #insert_char(c) ⇒ Object
- #insert_string(str) ⇒ Object
- #join_lines(row = @last_row, strip = DONT_STRIP_LINE) ⇒ Object
- #join_lines_upward(row = @last_row, strip = DONT_STRIP_LINE) ⇒ Object
- #length ⇒ Object
- #line_at(y) ⇒ Object
- #lsp_uri ⇒ Object
- #modified? ⇒ Boolean
- #nearest_basis_row_from(starting_row, next_line_check: true) ⇒ Integer
- #nice_name ⇒ Object
- #paint_column_markers ⇒ Object
- #paint_marks(row) ⇒ Object
-
#paint_single_row_mark(row, text_mark, string, curx, cury) ⇒ Object
Worker function for painting only part of a row.
-
#pan_view(x = 1, do_display = DO_DISPLAY) ⇒ Object
Returns the amount the view was actually panned.
- #pan_view_to(left_column, do_display = DO_DISPLAY) ⇒ Object
-
#paragraph_under_cursor ⇒ Object
Returns an array of lines of the current paragraph.
-
#paragraph_under_cursor_pos ⇒ Object
Returns the coordinates of the first and last line of the current paragraph.
- #parsed_indent(opts = {}) ⇒ Object
-
#paste(text, do_parsed_indent: false, typing: false) ⇒ Object
text is an array of Strings, or a String with zero or more newlines (“n”).
-
#pitch_view(y = 1, do_pitch_cursor = DONT_PITCH_CURSOR, do_display = DO_DISPLAY) ⇒ Object
Returns the amount the view was actually pitched.
- #pitch_view_to(new_top_line, do_pitch_cursor = DONT_PITCH_CURSOR, do_display = DO_DISPLAY) ⇒ Object
- #pos_of_next(regexp, start_row, start_col) ⇒ Object
- #pos_of_pair_match(row = @last_row, col = @last_col) ⇒ Object
- #pos_of_prev(regexp, start_row, start_col) ⇒ Object
-
#print_line(line) ⇒ Object
This method assumes that the cursor has been set up already at the left-most column of the correct on-screen row.
- #print_padding_from(col) ⇒ Object
- #print_string(string, formatting = ( @token_formats[ @continued_format_class ] || @default_formatting )) ⇒ Object
-
#record_mark_start_and_end ⇒ Object
@mark_start[ “col” ] is inclusive, @mark_end[ “col” ] is exclusive.
- #remove_selection(do_display = DO_DISPLAY) ⇒ Object
-
#replace_all(regexp, replacement, within_search_area: false) ⇒ Integer
The number of replacements made.
- #replace_char(c) ⇒ Object
- #reset_display ⇒ Object
-
#row_of(y) ⇒ Object
Translates the window row, y, to a buffer-relative row index.
-
#row_to_y(row) ⇒ Object
Returns nil if the row is off-screen.
- #save(filename = nil, prompt_overwrite = DONT_PROMPT_OVERWRITE) ⇒ Object
-
#save_copy(filename) ⇒ Object
Returns true on successful write.
- #search_area? ⇒ Boolean
- #search_area_lines ⇒ Array<String>
- #seek(regexp, direction = :down) ⇒ Object
- #select(from_regexp, to_regexp, include_ending: true) ⇒ Object
- #select_all ⇒ Object
- #select_current_line ⇒ Object
- #select_word ⇒ Object
- #select_word_another ⇒ Object
- #select_wrapping_block ⇒ Object
- #selected_lines ⇒ Object
- #selected_string ⇒ Object
- #selected_text ⇒ Array<String>?
- #selecting? ⇒ Boolean
- #selection_mark ⇒ Object
- #selection_mode_block ⇒ Object
- #selection_mode_normal ⇒ Object
- #set_indent(row, level, opts = {}) ⇒ Object
- #set_language(_language) ⇒ Object
- #set_modified(do_display = DO_DISPLAY, use_md5 = DONT_USE_MD5, modified_from_line: 0) ⇒ Object
- #set_search_area(mark) ⇒ Object
- #set_selection(start_row, start_col, end_row, end_col) ⇒ Object
- #set_selection_current_line ⇒ Object
- #set_type(type) ⇒ Object
-
#show_character(row, col) ⇒ Object
col and row are given relative to the buffer, not any window or screen.
- #surround(text, parenthesis) ⇒ Object
- #tab_expanded_column(col, row) ⇒ Object
- #take_snapshot(typing: false) ⇒ Object
- #to_a ⇒ Object
- #toggle_bookmark ⇒ Object
- #toggle_selection ⇒ Object
-
#truncate_off_screen(string, write_cursor_col) ⇒ Object
Prints text to the screen, truncating where necessary.
- #uncomment ⇒ Object
- #undo ⇒ Object
- #unindent(row = @last_row, do_display = DO_DISPLAY) ⇒ Object
-
#unundo ⇒ Object
Since redo is a Ruby keyword…
- #word_before_cursor ⇒ Object
- #word_under_cursor ⇒ Object
- #word_under_cursor_pos(options = {}) ⇒ Object
-
#words(filter_regexp = nil) ⇒ Object
TODO paragraph_before_cursor(_pos)?.
- #wrap_paragraph ⇒ Object
Constructor Details
#initialize(options = {}) ⇒ Buffer
Set name to nil to create a buffer that is not associated with a file.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/diakonos/buffer.rb', line 52 def initialize( = {} ) @name = [ 'filepath' ] @modified = false @time_last_viewed = Time.now @buffer_states = Array.new @cursor_states = Array.new if @name.nil? @lines = Array.new @lines[ 0 ] = "" @last_modification_check = Time.now else @name = File.( @name ) if FileTest.exist? @name @lines = IO.readlines( @name ) if ( @lines.empty? ) || ( @lines[ -1 ][ -1.. ] == "\n" ) @lines.push "" end @lines = @lines.collect(&:chomp) @last_modification_check = File.mtime(@name) else @lines = Array.new @lines[ 0 ] = "" @last_modification_check = Time.now end end @current_buffer_state = 0 [ 'display' ] ||= Hash.new @top_line = [ 'display' ][ 'top_line' ] || 0 @left_column = [ 'display' ][ 'left_column' ] || 0 @desired_column = @left_column @mark_anchor = nil @text_marks = Hash.new @selection_mode = :normal @last_search_regexps = Array( ['last_search_regexps'] ).map { |r| Regexp.new(r) } @highlight_regexp = nil @last_search = nil @lsp_session = nil @changing_selection = false @typing = false [ 'cursor' ] ||= Hash.new @last_col = [ 'cursor' ][ 'col' ] || 0 @last_row = [ 'cursor' ][ 'row' ] || 0 @last_screen_y = @last_row - @top_line @last_screen_x = @last_col - @left_column @last_screen_col = @last_screen_x @read_only = [ 'read_only' ] || READ_WRITE @bookmarks = Array.new @highlight_cache = [] @highlight_cache_valid_to = -1 @lang_stack = Array.new configure if @settings[ "convert_tabs" ] tabs_subbed = false @lines.collect! do |line| new_line = line.( @tab_size ) tabs_subbed = ( tabs_subbed || new_line != line ) # Return value for collect: new_line end @modified = ( @modified || tabs_subbed ) if tabs_subbed $diakonos.set_iline "(spaces substituted for tab characters)" end end @buffer_states[ @current_buffer_state ] = @lines @cursor_states[ @current_buffer_state ] = [ @last_row, @last_col ] end |
Instance Attribute Details
#changing_selection ⇒ Object (readonly)
Returns the value of attribute changing_selection.
5 6 7 |
# File 'lib/diakonos/buffer.rb', line 5 def changing_selection @changing_selection end |
#desired_column=(value) ⇒ Object (writeonly)
Sets the attribute desired_column
6 7 8 |
# File 'lib/diakonos/buffer.rb', line 6 def desired_column=(value) @desired_column = value end |
#language ⇒ Object (readonly)
Returns the value of attribute language.
5 6 7 |
# File 'lib/diakonos/buffer.rb', line 5 def language @language end |
#last_col ⇒ Object (readonly)
Returns the value of attribute last_col.
5 6 7 |
# File 'lib/diakonos/buffer/cursor.rb', line 5 def last_col @last_col end |
#last_row ⇒ Object (readonly)
Returns the value of attribute last_row.
5 6 7 |
# File 'lib/diakonos/buffer/cursor.rb', line 5 def last_row @last_row end |
#last_screen_col ⇒ Object (readonly)
Returns the value of attribute last_screen_col.
5 6 7 |
# File 'lib/diakonos/buffer/cursor.rb', line 5 def last_screen_col @last_screen_col end |
#last_screen_x ⇒ Object (readonly)
Returns the value of attribute last_screen_x.
5 6 7 |
# File 'lib/diakonos/buffer/cursor.rb', line 5 def last_screen_x @last_screen_x end |
#last_screen_y ⇒ Object (readonly)
Returns the value of attribute last_screen_y.
5 6 7 |
# File 'lib/diakonos/buffer/cursor.rb', line 5 def last_screen_y @last_screen_y end |
#last_search_regexps ⇒ Object (readonly)
Returns the value of attribute last_search_regexps.
5 6 7 |
# File 'lib/diakonos/buffer/searching.rb', line 5 def last_search_regexps @last_search_regexps end |
#left_column ⇒ Object (readonly)
Returns the value of attribute left_column.
6 7 8 |
# File 'lib/diakonos/buffer/display.rb', line 6 def left_column @left_column end |
#lines ⇒ Object
Returns the value of attribute lines.
4 5 6 |
# File 'lib/diakonos/buffer.rb', line 4 def lines @lines end |
#lsp_session ⇒ Object
Returns the value of attribute lsp_session.
4 5 6 |
# File 'lib/diakonos/buffer.rb', line 4 def lsp_session @lsp_session end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
5 6 7 |
# File 'lib/diakonos/buffer.rb', line 5 def name @name end |
#num_matches_found ⇒ Object (readonly)
Returns the value of attribute num_matches_found.
5 6 7 |
# File 'lib/diakonos/buffer/searching.rb', line 5 def num_matches_found @num_matches_found end |
#original_language ⇒ Object (readonly)
Returns the value of attribute original_language.
5 6 7 |
# File 'lib/diakonos/buffer.rb', line 5 def original_language @original_language end |
#read_only ⇒ Object
Returns the value of attribute read_only.
4 5 6 |
# File 'lib/diakonos/buffer.rb', line 4 def read_only @read_only end |
#selection_mode ⇒ Object (readonly)
Returns the value of attribute selection_mode.
5 6 7 |
# File 'lib/diakonos/buffer.rb', line 5 def selection_mode @selection_mode end |
#tab_size ⇒ Object (readonly)
Returns the value of attribute tab_size.
5 6 7 |
# File 'lib/diakonos/buffer.rb', line 5 def tab_size @tab_size end |
#top_line ⇒ Object (readonly)
Returns the value of attribute top_line.
6 7 8 |
# File 'lib/diakonos/buffer/display.rb', line 6 def top_line @top_line end |
Instance Method Details
#==(other) ⇒ Object
178 179 180 181 182 |
# File 'lib/diakonos/buffer.rb', line 178 def ==(other) return false if other.nil? @name == other.name end |
#[](arg) ⇒ Object
174 175 176 |
# File 'lib/diakonos/buffer.rb', line 174 def []( arg ) @lines[ arg ] end |
#_find_down(regexps, regexp, from_row, from_col, search_area) ⇒ Object
66 67 68 69 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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/diakonos/buffer/searching.rb', line 66 def _find_down(regexps, regexp, from_row, from_col, search_area) # Check the current row first. index = @lines[ from_row ].index( regexp, ( @last_finding ? @last_finding.start_col : from_col ) + 1 ) if index finding = confirm_finding( regexps, search_area, from_row, index, Regexp.last_match ) return finding if finding end # Check below the cursor. ( (from_row + 1)..search_area.end_row ).each do |i| line = @lines[ i ] if i == search_area.end_row line = line[ 0...search_area.end_col ] end index = line.index( regexp ) if index finding = confirm_finding( regexps, search_area, i, index, Regexp.last_match ) return finding if finding end end if index finding = confirm_finding( regexps, search_area, search_area.end_row, index, Regexp.last_match ) return finding if finding end # Wrap around. @wrapped = true index = @lines[ search_area.start_row ].index( regexp, search_area.start_col ) if index finding = confirm_finding( regexps, search_area, search_area.start_row, index, Regexp.last_match ) return finding if finding end ( search_area.start_row+1...from_row ).each do |i| index = @lines[ i ].index( regexp ) if index finding = confirm_finding( regexps, search_area, i, index, Regexp.last_match ) return finding if finding end end # And finally, the other side of the current row. if from_row == search_area.start_row index_col = search_area.start_col else index_col = 0 end index = @lines[from_row].index(regexp, index_col) if index && index <= (@last_finding ? @last_finding.start_col : from_col) confirm_finding( regexps, search_area, from_row, index, Regexp.last_match ) end end |
#_find_up(regexps, regexp, search_area, from_row, from_col) ⇒ Object
129 130 131 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 166 167 168 169 |
# File 'lib/diakonos/buffer/searching.rb', line 129 def _find_up(regexps, regexp, search_area, from_row, from_col) # Check the current row first. col_to_check = ( @last_finding ? @last_finding.end_col : from_col ) - 1 if ( col_to_check >= 0 ) && ( index = @lines[ from_row ][ 0...col_to_check ].rindex( regexp ) ) finding = confirm_finding( regexps, search_area, from_row, index, Regexp.last_match ) return finding if finding end # Check above the cursor. (from_row - 1).downto( 0 ) do |i| index = @lines[i].rindex(regexp) if index finding = confirm_finding( regexps, search_area, i, index, Regexp.last_match ) return finding if finding end end # Wrap around. @wrapped = true (@lines.length - 1).downto(from_row + 1) do |i| index = @lines[i].rindex(regexp) if index finding = confirm_finding( regexps, search_area, i, index, Regexp.last_match ) return finding if finding end end # And finally, the other side of the current row. search_col = ( @last_finding ? @last_finding.start_col : from_col ) + 1 index = @lines[ from_row ].rindex( regexp ) if index && index > search_col confirm_finding( regexps, search_area, from_row, index, Regexp.last_match ) end end |
#anchor_selection(row = @last_row, col = @last_col, do_display = DO_DISPLAY) ⇒ Object
192 193 194 195 196 197 198 199 200 |
# File 'lib/diakonos/buffer/selection.rb', line 192 def anchor_selection( row = @last_row, col = @last_col, do_display = DO_DISPLAY ) @mark_anchor = ( @mark_anchor || Hash.new ) @mark_anchor[ "row" ] = row @mark_anchor[ "col" ] = col record_mark_start_and_end @changing_selection = true @auto_anchored = false display if do_display end |
#anchor_unanchored_selection(*args) ⇒ Object
202 203 204 205 206 207 208 |
# File 'lib/diakonos/buffer/selection.rb', line 202 def anchor_unanchored_selection(*args) if @mark_anchor.nil? anchor_selection(*args) @changing_selection = false end @auto_anchored = true end |
#carriage_return ⇒ Object
408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
# File 'lib/diakonos/buffer.rb', line 408 def carriage_return take_snapshot row = @last_row col = @last_col @lines = @lines[ 0...row ] + [ @lines[ row ][ 0...col ] ] + [ @lines[ row ][ col.. ] ] + @lines[ (row+1).. ] cursor_to( row + 1, 0 ) if @auto_indent parsed_indent undoable: false end set_modified modified_from_line: row end |
#clear_matches(do_display = DONT_DISPLAY) ⇒ Object
366 367 368 369 370 |
# File 'lib/diakonos/buffer/searching.rb', line 366 def clear_matches( do_display = DONT_DISPLAY ) @text_marks[ :found ] = [] @highlight_regexp = nil display if do_display end |
#clear_pair_highlight ⇒ Object
453 454 455 |
# File 'lib/diakonos/buffer/searching.rb', line 453 def clear_pair_highlight @text_marks[ :pair ] = nil end |
#clear_search_area ⇒ Object
27 28 29 30 31 |
# File 'lib/diakonos/buffer/searching.rb', line 27 def clear_search_area @search_area = nil @text_marks.delete :search_area_pre @text_marks.delete :search_area_post end |
#close_code ⇒ Object
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
# File 'lib/diakonos/buffer.rb', line 279 def close_code line = @lines[ @last_row ] @closers.each_value do |h| h[ :regexp ] =~ line lm = Regexp.last_match if lm str = ( case h[ :closer ] when String if lm[ 1 ].nil? h[ :closer ] else lm[ 1 ].gsub( Regexp.new( "(#{ Regexp.escape( lm[1] ) })" ), h[ :closer ] ) end when Proc h[ :closer ].call( lm ).to_s end ) r, c = @last_row, @last_col paste str, do_parsed_indent: @indent_closers, typing: false cursor_to r, c if /%_/ === str find [/%_/], direction: :down, replacement: '', auto_choice: CHOICE_YES_AND_STOP end end end end |
#collapse_whitespace ⇒ Object
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 |
# File 'lib/diakonos/buffer.rb', line 310 def collapse_whitespace if selection_mark remove_selection DONT_DISPLAY end line = @lines[ @last_row ] head = line[ 0...@last_col ] tail = line[ @last_col.. ] new_head = head.sub( /\s+$/, '' ) new_line = new_head + tail.sub( /^\s+/, ' ' ) if new_line != line take_snapshot(typing: true) @lines[ @last_row ] = new_line cursor_to( @last_row, @last_col - ( head.length - new_head.length ) ) set_modified modified_from_line: @last_row end end |
#column_of(x) ⇒ Object
Translates the window column, x, to a buffer-relative column index.
452 453 454 |
# File 'lib/diakonos/buffer.rb', line 452 def column_of( x ) @left_column + x end |
#column_to_x(col) ⇒ Object
Returns nil if the column is off-screen.
471 472 473 474 475 476 477 |
# File 'lib/diakonos/buffer.rb', line 471 def column_to_x( col ) return nil if col.nil? x = col - @left_column x = nil if ( x < 0 ) || ( x > @left_column + Curses.cols - 1 ) x end |
#columnize(delimiter = /=>?|:|,/, num_spaces_padding = 1) ⇒ Object
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 |
# File 'lib/diakonos/buffer.rb', line 328 def columnize( delimiter = /=>?|:|,/, num_spaces_padding = 1 ) take_snapshot lines = self.selected_lines column_width = 0 lines.each do |line| pos = ( line =~ delimiter ) if pos column_width = [ pos, column_width ].max end end padding = ' ' * num_spaces_padding one_modified = false lines.each do |line| old_line = line.dup if line =~ /^(.+?)(#{delimiter.source})(.*)$/ pre = ::Regexp.last_match(1) del = ::Regexp.last_match(2) post = ::Regexp.last_match(3) if pre !~ /\s$/ del = " #{del}" end if post !~ /^\s/ del = "#{del} " end del.sub!( /^\s+/, padding ) del.sub!( /\s+$/, padding ) line.replace( ( "%-#{column_width}s" % pre ) + del + post ) end one_modified ||= ( line != old_line ) end if one_modified set_modified modified_from_line: (@text_marks[:selection]&.start_row || @last_row) end end |
#comment_out ⇒ Object
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 |
# File 'lib/diakonos/buffer.rb', line 367 def comment_out take_snapshot one_modified = false closer = @settings[ "lang.#{@language}.comment_close_string" ].to_s self.selected_lines.each do |line| next if line.strip.empty? old_line = line.dup line.gsub!( /^(\s*)/, "\\1" + @settings[ "lang.#{@language}.comment_string" ].to_s ) if ! closer.empty? && line !~ /#{Regexp.escape(closer)}$/ line << closer end one_modified ||= ( line != old_line ) end if one_modified set_modified modified_from_line: (@text_marks[:selection]&.start_row || @last_row) end end |
#configure(language = ( $diakonos.get_language_from_shabang( @lines[ 0 ] ) || $diakonos.get_language_from_name( @name ) || LANG_TEXT )) ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/diakonos/buffer.rb', line 126 def configure( language = ( $diakonos.get_language_from_shabang( @lines[ 0 ] ) || $diakonos.get_language_from_name( @name ) || LANG_TEXT ) ) reset_display set_language language @original_language = @language build_highlight_cache end |
#confirm_finding(regexps, search_area, from_row, from_col, match) ⇒ Object
49 50 51 52 53 |
# File 'lib/diakonos/buffer/searching.rb', line 49 def confirm_finding( regexps, search_area, from_row, from_col, match ) found_text = match[0] range = ::Diakonos::Range.new(from_row, from_col, from_row, from_col + found_text.length) Finding.confirm(range, regexps, @lines, search_area, match) end |
#context ⇒ Object
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 |
# File 'lib/diakonos/buffer.rb', line 628 def context retval = Array.new row = @last_row clevel = indentation_level( row ) while row > 0 && clevel < 0 row = row - 1 clevel = indentation_level( row ) end clevel = 0 if clevel < 0 while row > 0 row = row - 1 line = @lines[ row ] if ! line.strip.empty? && ( line !~ @settings[ "lang.#{@language}.context.ignore" ] ) level = indentation_level( row ) if level < clevel && level > -1 retval.unshift line clevel = level break if clevel == 0 end end end retval end |
#copy_selection ⇒ Object
228 229 230 |
# File 'lib/diakonos/buffer/selection.rb', line 228 def copy_selection selected_text end |
#current_column ⇒ Object
495 496 497 |
# File 'lib/diakonos/buffer.rb', line 495 def current_column @last_col end |
#current_line ⇒ Object
432 433 434 |
# File 'lib/diakonos/buffer.rb', line 432 def current_line @lines[ @last_row ] end |
#current_row ⇒ Object
479 480 481 |
# File 'lib/diakonos/buffer.rb', line 479 def current_row @last_row end |
#cursor_to(row, col, do_display = DONT_DISPLAY, stopped_typing = STOPPED_TYPING, adjust_row = ADJUST_ROW) ⇒ Object
Returns true iff the cursor changed positions in the buffer.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/diakonos/buffer/cursor.rb', line 8 def cursor_to( row, col, do_display = DONT_DISPLAY, stopped_typing = STOPPED_TYPING, adjust_row = ADJUST_ROW ) old_last_row = @last_row old_last_col = @last_col row = NumberFitter.fit( number: row, min: 0, max: @lines.length - 1, ) if col < 0 if adjust_row if row > 0 row = row - 1 col = @lines[ row ].length else col = 0 end else col = 0 end elsif col > @lines[ row ].length if adjust_row if row < @lines.length - 1 row = row + 1 col = 0 else col = @lines[ row ].length end else col = @lines[ row ].length end end if adjust_row @desired_column = col else goto_col = [ @desired_column, @lines[ row ].length ].min if col < goto_col col = goto_col end end new_col = ( col, row ) view_changed = show_character( row, new_col ) @last_screen_y = row - @top_line @last_screen_x = new_col - @left_column @typing = false if stopped_typing @last_row = row @last_col = col @last_screen_col = new_col record_mark_start_and_end selection_removed = false if ! @auto_anchored && ! @changing_selection && selecting? remove_selection( DONT_DISPLAY ) selection_removed = true end @auto_anchored = false old_pair = @text_marks[ :pair ] if @settings[ 'view.pairs.highlight' ] highlight_pair elsif old_pair clear_pair_highlight end highlight_changed = old_pair != @text_marks[ :pair ] if selection_removed || ( do_display && ( selecting? || view_changed || highlight_changed ) ) display else $diakonos.display_mutex.synchronize do @win_main.setpos( @last_screen_y, @last_screen_x ) end end $diakonos.update_status_line $diakonos.update_context_line ( @last_row != old_last_row || @last_col != old_last_col ) end |
#cursor_to_bol ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/diakonos/buffer/cursor.rb', line 95 def cursor_to_bol row = @last_row case @settings[ "bol_behaviour" ] when BOL_ZERO col = 0 when BOL_FIRST_CHAR col = ( ( @lines[ row ] =~ /\S/ ) || 0 ) when BOL_ALT_ZERO if @last_col == 0 col = ( @lines[ row ] =~ /\S/ ) else col = 0 end # when BOL_ALT_FIRST_CHAR else first_char_col = ( ( @lines[ row ] =~ /\S/ ) || 0 ) if @last_col == first_char_col col = 0 else col = first_char_col end end cursor_to( row, col, DO_DISPLAY ) end |
#cursor_to_bov ⇒ Object
Bottom of view
151 152 153 |
# File 'lib/diakonos/buffer/cursor.rb', line 151 def cursor_to_bov cursor_to( row_of( 0 + $diakonos.main_window_height - 1 ), @last_col, DO_DISPLAY ) end |
#cursor_to_eof ⇒ Object
91 92 93 |
# File 'lib/diakonos/buffer/cursor.rb', line 91 def cursor_to_eof cursor_to( @lines.length - 1, @lines[ -1 ].length, DO_DISPLAY ) end |
#cursor_to_eol ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/diakonos/buffer/cursor.rb', line 120 def cursor_to_eol y = @win_main.cury end_col = line_at( y ).length last_char_col = line_at( y ).rstrip.length case @settings[ 'eol_behaviour' ] when EOL_END col = end_col when EOL_LAST_CHAR col = last_char_col when EOL_ALT_LAST_CHAR if @last_col == last_char_col col = end_col else col = last_char_col end else if @last_col == end_col col = last_char_col else col = end_col end end cursor_to( @last_row, col, DO_DISPLAY ) end |
#cursor_to_tov ⇒ Object
Top of view
146 147 148 |
# File 'lib/diakonos/buffer/cursor.rb', line 146 def cursor_to_tov cursor_to( row_of( 0 ), @last_col, DO_DISPLAY ) end |
#delete ⇒ Object
x and y are given window-relative, not buffer-relative.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/diakonos/buffer/delete.rb', line 6 def delete if selection_mark delete_selection else row = @last_row col = @last_col if ( row >= 0 ) && ( col >= 0 ) line = @lines[ row ] if col == line.length if row < @lines.length - 1 # Delete newline, and concat next line join_lines( row ) cursor_to( @last_row, @last_col ) end else take_snapshot(typing: true) @lines[ row ] = line[ 0...col ] + line[ (col + 1).. ] set_modified modified_from_line: row end end end end |
#delete_from(char) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/diakonos/buffer/delete.rb', line 100 def delete_from( char ) remove_selection( DONT_DISPLAY ) if selection_mark first_row = row = @last_row index = @lines[ @last_row ].rindex( char, @last_col-1 ) while row > 0 && index.nil? row -= 1 index = @lines[ row ].rindex( char ) end if index deleted_text = delete_from_to( row, index+1, first_row, @last_col ) cursor_to( row, index+1 ) deleted_text end end |
#delete_from_to(row_from, col_from, row_to, col_to) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/diakonos/buffer/delete.rb', line 68 def delete_from_to( row_from, col_from, row_to, col_to ) take_snapshot if row_to == row_from retval = [ @lines[ row_to ].slice!( col_from, col_to - col_from ) ] else pre_head = @lines[ row_from ][ 0...col_from ] post_tail = @lines[ row_to ][ col_to.. ] head = @lines[ row_from ].slice!( col_from..-1 ) tail = @lines[ row_to ].slice!( 0...col_to ) retval = [ head ] + @lines.slice!( row_from + 1, row_to - row_from ) + [ tail ] @lines[ row_from ] = pre_head + post_tail end set_modified modified_from_line: row_from retval end |
#delete_line ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/diakonos/buffer/delete.rb', line 29 def delete_line remove_selection( DONT_DISPLAY ) if selection_mark row = @last_row take_snapshot retval = nil if @lines.length == 1 retval = @lines[ 0 ] @lines[ 0 ] = "" else retval = @lines[ row ] @lines.delete_at row end cursor_to( row, 0 ) set_modified modified_from_line: row retval end |
#delete_selection(do_display = DO_DISPLAY) ⇒ Object
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/diakonos/buffer/selection.rb', line 281 def delete_selection( do_display = DO_DISPLAY ) return if @text_marks[ :selection ].nil? take_snapshot selection = @text_marks[ :selection ] start_row = selection.start_row start_col = selection.start_col end_row = selection.end_row end_col = selection.end_col start_line = @lines[ start_row ] if end_row == selection.start_row @lines[ start_row ] = start_line[ 0...start_col ] + start_line[ end_col.. ] else case @selection_mode when :normal end_line = @lines[ end_row ] @lines[ start_row ] = start_line[ 0...start_col ] + end_line[ end_col.. ] @lines = @lines[ 0..start_row ] + @lines[ (end_row + 1).. ] when :block @lines[ start_row..end_row ] = @lines[ start_row..end_row ].collect { |line| line[ 0...start_col ] + ( line[ end_col.. ] || '' ) } end end cursor_to start_row, start_col remove_selection DONT_DISPLAY set_modified do_display, modified_from_line: start_row end |
#delete_to(char) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/diakonos/buffer/delete.rb', line 84 def delete_to( char ) remove_selection( DONT_DISPLAY ) if selection_mark first_row = row = @last_row index = @lines[ @last_row ].index( char, @last_col+1 ) while row < @lines.length - 1 && index.nil? row += 1 index = @lines[ row ].index( char ) end if index delete_from_to( first_row, @last_col, row, index ) end end |
#delete_to_and_from(char, inclusive = NOT_INCLUSIVE) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 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 166 |
# File 'lib/diakonos/buffer/delete.rb', line 118 def delete_to_and_from( char, inclusive = NOT_INCLUSIVE ) remove_selection( DONT_DISPLAY ) if selection_mark start_char = end_char = char case char when '(' end_char = ')' when '{' end_char = '}' when '[' end_char = ']' when '<' end_char = '>' when ')' end_char = '(' when '}' end_char = '{' when ']' end_char = '[' when '>' end_char = '<' end row = @last_row start_index = @lines[ @last_row ].rindex( start_char, @last_col ) while row > 0 && start_index.nil? row -= 1 start_index = @lines[ row ].rindex( start_char ) end start_row = row row = @last_row end_index = @lines[ row ].index( end_char, @last_col+1 ) while row < @lines.length - 1 && end_index.nil? row += 1 end_index = @lines[ row ].index( end_char ) end end_row = row if start_index && end_index if inclusive end_index += 1 else start_index += 1 end cursor_to( start_row, start_index ) delete_from_to( start_row, start_index, end_row, end_index ) end end |
#delete_to_eol ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/diakonos/buffer/delete.rb', line 48 def delete_to_eol remove_selection( DONT_DISPLAY ) if selection_mark row = @last_row col = @last_col take_snapshot if @settings[ 'delete_newline_on_delete_to_eol' ] && col == @lines[ row ].size next_line = @lines.delete_at( row + 1 ) @lines[ row ] << next_line retval = [ "\n" ] else retval = [ @lines[ row ][ col.. ] ] @lines[ row ] = @lines[ row ][ 0...col ] end set_modified modified_from_line: row retval end |
#diagnostics_for_current_line ⇒ Object
483 484 485 |
# File 'lib/diakonos/buffer.rb', line 483 def diagnostics_for_current_line diagnostics_for_line(line: @last_row) end |
#diagnostics_for_line(line:) ⇒ Object
487 488 489 490 491 492 493 |
# File 'lib/diakonos/buffer.rb', line 487 def diagnostics_for_line(line:) if @lsp_session && lsp_uri @lsp_session.diagnostics_for_line(uri: lsp_uri, line:) else [] end end |
#display ⇒ Object
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
# File 'lib/diakonos/buffer/display.rb', line 293 def display @pen_down = false # Ensure highlight cache is valid up to @top_line - 1 if @top_line > 0 if @highlight_cache_valid_to < @top_line - 1 rebuild_start = @highlight_cache_valid_to + 1 restore_highlight_state( @highlight_cache_valid_to >= 0 ? @highlight_cache[@highlight_cache_valid_to] : nil ) (rebuild_start..(@top_line - 1)).each do |i| print_line @lines[i].( @tab_size ) @highlight_cache[i] = snapshot_highlight_state end @highlight_cache_valid_to = @top_line - 1 end restore_highlight_state @highlight_cache[@top_line - 1] else restore_highlight_state nil end @pen_down = true # Draw each on-screen line. y = 0 @lines[ @top_line...($diakonos.main_window_height + @top_line) ].each_with_index do |line, row| if @win_line_numbers @win_line_numbers.setpos( y, 0 ) @win_line_numbers.attrset @settings[ 'view.line_numbers.format' ] n = ( @top_line+row+1 ).to_s @win_line_numbers.addstr( @settings[ 'view.line_numbers.number_format' ] % [ n[ -[ @settings[ 'view.line_numbers.width' ], n.length ].min.. ], ] ) line_index = @top_line + row if diagnostics_for_line(line: line_index).any? @win_line_numbers.addstr( @settings[ 'view.line_numbers.diagnostic_marker' ] || '●' ) else @win_line_numbers.addstr( ' ' ) end end @win_main.setpos( y, 0 ) print_line line.( @tab_size ) line_index = @top_line + row @highlight_cache[line_index] = snapshot_highlight_state if line_index > @highlight_cache_valid_to @highlight_cache_valid_to = line_index end @win_main.setpos( y, 0 ) paint_marks line_index y += 1 end # Paint the empty space below the file if the file is too short to fit in one screen. ( y...$diakonos.main_window_height ).each do |y| if @win_line_numbers @win_line_numbers.setpos( y, 0 ) @win_line_numbers.attrset @settings[ 'view.line_numbers.format' ] @win_line_numbers.addstr( ' ' * (@settings[ 'view.line_numbers.width' ] + COLUMNS_FOR_DIAGNOSTICS) ) end @win_main.setpos( y, 0 ) @win_main.attrset @default_formatting linestr = " " * Curses.cols if @settings[ "view.nonfilelines.visible" ] linestr[ 0 ] = ( @settings[ "view.nonfilelines.character" ] || "~" ) end @win_main.addstr linestr end paint_column_markers @win_line_numbers&.refresh @win_main.setpos( @last_screen_y, @last_screen_x ) @win_main.refresh if @language != @original_language set_language( @original_language ) end @time_last_viewed = Time.now end |
#file_different? ⇒ Boolean
Compares MD5 sums of buffer and actual file on disk. Returns true if there is no file on disk.
146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/diakonos/buffer/file.rb', line 146 def file_different? if @name && File.exist?( @name ) Digest::MD5.hexdigest( @lines.join( "\n" ) ) != Digest::MD5.hexdigest( File.read( @name ) ) else true end end |
#file_modified? ⇒ Boolean
Check if the file which is being edited has been modified since the last time we checked it.
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/diakonos/buffer/file.rb', line 125 def file_modified? modified = false if @name begin mtime = File.mtime( @name ) if mtime > @last_modification_check modified = true @last_modification_check = mtime end rescue Errno::ENOENT # Ignore if file doesn't exist end end modified end |
#find(regexps, options = {}) ⇒ Integer
split across newline characters. Once the first element is found, each successive element must match against lines following the first element.
176 177 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 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/diakonos/buffer/searching.rb', line 176 def find( regexps, = {} ) return if regexps.nil? regexp = regexps[ 0 ] return if regexp.nil? || regexp == // direction = [ :direction ] replacement = [ :replacement ] auto_choice = [ :auto_choice ] from_row = [ :starting_row ] || @last_row from_col = [ :starting_col ] || @last_col show_context_after = [ :show_context_after ] if [:starting] @num_matches_found = nil end num_replacements = 0 # TODO: Just use Range here instead of TextMark? search_area = @search_area || TextMark.new( ::Diakonos::Range.new(0, 0, @lines.size - 1, @lines[ -1 ].size), nil ) if ! search_area.contains?( from_row, from_col ) from_row, from_col = search_area.start_row, search_area.start_col end if direction == :opposite direction = OPPOSITE_DIRECTION[@last_search_direction] end @last_search_regexps = regexps @last_search_direction = direction @wrapped = false if direction == :down finding = _find_down(regexps, regexp, from_row, from_col, search_area) elsif direction == :up finding = _find_up(regexps, regexp, search_area, from_row, from_col) end if ! finding remove_selection DONT_DISPLAY clear_matches DO_DISPLAY if ! [ :quiet ] && ( replacement.nil? || num_replacements == 0 ) $diakonos.set_iline "/#{regexp.source}/ not found." end else if @wrapped && ! [ :quiet ] if @search_area $diakonos.set_iline( "(search wrapped around to start of search area)" ) else $diakonos.set_iline( "(search wrapped around BOF/EOF)" ) end end remove_selection( DONT_DISPLAY ) @last_finding = finding if @settings[ "found_cursor_start" ] anchor_selection( finding.end_row, finding.end_col, DONT_DISPLAY ) cursor_to( finding.start_row, finding.start_col ) else anchor_selection( finding.start_row, finding.start_col, DONT_DISPLAY ) cursor_to( finding.end_row, finding.end_col ) end if show_context_after watermark = Curses.lines / 6 if @last_row - @top_line > watermark pitch_view( @last_row - @top_line - watermark ) end end @changing_selection = false if regexps.length == 1 @highlight_regexp = regexp highlight_matches else clear_matches end display if replacement # Substitute placeholders (e.g. \1) in str for the group matches of the last match. actual_replacement = replacement.dup actual_replacement.gsub!( /\\(\\|\d+)/ ) do ref = ::Regexp.last_match(1) if ref == "\\" "\\" else finding.captured_group(ref.to_i) end end choices = [ CHOICE_YES, CHOICE_NO, CHOICE_ALL, CHOICE_CANCEL, CHOICE_YES_AND_STOP ] if @search_area choices << CHOICE_WITHIN_SELECTION end choice = auto_choice || $diakonos.get_choice( "#{@num_matches_found} match#{ @num_matches_found != 1 ? 'es' : '' } - Replace this one?", choices, CHOICE_YES ) case choice when CHOICE_YES paste [ actual_replacement ] num_replacements += 1 + find( regexps, direction:, replacement: ) when CHOICE_ALL num_replacements += replace_all(regexp, replacement) when CHOICE_WITHIN_SELECTION num_replacements += replace_all(regexp, replacement, within_search_area: true) when CHOICE_NO num_replacements += find( regexps, direction:, replacement: ) when CHOICE_CANCEL # Do nothing further. when CHOICE_YES_AND_STOP paste [ actual_replacement ] num_replacements += 1 # Do nothing further. end end end num_replacements end |
#find_again(last_search_regexps, direction = @last_search_direction) ⇒ Object
457 458 459 460 461 462 463 464 |
# File 'lib/diakonos/buffer/searching.rb', line 457 def find_again( last_search_regexps, direction = @last_search_direction ) if @last_search_regexps.nil? || @last_search_regexps.empty? @last_search_regexps = last_search_regexps end if @last_search_regexps find(@last_search_regexps, direction:) end end |
#find_opening_match(line, bos_allowed: true, match_close: true) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/diakonos/buffer/display.rb', line 8 def find_opening_match(line, bos_allowed: true, match_close: true) open_index = line.length open_token_class = nil open_match_text = nil match = nil match_text = nil @token_regexps.each do |token_class, regexp| match = regexp.match(line) if match if match.length > 1 index = match.begin 1 match_text = match[ 1 ] whole_match_index = match.begin 0 else whole_match_index = index = match.begin( 0 ) match_text = match[ 0 ] end bos_condition = ( ! regexp.uses_bos || ( bos_allowed && (whole_match_index == 0) ) ) index_is_earlier = (index < open_index) can_be_closed = (! match_close || @close_token_regexps[token_class]) if( bos_condition && index_is_earlier && can_be_closed ) open_index = index open_token_class = token_class open_match_text = match_text end end end [open_index, open_token_class, open_match_text] end |
#forgotten? ⇒ Boolean
438 439 440 441 442 443 444 |
# File 'lib/diakonos/buffer.rb', line 438 def forgotten? @settings['close_forgotten_buffers_after'] && @time_last_viewed < ( Time.now - @settings['close_forgotten_buffers_after'] * SECONDS_PER_DAY ) end |
#go_block_inner ⇒ Object
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/diakonos/buffer/cursor.rb', line 208 def go_block_inner initial_level = indentation_level( @last_row ) new_row = @lines.length ( @last_row...@lines.length ).each do |row| next if @lines[ row ].strip.empty? level = indentation_level( row ) if level > initial_level new_row = row break elsif level < initial_level new_row = @last_row break end end go_to_line( new_row, @lines[ new_row ].index( /\S/ ) ) end |
#go_block_next ⇒ Object
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/diakonos/buffer/cursor.rb', line 226 def go_block_next initial_level = indentation_level( @last_row ) new_row = @last_row passed = false ( @last_row+1...@lines.length ).each do |row| next if @lines[ row ].strip.empty? level = indentation_level( row ) if ! passed if level < initial_level passed = true end elsif level == initial_level new_row = row break elsif level < initial_level - 1 break end end go_to_line( new_row, @lines[ new_row ].index( /\S/ ) ) end |
#go_block_outer ⇒ Object
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/diakonos/buffer/cursor.rb', line 186 def go_block_outer initial_level = indentation_level( @last_row ) new_row = @last_row passed = false new_level = initial_level ( 0...@last_row ).reverse_each do |row| next if @lines[ row ].strip.empty? level = indentation_level( row ) if ! passed passed = ( level < initial_level ) new_level = level elsif level < new_level new_row = ( row+1..@last_row ).find { |r| ! @lines[ r ].strip.empty? } break end end go_to_line( new_row, @lines[ new_row ].index( /\S/ ) ) end |
#go_block_previous ⇒ Object
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/diakonos/buffer/cursor.rb', line 248 def go_block_previous initial_level = indentation_level( @last_row ) new_row = @last_row passed = false # search for unindent passed2 = false # search for reindent ( 0...@last_row ).reverse_each do |row| next if @lines[ row ].strip.empty? level = indentation_level( row ) if ! passed if level < initial_level passed = true end elsif ! passed2 if level >= initial_level new_row = row passed2 = true elsif level <= initial_level - 2 # No previous block break end elsif level < initial_level new_row = (row+1..@last_row).find { |r| ! @lines[ r ].strip.empty? } break end end go_to_line( new_row, @lines[ new_row ].index( /\S/ ) ) end |
#go_to_char(char, after = ON_CHAR) ⇒ Object
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/diakonos/buffer/cursor.rb', line 279 def go_to_char( char, after = ON_CHAR ) r = @last_row i = @lines[ r ].index( char, @last_col + 1 ) if i if after i += 1 end return cursor_to r, i, DO_DISPLAY end loop do r += 1 break if r >= @lines.size i = @lines[ r ].index( char ) if i if after i += 1 end return cursor_to r, i, DO_DISPLAY end end end |
#go_to_char_previous(char, after = ON_CHAR) ⇒ Object
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/diakonos/buffer/cursor.rb', line 303 def go_to_char_previous( char, after = ON_CHAR ) r = @last_row search_from = @last_col - 1 if search_from >= 0 i = @lines[ r ].rindex( char, search_from ) if i if after i += 1 end return cursor_to r, i, DO_DISPLAY end end loop do r -= 1 break if r < 0 i = @lines[ r ].rindex( char ) if i if after i += 1 end return cursor_to r, i, DO_DISPLAY end end end |
#go_to_line(line = nil, column = nil, do_display = DO_DISPLAY) ⇒ Object
182 183 184 |
# File 'lib/diakonos/buffer/cursor.rb', line 182 def go_to_line( line = nil, column = nil, do_display = DO_DISPLAY ) cursor_to( line || @last_row, column || 0, do_display ) end |
#go_to_next_bookmark ⇒ Object
5 6 7 8 9 10 11 12 13 |
# File 'lib/diakonos/buffer/bookmarking.rb', line 5 def go_to_next_bookmark cur_pos = Bookmark.new( self, @last_row, @last_col ) next_bm = @bookmarks.find { |bm| bm > cur_pos } if next_bm cursor_to( next_bm.row, next_bm.col, DO_DISPLAY ) end end |
#go_to_pair_match ⇒ Object
433 434 435 436 437 438 439 |
# File 'lib/diakonos/buffer/searching.rb', line 433 def go_to_pair_match row, col = pos_of_pair_match if row && col && cursor_to(row, col) highlight_pair display end end |
#go_to_previous_bookmark ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/diakonos/buffer/bookmarking.rb', line 15 def go_to_previous_bookmark cur_pos = Bookmark.new( self, @last_row, @last_col ) # There's no reverse_find method, so, we have to do this manually. prev = nil @bookmarks.reverse_each do |bm| if bm < cur_pos prev = bm break end end if prev cursor_to( prev.row, prev.col, DO_DISPLAY ) end end |
#grep(regexp_source) ⇒ Object
Returns an Array of results, where each result is a String usually containing n‘s due to context
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 |
# File 'lib/diakonos/buffer/searching.rb', line 534 def grep( regexp_source ) if @name filename = File.basename( @name ) filepath = @name else filename = "(unnamed buffer)" filepath = "(unnamed buffer #{object_id})" end ::Diakonos.grep_array( Regexp.new( regexp_source ), @lines, $diakonos.settings[ 'grep.context' ], "#{filename}:", filepath ) end |
#highlight_matches(regexp = @highlight_regexp) ⇒ Object
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
# File 'lib/diakonos/buffer/searching.rb', line 335 def highlight_matches( regexp = @highlight_regexp ) @highlight_regexp = regexp return if @highlight_regexp.nil? if @search_area lines = self.search_area_lines line_index_offset = @search_area.start_row col_offset = @search_area.start_col else lines = @lines line_index_offset = 0 col_offset = 0 end grepped_lines = lines.grep_indices( @highlight_regexp ) grepped_lines.count found_marks = grepped_lines.collect { |line_index, start_col, end_col| TextMark.new( ::Diakonos::Range.new( line_index + line_index_offset, start_col + ( line_index == 0 ? col_offset : 0 ), line_index + line_index_offset, end_col, ), @settings["lang.#{@language}.format.found"] ) } @text_marks[:found] = found_marks @num_matches_found ||= found_marks.size end |
#highlight_pair ⇒ Object
441 442 443 444 445 446 447 448 449 450 451 |
# File 'lib/diakonos/buffer/searching.rb', line 441 def highlight_pair match_row, match_col = pos_of_pair_match( @last_row, @last_col ) if match_col.nil? @text_marks[ :pair ] = nil else @text_marks[ :pair ] = TextMark.new( ::Diakonos::Range.new(match_row, match_col, match_row, match_col + 1), @settings[ "lang.#{@language}.format.pair" ] || @settings[ "lang.shared.format.pair" ] ) end end |
#in_line(x, y) ⇒ Object
Returns true iff the given column, x, is less than the length of the given line, y.
447 448 449 |
# File 'lib/diakonos/buffer.rb', line 447 def in_line( x, y ) x + @left_column < line_at( y ).length end |
#indent(row = @last_row, do_display = DO_DISPLAY) ⇒ Object
166 167 168 169 |
# File 'lib/diakonos/buffer/indentation.rb', line 166 def indent( row = @last_row, do_display = DO_DISPLAY ) level = indentation_level( row, DONT_USE_INDENT_IGNORE ) set_indent row, level + 1, do_display: end |
#indentation_level(row, use_indent_ignore = USE_INDENT_IGNORE) ⇒ Object
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/diakonos/buffer/indentation.rb', line 51 def indentation_level( row, use_indent_ignore = USE_INDENT_IGNORE ) line = @lines[ row ] if use_indent_ignore if line =~ /^[\s#{@indent_ignore_charset}]*$/ || line == "" level = 0 elsif line =~ /^([\s#{@indent_ignore_charset}]+)[^\s#{@indent_ignore_charset}]/ whitespace = ::Regexp.last_match(1).( @tab_size ) level = whitespace.length / @indent_size if @indent_roundup && ( whitespace.length % @indent_size > 0 ) level += 1 end else level = 0 end else level = 0 if line =~ /^([\s]+)/ whitespace = ::Regexp.last_match(1).( @tab_size ) level = whitespace.length / @indent_size if @indent_roundup && ( whitespace.length % @indent_size > 0 ) level += 1 end end end level end |
#insert_char(c) ⇒ Object
208 209 210 211 212 213 214 215 |
# File 'lib/diakonos/buffer.rb', line 208 def insert_char( c ) row = @last_row col = @last_col take_snapshot(typing: true) line = @lines[ row ] @lines[ row ] = line[ 0...col ] + c.chr + line[ col.. ] set_modified modified_from_line: row end |
#insert_string(str) ⇒ Object
217 218 219 220 221 222 223 224 |
# File 'lib/diakonos/buffer.rb', line 217 def insert_string( str ) row = @last_row col = @last_col take_snapshot(typing: true) line = @lines[ row ] @lines[ row ] = line[ 0...col ] + str + line[ col.. ] set_modified modified_from_line: row end |
#join_lines(row = @last_row, strip = DONT_STRIP_LINE) ⇒ Object
267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/diakonos/buffer.rb', line 267 def join_lines( row = @last_row, strip = DONT_STRIP_LINE ) take_snapshot(typing: true) next_line = @lines.delete_at( row + 1 ) return false if next_line.nil? if strip next_line = ' ' + next_line.strip end @lines[ row ] << next_line set_modified modified_from_line: row end |
#join_lines_upward(row = @last_row, strip = DONT_STRIP_LINE) ⇒ Object
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/diakonos/buffer.rb', line 240 def join_lines_upward( row = @last_row, strip = DONT_STRIP_LINE ) return false if row == 0 take_snapshot line = @lines.delete_at( row ) old_line = @lines[ row-1 ] new_x_pos = old_line.length if strip line.strip! # Only prepend a space if the line above isn't empty. if ! old_line.strip.empty? line = ' ' + line new_x_pos += 1 end end @lines[ row-1 ] << line cursor_to( row-1, new_x_pos ) set_modified modified_from_line: row - 1 end |
#length ⇒ Object
184 185 186 |
# File 'lib/diakonos/buffer.rb', line 184 def length @lines.length end |
#line_at(y) ⇒ Object
423 424 425 426 427 428 429 430 |
# File 'lib/diakonos/buffer.rb', line 423 def line_at( y ) row = @top_line + y if row < 0 nil else @lines[ row ] end end |
#lsp_uri ⇒ Object
499 500 501 502 503 |
# File 'lib/diakonos/buffer.rb', line 499 def lsp_uri if name "#{Lsp::FILE_URI_PREFIX}#{name}" end end |
#modified? ⇒ Boolean
192 193 194 |
# File 'lib/diakonos/buffer.rb', line 192 def modified? @modified end |
#nearest_basis_row_from(starting_row, next_line_check: true) ⇒ Integer
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/diakonos/buffer/indentation.rb', line 83 def nearest_basis_row_from(starting_row, next_line_check: true) row = starting_row-1 if @lines[row] =~ @indenters_next_line || @lines[row] =~ @indenters return row end loop do return nil if row.nil? || row < 0 while ( @lines[row] =~ /^[\s#{@indent_ignore_charset}]*$/ || @lines[row] =~ @settings[ "lang.#{@language}.indent.ignore" ] || @lines[row] =~ @settings[ "lang.#{@language}.indent.not_indented" ] ) row = nearest_basis_row_from(row) return nil if row.nil? end if next_line_check row_before = nearest_basis_row_from(row, next_line_check: false) if row_before && @lines[row_before] =~ @indenters_next_line row = row_before next end end break end row end |
#nice_name ⇒ Object
196 197 198 |
# File 'lib/diakonos/buffer.rb', line 196 def nice_name @name || @settings[ "status.unnamed_str" ] end |
#paint_column_markers ⇒ Object
159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/diakonos/buffer/display.rb', line 159 def paint_column_markers $diakonos.column_markers.each_value do |data| column = data[ :column ] next if column.nil? next if column > Curses.cols - @left_column || column - @left_column < 0 num_lines_to_paint = [ $diakonos.main_window_height, @lines.size - @top_line ].min ( 0...num_lines_to_paint ).each do |row| @win_main.setpos( row, column - @left_column ) @win_main.attrset data[ :format ] @win_main.addstr( @lines[ @top_line + row ][ column + @left_column ] || ' ' ) end end end |
#paint_marks(row) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 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 |
# File 'lib/diakonos/buffer/display.rb', line 114 def paint_marks( row ) string = @lines[ row ][ @left_column...@left_column + Curses.cols ] return if string.nil? || string == "" string = string.( @tab_size ) cury = @win_main.cury curx = @win_main.curx @text_marks.values.flatten.reverse_each do |text_mark| next if text_mark.nil? @win_main.attrset text_mark.formatting case @selection_mode when :normal if ( (text_mark.start_row + 1)..(text_mark.end_row - 1) ) === row @win_main.setpos( cury, curx ) @win_main.addstr string elsif row == text_mark.start_row && row == text_mark.end_row paint_single_row_mark( row, text_mark, string, curx, cury ) elsif row == text_mark.start_row = ( text_mark.start_col, row ) if < @left_column + Curses.cols left = [ - @left_column, 0 ].max @win_main.setpos( cury, curx + left ) @win_main.addstr string[ left.. ] end elsif row == text_mark.end_row right = ( text_mark.end_col, row ) - @left_column @win_main.setpos( cury, curx ) @win_main.addstr string[ 0...right ] else # This row not in selection. end when :block if ( text_mark.start_row <= row && row <= text_mark.end_row || text_mark.end_row <= row && row <= text_mark.start_row ) paint_single_row_mark( row, text_mark, string, curx, cury ) end end end end |
#paint_single_row_mark(row, text_mark, string, curx, cury) ⇒ Object
Worker function for painting only part of a row.
102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/diakonos/buffer/display.rb', line 102 def paint_single_row_mark( row, text_mark, string, curx, cury ) = ( text_mark.start_col, row ) if < @left_column + Curses.cols left = [ - @left_column, 0 ].max right = ( text_mark.end_col, row ) - @left_column if left < right @win_main.setpos( cury, curx + left ) @win_main.addstr string[ left...right ] end end end |
#pan_view(x = 1, do_display = DO_DISPLAY) ⇒ Object
Returns the amount the view was actually panned.
512 513 514 515 516 |
# File 'lib/diakonos/buffer.rb', line 512 def pan_view( x = 1, do_display = DO_DISPLAY ) old_left_column = @left_column pan_view_to( @left_column + x, do_display ) @left_column - old_left_column end |
#pan_view_to(left_column, do_display = DO_DISPLAY) ⇒ Object
505 506 507 508 509 |
# File 'lib/diakonos/buffer.rb', line 505 def pan_view_to( left_column, do_display = DO_DISPLAY ) @left_column = [ left_column, 0 ].max record_mark_start_and_end display if do_display end |
#paragraph_under_cursor ⇒ Object
Returns an array of lines of the current paragraph.
703 704 705 706 |
# File 'lib/diakonos/buffer.rb', line 703 def paragraph_under_cursor ( first, _ ), ( last, _ ) = paragraph_under_cursor_pos @lines[ first..last ] end |
#paragraph_under_cursor_pos ⇒ Object
Returns the coordinates of the first and last line of the current paragraph.
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 |
# File 'lib/diakonos/buffer.rb', line 710 def paragraph_under_cursor_pos if @lines[ @last_row ] =~ /^\s*$/ return [ [ @last_row, 0 ], [ @last_row, @lines[ @last_row ].length - 1 ], ] end upper_boundary = 0 lower_boundary = @lines.size - 1 @last_row.downto( 0 ) do |i| line = @lines[ i ] if line =~ /^\s*$/ upper_boundary = i + 1 break end end @last_row.upto( @lines.size - 1 ) do |i| line = @lines[ i ] if line =~ /^\s*$/ lower_boundary = i - 1 break end end [ [ upper_boundary, 0 ], [ lower_boundary, @lines[ lower_boundary ].length - 1 ], ] end |
#parsed_indent(opts = {}) ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 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 |
# File 'lib/diakonos/buffer/indentation.rb', line 116 def parsed_indent( opts = {} ) row = opts.fetch( :row, @last_row ) do_display = opts.fetch( :do_display, true ) undoable = opts.fetch( :undoable, true ) cursor_eol = opts.fetch( :cursor_eol, false ) if row == 0 || @lines[ row ] =~ @settings[ "lang.#{@language}.indent.not_indented" ] level = 0 else basis_row = nearest_basis_row_from(row) if basis_row.nil? level = 0 else # @lines[basis_row] += " // x" level = indentation_level(basis_row) prev_line = @lines[basis_row] line = @lines[row] if @preventers prev_line = prev_line.gsub( @preventers, "" ) line = line.gsub( @preventers, "" ) end nl_indenter_index = (prev_line =~ @indenters_next_line) if nl_indenter_index && basis_row == row-1 level += 1 elsif prev_line =~ @indenters last_indenter = last_match_index(prev_line, @indenters) last_unindenter = last_match_index(prev_line, @unindenters) if last_unindenter.nil? || last_indenter >= last_unindenter level += 1 end end unindenter_index = (line =~ @unindenters) if unindenter_index indenter_index = (line =~ @indenters) if indenter_index.nil? || unindenter_index <= indenter_index level -= 1 end end end end set_indent row, level, do_display:, undoable:, cursor_eol: end |
#paste(text, do_parsed_indent: false, typing: false) ⇒ Object
text is an array of Strings, or a String with zero or more newlines (“n”)
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
# File 'lib/diakonos/buffer/selection.rb', line 314 def paste( text, do_parsed_indent: false, typing: false ) return if text.nil? if ! text.kind_of?(Array) s = text.to_s if s.include?( "\n" ) text = s.split( "\n", -1 ) else text = [ s ] end end take_snapshot(typing:) delete_selection DONT_DISPLAY row = @last_row col = @last_col new_col = nil line = @lines[ row ] if text.length == 1 @lines[ row ] = line[ 0...col ] + text[ 0 ] + line[ col.. ] if do_parsed_indent parsed_indent row:, do_display: false end cursor_to( @last_row, @last_col + text[ 0 ].length, DONT_DISPLAY, ! typing ) elsif text.length > 1 case @selection_mode when :normal @lines[ row ] = line[ 0...col ] + text[ 0 ] @lines[ row + 1, 0 ] = text[ -1 ] + line[ col.. ] @lines[ row + 1, 0 ] = text[ 1..-2 ] new_col = column_of( text[ -1 ].length ) when :block @lines += [ '' ] * [ 0, ( row + text.length - @lines.length ) ].max range = row...( row + text.length ) @lines[range] = ( @lines[range] .collect .with_index { |line,index| pre = line[0...col].ljust(col) post = line[col..] "#{pre}#{text[ index ]}#{post}" } ) new_col = col + text[-1].length end new_row = @last_row + text.length - 1 if do_parsed_indent ( row..new_row ).each do |r| parsed_indent row: r, do_display: false end end cursor_to( new_row, new_col ) end set_modified modified_from_line: row end |
#pitch_view(y = 1, do_pitch_cursor = DONT_PITCH_CURSOR, do_display = DO_DISPLAY) ⇒ Object
Returns the amount the view was actually pitched.
590 591 592 |
# File 'lib/diakonos/buffer.rb', line 590 def pitch_view( y = 1, do_pitch_cursor = DONT_PITCH_CURSOR, do_display = DO_DISPLAY ) pitch_view_to( @top_line + y, do_pitch_cursor, do_display ) end |
#pitch_view_to(new_top_line, do_pitch_cursor = DONT_PITCH_CURSOR, do_display = DO_DISPLAY) ⇒ Object
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 |
# File 'lib/diakonos/buffer.rb', line 518 def pitch_view_to( new_top_line, do_pitch_cursor = DONT_PITCH_CURSOR, do_display = DO_DISPLAY ) old_top_line = @top_line if new_top_line < 0 @top_line = 0 elsif new_top_line + $diakonos.main_window_height > @lines.length @top_line = [ @lines.length - $diakonos.main_window_height, 0 ].max else @top_line = new_top_line end old_row = @last_row old_col = @last_col changed = ( @top_line - old_top_line ) if changed != 0 && do_pitch_cursor @last_row += changed end height = [ $diakonos.main_window_height, @lines.length ].min @last_row = NumberFitter.fit( number: @last_row, min: @top_line, max: @top_line + height - 1, ) if @last_row - @top_line < @settings["view.margin.y"] @last_row = NumberFitter.fit( number: @top_line + @settings["view.margin.y"], min: @top_line, max: @top_line + height - 1, ) elsif @top_line + height - 1 - @last_row < @settings[ "view.margin.y" ] @last_row = NumberFitter.fit( number: @top_line + height - 1 - @settings[ "view.margin.y" ], min: @top_line, max: @top_line + height - 1, ) end @last_col = NumberFitter.fit( number: @last_col, min: @left_column, max: [ @left_column + Curses.cols - 1, @lines[@last_row].length, ].min ) @last_screen_y = @last_row - @top_line @last_screen_x = ( @last_col, @last_row ) - @left_column record_mark_start_and_end if changed != 0 if ! @auto_anchored && ! @changing_selection && selecting? remove_selection DONT_DISPLAY end highlight_matches if $diakonos.there_was_non_movement $diakonos.push_cursor_state( old_top_line, old_row, old_col ) end end display if do_display changed end |
#pos_of_next(regexp, start_row, start_col) ⇒ Object
372 373 374 375 376 377 378 379 380 381 382 |
# File 'lib/diakonos/buffer/searching.rb', line 372 def pos_of_next( regexp, start_row, start_col ) row, col = start_row, start_col col = @lines[ row ].index( regexp, col ) while col.nil? && row < @lines.length - 1 row += 1 col = @lines[ row ].index( regexp ) end if col [ row, col, Regexp.last_match( 0 ) ] end end |
#pos_of_pair_match(row = @last_row, col = @last_col) ⇒ Object
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 |
# File 'lib/diakonos/buffer/searching.rb', line 402 def pos_of_pair_match( row = @last_row, col = @last_col ) c = @lines[ row ][ col ] data = CHARACTER_PAIRS[ c ] return if data.nil? d = data[ :partner ] c_ = Regexp.escape c d_ = Regexp.escape d target = /(?:#{c_}|#{d_})/ case data[ :direction ] when :forward row, col, char = pos_of_next( target, row, col + 1 ) while char == c # Take care of nested pairs row, col = pos_of_pair_match( row, col ) break if col.nil? row, col, char = pos_of_next( target, row, col + 1 ) end when :backward row, col, char = pos_of_prev( target, row, col - 1 ) while char == c # Take care of nested pairs row, col = pos_of_pair_match( row, col ) break if col.nil? row, col, char = pos_of_prev( target, row, col - 1 ) end end [ row, col ] end |
#pos_of_prev(regexp, start_row, start_col) ⇒ Object
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 |
# File 'lib/diakonos/buffer/searching.rb', line 384 def pos_of_prev( regexp, start_row, start_col ) row, col = start_row, start_col if col < 0 row -= 1 col = -1 end return if row < 0 col = @lines[ row ].rindex( regexp, col ) while col.nil? && row > 0 row -= 1 col = @lines[ row ].rindex( regexp ) end if col [ row, col, Regexp.last_match( 0 ) ] end end |
#print_line(line) ⇒ Object
This method assumes that the cursor has been set up already at the left-most column of the correct on-screen row. It merely unintelligently prints the characters on the current curses line, refusing to print characters of the in-buffer line which are offscreen.
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/diakonos/buffer/display.rb', line 186 def print_line( line ) i = 0 substr = nil while i < line.length substr = line[ i.. ] if @continued_format_class close_index, close_match_text = find_closing_match( substr, @close_token_regexps[@continued_format_class], bos_allowed: i == 0 ) if close_match_text.nil? print_string truncate_off_screen( substr, i ) print_padding_from( line.length ) i = line.length else end_index = close_index + close_match_text.length print_string truncate_off_screen( substr[ 0...end_index ], i ) @continued_format_class = nil i += end_index end else first_index, first_token_class, first_word = find_opening_match( substr, bos_allowed: i == 0, match_close: false ) if @lang_stack.any? prev_lang, close_token_class = @lang_stack[-1] close_index, close_match_text = find_closing_match( substr, $diakonos.close_token_regexps[prev_lang][close_token_class], bos_allowed: i == 0 ) if close_match_text && close_index <= first_index # Print any remaining text in the embedded language s = substr[0...close_index] print_string( truncate_off_screen(s, i) ) i += s.length @lang_stack.pop set_language prev_lang print_string( truncate_off_screen( substr[ close_index...(close_index + close_match_text.length) ], i ), @token_formats[close_token_class] ) i += close_match_text.length # Continue printing from here. next end end if first_word if first_index > 0 # Print any preceding text in the default format print_string truncate_off_screen( substr[ 0...first_index ], i ) i += substr[ 0...first_index ].length end print_string( truncate_off_screen( first_word, i ), @token_formats[ first_token_class ] ) i += first_word.length if @close_token_regexps[first_token_class] change_to = @settings["lang.#{@language}.tokens.#{first_token_class}.change_to"] if change_to @lang_stack.push [ @language, first_token_class ] set_language change_to else @continued_format_class = first_token_class end end else print_string truncate_off_screen( substr, i ) i += substr.length break end end end print_padding_from i end |
#print_padding_from(col) ⇒ Object
279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/diakonos/buffer/display.rb', line 279 def print_padding_from( col ) return if ! @pen_down if col < @left_column remainder = Curses.cols else remainder = @left_column + Curses.cols - col end if remainder > 0 print_string( " " * remainder ) end end |
#print_string(string, formatting = ( @token_formats[ @continued_format_class ] || @default_formatting )) ⇒ Object
174 175 176 177 178 179 180 |
# File 'lib/diakonos/buffer/display.rb', line 174 def print_string( string, formatting = ( @token_formats[ @continued_format_class ] || @default_formatting ) ) return if ! @pen_down return if string.nil? @win_main.attrset formatting @win_main.addstr string end |
#record_mark_start_and_end ⇒ Object
@mark_start[ “col” ] is inclusive, @mark_end[ “col” ] is exclusive.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/diakonos/buffer/selection.rb', line 7 def record_mark_start_and_end if @mark_anchor.nil? @text_marks[ :selection ] = nil return end crow = @last_row ccol = @last_col arow = @mark_anchor[ 'row' ] acol = @mark_anchor[ 'col' ] case @selection_mode when :normal anchor_first = true if crow < arow anchor_first = false elsif crow > arow anchor_first = true elsif ccol < acol anchor_first = false end if anchor_first @text_marks[ :selection ] = TextMark.new( ::Diakonos::Range.new(arow, acol, crow, ccol), @selection_formatting ) else @text_marks[ :selection ] = TextMark.new( ::Diakonos::Range.new(crow, ccol, arow, acol), @selection_formatting ) end when :block if crow < arow if ccol < acol # Northwest @text_marks[ :selection ] = TextMark.new( ::Diakonos::Range.new(crow, ccol, arow, acol), @selection_formatting ) else # Northeast @text_marks[ :selection ] = TextMark.new( ::Diakonos::Range.new(crow, acol, arow, ccol), @selection_formatting ) end elsif ccol < acol # Southwest @text_marks[ :selection ] = TextMark.new( ::Diakonos::Range.new(arow, ccol, crow, acol), @selection_formatting ) else # Southeast @text_marks[ :selection ] = TextMark.new( ::Diakonos::Range.new(arow, acol, crow, ccol), @selection_formatting ) end end end |
#remove_selection(do_display = DO_DISPLAY) ⇒ Object
210 211 212 213 214 215 216 217 218 |
# File 'lib/diakonos/buffer/selection.rb', line 210 def remove_selection( do_display = DO_DISPLAY ) return if selection_mark.nil? @mark_anchor = nil record_mark_start_and_end @changing_selection = false @last_finding = nil display if do_display end |
#replace_all(regexp, replacement, within_search_area: false) ⇒ Integer
Returns the number of replacements made.
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 |
# File 'lib/diakonos/buffer/searching.rb', line 301 def replace_all( regexp, replacement, within_search_area: false ) return if ( regexp.nil? || replacement.nil? ) num_replacements = 0 take_snapshot if within_search_area && @search_area lines = self.search_area_lines else lines = @lines end lines_modified = lines.collect { |line| num_replacements += line.scan(regexp).size line.gsub( regexp, replacement ) } if within_search_area && @search_area @lines[@search_area.start_row][@search_area.start_col..-1] = lines_modified[0] if @search_area.end_row - @search_area.start_row > 1 @lines[@search_area.start_row+1..@search_area.end_row-1] = lines_modified[1..-2] end @lines[@search_area.end_row][0..@search_area.end_col] = lines_modified[-1] else @lines = lines_modified end set_modified modified_from_line: 0 clear_matches display num_replacements end |
#replace_char(c) ⇒ Object
200 201 202 203 204 205 206 |
# File 'lib/diakonos/buffer.rb', line 200 def replace_char( c ) row = @last_row col = @last_col take_snapshot(typing: true) @lines[ row ][ col ] = c set_modified modified_from_line: row end |
#reset_display ⇒ Object
139 140 141 142 |
# File 'lib/diakonos/buffer.rb', line 139 def reset_display @win_main = $diakonos.win_main @win_line_numbers = $diakonos.win_line_numbers end |
#row_of(y) ⇒ Object
Translates the window row, y, to a buffer-relative row index.
457 458 459 |
# File 'lib/diakonos/buffer.rb', line 457 def row_of( y ) @top_line + y end |
#row_to_y(row) ⇒ Object
Returns nil if the row is off-screen.
462 463 464 465 466 467 468 |
# File 'lib/diakonos/buffer.rb', line 462 def row_to_y( row ) return nil if row.nil? y = row - @top_line y = nil if ( y < 0 ) || ( y > @top_line + $diakonos.main_window_height - 1 ) y end |
#save(filename = nil, prompt_overwrite = DONT_PROMPT_OVERWRITE) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/diakonos/buffer/file.rb', line 5 def save( filename = nil, prompt_overwrite = DONT_PROMPT_OVERWRITE ) if filename name = File.( filename ) else name = @name end if( @read_only && FileTest.exist?(@name) && FileTest.exist?(name) && ( File.stat(@name).ino == File.stat(name).ino ) ) $diakonos.set_iline "#{name} cannot be saved since it is read-only." else @read_only = false if name.nil? $diakonos.save_file_as else proceed = true if prompt_overwrite && FileTest.exist?( name ) proceed = false choice = $diakonos.get_choice( "Overwrite existing '#{name}'?", [ CHOICE_YES, CHOICE_NO ], CHOICE_NO ) case choice when CHOICE_YES proceed = true when CHOICE_NO proceed = false end end if file_modified? proceed = ! $diakonos.revert( "File has been altered externally. Load on-disk version?" ) end if proceed save_copy name @name = name @last_modification_check = File.mtime( @name ) saved = true if @name =~ %r{#{$diakonos.diakonos_home}/.*\.conf} $diakonos.load_configuration $diakonos.initialize_display end @modified = false display $diakonos.update_status_line end end end saved end |
#save_copy(filename) ⇒ Object
Returns true on successful write.
68 69 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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/diakonos/buffer/file.rb', line 68 def save_copy( filename ) return false if filename.nil? name = File.( filename ) if @settings['save_backup_files'] begin FileUtils.cp name, name+'~', preserve: true rescue Errno::ENOENT # Do nothing if file didn't exist yet end end File.open( name, "w" ) do |f| was_modified = false @lines[ 0..-2 ].each do |line| if @settings[ 'strip_trailing_whitespace_on_save' ] stripped = line.rstrip! was_modified ||= stripped end f.puts line end line = @lines[ -1 ] if @settings[ 'strip_trailing_whitespace_on_save' ] stripped = line.rstrip! was_modified ||= stripped end if line != "" # No final newline character if @settings[ "eof_newline" ] line << "\n" @lines << '' was_modified = true end f.print line end if ( @settings['strip_trailing_whitespace_on_save'] && @last_col > @lines[@last_row].size ) cursor_to @last_row, @lines[ @last_row ].size end if was_modified set_modified end end end |
#search_area? ⇒ Boolean
23 24 25 |
# File 'lib/diakonos/buffer/searching.rb', line 23 def search_area? @search_area end |
#search_area_lines ⇒ Array<String>
56 57 58 59 60 61 62 63 64 |
# File 'lib/diakonos/buffer/searching.rb', line 56 def search_area_lines return [] if @search_area.nil? lines = @lines[@search_area.start_row..@search_area.end_row] lines[0] = lines[0][@search_area.start_col..] lines[-1] = lines[-1][0..@search_area.end_col] lines end |
#seek(regexp, direction = :down) ⇒ Object
466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 |
# File 'lib/diakonos/buffer/searching.rb', line 466 def seek( regexp, direction = :down ) return if regexp.nil? || regexp == // found_row = nil found_col = nil found_text = nil catch :found do if direction == :down # Check the current row first. index, match_text = @lines[ @last_row ].group_index( regexp, @last_col + 1 ) if index found_row = @last_row found_col = index found_text = match_text throw :found end # Check below the cursor. ( (@last_row + 1)...@lines.length ).each do |i| index, match_text = @lines[ i ].group_index( regexp ) if index found_row = i found_col = index found_text = match_text throw :found end end else # Check the current row first. col_to_check = @last_col - 1 if col_to_check >= 0 index, match_text = @lines[ @last_row ].group_rindex( regexp, col_to_check ) if index found_row = @last_row found_col = index found_text = match_text throw :found end end # Check above the cursor. (@last_row - 1).downto( 0 ) do |i| index, match_text = @lines[ i ].group_rindex( regexp ) if index found_row = i found_col = index found_text = match_text throw :found end end end end if found_text cursor_to( found_row, found_col ) display true end end |
#select(from_regexp, to_regexp, include_ending: true) ⇒ Object
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/diakonos/buffer/selection.rb', line 156 def select( from_regexp, to_regexp, include_ending: true ) start_row = nil @lines[ 0..@last_row ].reverse.each_with_index do |line,index| if line =~ from_regexp start_row = @last_row - index break end end if start_row end_row = nil @lines[ start_row.. ].each_with_index do |line,index| if line =~ to_regexp end_row = start_row + index break end end if end_row if include_ending end_row += 1 end anchor_selection( start_row, 0, DONT_DISPLAY ) cursor_to( end_row, 0 ) display end end end |
#select_all ⇒ Object
91 92 93 94 95 |
# File 'lib/diakonos/buffer/selection.rb', line 91 def select_all selection_mode_normal anchor_selection( 0, 0, DONT_DISPLAY ) cursor_to( @lines.length - 1, @lines[ -1 ].length, DO_DISPLAY ) end |
#select_current_line ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/diakonos/buffer/selection.rb', line 70 def select_current_line selection_mode_normal anchor_selection( @last_row, 0, DONT_DISPLAY ) if @last_row == @lines.size - 1 row = @last_row col = @lines[ @last_row ].size else row = @last_row + 1 col = 0 end cursor_to( row, col, DO_DISPLAY ) end |
#select_word ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/diakonos/buffer/selection.rb', line 132 def select_word coords = word_under_cursor_pos( or_after: true ) if coords.nil? remove_selection else cursor_to(*coords[0]) anchor_selection cursor_to(*coords[1]) display end end |
#select_word_another ⇒ Object
144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/diakonos/buffer/selection.rb', line 144 def select_word_another m = selection_mark if m.nil? select_word else row, col, _ = pos_of_next( /\w\b/, @last_row, @last_col ) if row && col cursor_to row, col+1, DO_DISPLAY end end end |
#select_wrapping_block ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/diakonos/buffer/selection.rb', line 97 def select_wrapping_block block_level = indentation_level( @last_row ) if selecting? block_level -= 1 end if block_level <= 0 return select_all end end_row = start_row = @last_row # Find block end ( @last_row...@lines.size ).each do |row| next if @lines[ row ].strip.empty? if indentation_level( row ) < block_level end_row = row break end end # Go to block beginning ( 0...@last_row ).reverse_each do |row| next if @lines[ row ].strip.empty? if indentation_level( row ) < block_level start_row = row + 1 break end end anchor_selection( end_row, 0 ) cursor_to( start_row, 0, DO_DISPLAY ) end |
#selected_lines ⇒ Object
259 260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'lib/diakonos/buffer/selection.rb', line 259 def selected_lines selection = selection_mark if selection if selection.end_col == 0 end_row = selection.end_row - 1 else end_row = selection.end_row end @lines[ selection.start_row..end_row ] else [ @lines[ @last_row ] ] end end |
#selected_string ⇒ Object
250 251 252 253 254 255 256 257 |
# File 'lib/diakonos/buffer/selection.rb', line 250 def selected_string lines = selected_text if lines lines.join( "\n" ) else nil end end |
#selected_text ⇒ Array<String>?
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/diakonos/buffer/selection.rb', line 233 def selected_text selection = selection_mark if selection.nil? nil elsif selection.start_row == selection.end_row [ @lines[ selection.start_row ][ selection.start_col...selection.end_col ] ] elsif @selection_mode == :block @lines[ selection.start_row..selection.end_row ].collect { |line| line[ selection.start_col...selection.end_col ] } else [ @lines[ selection.start_row ][ selection.start_col.. ] ] + ( @lines[ (selection.start_row + 1)..(selection.end_row - 1) ] || [] ) + [ @lines[ selection.end_row ][ 0...selection.end_col ] ] end end |
#selecting? ⇒ Boolean
66 67 68 |
# File 'lib/diakonos/buffer/selection.rb', line 66 def selecting? !! selection_mark end |
#selection_mark ⇒ Object
62 63 64 |
# File 'lib/diakonos/buffer/selection.rb', line 62 def selection_mark @text_marks[:selection] end |
#selection_mode_block ⇒ Object
273 274 275 |
# File 'lib/diakonos/buffer/selection.rb', line 273 def selection_mode_block @selection_mode = :block end |
#selection_mode_normal ⇒ Object
277 278 279 |
# File 'lib/diakonos/buffer/selection.rb', line 277 def selection_mode_normal @selection_mode = :normal end |
#set_indent(row, level, opts = {}) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/diakonos/buffer/indentation.rb', line 16 def set_indent( row, level, opts = {} ) do_display = opts.fetch( :do_display, true ) undoable = opts.fetch( :undoable, true ) cursor_eol = opts.fetch( :cursor_eol, false ) @lines[ row ] =~ /^([\s#{@indent_ignore_charset}]*)(.*)$/ current_indent_text = ( ::Regexp.last_match(1) || "" ) rest = ( ::Regexp.last_match(2) || "" ) current_indent_text.gsub!( /\t/, ' ' * @tab_size ) indentation = @indent_size * [ level, 0 ].max if current_indent_text.length >= indentation indent_text = current_indent_text[ 0...indentation ] else indent_text = current_indent_text + " " * ( indentation - current_indent_text.length ) end if @settings[ "lang.#{@language}.indent.using_tabs" ] num_tabs = 0 indent_text.gsub!( / {#{@tab_size}}/ ) do num_tabs += 1 "\t" end indentation -= num_tabs * ( @tab_size - 1 ) end take_snapshot(typing: true) if do_display && undoable @lines[ row ] = indent_text + rest if do_display cursor_to( row, cursor_eol ? @lines[row].length : indentation ) end set_modified do_display, modified_from_line: row end |
#set_language(_language) ⇒ Object
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/diakonos/buffer.rb', line 144 def set_language( _language ) @settings = $diakonos.settings @language = _language @surround_pairs = $diakonos.surround_pairs[ @language ] @token_regexps = $diakonos.token_regexps[ @language ] @close_token_regexps = $diakonos.close_token_regexps[ @language ] @token_formats = $diakonos.token_formats[ @language ] @indenters = $diakonos.indenters[ @language ] @indenters_next_line = $diakonos.indenters_next_line[ @language ] @unindenters = $diakonos.unindenters[ @language ] @preventers = @settings[ "lang.#{@language}.indent.preventers" ] @closers = $diakonos.closers[ @language ] || Hash.new @auto_indent = @settings[ "lang.#{@language}.indent.auto" ] @indent_size = ( @settings[ "lang.#{@language}.indent.size" ] || 4 ) @indent_roundup = ( @settings[ "lang.#{@language}.indent.roundup" ].nil? ? true : @settings[ "lang.#{@language}.indent.roundup" ] ) @indent_closers = ( @settings[ "lang.#{@language}.indent.closers" ].nil? ? false : @settings[ "lang.#{@language}.indent.closers" ] ) @default_formatting = ( @settings[ "lang.#{@language}.format.default" ] || Curses::A_NORMAL ) @selection_formatting = ( @settings[ "lang.#{@language}.format.selection" ] || Curses::A_REVERSE ) @indent_ignore_charset = ( @settings[ "lang.#{@language}.indent.ignore.charset" ] || "" ) @tab_size = ( @settings[ "lang.#{@language}.tabsize" ] || DEFAULT_TAB_SIZE ) end |
#set_modified(do_display = DO_DISPLAY, use_md5 = DONT_USE_MD5, modified_from_line: 0) ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/diakonos/buffer/file.rb', line 158 def set_modified( do_display = DO_DISPLAY, use_md5 = DONT_USE_MD5, modified_from_line: 0 ) invalidate_highlight_cache_from( line: modified_from_line ) if @read_only $diakonos.set_iline "Warning: Modifying a read-only file." end @modified = use_md5 ? file_different? : true clear_matches @lsp_session&.notify_did_change(buffer: self) if do_display $diakonos.update_status_line display end end |
#set_search_area(mark) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/diakonos/buffer/searching.rb', line 33 def set_search_area(mark) if mark.nil? raise 'Call Diakonos::Buffer#clear_search_area instead' end @search_area = mark @text_marks[ :search_area_pre ] = TextMark.new( ::Diakonos::Range.new(0, 0, mark.start_row, mark.start_col), @settings[ 'view.non_search_area.format' ] ) @text_marks[ :search_area_post ] = TextMark.new( ::Diakonos::Range.new(mark.end_row, mark.end_col, @lines.length - 1, @lines[ -1 ].length), @settings[ 'view.non_search_area.format' ] ) end |
#set_selection(start_row, start_col, end_row, end_col) ⇒ Object
184 185 186 187 188 189 190 |
# File 'lib/diakonos/buffer/selection.rb', line 184 def set_selection( start_row, start_col, end_row, end_col ) @text_marks[ :selection ] = TextMark.new( ::Diakonos::Range.new(start_row, start_col, end_row, end_col), @selection_formatting ) @changing_selection = false end |
#set_selection_current_line ⇒ Object
83 84 85 86 87 88 89 |
# File 'lib/diakonos/buffer/selection.rb', line 83 def set_selection_current_line @text_marks[ :selection ] = TextMark.new( ::Diakonos::Range.new(@last_row, 0, @last_row, @lines[ @last_row ].size), @selection_formatting ) @lines[ @last_row ] end |
#set_type(type) ⇒ Object
652 653 654 655 656 657 658 |
# File 'lib/diakonos/buffer.rb', line 652 def set_type( type ) return false if type.nil? configure( type ) display true end |
#show_character(row, col) ⇒ Object
col and row are given relative to the buffer, not any window or screen. Returns true if the view changed positions.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/diakonos/buffer/cursor.rb', line 157 def show_character( row, col ) old_top_line = @top_line old_left_column = @left_column while row < @top_line + @settings[ "view.margin.y" ] amount = (-1) * @settings[ "view.jump.y" ] break if ( pitch_view( amount, DONT_PITCH_CURSOR, DONT_DISPLAY ) != amount ) end while row > @top_line + $diakonos.main_window_height - 1 - @settings[ "view.margin.y" ] amount = @settings[ "view.jump.y" ] break if ( pitch_view( amount, DONT_PITCH_CURSOR, DONT_DISPLAY ) != amount ) end while col < @left_column + @settings[ "view.margin.x" ] amount = (-1) * @settings[ "view.jump.x" ] break if ( pan_view( amount, DONT_DISPLAY ) != amount ) end while col > @left_column + $diakonos.main_window_width - @settings[ "view.margin.x" ] - 2 amount = @settings[ "view.jump.x" ] break if ( pan_view( amount, DONT_DISPLAY ) != amount ) end @top_line != old_top_line || @left_column != old_left_column end |
#surround(text, parenthesis) ⇒ Object
226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/diakonos/buffer.rb', line 226 def surround( text, parenthesis ) pattern, pair = @surround_pairs.select { |r, _| parenthesis =~ r }.to_a[0] if pair.nil? $diakonos.set_iline "No matching parentheses pair found." nil else pair.map! do |paren| parenthesis.gsub( pattern, paren ) end pair[ 0 ] + text.join( "\n" ) + pair[ 1 ] end end |
#tab_expanded_column(col, row) ⇒ Object
5 6 7 8 9 10 11 12 13 14 |
# File 'lib/diakonos/buffer/indentation.rb', line 5 def ( col, row ) delta = 0 line = @lines[ row ] for i in 0...col if line[ i ] == "\t" delta += ( @tab_size - ( (i+delta) % @tab_size ) ) - 1 end end col + delta end |
#take_snapshot(typing: false) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/diakonos/buffer/undo.rb', line 8 def take_snapshot( typing: false ) do_it = false if ( ! @modified && file_modified? && file_different? && $diakonos.revert( "File has been altered externally. Load on-disk version?" ) ) return end if @typing != typing @typing = typing # If we just started typing, take a snapshot, but don't continue # taking snapshots for every keystroke if typing do_it = true end end if ! @typing do_it = true end if do_it undo_size = 0 @buffer_states[ 1.. ].each do |state| undo_size += state.length end while ( ( undo_size + @lines.length ) >= @settings[ "max_undo_lines" ] ) && @buffer_states.length > 1 @cursor_states.pop popped_state = @buffer_states.pop undo_size = undo_size - popped_state.length end if @current_buffer_state > 0 @buffer_states.unshift @lines.deep_clone @cursor_states.unshift [ @last_row, @last_col ] end @buffer_states.unshift @lines.deep_clone @cursor_states.unshift [ @last_row, @last_col ] @current_buffer_state = 0 @lines = @buffer_states[ @current_buffer_state ] end end |
#to_a ⇒ Object
188 189 190 |
# File 'lib/diakonos/buffer.rb', line 188 def to_a @lines.dup end |
#toggle_bookmark ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/diakonos/buffer/bookmarking.rb', line 30 def toggle_bookmark bookmark = Bookmark.new( self, @last_row, @last_col ) existing = @bookmarks.find { |bm| bm == bookmark } if existing @bookmarks.delete existing $diakonos.set_iline "Bookmark #{existing} deleted." else @bookmarks.push bookmark @bookmarks.sort $diakonos.set_iline "Bookmark #{bookmark} set." end end |
#toggle_selection ⇒ Object
220 221 222 223 224 225 226 |
# File 'lib/diakonos/buffer/selection.rb', line 220 def toggle_selection if @changing_selection remove_selection else anchor_selection end end |
#truncate_off_screen(string, write_cursor_col) ⇒ Object
Prints text to the screen, truncating where necessary. Returns nil if the string is completely off-screen. write_cursor_col is buffer-relative, not screen-relative
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/diakonos/buffer/display.rb', line 77 def truncate_off_screen( string, write_cursor_col ) retval = string # Truncate based on left edge of display area if write_cursor_col < @left_column retval = retval[ (@left_column - write_cursor_col).. ] write_cursor_col = @left_column end if retval && ( # Truncate based on right edge of display area write_cursor_col + retval.length > @left_column + Curses.cols - 1 ) new_length = ( @left_column + Curses.cols - write_cursor_col ) if new_length <= 0 retval = nil else retval = retval[ 0...new_length ] end end retval == "" ? nil : retval end |
#uncomment ⇒ Object
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
# File 'lib/diakonos/buffer.rb', line 389 def uncomment take_snapshot comment_string = Regexp.escape( @settings[ "lang.#{@language}.comment_string" ].to_s ) comment_close_string = Regexp.escape( @settings[ "lang.#{@language}.comment_close_string" ].to_s ) one_modified = false self.selected_lines.each do |line| old_line = line.dup comment_regexp = /^(\s*)#{comment_string}/ line.gsub!( comment_regexp, "\\1" ) if line !~ comment_regexp line.gsub!( /#{comment_close_string}$/, '' ) end one_modified ||= ( line != old_line ) end if one_modified set_modified modified_from_line: (@text_marks[:selection]&.start_row || @last_row) end end |
#undo ⇒ Object
55 56 57 58 59 60 61 62 63 |
# File 'lib/diakonos/buffer/undo.rb', line 55 def undo return if @current_buffer_state >= @buffer_states.length - 1 @current_buffer_state += 1 @lines = @buffer_states[ @current_buffer_state ] cursor_to( @cursor_states[ @current_buffer_state - 1 ][ 0 ], @cursor_states[ @current_buffer_state - 1 ][ 1 ] ) $diakonos.set_iline "Undo level: #{@current_buffer_state} of #{@buffer_states.length - 1}" set_modified DO_DISPLAY, DO_USE_MD5, modified_from_line: 0 end |
#unindent(row = @last_row, do_display = DO_DISPLAY) ⇒ Object
171 172 173 174 |
# File 'lib/diakonos/buffer/indentation.rb', line 171 def unindent( row = @last_row, do_display = DO_DISPLAY ) level = indentation_level( row, DONT_USE_INDENT_IGNORE ) set_indent row, level - 1, do_display: end |
#unundo ⇒ Object
Since redo is a Ruby keyword…
66 67 68 69 70 71 72 73 74 |
# File 'lib/diakonos/buffer/undo.rb', line 66 def unundo return if @current_buffer_state <= 0 @current_buffer_state += -1 @lines = @buffer_states[ @current_buffer_state ] cursor_to( @cursor_states[ @current_buffer_state ][ 0 ], @cursor_states[ @current_buffer_state ][ 1 ] ) $diakonos.set_iline "Undo level: #{@current_buffer_state} of #{@buffer_states.length - 1}" set_modified DO_DISPLAY, DO_USE_MD5, modified_from_line: 0 end |
#word_before_cursor ⇒ Object
687 688 689 690 691 692 693 694 695 696 697 698 699 |
# File 'lib/diakonos/buffer.rb', line 687 def word_before_cursor word = nil @lines[ @last_row ].scan( WORD_REGEXP ) do |match_text| last_match = Regexp.last_match if last_match.begin( 0 ) <= @last_col && @last_col <= last_match.end( 0 ) word = match_text break end end word end |
#word_under_cursor ⇒ Object
660 661 662 663 664 665 666 667 |
# File 'lib/diakonos/buffer.rb', line 660 def word_under_cursor pos = word_under_cursor_pos return if pos.nil? col1 = pos[ 0 ][ 1 ] col2 = pos[ 1 ][ 1 ] @lines[ @last_row ][ col1...col2 ] end |
#word_under_cursor_pos(options = {}) ⇒ Object
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 |
# File 'lib/diakonos/buffer.rb', line 669 def word_under_cursor_pos( = {} ) or_after = [:or_after] @lines[ @last_row ].scan( WORD_REGEXP ) do last_match = Regexp.last_match if ( last_match.begin( 0 ) <= @last_col && @last_col < last_match.end( 0 ) || or_after && last_match.begin(0) > @last_col ) return [ [ @last_row, last_match.begin( 0 ) ], [ @last_row, last_match.end( 0 ) ], ] end end nil end |
#words(filter_regexp = nil) ⇒ Object
TODO paragraph_before_cursor(_pos)?
744 745 746 747 |
# File 'lib/diakonos/buffer.rb', line 744 def words( filter_regexp = nil ) w = @lines.join( ' ' ).scan( WORD_REGEXP ) filter_regexp ? w.grep( filter_regexp ) : w end |
#wrap_paragraph ⇒ Object
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 |
# File 'lib/diakonos/buffer.rb', line 594 def wrap_paragraph start_row = end_row = @last_row until start_row == 0 || @lines[ start_row - 1 ].strip == '' start_row -= 1 end until end_row == @lines.size || @lines[ end_row ].strip == '' end_row += 1 end lines = [] line = '' words = @lines[ start_row...end_row ].join( ' ' ).scan( /\S+/ ) words.each do |word| if word =~ /^[a-z']+[.!?]$/ word = "#{word} " end if line.length + word.length + 1 > ( @settings[ "lang.#{@language}.wrap_margin" ] || 80 ) lines << line.strip line = '' end line << " #{word}" end line.strip! if ! line.empty? lines << line end if @lines[ start_row...end_row ] != lines take_snapshot @lines[ start_row...end_row ] = lines set_modified modified_from_line: start_row cursor_to start_row + lines.length, lines[-1].length end end |