diakonos 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +172 -0
- data/README +75 -0
- data/bin/diakonos +6 -0
- data/diakonos.conf +960 -0
- data/home-on-save.rb +6 -0
- data/lib/diakonos.rb +2397 -0
- data/lib/diakonos/array.rb +10 -0
- data/lib/diakonos/bignum.rb +6 -0
- data/lib/diakonos/bookmark.rb +51 -0
- data/lib/diakonos/buffer-hash.rb +18 -0
- data/lib/diakonos/buffer.rb +1700 -0
- data/lib/diakonos/clipboard.rb +47 -0
- data/lib/diakonos/ctag.rb +28 -0
- data/lib/diakonos/enumerable.rb +15 -0
- data/lib/diakonos/finding.rb +32 -0
- data/lib/diakonos/fixnum.rb +13 -0
- data/lib/diakonos/hash.rb +101 -0
- data/lib/diakonos/keycode.rb +110 -0
- data/lib/diakonos/object.rb +6 -0
- data/lib/diakonos/readline.rb +192 -0
- data/lib/diakonos/regexp.rb +6 -0
- data/lib/diakonos/sized-array.rb +48 -0
- data/lib/diakonos/string.rb +318 -0
- data/lib/diakonos/text-mark.rb +19 -0
- data/lib/diakonos/window.rb +32 -0
- data/test/buffer-test.rb +37 -0
- data/test/clipboard-test.rb +70 -0
- data/test/diakonos-test.rb +14 -0
- data/test/hash-test.rb +404 -0
- data/test/regexp-test.rb +26 -0
- data/test/sizedarray-test.rb +113 -0
- data/test/string-test.rb +160 -0
- metadata +77 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
class SizedArray < Array
|
2
|
+
attr_reader :capacity
|
3
|
+
|
4
|
+
def initialize( capacity = 10, *args )
|
5
|
+
@capacity = capacity
|
6
|
+
super( *args )
|
7
|
+
end
|
8
|
+
|
9
|
+
def resize
|
10
|
+
if size > @capacity
|
11
|
+
slice!( (0...-@capacity) )
|
12
|
+
end
|
13
|
+
end
|
14
|
+
private :resize
|
15
|
+
|
16
|
+
def concat( other_array )
|
17
|
+
super( other_array )
|
18
|
+
resize
|
19
|
+
return self
|
20
|
+
end
|
21
|
+
|
22
|
+
def fill( *args )
|
23
|
+
retval = super( *args )
|
24
|
+
resize
|
25
|
+
return self
|
26
|
+
end
|
27
|
+
|
28
|
+
def <<( item )
|
29
|
+
retval = super( item )
|
30
|
+
if size > @capacity
|
31
|
+
retval = shift
|
32
|
+
end
|
33
|
+
return retval
|
34
|
+
end
|
35
|
+
|
36
|
+
def push( item )
|
37
|
+
self << item
|
38
|
+
end
|
39
|
+
|
40
|
+
def unshift( item )
|
41
|
+
retval = super( item )
|
42
|
+
if size > @capacity
|
43
|
+
retval = pop
|
44
|
+
end
|
45
|
+
return retval
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,318 @@
|
|
1
|
+
class String
|
2
|
+
def subHome
|
3
|
+
return gsub( /~/, ENV[ "HOME" ] )
|
4
|
+
end
|
5
|
+
|
6
|
+
def keyCode
|
7
|
+
retval = nil
|
8
|
+
case downcase
|
9
|
+
when "down"
|
10
|
+
retval = Curses::KEY_DOWN
|
11
|
+
when "up"
|
12
|
+
retval = Curses::KEY_UP
|
13
|
+
when "left"
|
14
|
+
retval = Curses::KEY_LEFT
|
15
|
+
when "right"
|
16
|
+
retval = Curses::KEY_RIGHT
|
17
|
+
when "home"
|
18
|
+
retval = Curses::KEY_HOME
|
19
|
+
when "end"
|
20
|
+
retval = Curses::KEY_END
|
21
|
+
when "insert", "ins"
|
22
|
+
retval = Curses::KEY_IC
|
23
|
+
when "delete", "del"
|
24
|
+
retval = Curses::KEY_DC
|
25
|
+
when "backspace"
|
26
|
+
retval = Diakonos::BACKSPACE
|
27
|
+
when "tab"
|
28
|
+
retval = 9
|
29
|
+
when "pageup", "page-up"
|
30
|
+
retval = Curses::KEY_PPAGE
|
31
|
+
when "pagedown", "page-down"
|
32
|
+
retval = Curses::KEY_NPAGE
|
33
|
+
when "enter", "return"
|
34
|
+
retval = Diakonos::ENTER
|
35
|
+
when "numpad7", "keypad7", "kp-7"
|
36
|
+
retval = Curses::KEY_A1
|
37
|
+
when "numpad9", "keypad9", "kp-9"
|
38
|
+
retval = Curses::KEY_A3
|
39
|
+
when "numpad5", "keypad5", "kp-5"
|
40
|
+
retval = Curses::KEY_B2
|
41
|
+
when "numpad1", "keypad1", "kp-1"
|
42
|
+
retval = Curses::KEY_C1
|
43
|
+
when "numpad3", "keypad3", "kp-3"
|
44
|
+
retval = Curses::KEY_C3
|
45
|
+
when "escape", "esc"
|
46
|
+
retval = Diakonos::ESCAPE
|
47
|
+
when "space"
|
48
|
+
retval = 32
|
49
|
+
when "ctrl+space"
|
50
|
+
retval = 0
|
51
|
+
when "find"
|
52
|
+
retval = Curses::KEY_FIND
|
53
|
+
when "select"
|
54
|
+
retval = Curses::KEY_SELECT
|
55
|
+
when "suspend"
|
56
|
+
retval = Curses::KEY_SUSPEND
|
57
|
+
when /^f(\d\d?)$/
|
58
|
+
retval = Curses::KEY_F0 + $1.to_i
|
59
|
+
when /^ctrl\+[a-gi-z]$/
|
60
|
+
retval = downcase[ -1 ] - 96
|
61
|
+
when /^ctrl\+h$/
|
62
|
+
retval = Diakonos::CTRL_H
|
63
|
+
when /^alt\+(.)$/
|
64
|
+
retval = [ Diakonos::ESCAPE, $1[ 0 ] ]
|
65
|
+
when /^ctrl\+alt\+(.)$/, /^alt\+ctrl\+(.)$/
|
66
|
+
retval = [ Diakonos::ESCAPE, downcase[ -1 ] - 96 ]
|
67
|
+
when /^keycode(\d+)$/
|
68
|
+
retval = $1.to_i
|
69
|
+
when /^.$/
|
70
|
+
retval = self[ 0 ]
|
71
|
+
end
|
72
|
+
if retval.class != Array
|
73
|
+
retval = [ retval ]
|
74
|
+
end
|
75
|
+
return retval
|
76
|
+
end
|
77
|
+
|
78
|
+
def toFormatting
|
79
|
+
formatting = Curses::A_NORMAL
|
80
|
+
split( /\s+/ ).each do |format|
|
81
|
+
case format.downcase
|
82
|
+
when "normal"
|
83
|
+
formatting = Curses::A_NORMAL
|
84
|
+
when "black", "0"
|
85
|
+
formatting = formatting | Curses::color_pair( Curses::COLOR_BLACK )
|
86
|
+
when "red", "1"
|
87
|
+
formatting = formatting | Curses::color_pair( Curses::COLOR_RED )
|
88
|
+
when "green", "2"
|
89
|
+
formatting = formatting | Curses::color_pair( Curses::COLOR_GREEN )
|
90
|
+
when "yellow", "brown", "3"
|
91
|
+
formatting = formatting | Curses::color_pair( Curses::COLOR_YELLOW )
|
92
|
+
when "blue", "4"
|
93
|
+
formatting = formatting | Curses::color_pair( Curses::COLOR_BLUE )
|
94
|
+
when "magenta", "purple", "5"
|
95
|
+
formatting = formatting | Curses::color_pair( Curses::COLOR_MAGENTA )
|
96
|
+
when "cyan", "6"
|
97
|
+
formatting = formatting | Curses::color_pair( Curses::COLOR_CYAN )
|
98
|
+
when "white", "7"
|
99
|
+
formatting = formatting | Curses::color_pair( Curses::COLOR_WHITE )
|
100
|
+
when "standout", "s", "so"
|
101
|
+
formatting = formatting | Curses::A_STANDOUT
|
102
|
+
when "underline", "u", "un", "ul"
|
103
|
+
formatting = formatting | Curses::A_UNDERLINE
|
104
|
+
when "reverse", "r", "rev", "inverse", "i", "inv"
|
105
|
+
formatting = formatting | Curses::A_REVERSE
|
106
|
+
when "blink", "bl", "blinking"
|
107
|
+
formatting = formatting | Curses::A_BLINK
|
108
|
+
when "dim", "d"
|
109
|
+
formatting = formatting | Curses::A_DIM
|
110
|
+
when "bold", "b", "bo"
|
111
|
+
formatting = formatting | Curses::A_BOLD
|
112
|
+
else
|
113
|
+
if ( colour_number = format.to_i ) > Curses::COLOR_WHITE
|
114
|
+
formatting = formatting | Curses::color_pair( colour_number )
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
return formatting
|
119
|
+
end
|
120
|
+
|
121
|
+
def toColourConstant
|
122
|
+
retval = Curses::COLOR_WHITE
|
123
|
+
case downcase
|
124
|
+
when "black", "0"
|
125
|
+
retval = Curses::COLOR_BLACK
|
126
|
+
when "red", "1"
|
127
|
+
retval = Curses::COLOR_RED
|
128
|
+
when "green", "2"
|
129
|
+
retval = Curses::COLOR_GREEN
|
130
|
+
when "yellow", "brown", "3"
|
131
|
+
retval = Curses::COLOR_YELLOW
|
132
|
+
when "blue", "4"
|
133
|
+
retval = Curses::COLOR_BLUE
|
134
|
+
when "magenta", "purple", "5"
|
135
|
+
retval = Curses::COLOR_MAGENTA
|
136
|
+
when "cyan", "6"
|
137
|
+
retval = Curses::COLOR_CYAN
|
138
|
+
when "white", "7"
|
139
|
+
retval = Curses::COLOR_WHITE
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def toDirection( default = :down )
|
144
|
+
direction = nil
|
145
|
+
case self
|
146
|
+
when "up"
|
147
|
+
direction = :up
|
148
|
+
when /other/
|
149
|
+
direction = :opposite
|
150
|
+
when "down"
|
151
|
+
direction = :down
|
152
|
+
when "forward"
|
153
|
+
direction = :forward
|
154
|
+
when "backward"
|
155
|
+
direction = :backward
|
156
|
+
else
|
157
|
+
direction = default
|
158
|
+
end
|
159
|
+
return direction
|
160
|
+
end
|
161
|
+
|
162
|
+
def to_a
|
163
|
+
return [ self ]
|
164
|
+
end
|
165
|
+
|
166
|
+
def to_b
|
167
|
+
retval = false
|
168
|
+
case downcase
|
169
|
+
when "true", "t", "1", "yes", "y", "on", "+"
|
170
|
+
retval = true
|
171
|
+
end
|
172
|
+
return retval
|
173
|
+
end
|
174
|
+
|
175
|
+
def indentation_level( indent_size, indent_roundup, tab_size = Diakonos::DEFAULT_TAB_SIZE, indent_ignore_charset = nil )
|
176
|
+
if indent_ignore_charset == nil
|
177
|
+
level = 0
|
178
|
+
if self =~ /^([\s]+)/
|
179
|
+
#whitespace = $1.gsub( /\t/, ' ' * tab_size )
|
180
|
+
whitespace = $1.expandTabs( tab_size )
|
181
|
+
level = whitespace.length / indent_size
|
182
|
+
if indent_roundup and ( whitespace.length % indent_size > 0 )
|
183
|
+
level += 1
|
184
|
+
end
|
185
|
+
end
|
186
|
+
else
|
187
|
+
if self =~ /^[\s#{indent_ignore_charset}]*$/ or self == ""
|
188
|
+
level = -1
|
189
|
+
elsif self =~ /^([\s#{indent_ignore_charset}]+)/
|
190
|
+
#whitespace = $1.gsub( /\t/, ' ' * tab_size )
|
191
|
+
whitespace = $1.expandTabs( tab_size )
|
192
|
+
level = whitespace.length / indent_size
|
193
|
+
if indent_roundup and ( whitespace.length % indent_size > 0 )
|
194
|
+
level += 1
|
195
|
+
end
|
196
|
+
else
|
197
|
+
level = 0
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
return level
|
202
|
+
end
|
203
|
+
|
204
|
+
def expandTabs( tab_size = Diakonos::DEFAULT_TAB_SIZE )
|
205
|
+
s = dup
|
206
|
+
while s.sub!( /\t/ ) { |match_text|
|
207
|
+
match = Regexp.last_match
|
208
|
+
index = match.begin( 0 )
|
209
|
+
# Return value for block:
|
210
|
+
" " * ( tab_size - ( index % tab_size ) )
|
211
|
+
}
|
212
|
+
end
|
213
|
+
return s
|
214
|
+
end
|
215
|
+
|
216
|
+
def newlineSplit
|
217
|
+
retval = split( /\\n/ )
|
218
|
+
if self =~ /\\n$/
|
219
|
+
retval << ""
|
220
|
+
end
|
221
|
+
if retval.length > 1
|
222
|
+
retval[ 0 ] << "$"
|
223
|
+
retval[ 1..-2 ].collect do |el|
|
224
|
+
"^" << el << "$"
|
225
|
+
end
|
226
|
+
retval[ -1 ] = "^" << retval[ -1 ]
|
227
|
+
end
|
228
|
+
return retval
|
229
|
+
end
|
230
|
+
|
231
|
+
# Works like normal String#index except returns the index
|
232
|
+
# of the first matching regexp group if one or more groups are specified
|
233
|
+
# in the regexp. Both the index and the matched text are returned.
|
234
|
+
def group_index( regexp, offset = 0 )
|
235
|
+
if regexp.class != Regexp
|
236
|
+
return index( regexp, offset )
|
237
|
+
end
|
238
|
+
|
239
|
+
i = nil
|
240
|
+
match_text = nil
|
241
|
+
working_offset = 0
|
242
|
+
loop do
|
243
|
+
index( regexp, working_offset )
|
244
|
+
match = Regexp.last_match
|
245
|
+
if match
|
246
|
+
i = match.begin( 0 )
|
247
|
+
match_text = match[ 0 ]
|
248
|
+
if match.length > 1
|
249
|
+
# Find first matching group
|
250
|
+
1.upto( match.length - 1 ) do |match_item_index|
|
251
|
+
if match[ match_item_index ] != nil
|
252
|
+
i = match.begin( match_item_index )
|
253
|
+
match_text = match[ match_item_index ]
|
254
|
+
break
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
break if i >= offset
|
260
|
+
else
|
261
|
+
i = nil
|
262
|
+
break
|
263
|
+
end
|
264
|
+
working_offset += 1
|
265
|
+
end
|
266
|
+
|
267
|
+
return i, match_text
|
268
|
+
end
|
269
|
+
|
270
|
+
# Works like normal String#rindex except returns the index
|
271
|
+
# of the first matching regexp group if one or more groups are specified
|
272
|
+
# in the regexp. Both the index and the matched text are returned.
|
273
|
+
def group_rindex( regexp, offset = length )
|
274
|
+
if regexp.class != Regexp
|
275
|
+
return rindex( regexp, offset )
|
276
|
+
end
|
277
|
+
|
278
|
+
i = nil
|
279
|
+
match_text = nil
|
280
|
+
working_offset = length
|
281
|
+
loop do
|
282
|
+
rindex( regexp, working_offset )
|
283
|
+
match = Regexp.last_match
|
284
|
+
if match
|
285
|
+
i = match.end( 0 ) - 1
|
286
|
+
match_text = match[ 0 ]
|
287
|
+
if match.length > 1
|
288
|
+
# Find first matching group
|
289
|
+
1.upto( match.length - 1 ) do |match_item_index|
|
290
|
+
if match[ match_item_index ] != nil
|
291
|
+
i = match.end( match_item_index ) - 1
|
292
|
+
match_text = match[ match_item_index ]
|
293
|
+
break
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
if match_text == ""
|
299
|
+
# Assume that an empty string means that it matched $
|
300
|
+
i += 1
|
301
|
+
end
|
302
|
+
|
303
|
+
break if i <= offset
|
304
|
+
else
|
305
|
+
i = nil
|
306
|
+
break
|
307
|
+
end
|
308
|
+
working_offset -= 1
|
309
|
+
end
|
310
|
+
|
311
|
+
return i, match_text
|
312
|
+
end
|
313
|
+
|
314
|
+
def movement?
|
315
|
+
return ( ( self =~ /^((cursor|page|scroll)(Up|Down|Left|Right)|find)/ ) != nil )
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Diakonos
|
2
|
+
|
3
|
+
class TextMark
|
4
|
+
attr_reader :formatting, :start_row, :start_col, :end_row, :end_col
|
5
|
+
|
6
|
+
def initialize( start_row, start_col, end_row, end_col, formatting )
|
7
|
+
@start_row = start_row
|
8
|
+
@start_col = start_col
|
9
|
+
@end_row = end_row
|
10
|
+
@end_col = end_col
|
11
|
+
@formatting = formatting
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
return "(#{start_row},#{start_col})-(#{end_row},#{end_col}) #{formatting}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Curses::Window
|
2
|
+
def puts( string = "" )
|
3
|
+
addstr( string + "\n" )
|
4
|
+
end
|
5
|
+
|
6
|
+
# setpos, but with some boundary checks
|
7
|
+
def setpos_( y, x )
|
8
|
+
$diakonos.debugLog "setpos: y < 0 (#{y})" if y < 0
|
9
|
+
$diakonos.debugLog "setpos: x < 0 (#{x})" if x < 0
|
10
|
+
$diakonos.debugLog "setpos: y > lines (#{y})" if y > Curses::lines
|
11
|
+
$diakonos.debugLog "setpos: x > cols (#{x})" if x > Curses::cols
|
12
|
+
setpos( y, x )
|
13
|
+
end
|
14
|
+
|
15
|
+
def addstr_( string )
|
16
|
+
x = curx
|
17
|
+
y = cury
|
18
|
+
x2 = curx + string.length
|
19
|
+
|
20
|
+
if y < 0 or x < 0 or y > Curses::lines or x > Curses::cols or x2 < 0 or x2 > Curses::cols
|
21
|
+
begin
|
22
|
+
raise Exception
|
23
|
+
rescue Exception => e
|
24
|
+
$diakonos.debugLog e.backtrace[ 1 ]
|
25
|
+
$diakonos.debugLog e.backtrace[ 2 ]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
addstr( string )
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
data/test/buffer-test.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'diakonos'
|
5
|
+
|
6
|
+
class TC_Buffer < Test::Unit::TestCase
|
7
|
+
SAMPLE_FILE = File.dirname( File.expand_path( __FILE__ ) ) + '/sample-file.rb'
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@d = Diakonos::Diakonos.new [ '-e', 'quit' ]
|
11
|
+
@d.start
|
12
|
+
end
|
13
|
+
|
14
|
+
def teardown
|
15
|
+
system "reset"
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_selected_text
|
19
|
+
@d.openFile( SAMPLE_FILE )
|
20
|
+
b = Diakonos::Buffer.new( @d, SAMPLE_FILE )
|
21
|
+
@d.anchorSelection
|
22
|
+
@d.cursorDown
|
23
|
+
@d.cursorDown
|
24
|
+
@d.cursorDown
|
25
|
+
@d.copySelection
|
26
|
+
assert_equal(
|
27
|
+
[
|
28
|
+
"#!/usr/bin/env ruby",
|
29
|
+
"",
|
30
|
+
"# This is only a sample file used in the tests.",
|
31
|
+
""
|
32
|
+
],
|
33
|
+
@d.clipboard.clip
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|