diakonos 0.8.8 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +433 -0
  3. data/LICENCE.md +675 -0
  4. data/bin/diakonos +6 -0
  5. data/diakonos-256-colour.conf +220 -0
  6. data/diakonos.conf +1802 -0
  7. data/help/about-help.dhf +31 -0
  8. data/help/clipboard.dhf +45 -0
  9. data/help/close-file.dhf +6 -0
  10. data/help/code-block-navigation.dhf +16 -0
  11. data/help/column-markers.dhf +15 -0
  12. data/help/config.dhf +69 -0
  13. data/help/cursor-stack.dhf +19 -0
  14. data/help/delete.dhf +41 -0
  15. data/help/extensions.dhf +125 -0
  16. data/help/file-type.dhf +24 -0
  17. data/help/key-mapping.dhf +127 -0
  18. data/help/line-numbers.dhf +22 -0
  19. data/help/macros.dhf +27 -0
  20. data/help/new-file.dhf +6 -0
  21. data/help/open-file.dhf +21 -0
  22. data/help/quit.dhf +7 -0
  23. data/help/resizing.dhf +19 -0
  24. data/help/ruby.dhf +17 -0
  25. data/help/save-file.dhf +10 -0
  26. data/help/scripting.dhf +92 -0
  27. data/help/search.dhf +103 -0
  28. data/help/shell.dhf +60 -0
  29. data/help/speed.dhf +23 -0
  30. data/help/support.dhf +15 -0
  31. data/help/switch-buffers.dhf +15 -0
  32. data/help/tabs.dhf +36 -0
  33. data/help/undo.dhf +9 -0
  34. data/help/uninstall.dhf +18 -0
  35. data/help/welcome.dhf +32 -0
  36. data/help/word-wrap.dhf +17 -0
  37. data/lib/diakonos/about.rb +69 -0
  38. data/lib/diakonos/bookmark.rb +46 -0
  39. data/lib/diakonos/buffer/bookmarking.rb +47 -0
  40. data/lib/diakonos/buffer/cursor.rb +335 -0
  41. data/lib/diakonos/buffer/delete.rb +170 -0
  42. data/lib/diakonos/buffer/display.rb +356 -0
  43. data/lib/diakonos/buffer/file.rb +157 -0
  44. data/lib/diakonos/buffer/indentation.rb +175 -0
  45. data/lib/diakonos/buffer/searching.rb +552 -0
  46. data/lib/diakonos/buffer/selection.rb +360 -0
  47. data/lib/diakonos/buffer/undo.rb +73 -0
  48. data/lib/diakonos/buffer-hash.rb +60 -0
  49. data/lib/diakonos/buffer-management.rb +59 -0
  50. data/lib/diakonos/buffer.rb +698 -0
  51. data/lib/diakonos/clipboard-klipper-dbus.rb +62 -0
  52. data/lib/diakonos/clipboard-klipper.rb +62 -0
  53. data/lib/diakonos/clipboard-osx.rb +59 -0
  54. data/lib/diakonos/clipboard-xclip.rb +60 -0
  55. data/lib/diakonos/clipboard.rb +47 -0
  56. data/lib/diakonos/config-file.rb +67 -0
  57. data/lib/diakonos/config.rb +381 -0
  58. data/lib/diakonos/core-ext/enumerable.rb +15 -0
  59. data/lib/diakonos/core-ext/hash.rb +60 -0
  60. data/lib/diakonos/core-ext/object.rb +6 -0
  61. data/lib/diakonos/core-ext/regexp.rb +6 -0
  62. data/lib/diakonos/core-ext/string.rb +122 -0
  63. data/lib/diakonos/ctag.rb +28 -0
  64. data/lib/diakonos/cursor.rb +27 -0
  65. data/lib/diakonos/display/format.rb +75 -0
  66. data/lib/diakonos/display.rb +336 -0
  67. data/lib/diakonos/extension-set.rb +49 -0
  68. data/lib/diakonos/extension.rb +34 -0
  69. data/lib/diakonos/finding.rb +40 -0
  70. data/lib/diakonos/functions/basics.rb +34 -0
  71. data/lib/diakonos/functions/bookmarking.rb +61 -0
  72. data/lib/diakonos/functions/buffers.rb +489 -0
  73. data/lib/diakonos/functions/clipboard.rb +70 -0
  74. data/lib/diakonos/functions/cursor.rb +264 -0
  75. data/lib/diakonos/functions/grepping.rb +83 -0
  76. data/lib/diakonos/functions/indentation.rb +71 -0
  77. data/lib/diakonos/functions/readline.rb +93 -0
  78. data/lib/diakonos/functions/search.rb +179 -0
  79. data/lib/diakonos/functions/selection.rb +98 -0
  80. data/lib/diakonos/functions/sessions.rb +78 -0
  81. data/lib/diakonos/functions/shell.rb +250 -0
  82. data/lib/diakonos/functions/tags.rb +65 -0
  83. data/lib/diakonos/functions/text-manipulation.rb +196 -0
  84. data/lib/diakonos/functions-deprecated.rb +77 -0
  85. data/lib/diakonos/functions.rb +292 -0
  86. data/lib/diakonos/grep.rb +98 -0
  87. data/lib/diakonos/help.rb +47 -0
  88. data/lib/diakonos/hooks.rb +13 -0
  89. data/lib/diakonos/installation.rb +19 -0
  90. data/lib/diakonos/interaction-handler.rb +216 -0
  91. data/lib/diakonos/interaction.rb +52 -0
  92. data/lib/diakonos/key-map.rb +62 -0
  93. data/lib/diakonos/keying.rb +442 -0
  94. data/lib/diakonos/line-mover.rb +42 -0
  95. data/lib/diakonos/list.rb +59 -0
  96. data/lib/diakonos/logging.rb +27 -0
  97. data/lib/diakonos/mode.rb +17 -0
  98. data/lib/diakonos/mouse.rb +18 -0
  99. data/lib/diakonos/number-fitter.rb +11 -0
  100. data/lib/diakonos/range.rb +31 -0
  101. data/lib/diakonos/readline/functions.rb +82 -0
  102. data/lib/diakonos/readline.rb +222 -0
  103. data/lib/diakonos/search.rb +58 -0
  104. data/lib/diakonos/sessions.rb +257 -0
  105. data/lib/diakonos/sized-array.rb +48 -0
  106. data/lib/diakonos/text-mark.rb +19 -0
  107. data/lib/diakonos/vendor/fuzzy_file_finder.rb +365 -0
  108. data/lib/diakonos/version.rb +25 -0
  109. data/lib/diakonos/window.rb +43 -0
  110. data/lib/diakonos.rb +592 -0
  111. metadata +160 -66
