diakonos 0.8.11 → 0.9.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +439 -0
- data/LICENCE.md +675 -0
- data/bin/diakonos +6 -0
- data/diakonos-256-colour.conf +220 -0
- data/diakonos.conf +1802 -0
- data/help/about-help.dhf +31 -0
- data/help/clipboard.dhf +45 -0
- data/help/close-file.dhf +6 -0
- data/help/code-block-navigation.dhf +16 -0
- data/help/column-markers.dhf +15 -0
- data/help/config.dhf +69 -0
- data/help/cursor-stack.dhf +19 -0
- data/help/delete.dhf +41 -0
- data/help/extensions.dhf +125 -0
- data/help/file-type.dhf +24 -0
- data/help/key-mapping.dhf +127 -0
- data/help/line-numbers.dhf +22 -0
- data/help/macros.dhf +27 -0
- data/help/new-file.dhf +6 -0
- data/help/open-file.dhf +21 -0
- data/help/quit.dhf +7 -0
- data/help/resizing.dhf +19 -0
- data/help/ruby.dhf +17 -0
- data/help/save-file.dhf +10 -0
- data/help/scripting.dhf +92 -0
- data/help/search.dhf +103 -0
- data/help/shell.dhf +60 -0
- data/help/speed.dhf +23 -0
- data/help/support.dhf +15 -0
- data/help/switch-buffers.dhf +15 -0
- data/help/tabs.dhf +36 -0
- data/help/undo.dhf +9 -0
- data/help/uninstall.dhf +18 -0
- data/help/welcome.dhf +32 -0
- data/help/word-wrap.dhf +17 -0
- data/lib/diakonos/about.rb +70 -0
- data/lib/diakonos/bookmark.rb +46 -0
- data/lib/diakonos/buffer/bookmarking.rb +47 -0
- data/lib/diakonos/buffer/cursor.rb +335 -0
- data/lib/diakonos/buffer/delete.rb +170 -0
- data/lib/diakonos/buffer/display.rb +362 -0
- data/lib/diakonos/buffer/file.rb +157 -0
- data/lib/diakonos/buffer/indentation.rb +175 -0
- data/lib/diakonos/buffer/searching.rb +552 -0
- data/lib/diakonos/buffer/selection.rb +360 -0
- data/lib/diakonos/buffer/undo.rb +73 -0
- data/lib/diakonos/buffer-hash.rb +60 -0
- data/lib/diakonos/buffer-management.rb +59 -0
- data/lib/diakonos/buffer.rb +698 -0
- data/lib/diakonos/clipboard-klipper-dbus.rb +62 -0
- data/lib/diakonos/clipboard-klipper.rb +62 -0
- data/lib/diakonos/clipboard-osx.rb +59 -0
- data/lib/diakonos/clipboard-xclip.rb +60 -0
- data/lib/diakonos/clipboard.rb +47 -0
- data/lib/diakonos/config-file.rb +67 -0
- data/lib/diakonos/config.rb +382 -0
- data/lib/diakonos/core-ext/enumerable.rb +15 -0
- data/lib/diakonos/core-ext/hash.rb +60 -0
- data/lib/diakonos/core-ext/object.rb +6 -0
- data/lib/diakonos/core-ext/regexp.rb +6 -0
- data/lib/diakonos/core-ext/string.rb +122 -0
- data/lib/diakonos/ctag.rb +28 -0
- data/lib/diakonos/cursor.rb +27 -0
- data/lib/diakonos/display/format.rb +75 -0
- data/lib/diakonos/display.rb +336 -0
- data/lib/diakonos/extension-set.rb +49 -0
- data/lib/diakonos/extension.rb +34 -0
- data/lib/diakonos/finding.rb +40 -0
- data/lib/diakonos/functions/basics.rb +34 -0
- data/lib/diakonos/functions/bookmarking.rb +61 -0
- data/lib/diakonos/functions/buffers.rb +491 -0
- data/lib/diakonos/functions/clipboard.rb +70 -0
- data/lib/diakonos/functions/cursor.rb +264 -0
- data/lib/diakonos/functions/grepping.rb +83 -0
- data/lib/diakonos/functions/indentation.rb +71 -0
- data/lib/diakonos/functions/readline.rb +93 -0
- data/lib/diakonos/functions/search.rb +179 -0
- data/lib/diakonos/functions/selection.rb +98 -0
- data/lib/diakonos/functions/sessions.rb +78 -0
- data/lib/diakonos/functions/shell.rb +250 -0
- data/lib/diakonos/functions/tags.rb +65 -0
- data/lib/diakonos/functions/text-manipulation.rb +196 -0
- data/lib/diakonos/functions-deprecated.rb +77 -0
- data/lib/diakonos/functions.rb +292 -0
- data/lib/diakonos/grep.rb +98 -0
- data/lib/diakonos/help.rb +47 -0
- data/lib/diakonos/hooks.rb +13 -0
- data/lib/diakonos/installation.rb +19 -0
- data/lib/diakonos/interaction-handler.rb +216 -0
- data/lib/diakonos/interaction.rb +52 -0
- data/lib/diakonos/key-map.rb +62 -0
- data/lib/diakonos/keying.rb +442 -0
- data/lib/diakonos/line-mover.rb +42 -0
- data/lib/diakonos/list.rb +59 -0
- data/lib/diakonos/logging.rb +27 -0
- data/lib/diakonos/mode.rb +17 -0
- data/lib/diakonos/mouse.rb +18 -0
- data/lib/diakonos/number-fitter.rb +11 -0
- data/lib/diakonos/range.rb +31 -0
- data/lib/diakonos/readline/functions.rb +82 -0
- data/lib/diakonos/readline.rb +223 -0
- data/lib/diakonos/search.rb +58 -0
- data/lib/diakonos/sessions.rb +257 -0
- data/lib/diakonos/sized-array.rb +48 -0
- data/lib/diakonos/text-mark.rb +19 -0
- data/lib/diakonos/vendor/fuzzy_file_finder.rb +386 -0
- data/lib/diakonos/version.rb +25 -0
- data/lib/diakonos/window.rb +43 -0
- data/lib/diakonos.rb +592 -0
- metadata +160 -68
@@ -0,0 +1,216 @@
|
|
1
|
+
module Diakonos
|
2
|
+
TAB = 9
|
3
|
+
ENTER = 13
|
4
|
+
ESCAPE = 27
|
5
|
+
BACKSPACE = 127
|
6
|
+
CTRL_C = 3
|
7
|
+
CTRL_D = 4
|
8
|
+
CTRL_K = 11
|
9
|
+
CTRL_Q = 17
|
10
|
+
CTRL_H = 263
|
11
|
+
CTRL_W = 23
|
12
|
+
RESIZE2 = 4294967295
|
13
|
+
|
14
|
+
# TODO: Turn the CHOICE_* constants into one or more Hashes?
|
15
|
+
|
16
|
+
CHOICE_NO = 0
|
17
|
+
CHOICE_YES = 1
|
18
|
+
CHOICE_ALL = 2
|
19
|
+
CHOICE_CANCEL = 3
|
20
|
+
CHOICE_YES_TO_ALL = 4
|
21
|
+
CHOICE_NO_TO_ALL = 5
|
22
|
+
CHOICE_YES_AND_STOP = 6
|
23
|
+
CHOICE_DELETE = 7
|
24
|
+
CHOICE_WITHIN_SELECTION = 8
|
25
|
+
|
26
|
+
class InteractionHandler
|
27
|
+
CHOICE_STRINGS = [
|
28
|
+
'(n)o',
|
29
|
+
'(y)es',
|
30
|
+
'(a)ll',
|
31
|
+
'(c)ancel',
|
32
|
+
'y(e)s to all',
|
33
|
+
'n(o) to all',
|
34
|
+
'yes and (s)top',
|
35
|
+
'(d)elete',
|
36
|
+
'all (w)ithin selection',
|
37
|
+
]
|
38
|
+
CHOICE_KEYS = [
|
39
|
+
["n".ord, "N".ord],
|
40
|
+
["y".ord, "Y".ord],
|
41
|
+
["a".ord, "A".ord],
|
42
|
+
["c".ord, "C".ord, ESCAPE, CTRL_C, CTRL_D, CTRL_Q],
|
43
|
+
["e".ord],
|
44
|
+
["o".ord],
|
45
|
+
["s".ord],
|
46
|
+
["d".ord],
|
47
|
+
["w".ord],
|
48
|
+
]
|
49
|
+
|
50
|
+
# TODO: Move win_interaction creation, etc. into this class.
|
51
|
+
# If necessary, expose it with attr_reader
|
52
|
+
# e.g. for @modes[ 'input' ].window = @win_interaction
|
53
|
+
def initialize(
|
54
|
+
win_main:,
|
55
|
+
win_interaction:,
|
56
|
+
cursor_manager:,
|
57
|
+
testing: false,
|
58
|
+
choice_delay: 3,
|
59
|
+
blink_string: "*" * 60,
|
60
|
+
blink_duration: 0.05
|
61
|
+
)
|
62
|
+
@win_main = win_main
|
63
|
+
@win_interaction = win_interaction
|
64
|
+
@cursor_manager = cursor_manager
|
65
|
+
@testing = testing
|
66
|
+
|
67
|
+
@choice_iterations = 0
|
68
|
+
@choice_delay = choice_delay
|
69
|
+
@blink_string = blink_string
|
70
|
+
@blink_duration = blink_duration
|
71
|
+
end
|
72
|
+
|
73
|
+
# Display text on the interaction line.
|
74
|
+
def set_iline(string = "")
|
75
|
+
return 0 if @testing
|
76
|
+
return 0 if $diakonos.readline
|
77
|
+
|
78
|
+
@iline = string
|
79
|
+
Curses::curs_set 0
|
80
|
+
@win_interaction.setpos( 0, 0 )
|
81
|
+
@win_interaction.addstr( "%-#{Curses::cols}s" % @iline )
|
82
|
+
@win_interaction.refresh
|
83
|
+
Curses::curs_set 1
|
84
|
+
string.length
|
85
|
+
end
|
86
|
+
|
87
|
+
def set_iline_if_empty(string)
|
88
|
+
if @iline.nil? || @iline.empty?
|
89
|
+
set_iline string
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def get_char(prompt)
|
94
|
+
set_iline prompt
|
95
|
+
char = @win_main.getch
|
96
|
+
set_iline
|
97
|
+
char
|
98
|
+
end
|
99
|
+
|
100
|
+
# choices should be an array of CHOICE_* constants.
|
101
|
+
# default is what is returned when Enter is pressed.
|
102
|
+
def get_choice( prompt, choices, default = nil )
|
103
|
+
retval = @iterated_choice
|
104
|
+
if retval
|
105
|
+
@choice_iterations -= 1
|
106
|
+
if @choice_iterations < 1
|
107
|
+
@iterated_choice = nil
|
108
|
+
$diakonos.do_display = true
|
109
|
+
end
|
110
|
+
return retval
|
111
|
+
end
|
112
|
+
|
113
|
+
@saved_main_x = @win_main.curx
|
114
|
+
@saved_main_y = @win_main.cury
|
115
|
+
|
116
|
+
msg = prompt + " "
|
117
|
+
choice_strings = choices.collect do |choice|
|
118
|
+
CHOICE_STRINGS[ choice ]
|
119
|
+
end
|
120
|
+
msg << choice_strings.join( ", " )
|
121
|
+
|
122
|
+
if default
|
123
|
+
set_iline msg
|
124
|
+
else
|
125
|
+
show_message msg
|
126
|
+
end
|
127
|
+
|
128
|
+
while retval.nil?
|
129
|
+
ch = @win_interaction.getch
|
130
|
+
if ch
|
131
|
+
c = ch.ord
|
132
|
+
else
|
133
|
+
next
|
134
|
+
end
|
135
|
+
|
136
|
+
case c
|
137
|
+
when Curses::KEY_NPAGE
|
138
|
+
@cursor_manager.page_down
|
139
|
+
when Curses::KEY_PPAGE
|
140
|
+
@cursor_manager.page_up
|
141
|
+
else
|
142
|
+
if @message_expiry && Time.now < @message_expiry
|
143
|
+
interaction_blink
|
144
|
+
show_message msg
|
145
|
+
else
|
146
|
+
case c
|
147
|
+
when ENTER
|
148
|
+
retval = default
|
149
|
+
when '0'.ord..'9'.ord
|
150
|
+
if @choice_iterations < 1
|
151
|
+
@choice_iterations = ( c - '0'.ord )
|
152
|
+
else
|
153
|
+
@choice_iterations = @choice_iterations * 10 + ( c - '0'.ord )
|
154
|
+
end
|
155
|
+
else
|
156
|
+
choices.each do |choice|
|
157
|
+
if CHOICE_KEYS[ choice ].include? c
|
158
|
+
retval = choice
|
159
|
+
break
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
if retval.nil?
|
165
|
+
interaction_blink( msg )
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
terminate_message
|
172
|
+
set_iline
|
173
|
+
|
174
|
+
if @choice_iterations > 0
|
175
|
+
@choice_iterations -= 1
|
176
|
+
@iterated_choice = retval
|
177
|
+
$diakonos.do_display = false
|
178
|
+
end
|
179
|
+
|
180
|
+
retval
|
181
|
+
end
|
182
|
+
|
183
|
+
private
|
184
|
+
|
185
|
+
def show_message( message, non_interaction_duration = @choice_delay )
|
186
|
+
terminate_message
|
187
|
+
|
188
|
+
@message_expiry = Time.now + non_interaction_duration
|
189
|
+
@message_thread = Thread.new do
|
190
|
+
time_left = @message_expiry - Time.now
|
191
|
+
while time_left > 0
|
192
|
+
set_iline "(#{time_left.round}) #{message}"
|
193
|
+
@win_main.setpos( @saved_main_y, @saved_main_x )
|
194
|
+
sleep 1
|
195
|
+
time_left = @message_expiry - Time.now
|
196
|
+
end
|
197
|
+
set_iline message
|
198
|
+
@win_main.setpos( @saved_main_y, @saved_main_x )
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def terminate_message
|
203
|
+
if @message_thread && @message_thread.alive?
|
204
|
+
@message_thread.terminate
|
205
|
+
@message_thread = nil
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def interaction_blink( message = nil )
|
210
|
+
terminate_message
|
211
|
+
set_iline @blink_string
|
212
|
+
sleep @blink_duration
|
213
|
+
set_iline message if message
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Diakonos
|
2
|
+
DONT_COMPLETE = false
|
3
|
+
|
4
|
+
class Diakonos
|
5
|
+
attr_reader :readline
|
6
|
+
|
7
|
+
# completion_array is the array of strings that tab completion can use
|
8
|
+
# @param options :initial_text, :completion_array, :history, :do_complete, :on_dirs
|
9
|
+
def get_user_input( prompt, options = {}, &block )
|
10
|
+
if @playing_macro
|
11
|
+
return @macro_input_history.shift
|
12
|
+
end
|
13
|
+
|
14
|
+
options[ :history ] ||= @rlh_general
|
15
|
+
options[ :initial_text ] ||= ""
|
16
|
+
options[ :do_complete ] ||= DONT_COMPLETE
|
17
|
+
options[ :on_dirs ] ||= :go_into_dirs
|
18
|
+
will_display_after_select = options.fetch( :will_display_after_select, false )
|
19
|
+
|
20
|
+
cursor_pos = set_iline( prompt )
|
21
|
+
@readline = Readline.new(
|
22
|
+
list_manager: self,
|
23
|
+
keystroke_processor: self,
|
24
|
+
testing: @testing,
|
25
|
+
window: @win_interaction,
|
26
|
+
start_pos: cursor_pos,
|
27
|
+
options: options,
|
28
|
+
&block
|
29
|
+
)
|
30
|
+
|
31
|
+
retval = @readline.get_input
|
32
|
+
if will_display_after_select
|
33
|
+
close_list_buffer do_display: ! retval
|
34
|
+
else
|
35
|
+
close_list_buffer
|
36
|
+
end
|
37
|
+
options[ :history ][ -1 ] = @readline.input
|
38
|
+
@readline = nil
|
39
|
+
|
40
|
+
if @macro_history
|
41
|
+
@macro_input_history.push retval
|
42
|
+
end
|
43
|
+
set_iline
|
44
|
+
|
45
|
+
retval
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_choice(*args)
|
49
|
+
@interaction_handler.get_choice *args
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Diakonos
|
2
|
+
module KeyMap
|
3
|
+
|
4
|
+
# path is an array of hash keys
|
5
|
+
# This method deletes a path of hash keys, with each step in the path
|
6
|
+
# being a recursively deeper key in a hash tree.
|
7
|
+
# Returns the possibly modified hash.
|
8
|
+
def delete_key_path( path )
|
9
|
+
if path.length > 1
|
10
|
+
subtree = self[ path[ 0 ] ]
|
11
|
+
if subtree.respond_to?( :delete_key_path )
|
12
|
+
subtree.delete_key_path( path[ 1..-1 ] )
|
13
|
+
if subtree.empty?
|
14
|
+
delete( path[ 0 ] )
|
15
|
+
end
|
16
|
+
end
|
17
|
+
elsif path.length == 1
|
18
|
+
delete( path[ 0 ] )
|
19
|
+
end
|
20
|
+
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def set_key_path( path, leaf )
|
25
|
+
if path.length > 1
|
26
|
+
node = self[ path[ 0 ] ]
|
27
|
+
if ! node.respond_to?( :set_key_path )
|
28
|
+
node = self[ path[ 0 ] ] = {}.extend( KeyMap )
|
29
|
+
end
|
30
|
+
node.set_key_path( path[ 1..-1 ], leaf )
|
31
|
+
elsif path.length == 1
|
32
|
+
self[ path[ 0 ] ] = leaf
|
33
|
+
end
|
34
|
+
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_node( path )
|
39
|
+
node = self[ path[ 0 ] ]
|
40
|
+
if path.length > 1
|
41
|
+
if node && node.respond_to?( :get_node )
|
42
|
+
return node.get_node( path[ 1..-1 ] )
|
43
|
+
end
|
44
|
+
elsif path.length == 1
|
45
|
+
return node
|
46
|
+
end
|
47
|
+
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_leaf( path )
|
52
|
+
node = get_node( path )
|
53
|
+
if node.respond_to?( :get_node )
|
54
|
+
# Only want a leaf node
|
55
|
+
nil
|
56
|
+
else
|
57
|
+
node
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|