diakonos 0.8.8 → 0.9.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +433 -0
  3. data/LICENCE.md +675 -0
  4. data/bin/diakonos +6 -0
  5. data/diakonos-256-colour.conf +220 -0
  6. data/diakonos.conf +1802 -0
  7. data/help/about-help.dhf +31 -0
  8. data/help/clipboard.dhf +45 -0
  9. data/help/close-file.dhf +6 -0
  10. data/help/code-block-navigation.dhf +16 -0
  11. data/help/column-markers.dhf +15 -0
  12. data/help/config.dhf +69 -0
  13. data/help/cursor-stack.dhf +19 -0
  14. data/help/delete.dhf +41 -0
  15. data/help/extensions.dhf +125 -0
  16. data/help/file-type.dhf +24 -0
  17. data/help/key-mapping.dhf +127 -0
  18. data/help/line-numbers.dhf +22 -0
  19. data/help/macros.dhf +27 -0
  20. data/help/new-file.dhf +6 -0
  21. data/help/open-file.dhf +21 -0
  22. data/help/quit.dhf +7 -0
  23. data/help/resizing.dhf +19 -0
  24. data/help/ruby.dhf +17 -0
  25. data/help/save-file.dhf +10 -0
  26. data/help/scripting.dhf +92 -0
  27. data/help/search.dhf +103 -0
  28. data/help/shell.dhf +60 -0
  29. data/help/speed.dhf +23 -0
  30. data/help/support.dhf +15 -0
  31. data/help/switch-buffers.dhf +15 -0
  32. data/help/tabs.dhf +36 -0
  33. data/help/undo.dhf +9 -0
  34. data/help/uninstall.dhf +18 -0
  35. data/help/welcome.dhf +32 -0
  36. data/help/word-wrap.dhf +17 -0
  37. data/lib/diakonos/about.rb +69 -0
  38. data/lib/diakonos/bookmark.rb +46 -0
  39. data/lib/diakonos/buffer/bookmarking.rb +47 -0
  40. data/lib/diakonos/buffer/cursor.rb +335 -0
  41. data/lib/diakonos/buffer/delete.rb +170 -0
  42. data/lib/diakonos/buffer/display.rb +356 -0
  43. data/lib/diakonos/buffer/file.rb +157 -0
  44. data/lib/diakonos/buffer/indentation.rb +175 -0
  45. data/lib/diakonos/buffer/searching.rb +552 -0
  46. data/lib/diakonos/buffer/selection.rb +360 -0
  47. data/lib/diakonos/buffer/undo.rb +73 -0
  48. data/lib/diakonos/buffer-hash.rb +60 -0
  49. data/lib/diakonos/buffer-management.rb +59 -0
  50. data/lib/diakonos/buffer.rb +698 -0
  51. data/lib/diakonos/clipboard-klipper-dbus.rb +62 -0
  52. data/lib/diakonos/clipboard-klipper.rb +62 -0
  53. data/lib/diakonos/clipboard-osx.rb +59 -0
  54. data/lib/diakonos/clipboard-xclip.rb +60 -0
  55. data/lib/diakonos/clipboard.rb +47 -0
  56. data/lib/diakonos/config-file.rb +67 -0
  57. data/lib/diakonos/config.rb +381 -0
  58. data/lib/diakonos/core-ext/enumerable.rb +15 -0
  59. data/lib/diakonos/core-ext/hash.rb +60 -0
  60. data/lib/diakonos/core-ext/object.rb +6 -0
  61. data/lib/diakonos/core-ext/regexp.rb +6 -0
  62. data/lib/diakonos/core-ext/string.rb +122 -0
  63. data/lib/diakonos/ctag.rb +28 -0
  64. data/lib/diakonos/cursor.rb +27 -0
  65. data/lib/diakonos/display/format.rb +75 -0
  66. data/lib/diakonos/display.rb +336 -0
  67. data/lib/diakonos/extension-set.rb +49 -0
  68. data/lib/diakonos/extension.rb +34 -0
  69. data/lib/diakonos/finding.rb +40 -0
  70. data/lib/diakonos/functions/basics.rb +34 -0
  71. data/lib/diakonos/functions/bookmarking.rb +61 -0
  72. data/lib/diakonos/functions/buffers.rb +489 -0
  73. data/lib/diakonos/functions/clipboard.rb +70 -0
  74. data/lib/diakonos/functions/cursor.rb +264 -0
  75. data/lib/diakonos/functions/grepping.rb +83 -0
  76. data/lib/diakonos/functions/indentation.rb +71 -0
  77. data/lib/diakonos/functions/readline.rb +93 -0
  78. data/lib/diakonos/functions/search.rb +179 -0
  79. data/lib/diakonos/functions/selection.rb +98 -0
  80. data/lib/diakonos/functions/sessions.rb +78 -0
  81. data/lib/diakonos/functions/shell.rb +250 -0
  82. data/lib/diakonos/functions/tags.rb +65 -0
  83. data/lib/diakonos/functions/text-manipulation.rb +196 -0
  84. data/lib/diakonos/functions-deprecated.rb +77 -0
  85. data/lib/diakonos/functions.rb +292 -0
  86. data/lib/diakonos/grep.rb +98 -0
  87. data/lib/diakonos/help.rb +47 -0
  88. data/lib/diakonos/hooks.rb +13 -0
  89. data/lib/diakonos/installation.rb +19 -0
  90. data/lib/diakonos/interaction-handler.rb +216 -0
  91. data/lib/diakonos/interaction.rb +52 -0
  92. data/lib/diakonos/key-map.rb +62 -0
  93. data/lib/diakonos/keying.rb +442 -0
  94. data/lib/diakonos/line-mover.rb +42 -0
  95. data/lib/diakonos/list.rb +59 -0
  96. data/lib/diakonos/logging.rb +27 -0
  97. data/lib/diakonos/mode.rb +17 -0
  98. data/lib/diakonos/mouse.rb +18 -0
  99. data/lib/diakonos/number-fitter.rb +11 -0
  100. data/lib/diakonos/range.rb +31 -0
  101. data/lib/diakonos/readline/functions.rb +82 -0
  102. data/lib/diakonos/readline.rb +222 -0
  103. data/lib/diakonos/search.rb +58 -0
  104. data/lib/diakonos/sessions.rb +257 -0
  105. data/lib/diakonos/sized-array.rb +48 -0
  106. data/lib/diakonos/text-mark.rb +19 -0
  107. data/lib/diakonos/vendor/fuzzy_file_finder.rb +365 -0
  108. data/lib/diakonos/version.rb +25 -0
  109. data/lib/diakonos/window.rb +43 -0
  110. data/lib/diakonos.rb +592 -0
  111. metadata +160 -66
@@ -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