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,98 @@
|
|
1
|
+
module Diakonos
|
2
|
+
module Functions
|
3
|
+
|
4
|
+
# Begins selecting text by anchoring (marking) the start of a selection.
|
5
|
+
def anchor_selection
|
6
|
+
buffer_current.anchor_selection
|
7
|
+
update_status_line
|
8
|
+
end
|
9
|
+
|
10
|
+
# Used for "shift+arrow" style selection.
|
11
|
+
def anchor_unanchored_selection( *method_and_args )
|
12
|
+
buffer_current.anchor_unanchored_selection
|
13
|
+
if method_and_args[0]
|
14
|
+
self.send method_and_args[0], *method_and_args[1..-1]
|
15
|
+
end
|
16
|
+
update_status_line
|
17
|
+
end
|
18
|
+
|
19
|
+
# Removes the highlighting from any text that matches the most recent
|
20
|
+
# search.
|
21
|
+
def clear_matches
|
22
|
+
buffer_current.clear_matches Buffer::DO_DISPLAY
|
23
|
+
end
|
24
|
+
|
25
|
+
# Unselects any current selection (stops selecting).
|
26
|
+
def remove_selection
|
27
|
+
buffer_current.remove_selection
|
28
|
+
update_status_line
|
29
|
+
end
|
30
|
+
|
31
|
+
# Selects the entire buffer contents.
|
32
|
+
def select_all
|
33
|
+
buffer_current.select_all
|
34
|
+
end
|
35
|
+
|
36
|
+
# Selects text between two regexps.
|
37
|
+
def select_block( beginning = nil, ending = nil, including_ending = true )
|
38
|
+
if beginning.nil?
|
39
|
+
input = get_user_input( "Start at regexp: " )
|
40
|
+
if input
|
41
|
+
beginning = Regexp.new input
|
42
|
+
end
|
43
|
+
end
|
44
|
+
if beginning && ending.nil?
|
45
|
+
input = get_user_input( "End before regexp: " )
|
46
|
+
if input
|
47
|
+
ending = Regexp.new input
|
48
|
+
end
|
49
|
+
end
|
50
|
+
if beginning && ending
|
51
|
+
buffer_current.select( beginning, ending, including_ending )
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Changes selection mode to block mode (rectangular selection).
|
56
|
+
def selection_mode_block
|
57
|
+
buffer_current.selection_mode_block
|
58
|
+
update_status_line
|
59
|
+
end
|
60
|
+
|
61
|
+
# Changes selection mode to normal mode (flow selection).
|
62
|
+
def selection_mode_normal
|
63
|
+
buffer_current.selection_mode_normal
|
64
|
+
update_status_line
|
65
|
+
end
|
66
|
+
|
67
|
+
# If currently selecting, stops selecting.
|
68
|
+
# If not currently selecting, begins selecting.
|
69
|
+
def toggle_selection
|
70
|
+
buffer_current.toggle_selection
|
71
|
+
update_status_line
|
72
|
+
end
|
73
|
+
|
74
|
+
# Selects the current line.
|
75
|
+
def select_line
|
76
|
+
buffer_current.select_current_line
|
77
|
+
update_status_line
|
78
|
+
end
|
79
|
+
|
80
|
+
# Selects the code block which wraps the current cursor position.
|
81
|
+
# Execute multiple times in succession to select increasingly outer code blocks.
|
82
|
+
def select_wrapping_block
|
83
|
+
buffer_current.select_wrapping_block
|
84
|
+
update_status_line
|
85
|
+
end
|
86
|
+
|
87
|
+
# Selects the word at the current cursor position.
|
88
|
+
# If the cursor is not on a word character, the first word following the cursor is selected.
|
89
|
+
def select_word
|
90
|
+
buffer_current.select_word
|
91
|
+
end
|
92
|
+
|
93
|
+
def select_word_another
|
94
|
+
buffer_current.select_word_another
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Diakonos
|
2
|
+
module Functions
|
3
|
+
|
4
|
+
def merge_session_settings
|
5
|
+
@settings.merge! @session.settings
|
6
|
+
end
|
7
|
+
|
8
|
+
def change_session_setting( key_ = nil, value = nil, do_redraw = DONT_REDRAW )
|
9
|
+
if key_.nil?
|
10
|
+
key = get_user_input( "Setting: " )
|
11
|
+
else
|
12
|
+
key = key_
|
13
|
+
end
|
14
|
+
|
15
|
+
if key
|
16
|
+
if value.nil?
|
17
|
+
value = get_user_input( "Value: " )
|
18
|
+
end
|
19
|
+
case @settings[ key ]
|
20
|
+
when String
|
21
|
+
value = value.to_s
|
22
|
+
when Integer
|
23
|
+
value = value.to_i
|
24
|
+
when TrueClass, FalseClass
|
25
|
+
value = value.to_b
|
26
|
+
end
|
27
|
+
@session.settings[ key ] = value
|
28
|
+
merge_session_settings
|
29
|
+
redraw if do_redraw
|
30
|
+
set_iline "#{key} = #{value}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def name_session
|
35
|
+
name = get_user_input( 'Session name: ' )
|
36
|
+
if name
|
37
|
+
@session = Session.new("#{@session_dir}/#{name}")
|
38
|
+
save_session
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def set_session_dir
|
43
|
+
path = get_user_input(
|
44
|
+
"Session directory: ",
|
45
|
+
history: @rlh_files,
|
46
|
+
initial_text: @session.dir,
|
47
|
+
do_complete: DONT_COMPLETE,
|
48
|
+
on_dirs: :accept_dirs
|
49
|
+
)
|
50
|
+
if path
|
51
|
+
@session.dir = File.expand_path( path )
|
52
|
+
save_session
|
53
|
+
set_iline "Session dir changed to: #{@session.dir}"
|
54
|
+
else
|
55
|
+
set_iline "(Session dir is: #{@session.dir})"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def toggle_session_setting( key_ = nil, do_redraw = DONT_REDRAW )
|
60
|
+
key = key_ || get_user_input( "Setting: " )
|
61
|
+
return if key.nil?
|
62
|
+
|
63
|
+
value = nil
|
64
|
+
if @session.settings[ key ].class == TrueClass || @session.settings[ key ].class == FalseClass
|
65
|
+
value = ! @session.settings[ key ]
|
66
|
+
elsif @settings[ key ].class == TrueClass || @settings[ key ].class == FalseClass
|
67
|
+
value = ! @settings[ key ]
|
68
|
+
end
|
69
|
+
if value != nil # explicitly true or false
|
70
|
+
@session.settings[ key ] = value
|
71
|
+
merge_session_settings
|
72
|
+
redraw if do_redraw
|
73
|
+
set_iline "#{key} = #{value}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,250 @@
|
|
1
|
+
module Diakonos
|
2
|
+
module Functions
|
3
|
+
|
4
|
+
# Change the current working directory (CWD) of the Diakonos process.
|
5
|
+
# @param [String] dir The directory to change to
|
6
|
+
def chdir( dir = nil )
|
7
|
+
dir ||= get_user_input( "Change to directory: ", initial_text: Dir.pwd )
|
8
|
+
if dir
|
9
|
+
Dir.chdir dir
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Substitutes Diakonos shell variables in a String.
|
14
|
+
# - $f: The current buffer's filename
|
15
|
+
# - $d: The current buffer's directory
|
16
|
+
# - $F: A space-separated list of all buffer filenames
|
17
|
+
# - $i: A string acquired from the user with a prompt
|
18
|
+
# - $c: The current clipboard text
|
19
|
+
# - $s: The currently selected text
|
20
|
+
# @param [String] string
|
21
|
+
# The string containing variables to substitute
|
22
|
+
# @return [String]
|
23
|
+
# A new String with values substituted for all variables
|
24
|
+
def sub_shell_variables( string )
|
25
|
+
return if string.nil?
|
26
|
+
|
27
|
+
retval = string.dup
|
28
|
+
|
29
|
+
# Current buffer filename
|
30
|
+
retval.gsub!( /\$f/, ( $1 || "" ) + File.expand_path( buffer_current.name || "" ) )
|
31
|
+
# Current buffer dir
|
32
|
+
retval.gsub!( /\$d/, ( $1 || "" ) + File.dirname( File.expand_path( buffer_current.name || '' ) ) )
|
33
|
+
|
34
|
+
# space-separated list of all buffer filenames
|
35
|
+
name_array = Array.new
|
36
|
+
@buffers.each do |b|
|
37
|
+
name_array.push b.name
|
38
|
+
end
|
39
|
+
retval.gsub!( /\$F/, ( $1 || "" ) + ( name_array.join(' ') || "" ) )
|
40
|
+
|
41
|
+
# Get user input, sub it in
|
42
|
+
if retval =~ /\$i/
|
43
|
+
user_input = get_user_input(
|
44
|
+
"Argument: ",
|
45
|
+
history: @rlh_shell,
|
46
|
+
initial_text: buffer_current.selected_string
|
47
|
+
)
|
48
|
+
retval.gsub!( /\$i/, user_input )
|
49
|
+
end
|
50
|
+
|
51
|
+
# Current clipboard text
|
52
|
+
if retval =~ /\$[ck]/
|
53
|
+
clip_filename = @diakonos_home + "/clip.txt"
|
54
|
+
File.open( clip_filename, "w" ) do |clipfile|
|
55
|
+
if @clipboard.clip
|
56
|
+
clipfile.puts( @clipboard.clip.join( "\n" ) )
|
57
|
+
end
|
58
|
+
end
|
59
|
+
retval.gsub!( /\$[ck]/, clip_filename )
|
60
|
+
end
|
61
|
+
|
62
|
+
# Currently selected text
|
63
|
+
if retval =~ /\$s/
|
64
|
+
text_filename = @diakonos_home + "/selected.txt"
|
65
|
+
|
66
|
+
File.open( text_filename, "w" ) do |textfile|
|
67
|
+
selected_text = buffer_current.selected_text
|
68
|
+
if selected_text
|
69
|
+
textfile.puts( selected_text.join( "\n" ) )
|
70
|
+
end
|
71
|
+
end
|
72
|
+
retval.gsub!( /\$s/, text_filename )
|
73
|
+
end
|
74
|
+
|
75
|
+
retval
|
76
|
+
end
|
77
|
+
|
78
|
+
# Executes a command in a shell, captures the results, and displays them
|
79
|
+
# (if any) in a new buffer. Substitutes Diakonos shell variables.
|
80
|
+
# Interaction with Diakonos is not possible while the shell is running.
|
81
|
+
# For asynchronous shelling, use #spawn. The shell function does not
|
82
|
+
# allow interaction with applications run in the shell. Use #execute
|
83
|
+
# for interactivity.
|
84
|
+
#
|
85
|
+
# @param [String] command_
|
86
|
+
# The shell command to execute
|
87
|
+
# @param [String] result_filename
|
88
|
+
# The name of the temporary file to write the shell results to
|
89
|
+
# @see #sub_shell_variables
|
90
|
+
# @see #execute
|
91
|
+
# @see #spawn
|
92
|
+
# @see #paste_shell_result
|
93
|
+
def shell( command_ = nil, result_filename = 'shell-result.txt' )
|
94
|
+
command = command_ || get_user_input( "Command: ", history: @rlh_shell )
|
95
|
+
|
96
|
+
return if command.nil?
|
97
|
+
|
98
|
+
command = sub_shell_variables( command )
|
99
|
+
|
100
|
+
completed = false
|
101
|
+
result_file = "#{@diakonos_home}/#{result_filename}"
|
102
|
+
File.open( result_file , "w" ) do |f|
|
103
|
+
Curses::close_screen
|
104
|
+
|
105
|
+
stdin, stdout, stderr = Open3.popen3( command )
|
106
|
+
|
107
|
+
t1 = Thread.new do
|
108
|
+
stdout.each_line do |line|
|
109
|
+
f.puts line
|
110
|
+
end
|
111
|
+
end
|
112
|
+
t2 = Thread.new do
|
113
|
+
stderr.each_line do |line|
|
114
|
+
f.puts line
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
catch :stop do
|
119
|
+
loop do
|
120
|
+
begin
|
121
|
+
Timeout::timeout( 5 ) do
|
122
|
+
t1.join
|
123
|
+
t2.join
|
124
|
+
Curses::init_screen
|
125
|
+
refresh_all
|
126
|
+
completed = true
|
127
|
+
throw :stop
|
128
|
+
end
|
129
|
+
rescue Timeout::Error => e
|
130
|
+
choice = get_choice(
|
131
|
+
"Keep waiting for shell results?",
|
132
|
+
[ CHOICE_YES, CHOICE_NO ],
|
133
|
+
CHOICE_YES
|
134
|
+
)
|
135
|
+
if choice != CHOICE_YES
|
136
|
+
t1.terminate
|
137
|
+
t2.terminate
|
138
|
+
throw :stop
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
if File.size?( result_file )
|
146
|
+
open_file result_file
|
147
|
+
set_iline "#{completed ? '' : '(interrupted) '}Results for: #{command}"
|
148
|
+
else
|
149
|
+
set_iline "Empty result for: #{command}"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Executes a command in a shell, and displays the exit code.
|
154
|
+
# Results of the shell command are discarded.
|
155
|
+
# Substitutes Diakonos shell variables.
|
156
|
+
# Interaction with Diakonos is not possible while the shell is running.
|
157
|
+
# For asynchronous shelling, use #spawn. The #execute function allows
|
158
|
+
# interaction with shell programs that accept keyboard interaction.
|
159
|
+
#
|
160
|
+
# @param [String] command_
|
161
|
+
# The shell command to execute
|
162
|
+
# @see #sub_shell_variables
|
163
|
+
# @see #shell
|
164
|
+
# @see #spawn
|
165
|
+
# @see #paste_shell_result
|
166
|
+
def execute( command_ = nil )
|
167
|
+
command = command_ || get_user_input( "Command: ", history: @rlh_shell )
|
168
|
+
|
169
|
+
return if command.nil?
|
170
|
+
|
171
|
+
command = sub_shell_variables( command )
|
172
|
+
|
173
|
+
Curses::close_screen
|
174
|
+
|
175
|
+
success = system( command )
|
176
|
+
if ! success
|
177
|
+
result = "Could not execute: #{command}"
|
178
|
+
else
|
179
|
+
result = "Exit code: #{$?}"
|
180
|
+
end
|
181
|
+
|
182
|
+
Curses::init_screen
|
183
|
+
refresh_all
|
184
|
+
|
185
|
+
set_iline result
|
186
|
+
end
|
187
|
+
|
188
|
+
# Executes a command in a shell, captures the results, and pastes them
|
189
|
+
# in the current buffer at the current cursor location.
|
190
|
+
# Substitutes Diakonos shell variables.
|
191
|
+
# Interaction with Diakonos is not possible while the shell is running.
|
192
|
+
# For asynchronous shelling, use #spawn.
|
193
|
+
#
|
194
|
+
# @param [String] command_
|
195
|
+
# The shell command to execute
|
196
|
+
# @see #sub_shell_variables
|
197
|
+
# @see #execute
|
198
|
+
# @see #shell
|
199
|
+
# @see #spawn
|
200
|
+
def paste_shell_result( command_ = nil )
|
201
|
+
command = command_ || get_user_input( "Command: ", history: @rlh_shell )
|
202
|
+
|
203
|
+
return if command.nil?
|
204
|
+
|
205
|
+
command = sub_shell_variables( command )
|
206
|
+
|
207
|
+
Curses::close_screen
|
208
|
+
|
209
|
+
begin
|
210
|
+
buffer_current.paste( `#{command} 2<&1`.split( /\n/, -1 ) )
|
211
|
+
rescue Exception => e
|
212
|
+
debug_log e.message
|
213
|
+
debug_log e.backtrace.join( "\n\t" )
|
214
|
+
show_exception e
|
215
|
+
end
|
216
|
+
|
217
|
+
Curses::init_screen
|
218
|
+
refresh_all
|
219
|
+
end
|
220
|
+
|
221
|
+
# Executes a command in a shell, captures the results, and pastes them
|
222
|
+
# in the current buffer at the current cursor location.
|
223
|
+
# Substitutes Diakonos shell variables.
|
224
|
+
# The shell is executed in a separate thread, so interaction with Diakonos
|
225
|
+
# is possible during execution.
|
226
|
+
#
|
227
|
+
# @param [String] command_
|
228
|
+
# The shell command to execute
|
229
|
+
# @see #sub_shell_variables
|
230
|
+
# @see #execute
|
231
|
+
# @see #shell
|
232
|
+
# @see #paste_shell_result
|
233
|
+
def spawn( command_ = nil )
|
234
|
+
command = command_ || get_user_input( "Command: ", history: @rlh_shell )
|
235
|
+
|
236
|
+
return if command.nil?
|
237
|
+
|
238
|
+
command = sub_shell_variables( command )
|
239
|
+
|
240
|
+
Thread.new do
|
241
|
+
if system( command )
|
242
|
+
set_iline "Return code #{$?} from '#{command}'"
|
243
|
+
else
|
244
|
+
set_iline "Error code #{$?} executing '#{command}'"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
end
|
250
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Diakonos
|
2
|
+
module Functions
|
3
|
+
|
4
|
+
def go_to_tag( tag_ = nil )
|
5
|
+
load_tags
|
6
|
+
|
7
|
+
# If necessary, prompt for tag name.
|
8
|
+
|
9
|
+
if tag_.nil?
|
10
|
+
if buffer_current.changing_selection
|
11
|
+
selected_text = buffer_current.copy_selection[ 0 ]
|
12
|
+
end
|
13
|
+
tag_name = get_user_input(
|
14
|
+
"Tag name: ",
|
15
|
+
history: @rlh_general,
|
16
|
+
initial_text: selected_text || "",
|
17
|
+
completion_array: @tags.keys
|
18
|
+
)
|
19
|
+
else
|
20
|
+
tag_name = tag_
|
21
|
+
end
|
22
|
+
|
23
|
+
tag_array = @tags[ tag_name ]
|
24
|
+
if tag_array && tag_array.length > 0
|
25
|
+
if i = tag_array.index( @last_tag )
|
26
|
+
tag = ( tag_array[ i + 1 ] || tag_array[ 0 ] )
|
27
|
+
else
|
28
|
+
tag = tag_array[ 0 ]
|
29
|
+
end
|
30
|
+
@last_tag = tag
|
31
|
+
@tag_stack.push [ buffer_current.name, buffer_current.last_row, buffer_current.last_col ]
|
32
|
+
if switch_to( @buffers.find { |b| b.name == tag.file } )
|
33
|
+
#buffer_current.go_to_line( 0 )
|
34
|
+
else
|
35
|
+
open_file tag.file
|
36
|
+
end
|
37
|
+
line_number = tag.command.to_i
|
38
|
+
if line_number > 0
|
39
|
+
buffer_current.go_to_line( line_number - 1 )
|
40
|
+
else
|
41
|
+
find tag.command case_sensitive: true
|
42
|
+
end
|
43
|
+
elsif tag_name
|
44
|
+
set_iline "No such tag: '#{tag_name}'"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def go_to_tag_under_cursor
|
49
|
+
go_to_tag buffer_current.word_under_cursor
|
50
|
+
end
|
51
|
+
|
52
|
+
def pop_tag
|
53
|
+
tag = @tag_stack.pop
|
54
|
+
if tag
|
55
|
+
if ! switch_to( @buffers.find { |b| b.name == tag[ 0 ] } )
|
56
|
+
open_file tag[ 0 ]
|
57
|
+
end
|
58
|
+
buffer_current.cursor_to( tag[ 1 ], tag[ 2 ], Buffer::DO_DISPLAY )
|
59
|
+
else
|
60
|
+
set_iline "Tag stack empty."
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
require 'diakonos/line-mover'
|
2
|
+
|
3
|
+
module Diakonos
|
4
|
+
module Functions
|
5
|
+
|
6
|
+
def close_code
|
7
|
+
buffer_current.close_code
|
8
|
+
end
|
9
|
+
|
10
|
+
def collapse_whitespace
|
11
|
+
buffer_current.collapse_whitespace
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
def columnize( delimiter = nil, num_spaces_padding = 0 )
|
16
|
+
delimiter ||= get_user_input(
|
17
|
+
"Column delimiter (regexp): ",
|
18
|
+
history: @rlh_general,
|
19
|
+
initial_text: @settings[ "lang.#{buffer_current.original_language}.column_delimiters" ] || ''
|
20
|
+
)
|
21
|
+
if delimiter && num_spaces_padding
|
22
|
+
buffer_current.columnize Regexp.new( delimiter ), num_spaces_padding
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def comment_out
|
27
|
+
buffer_current.comment_out
|
28
|
+
end
|
29
|
+
|
30
|
+
def complete_word( direction = :down )
|
31
|
+
b = buffer_current
|
32
|
+
if b.selecting?
|
33
|
+
old_word = b.word_before_cursor
|
34
|
+
b.delete_selection
|
35
|
+
end
|
36
|
+
partial = b.word_before_cursor
|
37
|
+
return if partial.nil?
|
38
|
+
|
39
|
+
all_words = @buffers.find_all { |b_|
|
40
|
+
b_.original_language == b.original_language
|
41
|
+
}.collect { |b_|
|
42
|
+
b_.words( /^#{Regexp.escape(partial)}./ )
|
43
|
+
}.flatten
|
44
|
+
if all_words.any?
|
45
|
+
words = all_words.uniq.sort
|
46
|
+
if old_word
|
47
|
+
i = (
|
48
|
+
( direction == :up ? words.size - 1 : 1 ) +
|
49
|
+
words.find_index { |w|
|
50
|
+
w == old_word
|
51
|
+
}
|
52
|
+
) % words.size
|
53
|
+
else
|
54
|
+
freq_word = words.sort_by { |word|
|
55
|
+
all_words.find_all { |w| w == word }.size
|
56
|
+
}[ -1 ]
|
57
|
+
i = words.find_index { |w| w == freq_word }
|
58
|
+
end
|
59
|
+
word = words[ i ]
|
60
|
+
b.insert_string word[ partial.length..-1 ]
|
61
|
+
r, c = b.last_row, b.last_col
|
62
|
+
b.cursor_to( b.last_row, b.last_col + word.length - partial.length )
|
63
|
+
b.set_selection( r, c, r, c + word.length - partial.length )
|
64
|
+
n = words.size
|
65
|
+
middle_word = words[ i ].center( Curses::cols / 4, ' ' )
|
66
|
+
shown_words = [
|
67
|
+
words[ ( n+i-2 ) % n ],
|
68
|
+
words[ ( n+i-1 ) % n ],
|
69
|
+
middle_word,
|
70
|
+
words[ ( n+i+1 ) % n ],
|
71
|
+
words[ ( n+i+2 ) % n ],
|
72
|
+
].compact.uniq.reject { |w| w == middle_word.strip }.join( ' ' )
|
73
|
+
mi = shown_words.index( middle_word )
|
74
|
+
padding = " " * ( Curses::cols / 2 - mi - ( middle_word.length / 2 ) )
|
75
|
+
set_iline padding + shown_words
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def join_lines_upward
|
80
|
+
buffer_current.join_lines_upward( buffer_current.current_row, Buffer::STRIP_LINE )
|
81
|
+
end
|
82
|
+
|
83
|
+
def join_lines
|
84
|
+
buffer_current.join_lines( buffer_current.current_row, Buffer::STRIP_LINE )
|
85
|
+
end
|
86
|
+
|
87
|
+
def move_lines(direction:)
|
88
|
+
mover = LineMover.new(buffer: buffer_current)
|
89
|
+
mover.move_selected_lines(direction: direction)
|
90
|
+
end
|
91
|
+
|
92
|
+
def operate_on_string(
|
93
|
+
ruby_code = get_user_input(
|
94
|
+
'Ruby code: ',
|
95
|
+
history: @rlh_general,
|
96
|
+
initial_text: 'str.'
|
97
|
+
)
|
98
|
+
)
|
99
|
+
if ruby_code
|
100
|
+
str = buffer_current.selected_string
|
101
|
+
if str && ! str.empty?
|
102
|
+
buffer_current.paste eval( ruby_code )
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def operate_on_lines(
|
108
|
+
ruby_code = get_user_input(
|
109
|
+
'Ruby code: ',
|
110
|
+
history: @rlh_general,
|
111
|
+
initial_text: 'lines.collect { |l| l }'
|
112
|
+
)
|
113
|
+
)
|
114
|
+
if ruby_code
|
115
|
+
lines = buffer_current.selected_text
|
116
|
+
if lines && ! lines.empty?
|
117
|
+
if lines[ -1 ].empty?
|
118
|
+
lines.pop
|
119
|
+
popped = true
|
120
|
+
end
|
121
|
+
new_lines = eval( ruby_code )
|
122
|
+
if popped
|
123
|
+
new_lines << ''
|
124
|
+
end
|
125
|
+
buffer_current.paste new_lines
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def operate_on_each_line(
|
131
|
+
ruby_code = get_user_input(
|
132
|
+
'Ruby code: ',
|
133
|
+
history: @rlh_general,
|
134
|
+
initial_text: 'line.'
|
135
|
+
)
|
136
|
+
)
|
137
|
+
if ruby_code
|
138
|
+
lines = buffer_current.selected_text
|
139
|
+
if lines && ! lines.empty?
|
140
|
+
if lines[ -1 ].empty?
|
141
|
+
lines.pop
|
142
|
+
popped = true
|
143
|
+
end
|
144
|
+
new_lines = eval( "lines.collect { |line| #{ruby_code} }" )
|
145
|
+
if popped
|
146
|
+
new_lines << ''
|
147
|
+
end
|
148
|
+
buffer_current.paste new_lines
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def surround_line( envelope = nil )
|
154
|
+
buffer_current.set_selection_current_line
|
155
|
+
surround_selection envelope
|
156
|
+
end
|
157
|
+
|
158
|
+
def surround_paragraph( envelope = nil )
|
159
|
+
( first, _ ), ( last, length ) = buffer_current.paragraph_under_cursor_pos
|
160
|
+
buffer_current.set_selection( first, 0, last, length+1 )
|
161
|
+
surround_selection envelope
|
162
|
+
end
|
163
|
+
|
164
|
+
def surround_selection( parenthesis = nil )
|
165
|
+
if ! buffer_current.selecting?
|
166
|
+
set_iline "Nothing selected."
|
167
|
+
return
|
168
|
+
end
|
169
|
+
|
170
|
+
parenthesis ||= get_user_input( "Surround with: " )
|
171
|
+
if parenthesis
|
172
|
+
text = buffer_current.surround( buffer_current.selected_text, parenthesis )
|
173
|
+
if text
|
174
|
+
buffer_current.paste text
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def surround_word( envelope = nil )
|
180
|
+
( start_row, start_col ), ( end_row, end_col ) = buffer_current.word_under_cursor_pos
|
181
|
+
if start_row && start_col && end_row && end_col
|
182
|
+
buffer_current.set_selection( start_row, start_col, end_row, end_col )
|
183
|
+
surround_selection envelope
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def uncomment
|
188
|
+
buffer_current.uncomment
|
189
|
+
end
|
190
|
+
|
191
|
+
def wrap_paragraph
|
192
|
+
buffer_current.wrap_paragraph
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
end
|