diakonos 0.8.6 → 0.8.7
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +18 -0
- data/LICENCE +1 -1
- data/README +3 -3
- data/diakonos-256-colour.conf +1 -0
- data/diakonos.conf +237 -108
- data/lib/diakonos.rb +425 -2680
- data/lib/diakonos/array.rb +1 -1
- data/lib/diakonos/bignum.rb +4 -1
- data/lib/diakonos/bookmark.rb +7 -8
- data/lib/diakonos/buffer-hash.rb +55 -13
- data/lib/diakonos/buffer-management.rb +73 -0
- data/lib/diakonos/buffer.rb +327 -259
- data/lib/diakonos/clipboard.rb +4 -4
- data/lib/diakonos/config.rb +304 -0
- data/lib/diakonos/ctag.rb +3 -3
- data/lib/diakonos/display.rb +288 -0
- data/lib/diakonos/enumerable.rb +2 -2
- data/lib/diakonos/fixnum.rb +12 -8
- data/lib/diakonos/functions.rb +1420 -0
- data/lib/diakonos/grep.rb +78 -0
- data/lib/diakonos/hash.rb +26 -19
- data/lib/diakonos/help.rb +92 -0
- data/lib/diakonos/hooks.rb +13 -0
- data/lib/diakonos/interaction.rb +139 -0
- data/lib/diakonos/keycode.rb +3 -3
- data/lib/diakonos/keying.rb +124 -0
- data/lib/diakonos/list.rb +55 -0
- data/lib/diakonos/logging.rb +24 -0
- data/lib/diakonos/readline.rb +44 -25
- data/lib/diakonos/regexp.rb +1 -1
- data/lib/diakonos/sessions.rb +70 -0
- data/lib/diakonos/sized-array.rb +4 -4
- data/lib/diakonos/string.rb +44 -37
- data/lib/diakonos/text-mark.rb +1 -1
- data/lib/diakonos/vendor/fuzzy_file_finder.rb +353 -0
- data/test/buffer-test.rb +5 -5
- data/test/diakonos-test.rb +2 -2
- metadata +27 -14
data/lib/diakonos/array.rb
CHANGED
data/lib/diakonos/bignum.rb
CHANGED
data/lib/diakonos/bookmark.rb
CHANGED
@@ -11,25 +11,24 @@ class Bookmark
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def == (other)
|
14
|
-
return false if other
|
15
|
-
|
14
|
+
return false if other.nil?
|
15
|
+
( @buffer == other.buffer and @row == other.row and @col == other.col )
|
16
16
|
end
|
17
17
|
|
18
18
|
def <=> (other)
|
19
|
-
return nil if other
|
19
|
+
return nil if other.nil?
|
20
20
|
comparison = ( $diakonos.bufferToNumber( @buffer ) <=> $diakonos.bufferToNumber( other.buffer ) )
|
21
21
|
return comparison if comparison != 0
|
22
22
|
comparison = ( @row <=> other.row )
|
23
23
|
return comparison if comparison != 0
|
24
|
-
|
25
|
-
return comparison
|
24
|
+
@col <=> other.col
|
26
25
|
end
|
27
26
|
|
28
27
|
def < (other)
|
29
|
-
|
28
|
+
( ( self <=> other ) < 0 )
|
30
29
|
end
|
31
30
|
def > (other)
|
32
|
-
|
31
|
+
( ( self <=> other ) > 0 )
|
33
32
|
end
|
34
33
|
|
35
34
|
def incRow( increment )
|
@@ -44,7 +43,7 @@ class Bookmark
|
|
44
43
|
end
|
45
44
|
|
46
45
|
def to_s
|
47
|
-
|
46
|
+
"[#{@name}|#{@buffer.name}:#{@row+1},#{@col+1}]"
|
48
47
|
end
|
49
48
|
end
|
50
49
|
|
data/lib/diakonos/buffer-hash.rb
CHANGED
@@ -1,18 +1,60 @@
|
|
1
|
+
# A Hash which is iterated in insertion order.
|
2
|
+
# Keys are assumed to be paths; these paths are expanded on read and write.
|
1
3
|
class BufferHash < Hash
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
def initialize
|
5
|
+
@keys_ = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def [] ( key )
|
9
|
+
super File.expand_path( key.to_s )
|
10
|
+
end
|
11
|
+
|
12
|
+
def []= ( key, value )
|
13
|
+
key = File.expand_path( key.to_s )
|
14
|
+
if not @keys_.include?( key )
|
15
|
+
@keys_ << key
|
8
16
|
end
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
super
|
17
|
+
super key, value
|
18
|
+
end
|
19
|
+
|
20
|
+
def each
|
21
|
+
@keys_.each do |key|
|
22
|
+
yield key, self[ key ]
|
16
23
|
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def each_key
|
27
|
+
@keys_.each do |key|
|
28
|
+
yield key
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def each_value
|
33
|
+
@keys_.each do |key|
|
34
|
+
yield self[ key ]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def clear
|
39
|
+
@keys_ = []
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete( key )
|
44
|
+
@keys_.delete key
|
45
|
+
super
|
46
|
+
end
|
47
|
+
|
48
|
+
def keys
|
49
|
+
@keys_.dup
|
50
|
+
end
|
51
|
+
|
52
|
+
def values
|
53
|
+
@keys_.map { |key| self[ key ] }
|
54
|
+
end
|
55
|
+
|
56
|
+
def length
|
57
|
+
@keys_.length
|
58
|
+
end
|
17
59
|
end
|
18
60
|
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Diakonos
|
2
|
+
class Diakonos
|
3
|
+
attr_reader :current_buffer
|
4
|
+
|
5
|
+
def switchTo( buffer )
|
6
|
+
switched = false
|
7
|
+
if buffer
|
8
|
+
@buffer_stack -= [ @current_buffer ]
|
9
|
+
if @current_buffer
|
10
|
+
@buffer_stack.push @current_buffer
|
11
|
+
end
|
12
|
+
@current_buffer = buffer
|
13
|
+
runHookProcs( :after_buffer_switch, buffer )
|
14
|
+
updateStatusLine
|
15
|
+
updateContextLine
|
16
|
+
buffer.display
|
17
|
+
switched = true
|
18
|
+
end
|
19
|
+
|
20
|
+
switched
|
21
|
+
end
|
22
|
+
protected :switchTo
|
23
|
+
|
24
|
+
def remember_buffer( buffer )
|
25
|
+
if @buffer_history.last != buffer
|
26
|
+
@buffer_history << buffer
|
27
|
+
@buffer_history_pointer = @buffer_history.size - 1
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# The given buffer_number should be 1-based, not zero-based.
|
32
|
+
# Returns nil if no such buffer exists.
|
33
|
+
def bufferNumberToName( buffer_number )
|
34
|
+
return nil if buffer_number < 1
|
35
|
+
|
36
|
+
number = 1
|
37
|
+
buffer_name = nil
|
38
|
+
@buffers.each_key do |name|
|
39
|
+
if number == buffer_number
|
40
|
+
buffer_name = name
|
41
|
+
break
|
42
|
+
end
|
43
|
+
number += 1
|
44
|
+
end
|
45
|
+
buffer_name
|
46
|
+
end
|
47
|
+
|
48
|
+
# The returned value is 1-based, not zero-based.
|
49
|
+
# Returns nil if no such buffer exists.
|
50
|
+
def bufferToNumber( buffer )
|
51
|
+
number = 1
|
52
|
+
buffer_number = nil
|
53
|
+
@buffers.each_value do |b|
|
54
|
+
if b == buffer
|
55
|
+
buffer_number = number
|
56
|
+
break
|
57
|
+
end
|
58
|
+
number += 1
|
59
|
+
end
|
60
|
+
buffer_number
|
61
|
+
end
|
62
|
+
|
63
|
+
def show_buffer_file_diff( buffer = @current_buffer )
|
64
|
+
current_text_file = @diakonos_home + '/current-buffer'
|
65
|
+
buffer.saveCopy( current_text_file )
|
66
|
+
`#{@settings[ 'diff_command' ]} #{current_text_file} #{buffer.name} > #{@diff_filename}`
|
67
|
+
diff_buffer = openFile( @diff_filename )
|
68
|
+
yield diff_buffer
|
69
|
+
closeFile diff_buffer
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
data/lib/diakonos/buffer.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Diakonos
|
2
2
|
|
3
3
|
class Buffer
|
4
|
-
attr_reader :name, :key, :
|
4
|
+
attr_reader :name, :key, :original_language, :changing_selection, :read_only,
|
5
5
|
:last_col, :last_row, :tab_size, :last_screen_x, :last_screen_y, :last_screen_col
|
6
6
|
attr_writer :desired_column, :read_only
|
7
7
|
|
@@ -38,7 +38,7 @@ class Buffer
|
|
38
38
|
|
39
39
|
@buffer_states = Array.new
|
40
40
|
@cursor_states = Array.new
|
41
|
-
if @name
|
41
|
+
if @name
|
42
42
|
@name = @name.subHome
|
43
43
|
if FileTest.exists? @name
|
44
44
|
@lines = IO.readlines( @name )
|
@@ -94,7 +94,7 @@ class Buffer
|
|
94
94
|
@diakonos.setILine "(spaces substituted for tab characters)"
|
95
95
|
end
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
@buffer_states[ @current_buffer_state ] = @lines
|
99
99
|
@cursor_states[ @current_buffer_state ] = [ @last_row, @last_col ]
|
100
100
|
end
|
@@ -110,7 +110,7 @@ class Buffer
|
|
110
110
|
setLanguage language
|
111
111
|
@original_language = @language
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
114
|
def reset_win_main
|
115
115
|
@win_main = @diakonos.win_main
|
116
116
|
end
|
@@ -128,7 +128,7 @@ class Buffer
|
|
128
128
|
@auto_indent = @settings[ "lang.#{@language}.indent.auto" ]
|
129
129
|
@indent_size = ( @settings[ "lang.#{@language}.indent.size" ] or 4 )
|
130
130
|
@indent_roundup = @settings[ "lang.#{@language}.indent.roundup" ].nil? ? true : @settings[ "lang.#{@language}.indent.roundup" ]
|
131
|
-
@indent_closers = @settings[ "lang.#{@language}.indent.closers" ].nil? ?
|
131
|
+
@indent_closers = @settings[ "lang.#{@language}.indent.closers" ].nil? ? false : @settings[ "lang.#{@language}.indent.closers" ]
|
132
132
|
@default_formatting = ( @settings[ "lang.#{@language}.format.default" ] or Curses::A_NORMAL )
|
133
133
|
@selection_formatting = ( @settings[ "lang.#{@language}.format.selection" ] or Curses::A_REVERSE )
|
134
134
|
@indent_ignore_charset = ( @settings[ "lang.#{@language}.indent.ignore.charset" ] or "" )
|
@@ -137,41 +137,45 @@ class Buffer
|
|
137
137
|
protected :setLanguage
|
138
138
|
|
139
139
|
def [] ( arg )
|
140
|
-
|
140
|
+
@lines[ arg ]
|
141
141
|
end
|
142
|
-
|
142
|
+
|
143
143
|
def == (other)
|
144
144
|
return false if other.nil?
|
145
145
|
key == other.key
|
146
146
|
end
|
147
147
|
|
148
148
|
def length
|
149
|
-
|
149
|
+
@lines.length
|
150
|
+
end
|
151
|
+
|
152
|
+
def modified?
|
153
|
+
@modified
|
150
154
|
end
|
151
155
|
|
152
156
|
def nice_name
|
153
|
-
|
157
|
+
@name || @settings[ "status.unnamed_str" ]
|
154
158
|
end
|
155
159
|
|
156
160
|
def display
|
157
161
|
return if not @diakonos.do_display
|
158
|
-
|
162
|
+
|
159
163
|
Thread.new do
|
160
164
|
#if $profiling
|
161
165
|
#RubyProf.start
|
162
166
|
#end
|
163
|
-
|
167
|
+
|
164
168
|
if @diakonos.display_mutex.try_lock
|
165
169
|
begin
|
166
170
|
Curses::curs_set 0
|
167
|
-
|
171
|
+
|
168
172
|
@continued_format_class = nil
|
169
|
-
|
173
|
+
|
170
174
|
@pen_down = true
|
171
|
-
|
175
|
+
|
172
176
|
# First, we have to "draw" off-screen, in order to check for opening of
|
173
177
|
# multi-line highlights.
|
174
|
-
|
178
|
+
|
175
179
|
# So, first look backwards from the @top_line to find the first opening
|
176
180
|
# regexp match, if any.
|
177
181
|
index = @top_line - 1
|
@@ -179,22 +183,22 @@ class Buffer
|
|
179
183
|
open_index = -1
|
180
184
|
open_token_class = nil
|
181
185
|
open_match_text = nil
|
182
|
-
|
186
|
+
|
183
187
|
open_index, open_token_class, open_match_text = findOpeningMatch( line )
|
184
|
-
|
185
|
-
if open_token_class
|
188
|
+
|
189
|
+
if open_token_class
|
186
190
|
@pen_down = false
|
187
191
|
@lines[ index...@top_line ].each do |line|
|
188
192
|
printLine line
|
189
193
|
end
|
190
194
|
@pen_down = true
|
191
|
-
|
195
|
+
|
192
196
|
break
|
193
197
|
end
|
194
|
-
|
198
|
+
|
195
199
|
index = index - 1
|
196
200
|
end
|
197
|
-
|
201
|
+
|
198
202
|
# Draw each on-screen line.
|
199
203
|
y = 0
|
200
204
|
@lines[ @top_line...(@diakonos.main_window_height + @top_line) ].each_with_index do |line, row|
|
@@ -204,7 +208,7 @@ class Buffer
|
|
204
208
|
paintMarks @top_line + row
|
205
209
|
y += 1
|
206
210
|
end
|
207
|
-
|
211
|
+
|
208
212
|
# Paint the empty space below the file if the file is too short to fit in one screen.
|
209
213
|
( y...@diakonos.main_window_height ).each do |y|
|
210
214
|
@win_main.setpos( y, 0 )
|
@@ -213,17 +217,17 @@ class Buffer
|
|
213
217
|
if @settings[ "view.nonfilelines.visible" ]
|
214
218
|
linestr[ 0 ] = ( @settings[ "view.nonfilelines.character" ] or "~" )
|
215
219
|
end
|
216
|
-
|
220
|
+
|
217
221
|
@win_main.addstr linestr
|
218
222
|
end
|
219
|
-
|
223
|
+
|
220
224
|
@win_main.setpos( @last_screen_y , @last_screen_x )
|
221
225
|
@win_main.refresh
|
222
|
-
|
226
|
+
|
223
227
|
if @language != @original_language
|
224
228
|
setLanguage( @original_language )
|
225
229
|
end
|
226
|
-
|
230
|
+
|
227
231
|
Curses::curs_set 1
|
228
232
|
rescue Exception => e
|
229
233
|
@diakonos.log( "Display Exception:" )
|
@@ -236,7 +240,7 @@ class Buffer
|
|
236
240
|
else
|
237
241
|
@diakonos.displayEnqueue( self )
|
238
242
|
end
|
239
|
-
|
243
|
+
|
240
244
|
#if $profiling
|
241
245
|
#result = RubyProf.stop
|
242
246
|
#printer = RubyProf::GraphHtmlPrinter.new( result )
|
@@ -245,7 +249,7 @@ class Buffer
|
|
245
249
|
#end
|
246
250
|
#end
|
247
251
|
end
|
248
|
-
|
252
|
+
|
249
253
|
end
|
250
254
|
|
251
255
|
def findOpeningMatch( line, match_close = true, bos_allowed = true )
|
@@ -266,7 +270,7 @@ class Buffer
|
|
266
270
|
end
|
267
271
|
if ( not regexp.uses_bos ) or ( bos_allowed and ( whole_match_index == 0 ) )
|
268
272
|
if index < open_index
|
269
|
-
if ( ( not match_close ) or @close_token_regexps[ token_class ]
|
273
|
+
if ( ( not match_close ) or @close_token_regexps[ token_class ] )
|
270
274
|
open_index = index
|
271
275
|
open_token_class = token_class
|
272
276
|
open_match_text = match_text
|
@@ -276,7 +280,7 @@ class Buffer
|
|
276
280
|
end
|
277
281
|
end
|
278
282
|
|
279
|
-
|
283
|
+
[ open_index, open_token_class, open_match_text ]
|
280
284
|
end
|
281
285
|
|
282
286
|
def findClosingMatch( line_, regexp, bos_allowed = true, start_at = 0 )
|
@@ -303,14 +307,14 @@ class Buffer
|
|
303
307
|
end
|
304
308
|
end
|
305
309
|
|
306
|
-
|
310
|
+
[ close_index, close_match_text ]
|
307
311
|
end
|
308
312
|
protected :findClosingMatch
|
309
313
|
|
310
314
|
# @mark_start[ "col" ] is inclusive,
|
311
315
|
# @mark_end[ "col" ] is exclusive.
|
312
316
|
def recordMarkStartAndEnd
|
313
|
-
if @mark_anchor
|
317
|
+
if @mark_anchor
|
314
318
|
crow = @last_row
|
315
319
|
ccol = @last_col
|
316
320
|
anchor_first = true
|
@@ -344,14 +348,14 @@ class Buffer
|
|
344
348
|
@text_marks[ SELECTION ] = nil
|
345
349
|
end
|
346
350
|
end
|
347
|
-
|
351
|
+
|
348
352
|
def selection_mark
|
349
353
|
@text_marks[ SELECTION ]
|
350
354
|
end
|
351
355
|
def selecting?
|
352
356
|
!!selection_mark
|
353
357
|
end
|
354
|
-
|
358
|
+
|
355
359
|
def select_current_line
|
356
360
|
@text_marks[ SELECTION ] = TextMark.new(
|
357
361
|
@last_row,
|
@@ -362,15 +366,15 @@ class Buffer
|
|
362
366
|
)
|
363
367
|
@lines[ @last_row ]
|
364
368
|
end
|
365
|
-
|
369
|
+
|
366
370
|
def select_all
|
367
371
|
anchorSelection( 0, 0, DONT_DISPLAY )
|
368
372
|
cursorTo( @lines.length - 1, @lines[ -1 ].length, DO_DISPLAY )
|
369
373
|
end
|
370
|
-
|
374
|
+
|
371
375
|
def select( from_regexp, to_regexp, include_ending = true )
|
372
376
|
start_row = nil
|
373
|
-
|
377
|
+
|
374
378
|
@lines[ 0..@last_row ].reverse.each_with_index do |line,index|
|
375
379
|
if line =~ from_regexp
|
376
380
|
start_row = @last_row - index
|
@@ -401,14 +405,14 @@ class Buffer
|
|
401
405
|
# write_cursor_col is buffer-relative, not screen-relative
|
402
406
|
def truncateOffScreen( string, write_cursor_col )
|
403
407
|
retval = string
|
404
|
-
|
408
|
+
|
405
409
|
# Truncate based on left edge of display area
|
406
410
|
if write_cursor_col < @left_column
|
407
411
|
retval = retval[ (@left_column - write_cursor_col)..-1 ]
|
408
412
|
write_cursor_col = @left_column
|
409
413
|
end
|
410
414
|
|
411
|
-
if retval
|
415
|
+
if retval
|
412
416
|
# Truncate based on right edge of display area
|
413
417
|
if write_cursor_col + retval.length > @left_column + Curses::cols - 1
|
414
418
|
new_length = ( @left_column + Curses::cols - write_cursor_col )
|
@@ -419,28 +423,28 @@ class Buffer
|
|
419
423
|
end
|
420
424
|
end
|
421
425
|
end
|
422
|
-
|
423
|
-
|
426
|
+
|
427
|
+
retval == "" ? nil : retval
|
424
428
|
end
|
425
|
-
|
429
|
+
|
426
430
|
# For debugging purposes
|
427
431
|
def quotedOrNil( str )
|
428
|
-
if str
|
429
|
-
|
432
|
+
if str.nil?
|
433
|
+
"nil"
|
430
434
|
else
|
431
|
-
|
435
|
+
"'#{str}'"
|
432
436
|
end
|
433
437
|
end
|
434
|
-
|
438
|
+
|
435
439
|
def paintMarks( row )
|
436
440
|
string = @lines[ row ][ @left_column ... @left_column + Curses::cols ]
|
437
|
-
return if string
|
441
|
+
return if string.nil? or string == ""
|
438
442
|
string = string.expandTabs( @tab_size )
|
439
443
|
cury = @win_main.cury
|
440
444
|
curx = @win_main.curx
|
441
|
-
|
445
|
+
|
442
446
|
@text_marks.reverse_each do |text_mark|
|
443
|
-
if text_mark
|
447
|
+
if text_mark
|
444
448
|
@win_main.attrset text_mark.formatting
|
445
449
|
if ( (text_mark.start_row + 1) .. (text_mark.end_row - 1) ) === row
|
446
450
|
@win_main.setpos( cury, curx )
|
@@ -475,7 +479,7 @@ class Buffer
|
|
475
479
|
|
476
480
|
def printString( string, formatting = ( @token_formats[ @continued_format_class ] or @default_formatting ) )
|
477
481
|
return if not @pen_down
|
478
|
-
return if string
|
482
|
+
return if string.nil?
|
479
483
|
|
480
484
|
@win_main.attrset formatting
|
481
485
|
@win_main.addstr string
|
@@ -491,10 +495,10 @@ class Buffer
|
|
491
495
|
index = nil
|
492
496
|
while i < line.length
|
493
497
|
substr = line[ i..-1 ]
|
494
|
-
if @continued_format_class
|
498
|
+
if @continued_format_class
|
495
499
|
close_index, close_match_text = findClosingMatch( substr, @close_token_regexps[ @continued_format_class ], i == 0 )
|
496
500
|
|
497
|
-
if close_match_text
|
501
|
+
if close_match_text.nil?
|
498
502
|
printString truncateOffScreen( substr, i )
|
499
503
|
printPaddingFrom( line.length )
|
500
504
|
i = line.length
|
@@ -510,7 +514,7 @@ class Buffer
|
|
510
514
|
if @lang_stack.length > 0
|
511
515
|
prev_lang, close_token_class = @lang_stack[ -1 ]
|
512
516
|
close_index, close_match_text = findClosingMatch( substr, @diakonos.close_token_regexps[ prev_lang ][ close_token_class ], i == 0 )
|
513
|
-
if close_match_text
|
517
|
+
if close_match_text and close_index <= first_index
|
514
518
|
if close_index > 0
|
515
519
|
# Print any remaining text in the embedded language
|
516
520
|
printString truncateOffScreen( substr[ 0...close_index ], i )
|
@@ -531,7 +535,7 @@ class Buffer
|
|
531
535
|
end
|
532
536
|
end
|
533
537
|
|
534
|
-
if first_word
|
538
|
+
if first_word
|
535
539
|
if first_index > 0
|
536
540
|
# Print any preceding text in the default format
|
537
541
|
printString truncateOffScreen( substr[ 0...first_index ], i )
|
@@ -539,7 +543,7 @@ class Buffer
|
|
539
543
|
end
|
540
544
|
printString( truncateOffScreen( first_word, i ), @token_formats[ first_token_class ] )
|
541
545
|
i += first_word.length
|
542
|
-
if @close_token_regexps[ first_token_class ]
|
546
|
+
if @close_token_regexps[ first_token_class ]
|
543
547
|
if change_to = @settings[ "lang.#{@language}.tokens.#{first_token_class}.change_to" ]
|
544
548
|
@lang_stack.push [ @language, first_token_class ]
|
545
549
|
setLanguage change_to
|
@@ -566,84 +570,98 @@ class Buffer
|
|
566
570
|
else
|
567
571
|
remainder = @left_column + Curses::cols - col
|
568
572
|
end
|
569
|
-
|
573
|
+
|
570
574
|
if remainder > 0
|
571
575
|
printString( " " * remainder )
|
572
576
|
end
|
573
577
|
end
|
574
578
|
|
575
579
|
def save( filename = nil, prompt_overwrite = DONT_PROMPT_OVERWRITE )
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
580
|
+
if filename
|
581
|
+
name = filename.subHome
|
582
|
+
else
|
583
|
+
name = @name
|
584
|
+
end
|
585
|
+
|
586
|
+
if @read_only and FileTest.exists?( @name ) and FileTest.exists?( name ) and ( File.stat( @name ).ino == File.stat( name ).ino )
|
587
|
+
@diakonos.setILine "#{name} cannot be saved since it is read-only."
|
588
|
+
else
|
589
|
+
@read_only = false
|
590
|
+
if name.nil?
|
591
|
+
@diakonos.saveFileAs
|
584
592
|
else
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
proceed = ! @diakonos.revert( "File has been altered externally. Load on-disk version?" )
|
593
|
+
proceed = true
|
594
|
+
|
595
|
+
if prompt_overwrite and FileTest.exists? name
|
596
|
+
proceed = false
|
597
|
+
choice = @diakonos.getChoice(
|
598
|
+
"Overwrite existing '#{name}'?",
|
599
|
+
[ CHOICE_YES, CHOICE_NO ],
|
600
|
+
CHOICE_NO
|
601
|
+
)
|
602
|
+
case choice
|
603
|
+
when CHOICE_YES
|
604
|
+
proceed = true
|
605
|
+
when CHOICE_NO
|
606
|
+
proceed = false
|
607
|
+
end
|
608
|
+
end
|
609
|
+
|
610
|
+
if file_modified?
|
611
|
+
proceed = ! @diakonos.revert( "File has been altered externally. Load on-disk version?" )
|
612
|
+
end
|
613
|
+
|
614
|
+
if proceed
|
615
|
+
File.open( name, "w" ) do |f|
|
616
|
+
@lines[ 0..-2 ].each do |line|
|
617
|
+
if @settings[ 'strip_trailing_whitespace_on_save' ]
|
618
|
+
line.rstrip!
|
612
619
|
end
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
@diakonos.initializeDisplay
|
630
|
-
end
|
631
|
-
|
632
|
-
@modified = false
|
633
|
-
|
634
|
-
display
|
635
|
-
@diakonos.updateStatusLine
|
620
|
+
f.puts line
|
621
|
+
end
|
622
|
+
|
623
|
+
line = @lines[ -1 ]
|
624
|
+
if @settings[ 'strip_trailing_whitespace_on_save' ]
|
625
|
+
line.rstrip!
|
626
|
+
end
|
627
|
+
if line != ""
|
628
|
+
# No final newline character
|
629
|
+
f.print line
|
630
|
+
f.print "\n" if @settings[ "eof_newline" ]
|
631
|
+
end
|
632
|
+
|
633
|
+
if @settings[ 'strip_trailing_whitespace_on_save' ]
|
634
|
+
if @last_col > @lines[ @last_row ].size
|
635
|
+
cursorTo @last_row, @lines[ @last_row ].size
|
636
636
|
end
|
637
|
+
end
|
638
|
+
end
|
639
|
+
@name = name
|
640
|
+
@last_modification_check = File.mtime( @name )
|
641
|
+
saved = true
|
642
|
+
|
643
|
+
if @name == @diakonos.diakonos_conf
|
644
|
+
@diakonos.loadConfiguration
|
645
|
+
@diakonos.initializeDisplay
|
637
646
|
end
|
647
|
+
|
648
|
+
@modified = false
|
649
|
+
|
650
|
+
display
|
651
|
+
@diakonos.updateStatusLine
|
652
|
+
end
|
638
653
|
end
|
654
|
+
end
|
655
|
+
|
656
|
+
saved
|
639
657
|
end
|
640
658
|
|
641
659
|
# Returns true on successful write.
|
642
660
|
def saveCopy( filename )
|
643
661
|
return false if filename.nil?
|
644
|
-
|
662
|
+
|
645
663
|
name = filename.subHome
|
646
|
-
|
664
|
+
|
647
665
|
File.open( name, "w" ) do |f|
|
648
666
|
@lines[ 0..-2 ].each do |line|
|
649
667
|
f.puts line
|
@@ -654,8 +672,8 @@ class Buffer
|
|
654
672
|
f.print "\n" if @settings[ "eof_newline" ]
|
655
673
|
end
|
656
674
|
end
|
657
|
-
|
658
|
-
|
675
|
+
|
676
|
+
true
|
659
677
|
end
|
660
678
|
|
661
679
|
def replaceChar( c )
|
@@ -674,7 +692,7 @@ class Buffer
|
|
674
692
|
@lines[ row ] = line[ 0...col ] + c.chr + line[ col..-1 ]
|
675
693
|
setModified
|
676
694
|
end
|
677
|
-
|
695
|
+
|
678
696
|
def insertString( str )
|
679
697
|
row = @last_row
|
680
698
|
col = @last_col
|
@@ -686,7 +704,7 @@ class Buffer
|
|
686
704
|
|
687
705
|
# x and y are given window-relative, not buffer-relative.
|
688
706
|
def delete
|
689
|
-
if selection_mark
|
707
|
+
if selection_mark
|
690
708
|
deleteSelection
|
691
709
|
else
|
692
710
|
row = @last_row
|
@@ -707,7 +725,7 @@ class Buffer
|
|
707
725
|
end
|
708
726
|
end
|
709
727
|
end
|
710
|
-
|
728
|
+
|
711
729
|
def joinLines( row = @last_row, strip = DONT_STRIP_LINE )
|
712
730
|
takeSnapshot( TYPING )
|
713
731
|
next_line = @lines.delete_at( row + 1 )
|
@@ -717,7 +735,7 @@ class Buffer
|
|
717
735
|
@lines[ row ] << next_line
|
718
736
|
setModified
|
719
737
|
end
|
720
|
-
|
738
|
+
|
721
739
|
def close_code
|
722
740
|
line = @lines[ @last_row ]
|
723
741
|
@closers.each_value do |h|
|
@@ -736,12 +754,12 @@ class Buffer
|
|
736
754
|
end
|
737
755
|
end
|
738
756
|
end
|
739
|
-
|
757
|
+
|
740
758
|
def collapseWhitespace
|
741
759
|
if selection_mark
|
742
760
|
removeSelection DONT_DISPLAY
|
743
761
|
end
|
744
|
-
|
762
|
+
|
745
763
|
line = @lines[ @last_row ]
|
746
764
|
head = line[ 0...@last_col ]
|
747
765
|
tail = line[ @last_col..-1 ]
|
@@ -754,7 +772,7 @@ class Buffer
|
|
754
772
|
setModified
|
755
773
|
end
|
756
774
|
end
|
757
|
-
|
775
|
+
|
758
776
|
def selected_lines
|
759
777
|
selection = selection_mark
|
760
778
|
if selection
|
@@ -768,10 +786,10 @@ class Buffer
|
|
768
786
|
[ @lines[ @last_row ] ]
|
769
787
|
end
|
770
788
|
end
|
771
|
-
|
789
|
+
|
772
790
|
def columnize( delimiter = /=>?|:|,/, num_spaces_padding = 1 )
|
773
791
|
takeSnapshot
|
774
|
-
|
792
|
+
|
775
793
|
lines = selected_lines
|
776
794
|
column_width = 0
|
777
795
|
lines.each do |line|
|
@@ -780,10 +798,10 @@ class Buffer
|
|
780
798
|
column_width = [ pos, column_width ].max
|
781
799
|
end
|
782
800
|
end
|
783
|
-
|
801
|
+
|
784
802
|
padding = ' ' * num_spaces_padding
|
785
803
|
one_modified = false
|
786
|
-
|
804
|
+
|
787
805
|
lines.each do |line|
|
788
806
|
old_line = line.dup
|
789
807
|
if line =~ /^(.+?)(#{delimiter.source})(.*)$/
|
@@ -802,12 +820,12 @@ class Buffer
|
|
802
820
|
end
|
803
821
|
one_modified ||= ( line != old_line )
|
804
822
|
end
|
805
|
-
|
823
|
+
|
806
824
|
if one_modified
|
807
825
|
setModified
|
808
826
|
end
|
809
827
|
end
|
810
|
-
|
828
|
+
|
811
829
|
def comment_out
|
812
830
|
takeSnapshot
|
813
831
|
one_modified = false
|
@@ -821,7 +839,7 @@ class Buffer
|
|
821
839
|
setModified
|
822
840
|
end
|
823
841
|
end
|
824
|
-
|
842
|
+
|
825
843
|
def uncomment
|
826
844
|
takeSnapshot
|
827
845
|
comment_string = Regexp.escape( @settings[ "lang.#{@language}.comment_string" ].to_s )
|
@@ -839,7 +857,7 @@ class Buffer
|
|
839
857
|
end
|
840
858
|
|
841
859
|
def deleteLine
|
842
|
-
removeSelection( DONT_DISPLAY ) if selection_mark
|
860
|
+
removeSelection( DONT_DISPLAY ) if selection_mark
|
843
861
|
|
844
862
|
row = @last_row
|
845
863
|
takeSnapshot
|
@@ -858,17 +876,17 @@ class Buffer
|
|
858
876
|
end
|
859
877
|
|
860
878
|
def deleteToEOL
|
861
|
-
removeSelection( DONT_DISPLAY ) if selection_mark
|
879
|
+
removeSelection( DONT_DISPLAY ) if selection_mark
|
862
880
|
|
863
881
|
row = @last_row
|
864
882
|
col = @last_col
|
865
|
-
|
883
|
+
|
866
884
|
takeSnapshot
|
867
885
|
if @settings[ 'delete_newline_on_delete_to_eol' ] and col == @lines[ row ].size
|
868
886
|
next_line = @lines.delete_at( row + 1 )
|
869
887
|
@lines[ row ] << next_line
|
870
888
|
retval = ''
|
871
|
-
else
|
889
|
+
else
|
872
890
|
retval = [ @lines[ row ][ col..-1 ] ]
|
873
891
|
@lines[ row ] = @lines[ row ][ 0...col ]
|
874
892
|
end
|
@@ -877,6 +895,31 @@ class Buffer
|
|
877
895
|
retval
|
878
896
|
end
|
879
897
|
|
898
|
+
def delete_to( char )
|
899
|
+
removeSelection( DONT_DISPLAY ) if selection_mark
|
900
|
+
takeSnapshot
|
901
|
+
index = @lines[ @last_row ].index( char, @last_col )
|
902
|
+
if index
|
903
|
+
retval = @lines[ @last_row ].slice!( @last_col, index - @last_col )
|
904
|
+
setModified
|
905
|
+
retval
|
906
|
+
end
|
907
|
+
end
|
908
|
+
|
909
|
+
def delete_to_and_from( char )
|
910
|
+
removeSelection( DONT_DISPLAY ) if selection_mark
|
911
|
+
takeSnapshot
|
912
|
+
index_before = @lines[ @last_row ].rindex( char, @last_col )
|
913
|
+
index_after = @lines[ @last_row ].index( char, @last_col )
|
914
|
+
if index_before && index_after
|
915
|
+
index_before += 1
|
916
|
+
retval = @lines[ @last_row ].slice!( index_before, index_after - index_before )
|
917
|
+
cursorTo( @last_row, index_before )
|
918
|
+
setModified
|
919
|
+
retval
|
920
|
+
end
|
921
|
+
end
|
922
|
+
|
880
923
|
def carriageReturn
|
881
924
|
takeSnapshot
|
882
925
|
row = @last_row
|
@@ -898,40 +941,40 @@ class Buffer
|
|
898
941
|
@lines[ row ]
|
899
942
|
end
|
900
943
|
end
|
901
|
-
|
944
|
+
|
902
945
|
def current_line
|
903
946
|
@lines[ @last_row ]
|
904
947
|
end
|
905
948
|
|
906
949
|
# Returns true iff the given column, x, is less than the length of the given line, y.
|
907
950
|
def inLine( x, y )
|
908
|
-
|
951
|
+
x + @left_column < lineAt( y ).length
|
909
952
|
end
|
910
953
|
|
911
954
|
# Translates the window column, x, to a buffer-relative column index.
|
912
955
|
def columnOf( x )
|
913
|
-
|
956
|
+
@left_column + x
|
914
957
|
end
|
915
958
|
|
916
959
|
# Translates the window row, y, to a buffer-relative row index.
|
917
960
|
def rowOf( y )
|
918
|
-
|
961
|
+
@top_line + y
|
919
962
|
end
|
920
|
-
|
963
|
+
|
921
964
|
# Returns nil if the row is off-screen.
|
922
965
|
def rowToY( row )
|
923
|
-
return nil if row
|
966
|
+
return nil if row.nil?
|
924
967
|
y = row - @top_line
|
925
968
|
y = nil if ( y < 0 ) or ( y > @top_line + @diakonos.main_window_height - 1 )
|
926
|
-
|
969
|
+
y
|
927
970
|
end
|
928
|
-
|
971
|
+
|
929
972
|
# Returns nil if the column is off-screen.
|
930
973
|
def columnToX( col )
|
931
|
-
return nil if col
|
974
|
+
return nil if col.nil?
|
932
975
|
x = col - @left_column
|
933
976
|
x = nil if ( x < 0 ) or ( x > @left_column + Curses::cols - 1 )
|
934
|
-
|
977
|
+
x
|
935
978
|
end
|
936
979
|
|
937
980
|
def currentRow
|
@@ -948,7 +991,7 @@ class Buffer
|
|
948
991
|
@left_column = [ @left_column + x, 0 ].max
|
949
992
|
recordMarkStartAndEnd
|
950
993
|
display if do_display
|
951
|
-
|
994
|
+
@left_column - old_left_column
|
952
995
|
end
|
953
996
|
|
954
997
|
# Returns the amount the view was actually pitched.
|
@@ -963,17 +1006,17 @@ class Buffer
|
|
963
1006
|
else
|
964
1007
|
@top_line = new_top_line
|
965
1008
|
end
|
966
|
-
|
1009
|
+
|
967
1010
|
old_row = @last_row
|
968
1011
|
old_col = @last_col
|
969
|
-
|
1012
|
+
|
970
1013
|
changed = ( @top_line - old_top_line )
|
971
1014
|
if changed != 0 and do_pitch_cursor
|
972
1015
|
@last_row += changed
|
973
1016
|
end
|
974
|
-
|
1017
|
+
|
975
1018
|
height = [ @diakonos.main_window_height, @lines.length ].min
|
976
|
-
|
1019
|
+
|
977
1020
|
@last_row = @last_row.fit( @top_line, @top_line + height - 1 )
|
978
1021
|
if @last_row - @top_line < @settings[ "view.margin.y" ]
|
979
1022
|
@last_row = @top_line + @settings[ "view.margin.y" ]
|
@@ -985,9 +1028,9 @@ class Buffer
|
|
985
1028
|
@last_col = @last_col.fit( @left_column, [ @left_column + Curses::cols - 1, @lines[ @last_row ].length ].min )
|
986
1029
|
@last_screen_y = @last_row - @top_line
|
987
1030
|
@last_screen_x = tabExpandedColumn( @last_col, @last_row ) - @left_column
|
988
|
-
|
1031
|
+
|
989
1032
|
recordMarkStartAndEnd
|
990
|
-
|
1033
|
+
|
991
1034
|
if changed != 0
|
992
1035
|
highlightMatches
|
993
1036
|
if @diakonos.there_was_non_movement
|
@@ -997,9 +1040,9 @@ class Buffer
|
|
997
1040
|
|
998
1041
|
display if do_display
|
999
1042
|
|
1000
|
-
|
1043
|
+
changed
|
1001
1044
|
end
|
1002
|
-
|
1045
|
+
|
1003
1046
|
def pushCursorState( top_line, row, col, clear_stack_pointer = CLEAR_STACK_POINTER )
|
1004
1047
|
new_state = {
|
1005
1048
|
:top_line => top_line,
|
@@ -1019,7 +1062,7 @@ class Buffer
|
|
1019
1062
|
def cursorTo( row, col, do_display = DONT_DISPLAY, stopped_typing = STOPPED_TYPING, adjust_row = ADJUST_ROW )
|
1020
1063
|
old_last_row = @last_row
|
1021
1064
|
old_last_col = @last_col
|
1022
|
-
|
1065
|
+
|
1023
1066
|
row = row.fit( 0, @lines.length - 1 )
|
1024
1067
|
|
1025
1068
|
if col < 0
|
@@ -1059,7 +1102,7 @@ class Buffer
|
|
1059
1102
|
view_changed = showCharacter( row, new_col )
|
1060
1103
|
@last_screen_y = row - @top_line
|
1061
1104
|
@last_screen_x = new_col - @left_column
|
1062
|
-
|
1105
|
+
|
1063
1106
|
@typing = false if stopped_typing
|
1064
1107
|
@last_row = row
|
1065
1108
|
@last_col = col
|
@@ -1067,13 +1110,13 @@ class Buffer
|
|
1067
1110
|
changed = ( @last_row != old_last_row or @last_col != old_last_col )
|
1068
1111
|
if changed
|
1069
1112
|
recordMarkStartAndEnd
|
1070
|
-
|
1113
|
+
|
1071
1114
|
removed = false
|
1072
|
-
if not @changing_selection and selection_mark
|
1115
|
+
if not @changing_selection and selection_mark
|
1073
1116
|
removeSelection( DONT_DISPLAY )
|
1074
1117
|
removed = true
|
1075
1118
|
end
|
1076
|
-
if removed or ( do_display and ( selection_mark
|
1119
|
+
if removed or ( do_display and ( selection_mark or view_changed ) )
|
1077
1120
|
display
|
1078
1121
|
else
|
1079
1122
|
@diakonos.display_mutex.synchronize do
|
@@ -1082,11 +1125,13 @@ class Buffer
|
|
1082
1125
|
end
|
1083
1126
|
@diakonos.updateStatusLine
|
1084
1127
|
@diakonos.updateContextLine
|
1128
|
+
|
1129
|
+
@diakonos.remember_buffer self
|
1085
1130
|
end
|
1086
|
-
|
1087
|
-
|
1131
|
+
|
1132
|
+
changed
|
1088
1133
|
end
|
1089
|
-
|
1134
|
+
|
1090
1135
|
def cursorReturn( direction )
|
1091
1136
|
delta = 0
|
1092
1137
|
if @cursor_stack_pointer.nil?
|
@@ -1100,25 +1145,25 @@ class Buffer
|
|
1100
1145
|
else
|
1101
1146
|
@cursor_stack_pointer = ( @cursor_stack_pointer || @cursor_stack.length ) - 1 - delta
|
1102
1147
|
end
|
1103
|
-
|
1148
|
+
|
1104
1149
|
return_pointer = @cursor_stack_pointer
|
1105
|
-
|
1150
|
+
|
1106
1151
|
if @cursor_stack_pointer < 0
|
1107
1152
|
return_pointer = @cursor_stack_pointer = 0
|
1108
1153
|
elsif @cursor_stack_pointer >= @cursor_stack.length
|
1109
1154
|
return_pointer = @cursor_stack_pointer = @cursor_stack.length - 1
|
1110
1155
|
else
|
1111
1156
|
cursor_state = @cursor_stack[ @cursor_stack_pointer ]
|
1112
|
-
if cursor_state
|
1157
|
+
if cursor_state
|
1113
1158
|
pitchView( cursor_state[ :top_line ] - @top_line, DONT_PITCH_CURSOR, DO_DISPLAY )
|
1114
1159
|
cursorTo( cursor_state[ :row ], cursor_state[ :col ] )
|
1115
1160
|
@diakonos.updateStatusLine
|
1116
1161
|
end
|
1117
1162
|
end
|
1118
|
-
|
1119
|
-
|
1163
|
+
|
1164
|
+
[ return_pointer, @cursor_stack.size ]
|
1120
1165
|
end
|
1121
|
-
|
1166
|
+
|
1122
1167
|
def tabExpandedColumn( col, row )
|
1123
1168
|
delta = 0
|
1124
1169
|
line = @lines[ row ]
|
@@ -1127,7 +1172,7 @@ class Buffer
|
|
1127
1172
|
delta += ( @tab_size - ( (i+delta) % @tab_size ) ) - 1
|
1128
1173
|
end
|
1129
1174
|
end
|
1130
|
-
|
1175
|
+
col + delta
|
1131
1176
|
end
|
1132
1177
|
|
1133
1178
|
def cursorToEOF
|
@@ -1158,7 +1203,7 @@ class Buffer
|
|
1158
1203
|
end
|
1159
1204
|
cursorTo( row, col, DO_DISPLAY )
|
1160
1205
|
end
|
1161
|
-
|
1206
|
+
|
1162
1207
|
def cursorToEOL
|
1163
1208
|
y = @win_main.cury
|
1164
1209
|
end_col = lineAt( y ).length
|
@@ -1217,7 +1262,7 @@ class Buffer
|
|
1217
1262
|
break if( panView( amount, DONT_DISPLAY ) != amount )
|
1218
1263
|
end
|
1219
1264
|
|
1220
|
-
|
1265
|
+
@top_line != old_top_line or @left_column != old_left_column
|
1221
1266
|
end
|
1222
1267
|
|
1223
1268
|
def setIndent( row, level, do_display = DO_DISPLAY )
|
@@ -1263,7 +1308,7 @@ class Buffer
|
|
1263
1308
|
level = prev_line.indentation_level( @indent_size, @indent_roundup, @tab_size, @indent_ignore_charset )
|
1264
1309
|
|
1265
1310
|
line = @lines[ row ]
|
1266
|
-
if @preventers
|
1311
|
+
if @preventers
|
1267
1312
|
prev_line = prev_line.gsub( @preventers, "" )
|
1268
1313
|
line = line.gsub( @preventers, "" )
|
1269
1314
|
end
|
@@ -1313,7 +1358,7 @@ class Buffer
|
|
1313
1358
|
@last_finding = nil
|
1314
1359
|
display if do_display
|
1315
1360
|
end
|
1316
|
-
|
1361
|
+
|
1317
1362
|
def toggleSelection
|
1318
1363
|
if @changing_selection
|
1319
1364
|
removeSelection
|
@@ -1347,7 +1392,7 @@ class Buffer
|
|
1347
1392
|
end
|
1348
1393
|
|
1349
1394
|
def deleteSelection( do_display = DO_DISPLAY )
|
1350
|
-
return if @text_marks[ SELECTION ]
|
1395
|
+
return if @text_marks[ SELECTION ].nil?
|
1351
1396
|
|
1352
1397
|
takeSnapshot
|
1353
1398
|
|
@@ -1371,8 +1416,8 @@ class Buffer
|
|
1371
1416
|
|
1372
1417
|
# text is an array of Strings, or a String with zero or more newlines ("\n")
|
1373
1418
|
def paste( text, do_parsed_indent = false )
|
1374
|
-
return if text
|
1375
|
-
|
1419
|
+
return if text.nil?
|
1420
|
+
|
1376
1421
|
if not text.kind_of? Array
|
1377
1422
|
s = text.to_s
|
1378
1423
|
if s.include?( "\n" )
|
@@ -1381,11 +1426,11 @@ class Buffer
|
|
1381
1426
|
text = [ s ]
|
1382
1427
|
end
|
1383
1428
|
end
|
1384
|
-
|
1429
|
+
|
1385
1430
|
takeSnapshot
|
1386
|
-
|
1431
|
+
|
1387
1432
|
deleteSelection( DONT_DISPLAY )
|
1388
|
-
|
1433
|
+
|
1389
1434
|
row = @last_row
|
1390
1435
|
col = @last_col
|
1391
1436
|
line = @lines[ row ]
|
@@ -1407,7 +1452,7 @@ class Buffer
|
|
1407
1452
|
end
|
1408
1453
|
cursorTo( new_row, columnOf( text[ -1 ].length ) )
|
1409
1454
|
end
|
1410
|
-
|
1455
|
+
|
1411
1456
|
setModified
|
1412
1457
|
end
|
1413
1458
|
|
@@ -1418,14 +1463,14 @@ class Buffer
|
|
1418
1463
|
def find( regexps, options = {} )
|
1419
1464
|
return if regexps.nil?
|
1420
1465
|
regexp = regexps[ 0 ]
|
1421
|
-
return if regexp
|
1422
|
-
|
1466
|
+
return if regexp.nil? or regexp == //
|
1467
|
+
|
1423
1468
|
direction = options[ :direction ]
|
1424
1469
|
replacement = options[ :replacement ]
|
1425
1470
|
auto_choice = options[ :auto_choice ]
|
1426
1471
|
from_row = options[ :starting_row ] || @last_row
|
1427
1472
|
from_col = options[ :starting_col ] || @last_col
|
1428
|
-
|
1473
|
+
|
1429
1474
|
if direction == :opposite
|
1430
1475
|
case @last_search_direction
|
1431
1476
|
when :up
|
@@ -1436,16 +1481,16 @@ class Buffer
|
|
1436
1481
|
end
|
1437
1482
|
@last_search_regexps = regexps
|
1438
1483
|
@last_search_direction = direction
|
1439
|
-
|
1484
|
+
|
1440
1485
|
finding = nil
|
1441
1486
|
wrapped = false
|
1442
1487
|
match = nil
|
1443
|
-
|
1488
|
+
|
1444
1489
|
catch :found do
|
1445
|
-
|
1490
|
+
|
1446
1491
|
if direction == :down
|
1447
1492
|
# Check the current row first.
|
1448
|
-
|
1493
|
+
|
1449
1494
|
if index = @lines[ from_row ].index( regexp, ( @last_finding ? @last_finding.start_col : from_col ) + 1 )
|
1450
1495
|
match = Regexp.last_match
|
1451
1496
|
found_text = match[ 0 ]
|
@@ -1456,9 +1501,9 @@ class Buffer
|
|
1456
1501
|
finding = nil
|
1457
1502
|
end
|
1458
1503
|
end
|
1459
|
-
|
1504
|
+
|
1460
1505
|
# Check below the cursor.
|
1461
|
-
|
1506
|
+
|
1462
1507
|
( (from_row + 1)...@lines.length ).each do |i|
|
1463
1508
|
if index = @lines[ i ].index( regexp )
|
1464
1509
|
match = Regexp.last_match
|
@@ -1471,11 +1516,11 @@ class Buffer
|
|
1471
1516
|
end
|
1472
1517
|
end
|
1473
1518
|
end
|
1474
|
-
|
1519
|
+
|
1475
1520
|
# Wrap around.
|
1476
|
-
|
1521
|
+
|
1477
1522
|
wrapped = true
|
1478
|
-
|
1523
|
+
|
1479
1524
|
( 0...from_row ).each do |i|
|
1480
1525
|
if index = @lines[ i ].index( regexp )
|
1481
1526
|
match = Regexp.last_match
|
@@ -1488,9 +1533,9 @@ class Buffer
|
|
1488
1533
|
end
|
1489
1534
|
end
|
1490
1535
|
end
|
1491
|
-
|
1536
|
+
|
1492
1537
|
# And finally, the other side of the current row.
|
1493
|
-
|
1538
|
+
|
1494
1539
|
#if index = @lines[ from_row ].index( regexp, ( @last_finding ? @last_finding.start_col : from_col ) - 1 )
|
1495
1540
|
if index = @lines[ from_row ].index( regexp )
|
1496
1541
|
if index <= ( @last_finding ? @last_finding.start_col : from_col )
|
@@ -1504,10 +1549,10 @@ class Buffer
|
|
1504
1549
|
end
|
1505
1550
|
end
|
1506
1551
|
end
|
1507
|
-
|
1552
|
+
|
1508
1553
|
elsif direction == :up
|
1509
1554
|
# Check the current row first.
|
1510
|
-
|
1555
|
+
|
1511
1556
|
col_to_check = ( @last_finding ? @last_finding.end_col : from_col ) - 1
|
1512
1557
|
if ( col_to_check >= 0 ) and ( index = @lines[ from_row ][ 0...col_to_check ].rindex( regexp ) )
|
1513
1558
|
match = Regexp.last_match
|
@@ -1519,9 +1564,9 @@ class Buffer
|
|
1519
1564
|
finding = nil
|
1520
1565
|
end
|
1521
1566
|
end
|
1522
|
-
|
1567
|
+
|
1523
1568
|
# Check above the cursor.
|
1524
|
-
|
1569
|
+
|
1525
1570
|
(from_row - 1).downto( 0 ) do |i|
|
1526
1571
|
if index = @lines[ i ].rindex( regexp )
|
1527
1572
|
match = Regexp.last_match
|
@@ -1534,11 +1579,11 @@ class Buffer
|
|
1534
1579
|
end
|
1535
1580
|
end
|
1536
1581
|
end
|
1537
|
-
|
1582
|
+
|
1538
1583
|
# Wrap around.
|
1539
|
-
|
1584
|
+
|
1540
1585
|
wrapped = true
|
1541
|
-
|
1586
|
+
|
1542
1587
|
(@lines.length - 1).downto(from_row + 1) do |i|
|
1543
1588
|
if index = @lines[ i ].rindex( regexp )
|
1544
1589
|
match = Regexp.last_match
|
@@ -1551,9 +1596,9 @@ class Buffer
|
|
1551
1596
|
end
|
1552
1597
|
end
|
1553
1598
|
end
|
1554
|
-
|
1599
|
+
|
1555
1600
|
# And finally, the other side of the current row.
|
1556
|
-
|
1601
|
+
|
1557
1602
|
search_col = ( @last_finding ? @last_finding.start_col : from_col ) + 1
|
1558
1603
|
if index = @lines[ from_row ].rindex( regexp )
|
1559
1604
|
if index > search_col
|
@@ -1569,12 +1614,12 @@ class Buffer
|
|
1569
1614
|
end
|
1570
1615
|
end
|
1571
1616
|
end
|
1572
|
-
|
1617
|
+
|
1573
1618
|
if finding
|
1574
1619
|
if wrapped and not options[ :quiet ]
|
1575
1620
|
@diakonos.setILine( "(search wrapped around BOF/EOF)" )
|
1576
1621
|
end
|
1577
|
-
|
1622
|
+
|
1578
1623
|
removeSelection( DONT_DISPLAY )
|
1579
1624
|
@last_finding = finding
|
1580
1625
|
if @settings[ "found_cursor_start" ]
|
@@ -1586,7 +1631,7 @@ class Buffer
|
|
1586
1631
|
end
|
1587
1632
|
|
1588
1633
|
@changing_selection = false
|
1589
|
-
|
1634
|
+
|
1590
1635
|
if regexps.length == 1
|
1591
1636
|
@highlight_regexp = regexp
|
1592
1637
|
highlightMatches
|
@@ -1594,7 +1639,7 @@ class Buffer
|
|
1594
1639
|
clearMatches
|
1595
1640
|
end
|
1596
1641
|
display
|
1597
|
-
|
1642
|
+
|
1598
1643
|
if replacement
|
1599
1644
|
# Substitute placeholders (e.g. \1) in str for the group matches of the last match.
|
1600
1645
|
actual_replacement = replacement.dup
|
@@ -1606,7 +1651,7 @@ class Buffer
|
|
1606
1651
|
match[ ref.to_i ]
|
1607
1652
|
end
|
1608
1653
|
}
|
1609
|
-
|
1654
|
+
|
1610
1655
|
choice = auto_choice || @diakonos.getChoice(
|
1611
1656
|
"Replace?",
|
1612
1657
|
[ CHOICE_YES, CHOICE_NO, CHOICE_ALL, CHOICE_CANCEL, CHOICE_YES_AND_STOP ],
|
@@ -1637,7 +1682,7 @@ class Buffer
|
|
1637
1682
|
end
|
1638
1683
|
|
1639
1684
|
def replaceAll( regexp, replacement )
|
1640
|
-
return if( regexp
|
1685
|
+
return if( regexp.nil? or replacement.nil? )
|
1641
1686
|
|
1642
1687
|
@lines = @lines.collect { |line|
|
1643
1688
|
line.gsub( regexp, replacement )
|
@@ -1648,15 +1693,14 @@ class Buffer
|
|
1648
1693
|
|
1649
1694
|
display
|
1650
1695
|
end
|
1651
|
-
|
1652
|
-
def highlightMatches
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
end
|
1696
|
+
|
1697
|
+
def highlightMatches( regexp = @highlight_regexp )
|
1698
|
+
@highlight_regexp = regexp
|
1699
|
+
return if @highlight_regexp.nil?
|
1700
|
+
found_marks = @lines[ @top_line...(@top_line + @diakonos.main_window_height) ].grep_indices( @highlight_regexp ).collect do |line_index, start_col, end_col|
|
1701
|
+
TextMark.new( @top_line + line_index, start_col, @top_line + line_index, end_col, @settings[ "lang.#{@language}.format.found" ] )
|
1702
|
+
end
|
1703
|
+
@text_marks = [ @text_marks[ 0 ] ] + found_marks
|
1660
1704
|
end
|
1661
1705
|
|
1662
1706
|
def clearMatches( do_display = DONT_DISPLAY )
|
@@ -1675,59 +1719,59 @@ class Buffer
|
|
1675
1719
|
find( @last_search_regexps, :direction => direction )
|
1676
1720
|
end
|
1677
1721
|
end
|
1678
|
-
|
1722
|
+
|
1679
1723
|
def seek( regexp, direction = :down )
|
1680
|
-
return if regexp
|
1681
|
-
|
1724
|
+
return if regexp.nil? or regexp == //
|
1725
|
+
|
1682
1726
|
found_row = nil
|
1683
1727
|
found_col = nil
|
1684
1728
|
found_text = nil
|
1685
1729
|
wrapped = false
|
1686
|
-
|
1730
|
+
|
1687
1731
|
catch :found do
|
1688
1732
|
if direction == :down
|
1689
1733
|
# Check the current row first.
|
1690
|
-
|
1734
|
+
|
1691
1735
|
index, match_text = @lines[ @last_row ].group_index( regexp, @last_col + 1 )
|
1692
|
-
if index
|
1736
|
+
if index
|
1693
1737
|
found_row = @last_row
|
1694
1738
|
found_col = index
|
1695
1739
|
found_text = match_text
|
1696
1740
|
throw :found
|
1697
1741
|
end
|
1698
|
-
|
1742
|
+
|
1699
1743
|
# Check below the cursor.
|
1700
|
-
|
1744
|
+
|
1701
1745
|
( (@last_row + 1)...@lines.length ).each do |i|
|
1702
1746
|
index, match_text = @lines[ i ].group_index( regexp )
|
1703
|
-
if index
|
1747
|
+
if index
|
1704
1748
|
found_row = i
|
1705
1749
|
found_col = index
|
1706
1750
|
found_text = match_text
|
1707
1751
|
throw :found
|
1708
1752
|
end
|
1709
1753
|
end
|
1710
|
-
|
1754
|
+
|
1711
1755
|
else
|
1712
1756
|
# Check the current row first.
|
1713
|
-
|
1757
|
+
|
1714
1758
|
#col_to_check = ( @last_found_col or @last_col ) - 1
|
1715
1759
|
col_to_check = @last_col - 1
|
1716
1760
|
if col_to_check >= 0
|
1717
1761
|
index, match_text = @lines[ @last_row ].group_rindex( regexp, col_to_check )
|
1718
|
-
if index
|
1762
|
+
if index
|
1719
1763
|
found_row = @last_row
|
1720
1764
|
found_col = index
|
1721
1765
|
found_text = match_text
|
1722
1766
|
throw :found
|
1723
1767
|
end
|
1724
1768
|
end
|
1725
|
-
|
1769
|
+
|
1726
1770
|
# Check above the cursor.
|
1727
|
-
|
1771
|
+
|
1728
1772
|
(@last_row - 1).downto( 0 ) do |i|
|
1729
1773
|
index, match_text = @lines[ i ].group_rindex( regexp )
|
1730
|
-
if index
|
1774
|
+
if index
|
1731
1775
|
found_row = i
|
1732
1776
|
found_col = index
|
1733
1777
|
found_text = match_text
|
@@ -1736,15 +1780,27 @@ class Buffer
|
|
1736
1780
|
end
|
1737
1781
|
end
|
1738
1782
|
end
|
1739
|
-
|
1740
|
-
if found_text
|
1783
|
+
|
1784
|
+
if found_text
|
1741
1785
|
#@last_found_row = found_row
|
1742
1786
|
#@last_found_col = found_col
|
1743
1787
|
cursorTo( found_row, found_col )
|
1744
|
-
|
1788
|
+
|
1745
1789
|
display
|
1746
1790
|
end
|
1747
|
-
end
|
1791
|
+
end
|
1792
|
+
|
1793
|
+
# Returns an Array of results, where each result is a String usually
|
1794
|
+
# containing \n's due to context
|
1795
|
+
def grep( regexp_source )
|
1796
|
+
::Diakonos.grep_array(
|
1797
|
+
Regexp.new( regexp_source ),
|
1798
|
+
@lines,
|
1799
|
+
@diakonos.settings[ 'grep.context' ],
|
1800
|
+
"#{File.basename( @name )}:",
|
1801
|
+
@key
|
1802
|
+
)
|
1803
|
+
end
|
1748
1804
|
|
1749
1805
|
def setModified( do_display = DO_DISPLAY )
|
1750
1806
|
if @read_only
|
@@ -1754,14 +1810,14 @@ class Buffer
|
|
1754
1810
|
fmod = false
|
1755
1811
|
if not @modified
|
1756
1812
|
@modified = true
|
1757
|
-
fmod = file_modified
|
1813
|
+
fmod = file_modified?
|
1758
1814
|
end
|
1759
|
-
|
1815
|
+
|
1760
1816
|
reverted = false
|
1761
1817
|
if fmod
|
1762
1818
|
reverted = @diakonos.revert( "File has been altered externally. Load on-disk version?" )
|
1763
1819
|
end
|
1764
|
-
|
1820
|
+
|
1765
1821
|
if not reverted
|
1766
1822
|
clearMatches
|
1767
1823
|
if do_display
|
@@ -1770,16 +1826,16 @@ class Buffer
|
|
1770
1826
|
end
|
1771
1827
|
end
|
1772
1828
|
end
|
1773
|
-
|
1829
|
+
|
1774
1830
|
# Check if the file which is being edited has been modified since
|
1775
1831
|
# the last time we checked it; return true if so, false otherwise.
|
1776
|
-
def file_modified
|
1832
|
+
def file_modified?
|
1777
1833
|
modified = false
|
1778
|
-
|
1779
|
-
if @name
|
1834
|
+
|
1835
|
+
if @name
|
1780
1836
|
begin
|
1781
1837
|
mtime = File.mtime( @name )
|
1782
|
-
|
1838
|
+
|
1783
1839
|
if mtime > @last_modification_check
|
1784
1840
|
modified = true
|
1785
1841
|
@last_modification_check = mtime
|
@@ -1788,8 +1844,22 @@ class Buffer
|
|
1788
1844
|
# Ignore if file doesn't exist
|
1789
1845
|
end
|
1790
1846
|
end
|
1791
|
-
|
1792
|
-
|
1847
|
+
|
1848
|
+
modified
|
1849
|
+
end
|
1850
|
+
|
1851
|
+
# Compares MD5 sums of buffer and actual file on disk.
|
1852
|
+
# Returns true if there is no file on disk.
|
1853
|
+
def file_different?
|
1854
|
+
if @name
|
1855
|
+
Digest::MD5.hexdigest(
|
1856
|
+
@lines.join( "\n" )
|
1857
|
+
) != Digest::MD5.hexdigest(
|
1858
|
+
File.read( @name )
|
1859
|
+
)
|
1860
|
+
else
|
1861
|
+
true
|
1862
|
+
end
|
1793
1863
|
end
|
1794
1864
|
|
1795
1865
|
def takeSnapshot( typing = false )
|
@@ -1847,7 +1917,7 @@ class Buffer
|
|
1847
1917
|
setModified
|
1848
1918
|
end
|
1849
1919
|
end
|
1850
|
-
|
1920
|
+
|
1851
1921
|
def wrap_paragraph
|
1852
1922
|
start_row = end_row = @last_row
|
1853
1923
|
until start_row == 0 || @lines[ start_row - 1 ].strip == ''
|
@@ -1904,7 +1974,7 @@ class Buffer
|
|
1904
1974
|
break
|
1905
1975
|
end
|
1906
1976
|
end
|
1907
|
-
if prev
|
1977
|
+
if prev
|
1908
1978
|
cursorTo( prev.row, prev.col, DO_DISPLAY )
|
1909
1979
|
end
|
1910
1980
|
end
|
@@ -1945,22 +2015,20 @@ class Buffer
|
|
1945
2015
|
end
|
1946
2016
|
end
|
1947
2017
|
end
|
1948
|
-
|
2018
|
+
retval
|
1949
2019
|
end
|
1950
2020
|
|
1951
2021
|
def setType( type )
|
1952
|
-
|
1953
|
-
if type != nil
|
2022
|
+
if type
|
1954
2023
|
configure( type )
|
1955
2024
|
display
|
1956
|
-
|
2025
|
+
true
|
1957
2026
|
end
|
1958
|
-
return success
|
1959
2027
|
end
|
1960
|
-
|
2028
|
+
|
1961
2029
|
def wordUnderCursor
|
1962
2030
|
word = nil
|
1963
|
-
|
2031
|
+
|
1964
2032
|
@lines[ @last_row ].scan( /\w+/ ) do |match_text|
|
1965
2033
|
last_match = Regexp.last_match
|
1966
2034
|
if last_match.begin( 0 ) <= @last_col and @last_col < last_match.end( 0 )
|
@@ -1968,8 +2036,8 @@ class Buffer
|
|
1968
2036
|
break
|
1969
2037
|
end
|
1970
2038
|
end
|
1971
|
-
|
1972
|
-
|
2039
|
+
|
2040
|
+
word
|
1973
2041
|
end
|
1974
2042
|
end
|
1975
2043
|
|