diakonos 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,47 @@
1
+ module Diakonos
2
+
3
+ class Clipboard
4
+ def initialize( max_clips )
5
+ @clips = Array.new
6
+ @max_clips = max_clips
7
+ end
8
+
9
+ def [] ( arg )
10
+ return @clips[ arg ]
11
+ end
12
+
13
+ def clip
14
+ return @clips[ 0 ]
15
+ end
16
+
17
+ # text is an array of Strings
18
+ # Returns true iff a clip was added,
19
+ # and only non-nil text can be added.
20
+ def addClip( text )
21
+ return false if text == nil
22
+ @clips.unshift text
23
+ @clips.pop if @clips.length > @max_clips
24
+ return true
25
+ end
26
+
27
+ def each
28
+ @clips.each do |clip|
29
+ yield clip
30
+ end
31
+ end
32
+
33
+ # text is an array of Strings (lines)
34
+ # Appends the lines to the current clip.
35
+ # If no current clip, then a new clip is created.
36
+ # Returns true iff the text was successfully appended.
37
+ def appendToClip( text )
38
+ return false if text.nil?
39
+ return addClip( text ) if @clips.length == 0
40
+ last_clip = @clips[ 0 ]
41
+ last_clip.pop if last_clip[ -1 ] == ""
42
+ @clips[ 0 ] = last_clip + text
43
+ return true
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,28 @@
1
+ module Diakonos
2
+
3
+ class CTag
4
+ attr_reader :file, :command, :kind, :rest
5
+
6
+ def initialize( file, command, kind, rest )
7
+ @file = file
8
+ @command = command
9
+ @kind = kind
10
+ @rest = rest
11
+ end
12
+
13
+ def to_s
14
+ return "#{@file}:#{@command} (#{@kind}) #{@rest}"
15
+ end
16
+
17
+ def == ( other )
18
+ return (
19
+ other != nil and
20
+ @file == other.file and
21
+ @command == other.command and
22
+ @kind == other.kind and
23
+ @rest == other.rest
24
+ )
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,15 @@
1
+ module Enumerable
2
+ # Returns [array-index, string-index, string-index] triples for each match.
3
+ def grep_indices( regexp )
4
+ array = Array.new
5
+ each_with_index do |element,index|
6
+ element.scan( regexp ) do |match_text|
7
+ match = Regexp.last_match
8
+ strindex = match.begin( 0 )
9
+ array.push [ index, strindex, strindex + match_text.length ]
10
+ end
11
+ end
12
+ return array
13
+ end
14
+ end
15
+
@@ -0,0 +1,32 @@
1
+ module Diakonos
2
+
3
+ class Finding
4
+ attr_reader :start_row, :start_col, :end_row, :end_col
5
+ attr_writer :end_row, :end_col
6
+
7
+ def initialize( start_row, start_col, end_row, end_col )
8
+ @start_row = start_row
9
+ @start_col = start_col
10
+ @end_row = end_row
11
+ @end_col = end_col
12
+ end
13
+
14
+ def match( regexps, lines )
15
+ retval = true
16
+
17
+ i = @start_row + 1
18
+ regexps[ 1..-1 ].each do |re|
19
+ if lines[ i ] !~ re
20
+ retval = false
21
+ break
22
+ end
23
+ @end_row = i
24
+ @end_col = Regexp.last_match[ 0 ].length
25
+ i += 1
26
+ end
27
+
28
+ return retval
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,13 @@
1
+ require 'diakonos/keycode'
2
+
3
+ class Fixnum
4
+ include Diakonos::KeyCode
5
+
6
+ def fit( min, max )
7
+ return self if max < min
8
+ return min if self < min
9
+ return max if self > max
10
+ return self
11
+ end
12
+ end
13
+
@@ -0,0 +1,101 @@
1
+ class Hash
2
+ # path is an array of hash keys
3
+ # This method deletes a path of hash keys, with each step in the path
4
+ # being a recursively deeper key in a hash tree.
5
+ # Returns the possibly modified hash.
6
+ def deleteKeyPath( path )
7
+ if path.length > 1
8
+ subtree = self[ path[ 0 ] ]
9
+ if subtree.respond_to?( :deleteKeyPath )
10
+ subtree.deleteKeyPath( path[ 1..-1 ] )
11
+ if subtree.empty?
12
+ delete( path[ 0 ] )
13
+ end
14
+ end
15
+ elsif path.length == 1
16
+ delete( path[ 0 ] )
17
+ end
18
+
19
+ return self
20
+ end
21
+
22
+ def setKeyPath( path, leaf )
23
+ if path.length > 1
24
+ node = self[ path[ 0 ] ]
25
+ if not node.respond_to?( :setKeyPath )
26
+ node = self[ path[ 0 ] ] = Hash.new
27
+ end
28
+ node.setKeyPath( path[ 1..-1 ], leaf )
29
+ elsif path.length == 1
30
+ self[ path[ 0 ] ] = leaf
31
+ end
32
+
33
+ return self
34
+ end
35
+
36
+ def getNode( path )
37
+ node = self[ path[ 0 ] ]
38
+ if path.length > 1
39
+ if node != nil and node.respond_to?( :getNode )
40
+ return node.getNode( path[ 1..-1 ] )
41
+ end
42
+ elsif path.length == 1
43
+ return node
44
+ end
45
+
46
+ return nil
47
+ end
48
+
49
+ def getLeaf( path )
50
+ node = getNode( path )
51
+ if node.respond_to?( :getNode )
52
+ # Only want a leaf node
53
+ return nil
54
+ else
55
+ return node
56
+ end
57
+ end
58
+
59
+ def leaves( _leaves = Set.new )
60
+ each_value do |value|
61
+ if value.respond_to?( :leaves )
62
+ _leaves.merge value.leaves( _leaves )
63
+ else
64
+ _leaves << value
65
+ end
66
+ end
67
+
68
+ return _leaves
69
+ end
70
+
71
+ def paths_and_leaves( path_so_far = [], _paths_and_leaves = Set.new )
72
+ each do |key, value|
73
+ if value.respond_to?( :paths_and_leaves )
74
+ _paths_and_leaves.merge(
75
+ value.paths_and_leaves(
76
+ path_so_far + [ key ],
77
+ _paths_and_leaves
78
+ )
79
+ )
80
+ else
81
+ _paths_and_leaves << {
82
+ :path => path_so_far + [ key ],
83
+ :leaf => value
84
+ }
85
+ end
86
+ end
87
+
88
+ return _paths_and_leaves
89
+ end
90
+
91
+ def each_path_and_leaf( path_so_far = [] )
92
+ each do |key, value|
93
+ if value.respond_to?( :each_path_and_leaf )
94
+ value.each_path_and_leaf( path_so_far + [ key ] ) { |path, leaf| yield( path, leaf ) }
95
+ else
96
+ yield( path_so_far + [ key ], value )
97
+ end
98
+ end
99
+ end
100
+ end
101
+
@@ -0,0 +1,110 @@
1
+ module Diakonos
2
+
3
+ module KeyCode
4
+ KEYSTRINGS = [
5
+ "ctrl+space", # 0
6
+ "ctrl+a", # 1
7
+ "ctrl+b", # 2
8
+ "ctrl+c", # 3
9
+ "ctrl+d", # 4
10
+ "ctrl+e", # 5
11
+ "ctrl+f", # 6
12
+ "ctrl+g", # 7
13
+ nil, # 8
14
+ "tab", # 9
15
+ "ctrl+j", # 10
16
+ "ctrl+k", # 11
17
+ "ctrl+l", # 12
18
+ "enter", # 13
19
+ "ctrl+n", # 14
20
+ "ctrl+o", # 15
21
+ "ctrl+p", # 16
22
+ "ctrl+q", # 17
23
+ "ctrl+r", # 18
24
+ "ctrl+s", # 19
25
+ "ctrl+t", # 20
26
+ "ctrl+u", # 21
27
+ "ctrl+v", # 22
28
+ "ctrl+w", # 23
29
+ "ctrl+x", # 24
30
+ "ctrl+y", # 25
31
+ "ctrl+z", # 26
32
+ "esc", # 27
33
+ nil, # 28
34
+ nil, # 29
35
+ nil, # 30
36
+ nil, # 31
37
+ "space", # 32
38
+ 33.chr, 34.chr, 35.chr, 36.chr, 37.chr, 38.chr, 39.chr,
39
+ 40.chr, 41.chr, 42.chr, 43.chr, 44.chr, 45.chr, 46.chr, 47.chr, 48.chr, 49.chr,
40
+ 50.chr, 51.chr, 52.chr, 53.chr, 54.chr, 55.chr, 56.chr, 57.chr, 58.chr, 59.chr,
41
+ 60.chr, 61.chr, 62.chr, 63.chr, 64.chr, 65.chr, 66.chr, 67.chr, 68.chr, 69.chr,
42
+ 70.chr, 71.chr, 72.chr, 73.chr, 74.chr, 75.chr, 76.chr, 77.chr, 78.chr, 79.chr,
43
+ 80.chr, 81.chr, 82.chr, 83.chr, 84.chr, 85.chr, 86.chr, 87.chr, 88.chr, 89.chr,
44
+ 90.chr, 91.chr, 92.chr, 93.chr, 94.chr, 95.chr, 96.chr, 97.chr, 98.chr, 99.chr,
45
+ 100.chr, 101.chr, 102.chr, 103.chr, 104.chr, 105.chr, 106.chr, 107.chr, 108.chr, 109.chr,
46
+ 110.chr, 111.chr, 112.chr, 113.chr, 114.chr, 115.chr, 116.chr, 117.chr, 118.chr, 119.chr,
47
+ 120.chr, 121.chr, 122.chr, 123.chr, 124.chr, 125.chr, 126.chr,
48
+ "backspace" # 127
49
+ ]
50
+
51
+ def keyString
52
+ if self.class == Fixnum
53
+ retval = KEYSTRINGS[ self ]
54
+ end
55
+ if retval == nil
56
+ case self
57
+ when Curses::KEY_DOWN
58
+ retval = "down"
59
+ when Curses::KEY_UP
60
+ retval = "up"
61
+ when Curses::KEY_LEFT
62
+ retval = "left"
63
+ when Curses::KEY_RIGHT
64
+ retval = "right"
65
+ when Curses::KEY_HOME
66
+ retval = "home"
67
+ when Curses::KEY_END
68
+ retval = "end"
69
+ when Curses::KEY_IC
70
+ retval = "insert"
71
+ when Curses::KEY_DC
72
+ retval = "delete"
73
+ when Curses::KEY_PPAGE
74
+ retval = "page-up"
75
+ when Curses::KEY_NPAGE
76
+ retval = "page-down"
77
+ when Curses::KEY_A1
78
+ retval = "numpad7"
79
+ when Curses::KEY_A3
80
+ retval = "numpad9"
81
+ when Curses::KEY_B2
82
+ retval = "numpad5"
83
+ when Curses::KEY_C1
84
+ retval = "numpad1"
85
+ when Curses::KEY_C3
86
+ retval = "numpad3"
87
+ when Curses::KEY_FIND
88
+ retval = "find"
89
+ when Curses::KEY_SELECT
90
+ retval = "select"
91
+ when Curses::KEY_SUSPEND
92
+ retval = "suspend"
93
+ when Curses::KEY_F0..(Curses::KEY_F0 + 24)
94
+ retval = "f" + (self - Curses::KEY_F0).to_s
95
+ when CTRL_H
96
+ retval = "ctrl+h"
97
+ when Curses::KEY_RESIZE
98
+ retval = "resize"
99
+ when RESIZE2
100
+ retval = "resize2"
101
+ end
102
+ end
103
+ if retval == nil and self.class == Fixnum
104
+ retval = "keycode#{self}"
105
+ end
106
+ return retval
107
+ end
108
+ end
109
+
110
+ end
@@ -0,0 +1,6 @@
1
+ class Object
2
+ def deep_clone
3
+ Marshal::load( Marshal.dump( self ) )
4
+ end
5
+ end
6
+
@@ -0,0 +1,192 @@
1
+ module Diakonos
2
+
3
+ class Readline
4
+
5
+ # completion_array is the array of strings that tab completion can use
6
+ def initialize( diakonos, window, initial_text = "", completion_array = nil, history = [] )
7
+ @window = window
8
+ @diakonos = diakonos
9
+ @initial_text = initial_text
10
+ @completion_array = completion_array
11
+ @list_filename = @diakonos.list_filename
12
+
13
+ @history = history
14
+ @history << initial_text
15
+ @history_index = @history.length - 1
16
+ end
17
+
18
+ # Returns nil on cancel.
19
+ def readline
20
+ @input = @initial_text
21
+ @icurx = @window.curx
22
+ @icury = @window.cury
23
+ @window.addstr @initial_text
24
+ @input_cursor = @initial_text.length
25
+ @opened_list_file = false
26
+
27
+ loop do
28
+ c = @window.getch
29
+
30
+ case c
31
+ when Curses::KEY_DC
32
+ if @input_cursor < @input.length
33
+ @window.delch
34
+ @input = @input[ 0...@input_cursor ] + @input[ (@input_cursor + 1)..-1 ]
35
+ end
36
+ when BACKSPACE, CTRL_H
37
+ # Curses::KEY_LEFT
38
+ if @input_cursor > 0
39
+ @input_cursor += -1
40
+ @window.setpos( @window.cury, @window.curx - 1 )
41
+
42
+ # Curses::KEY_DC
43
+ if @input_cursor < @input.length
44
+ @window.delch
45
+ @input = @input[ 0...@input_cursor ] + @input[ (@input_cursor + 1)..-1 ]
46
+ end
47
+ end
48
+ when ENTER
49
+ break
50
+ when ESCAPE, CTRL_C, CTRL_D, CTRL_Q
51
+ @input = nil
52
+ break
53
+ when Curses::KEY_LEFT
54
+ if @input_cursor > 0
55
+ @input_cursor += -1
56
+ @window.setpos( @window.cury, @window.curx - 1 )
57
+ end
58
+ when Curses::KEY_RIGHT
59
+ if @input_cursor < @input.length
60
+ @input_cursor += 1
61
+ @window.setpos( @window.cury, @window.curx + 1 )
62
+ end
63
+ when Curses::KEY_HOME
64
+ @input_cursor = 0
65
+ @window.setpos( @icury, @icurx )
66
+ when Curses::KEY_END
67
+ @input_cursor = @input.length
68
+ @window.setpos( @window.cury, @icurx + @input.length )
69
+ when TAB
70
+ completeInput
71
+ when Curses::KEY_NPAGE
72
+ @diakonos.pageDown
73
+ when Curses::KEY_PPAGE
74
+ @diakonos.pageUp
75
+ when Curses::KEY_UP
76
+ if @history_index > 0
77
+ @history[ @history_index ] = @input
78
+ @history_index -= 1
79
+ @input = @history[ @history_index ]
80
+ cursorWriteInput
81
+ end
82
+ when Curses::KEY_DOWN
83
+ if @history_index < @history.length - 1
84
+ @history[ @history_index ] = @input
85
+ @history_index += 1
86
+ @input = @history[ @history_index ]
87
+ cursorWriteInput
88
+ end
89
+ when CTRL_K
90
+ @input = ""
91
+ cursorWriteInput
92
+ else
93
+ if c > 31 and c < 255 and c != BACKSPACE
94
+ if @input_cursor == @input.length
95
+ @input << c
96
+ @window.addch c
97
+ else
98
+ @input = @input[ 0...@input_cursor ] + c.chr + @input[ @input_cursor..-1 ]
99
+ @window.setpos( @window.cury, @window.curx + 1 )
100
+ redrawInput
101
+ end
102
+ @input_cursor += 1
103
+ else
104
+ @diakonos.log "Other input: #{c}"
105
+ end
106
+ end
107
+ end
108
+
109
+ @diakonos.closeListBuffer
110
+
111
+ @history[ -1 ] = @input
112
+
113
+ return @input
114
+ end
115
+
116
+ def redrawInput
117
+ curx = @window.curx
118
+ cury = @window.cury
119
+ @window.setpos( @icury, @icurx )
120
+ @window.addstr "%-#{ Curses::cols - curx }s%s" % [ @input, " " * ( Curses::cols - @input.length ) ]
121
+ @window.setpos( cury, curx )
122
+ @window.refresh
123
+ end
124
+
125
+ # Redisplays the input text starting at the start of the user input area,
126
+ # positioning the cursor at the end of the text.
127
+ def cursorWriteInput
128
+ if @input != nil
129
+ @input_cursor = @input.length
130
+ @window.setpos( @window.cury, @icurx + @input.length )
131
+ redrawInput
132
+ end
133
+ end
134
+
135
+ def completeInput
136
+ if @completion_array != nil and @input.length > 0
137
+ len = @input.length
138
+ matches = @completion_array.find_all { |el| el[ 0...len ] == @input and len < el.length }
139
+ else
140
+ matches = Dir.glob( ( @input.subHome() + "*" ).gsub( /\*\*/, "*" ) )
141
+ end
142
+
143
+ if matches.length == 1
144
+ @input = matches[ 0 ]
145
+ cursorWriteInput
146
+ File.open( @list_filename, "w" ) do |f|
147
+ f.puts "(unique)"
148
+ end
149
+ if @completion_array == nil and FileTest.directory?( @input )
150
+ @input << "/"
151
+ cursorWriteInput
152
+ completeInput
153
+ end
154
+ elsif matches.length > 1
155
+ common = matches[ 0 ]
156
+ File.open( @list_filename, "w" ) do |f|
157
+ i = nil
158
+ matches.each do |match|
159
+ f.puts match
160
+
161
+ if match[ 0 ] != common[ 0 ]
162
+ common = nil
163
+ break
164
+ end
165
+
166
+ up_to = [ common.length - 1, match.length - 1 ].min
167
+ i = 1
168
+ while ( i <= up_to ) and ( match[ 0..i ] == common[ 0..i ] )
169
+ i += 1
170
+ end
171
+ common = common[ 0...i ]
172
+ end
173
+ end
174
+ if common == nil
175
+ File.open( @list_filename, "w" ) do |f|
176
+ f.puts "(no matches)"
177
+ end
178
+ else
179
+ @input = common
180
+ cursorWriteInput
181
+ end
182
+ else
183
+ File.open( @list_filename, "w" ) do |f|
184
+ f.puts "(no matches)"
185
+ end
186
+ end
187
+ @diakonos.openListBuffer
188
+ @window.setpos( @window.cury, @window.curx )
189
+ end
190
+ end
191
+
192
+ end