@@ -0,0 +1,552 @@
1
+ module Diakonos
2
+
3
+ class Buffer
4
+
5
+ attr_reader :num_matches_found, :last_search_regexps
6
+
7
+ CHARACTER_PAIRS = {
8
+ '(' => { partner: ')', direction: :forward },
9
+ '<' => { partner: '>', direction: :forward },
10
+ '{' => { partner: '}', direction: :forward },
11
+ '[' => { partner: ']', direction: :forward },
12
+ ')' => { partner: '(', direction: :backward },
13
+ '>' => { partner: '<', direction: :backward },
14
+ '}' => { partner: '{', direction: :backward },
15
+ ']' => { partner: '[', direction: :backward },
16
+ }
17
+
18
+ OPPOSITE_DIRECTION = {
19
+ up: :down,
20
+ down: :up,
21
+ }
22
+
23
+ def search_area?
24
+ @search_area
25
+ end
26
+
27
+ def clear_search_area
28
+ @search_area = nil
29
+ @text_marks.delete :search_area_pre
30
+ @text_marks.delete :search_area_post
31
+ end
32
+
33
+ def set_search_area(mark)
34
+ if mark.nil?
35
+ raise 'Call Diakonos::Buffer#clear_search_area instead'
36
+ return
37
+ end
38
+
39
+ @search_area = mark
40
+ @text_marks[ :search_area_pre ] = TextMark.new(
41
+ ::Diakonos::Range.new(0, 0, mark.start_row, mark.start_col),
42
+ @settings[ 'view.non_search_area.format' ]
43
+ )
44
+ @text_marks[ :search_area_post ] = TextMark.new(
45
+ ::Diakonos::Range.new(mark.end_row, mark.end_col, @lines.length - 1, @lines[ -1 ].length),
46
+ @settings[ 'view.non_search_area.format' ]
47
+ )
48
+ end
49
+
50
+ def confirm_finding( regexps, search_area, from_row, from_col, match )
51
+ found_text = match[0]
52
+ range = ::Diakonos::Range.new(from_row, from_col, from_row, from_col + found_text.length)
53
+ Finding.confirm(range, regexps, @lines, search_area, match)
54
+ end
55
+
56
+ # @return [Array<String>]
57
+ def search_area_lines
58
+ return [] if @search_area.nil?
59
+
60
+ lines = @lines[@search_area.start_row..@search_area.end_row]
61
+ lines[0] = lines[0][@search_area.start_col..-1]
62
+ lines[-1] = lines[-1][0..@search_area.end_col]
63
+
64
+ lines
65
+ end
66
+
67
+ def _find_down(regexps, regexp, from_row, from_col, search_area)
68
+ # Check the current row first.
69
+
70
+ index = @lines[ from_row ].index(
71
+ regexp,
72
+ ( @last_finding ? @last_finding.start_col : from_col ) + 1
73
+ )
74
+ if index
75
+ finding = confirm_finding( regexps, search_area, from_row, index, Regexp.last_match )
76
+ return finding if finding
77
+ end
78
+
79
+ # Check below the cursor.
80
+
81
+ ( (from_row + 1)..search_area.end_row ).each do |i|
82
+ line = @lines[ i ]
83
+ if i == search_area.end_row
84
+ line = line[ 0...search_area.end_col ]
85
+ end
86
+ index = line.index( regexp )
87
+ if index
88
+ finding = confirm_finding( regexps, search_area, i, index, Regexp.last_match )
89
+ return finding if finding
90
+ end
91
+ end
92
+
93
+ if index
94
+ finding = confirm_finding( regexps, search_area, search_area.end_row, index, Regexp.last_match )
95
+ return finding if finding
96
+ end
97
+
98
+ # Wrap around.
99
+
100
+ @wrapped = true
101
+
102
+ index = @lines[ search_area.start_row ].index( regexp, search_area.start_col )
103
+ if index
104
+ finding = confirm_finding( regexps, search_area, search_area.start_row, index, Regexp.last_match )
105
+ return finding if finding
106
+ end
107
+
108
+ ( search_area.start_row+1...from_row ).each do |i|
109
+ index = @lines[ i ].index( regexp )
110
+ if index
111
+ finding = confirm_finding( regexps, search_area, i, index, Regexp.last_match )
112
+ return finding if finding
113
+ end
114
+ end
115
+
116
+ # And finally, the other side of the current row.
117
+
118
+ if from_row == search_area.start_row
119
+ index_col = search_area.start_col
120
+ else
121
+ index_col = 0
122
+ end
123
+ if index = @lines[ from_row ].index( regexp, index_col )
124
+ if index <= ( @last_finding ? @last_finding.start_col : from_col )
125
+ finding = confirm_finding( regexps, search_area, from_row, index, Regexp.last_match )
126
+ return finding if finding
127
+ end
128
+ end
129
+ end
130
+
131
+ def _find_up(regexps, regexp, search_area, from_row, from_col)
132
+ # Check the current row first.
133
+
134
+ col_to_check = ( @last_finding ? @last_finding.end_col : from_col ) - 1
135
+ if ( col_to_check >= 0 ) && ( index = @lines[ from_row ][ 0...col_to_check ].rindex( regexp ) )
136
+ finding = confirm_finding( regexps, search_area, from_row, index, Regexp.last_match )
137
+ return finding if finding
138
+ end
139
+
140
+ # Check above the cursor.
141
+
142
+ (from_row - 1).downto( 0 ) do |i|
143
+ if index = @lines[ i ].rindex( regexp )
144
+ finding = confirm_finding( regexps, search_area, i, index, Regexp.last_match )
145
+ return finding if finding
146
+ end
147
+ end
148
+
149
+ # Wrap around.
150
+
151
+ @wrapped = true
152
+
153
+ (@lines.length - 1).downto(from_row + 1) do |i|
154
+ if index = @lines[ i ].rindex( regexp )
155
+ finding = confirm_finding( regexps, search_area, i, index, Regexp.last_match )
156
+ return finding if finding
157
+ end
158
+ end
159
+
160
+ # And finally, the other side of the current row.
161
+
162
+ search_col = ( @last_finding ? @last_finding.start_col : from_col ) + 1
163
+ if index = @lines[ from_row ].rindex( regexp )
164
+ if index > search_col
165
+ finding = confirm_finding( regexps, search_area, from_row, index, Regexp.last_match )
166
+ return finding if finding
167
+ end
168
+ end
169
+ end
170
+
171
+ # @param regexps [Array] Regexps which represent a user-provided regexp,
172
+ # split across newline characters. Once the first element is found,
173
+ # each successive element must match against lines following the first
174
+ # element.
175
+ # @return [Integer] the number of replacements made
176
+ def find( regexps, options = {} )
177
+ return if regexps.nil?
178
+ regexp = regexps[ 0 ]
179
+ return if regexp.nil? || regexp == //
180
+
181
+ direction = options[ :direction ]
182
+ replacement = options[ :replacement ]
183
+ auto_choice = options[ :auto_choice ]
184
+ from_row = options[ :starting_row ] || @last_row
185
+ from_col = options[ :starting_col ] || @last_col
186
+ show_context_after = options[ :show_context_after ]
187
+
188
+ if options[:starting]
189
+ @num_matches_found = nil
190
+ end
191
+
192
+ num_replacements = 0
193
+
194
+ # TODO: Just use Range here instead of TextMark?
195
+ search_area = @search_area || TextMark.new( ::Diakonos::Range.new(0, 0, @lines.size - 1, @lines[ -1 ].size), nil )
196
+ if ! search_area.contains?( from_row, from_col )
197
+ from_row, from_col = search_area.start_row, search_area.start_col
198
+ end
199
+
200
+ if direction == :opposite
201
+ direction = OPPOSITE_DIRECTION[@last_search_direction]
202
+ end
203
+ @last_search_regexps = regexps
204
+ @last_search_direction = direction
205
+
206
+ @wrapped = false
207
+
208
+ if direction == :down
209
+ finding = _find_down(regexps, regexp, from_row, from_col, search_area)
210
+ elsif direction == :up
211
+ finding = _find_up(regexps, regexp, search_area, from_row, from_col)
212
+ end
213
+
214
+ if ! finding
215
+ remove_selection DONT_DISPLAY
216
+ clear_matches DO_DISPLAY
217
+ if ! options[ :quiet ] && ( replacement.nil? || num_replacements == 0 )
218
+ $diakonos.set_iline "/#{regexp.source}/ not found."
219
+ end
220
+ else
221
+ if @wrapped && ! options[ :quiet ]
222
+ if @search_area
223
+ $diakonos.set_iline( "(search wrapped around to start of search area)" )
224
+ else
225
+ $diakonos.set_iline( "(search wrapped around BOF/EOF)" )
226
+ end
227
+ end
228
+
229
+ remove_selection( DONT_DISPLAY )
230
+ @last_finding = finding
231
+ if @settings[ "found_cursor_start" ]
232
+ anchor_selection( finding.end_row, finding.end_col, DONT_DISPLAY )
233
+ cursor_to( finding.start_row, finding.start_col )
234
+ else
235
+ anchor_selection( finding.start_row, finding.start_col, DONT_DISPLAY )
236
+ cursor_to( finding.end_row, finding.end_col )
237
+ end
238
+ if show_context_after
239
+ watermark = Curses::lines / 6
240
+ if @last_row - @top_line > watermark
241
+ pitch_view( @last_row - @top_line - watermark )
242
+ end
243
+ end
244
+
245
+ @changing_selection = false
246
+
247
+ if regexps.length == 1
248
+ @highlight_regexp = regexp
249
+ highlight_matches
250
+ else
251
+ clear_matches
252
+ end
253
+ display
254
+
255
+ if replacement
256
+ # Substitute placeholders (e.g. \1) in str for the group matches of the last match.
257
+ actual_replacement = replacement.dup
258
+ actual_replacement.gsub!( /\\(\\|\d+)/ ) { |m|
259
+ ref = $1
260
+ if ref == "\\"
261
+ "\\"
262
+ else
263
+ finding.captured_group(ref.to_i)
264
+ end
265
+ }
266
+
267
+ choices = [ CHOICE_YES, CHOICE_NO, CHOICE_ALL, CHOICE_CANCEL, CHOICE_YES_AND_STOP, ]
268
+ if @search_area
269
+ choices << CHOICE_WITHIN_SELECTION
270
+ end
271
+ choice = auto_choice || $diakonos.get_choice(
272
+ "#{@num_matches_found} match#{ @num_matches_found != 1 ? 'es' : '' } - Replace this one?",
273
+ choices,
274
+ CHOICE_YES
275
+ )
276
+ case choice
277
+ when CHOICE_YES
278
+ paste [ actual_replacement ]
279
+ num_replacements += 1 + find( regexps, direction: direction, replacement: replacement )
280
+ when CHOICE_ALL
281
+ num_replacements += replace_all(regexp, replacement)
282
+ when CHOICE_WITHIN_SELECTION
283
+ num_replacements += replace_all(regexp, replacement, :within_search_area)
284
+ when CHOICE_NO
285
+ num_replacements += find( regexps, direction: direction, replacement: replacement )
286
+ when CHOICE_CANCEL
287
+ # Do nothing further.
288
+ when CHOICE_YES_AND_STOP
289
+ paste [ actual_replacement ]
290
+ num_replacements += 1
291
+ # Do nothing further.
292
+ end
293
+ end
294
+ end
295
+
296
+ num_replacements
297
+ end
298
+
299
+ # @return [Integer] the number of replacements made
300
+ def replace_all( regexp, replacement, within_search_area = false )
301
+ return if( regexp.nil? || replacement.nil? )
302
+
303
+ num_replacements = 0
304
+
305
+ take_snapshot
306
+
307
+ if within_search_area && @search_area
308
+ lines = self.search_area_lines
309
+ else
310
+ lines = @lines
311
+ end
312
+
313
+ lines_modified = lines.collect { |line|
314
+ num_replacements += line.scan(regexp).size
315
+ line.gsub( regexp, replacement )
316
+ }
317
+
318
+ if within_search_area && @search_area
319
+ @lines[@search_area.start_row][@search_area.start_col..-1] = lines_modified[0]
320
+ if @search_area.end_row - @search_area.start_row > 1
321
+ @lines[@search_area.start_row+1..@search_area.end_row-1] = lines_modified[1..-2]
322
+ end
323
+ @lines[@search_area.end_row][0..@search_area.end_col] = lines_modified[-1]
324
+ else
325
+ @lines = lines_modified
326
+ end
327
+
328
+ set_modified
329
+ clear_matches
330
+ display
331
+ num_replacements
332
+ end
333
+
334
+ def highlight_matches( regexp = @highlight_regexp )
335
+ @highlight_regexp = regexp
336
+ return if @highlight_regexp.nil?
337
+
338
+ if @search_area
339
+ lines = self.search_area_lines
340
+ line_index_offset = @search_area.start_row
341
+ col_offset = @search_area.start_col
342
+ else
343
+ lines = @lines
344
+ line_index_offset = 0
345
+ col_offset = 0
346
+ end
347
+
348
+ grepped_lines = lines.grep_indices( @highlight_regexp )
349
+ n = grepped_lines.count
350
+ found_marks = grepped_lines.collect do |line_index, start_col, end_col|
351
+ TextMark.new(
352
+ ::Diakonos::Range.new(
353
+ line_index + line_index_offset,
354
+ start_col + ( line_index == 0 ? col_offset : 0 ),
355
+ line_index + line_index_offset,
356
+ end_col,
357
+ ),
358
+ @settings["lang.#{@language}.format.found"]
359
+ )
360
+ end
361
+ @text_marks[:found] = found_marks
362
+ @num_matches_found ||= found_marks.size
363
+ end
364
+
365
+ def clear_matches( do_display = DONT_DISPLAY )
366
+ @text_marks[ :found ] = []
367
+ @highlight_regexp = nil
368
+ display if do_display
369
+ end
370
+
371
+ def pos_of_next( regexp, start_row, start_col )
372
+ row, col = start_row, start_col
373
+ col = @lines[ row ].index( regexp, col )
374
+ while col.nil? && row < @lines.length - 1
375
+ row += 1
376
+ col = @lines[ row ].index( regexp )
377
+ end
378
+ if col
379
+ [ row, col, Regexp.last_match( 0 ) ]
380
+ end
381
+ end
382
+
383
+ def pos_of_prev( regexp, start_row, start_col )
384
+ row, col = start_row, start_col
385
+ if col < 0
386
+ row -= 1
387
+ col = -1
388
+ end
389
+ return if row < 0
390
+
391
+ col = @lines[ row ].rindex( regexp, col )
392
+ while col.nil? && row > 0
393
+ row -= 1
394
+ col = @lines[ row ].rindex( regexp )
395
+ end
396
+ if col
397
+ [ row, col, Regexp.last_match( 0 ) ]
398
+ end
399
+ end
400
+
401
+ def pos_of_pair_match( row = @last_row, col = @last_col )
402
+ c = @lines[ row ][ col ]
403
+ data = CHARACTER_PAIRS[ c ]
404
+ return if data.nil?
405
+ d = data[ :partner ]
406
+ c_ = Regexp.escape c
407
+ d_ = Regexp.escape d
408
+ target = /(?:#{c_}|#{d_})/
409
+
410
+ case data[ :direction ]
411
+ when :forward
412
+ row, col, char = pos_of_next( target, row, col + 1 )
413
+ while char == c # Take care of nested pairs
414
+ row, col = pos_of_pair_match( row, col )
415
+ break if col.nil?
416
+ row, col, char = pos_of_next( target, row, col + 1 )
417
+ end
418
+ when :backward
419
+ row, col, char = pos_of_prev( target, row, col - 1 )
420
+ while char == c # Take care of nested pairs
421
+ row, col = pos_of_pair_match( row, col )
422
+ break if col.nil?
423
+ row, col, char = pos_of_prev( target, row, col - 1 )
424
+ end
425
+ end
426
+ [ row, col ]
427
+ end
428
+
429
+ def go_to_pair_match
430
+ row, col = pos_of_pair_match
431
+ if row && col
432
+ if cursor_to( row, col )
433
+ highlight_pair
434
+ display
435
+ end
436
+ end
437
+ end
438
+
439
+ def highlight_pair
440
+ match_row, match_col = pos_of_pair_match( @last_row, @last_col )
441
+ if match_col.nil?
442
+ @text_marks[ :pair ] = nil
443
+ else
444
+ @text_marks[ :pair ] = TextMark.new(
445
+ ::Diakonos::Range.new(match_row, match_col, match_row, match_col + 1),
446
+ @settings[ "lang.#{@language}.format.pair" ] || @settings[ "lang.shared.format.pair" ]
447
+ )
448
+ end
449
+ end
450
+
451
+ def clear_pair_highlight
452
+ @text_marks[ :pair ] = nil
453
+ end
454
+
455
+ def find_again( last_search_regexps, direction = @last_search_direction )
456
+ if @last_search_regexps.nil? || @last_search_regexps.empty?
457
+ @last_search_regexps = last_search_regexps
458
+ end
459
+ if @last_search_regexps
460
+ find @last_search_regexps, direction: direction
461
+ end
462
+ end
463
+
464
+ def seek( regexp, direction = :down )
465
+ return if regexp.nil? || regexp == //
466
+
467
+ found_row = nil
468
+ found_col = nil
469
+ found_text = nil
470
+
471
+ catch :found do
472
+ if direction == :down
473
+ # Check the current row first.
474
+
475
+ index, match_text = @lines[ @last_row ].group_index( regexp, @last_col + 1 )
476
+ if index
477
+ found_row = @last_row
478
+ found_col = index
479
+ found_text = match_text
480
+ throw :found
481
+ end
482
+
483
+ # Check below the cursor.
484
+
485
+ ( (@last_row + 1)...@lines.length ).each do |i|
486
+ index, match_text = @lines[ i ].group_index( regexp )
487
+ if index
488
+ found_row = i
489
+ found_col = index
490
+ found_text = match_text
491
+ throw :found
492
+ end
493
+ end
494
+
495
+ else
496
+ # Check the current row first.
497
+
498
+ col_to_check = @last_col - 1
499
+ if col_to_check >= 0
500
+ index, match_text = @lines[ @last_row ].group_rindex( regexp, col_to_check )
501
+ if index
502
+ found_row = @last_row
503
+ found_col = index
504
+ found_text = match_text
505
+ throw :found
506
+ end
507
+ end
508
+
509
+ # Check above the cursor.
510
+
511
+ (@last_row - 1).downto( 0 ) do |i|
512
+ index, match_text = @lines[ i ].group_rindex( regexp )
513
+ if index
514
+ found_row = i
515
+ found_col = index
516
+ found_text = match_text
517
+ throw :found
518
+ end
519
+ end
520
+ end
521
+ end
522
+
523
+ if found_text
524
+ cursor_to( found_row, found_col )
525
+ display
526
+ true
527
+ end
528
+ end
529
+
530
+ # Returns an Array of results, where each result is a String usually
531
+ # containing \n's due to context
532
+ def grep( regexp_source )
533
+ if @name
534
+ filename = File.basename( @name )
535
+ filepath = @name
536
+ else
537
+ filename = "(unnamed buffer)"
538
+ filepath = "(unnamed buffer #{object_id})"
539
+ end
540
+
541
+ ::Diakonos.grep_array(
542
+ Regexp.new( regexp_source ),
543
+ @lines,
544
+ $diakonos.settings[ 'grep.context' ],
545
+ "#{filename}:",
546
+ filepath
547
+ )
548
+ end
549
+
550
+ end
551
+
552
+ end