Module: VER::Methods::Control
- Defined in:
- lib/ver/methods/control.rb
Constant Summary collapse
- REPEAT_BREAK_CMD =
[ :repeat_command, :undo, :redo, ]
- REPEAT_BREAK_MODE =
[ :move, :search, ]
- ENV_EXPORTERS =
%w[ current_line current_word directory filepath line_index line_number scope selected_text ]
Class Method Summary collapse
- .chdir(text) ⇒ Object
- .clean_line(text, index, record = text) ⇒ Object
- .cursor_vertical_bottom(text) ⇒ Object
- .cursor_vertical_bottom_sol(text) ⇒ Object
- .cursor_vertical_center(text) ⇒ Object
- .cursor_vertical_center_sol(text) ⇒ Object
- .cursor_vertical_top(text) ⇒ Object
- .cursor_vertical_top_sol(text) ⇒ Object
- .enter(text, old_mode, new_mode) ⇒ Object
- .eval_buffer ⇒ Object
-
.exec_bundle ⇒ Object
Set up the env for a script, then execute it.
-
.exec_env_current_line ⇒ Object
textual content of the current line.
-
.exec_env_current_word ⇒ Object
the word in which the caret is located.
-
.exec_env_directory ⇒ Object
the folder of the current document (may not be set).
-
.exec_env_filepath ⇒ Object
path (including file name) for the current document (may not be set).
-
.exec_env_line_index ⇒ Object
the index in the current line which marks the caret’s location.
-
.exec_env_line_number ⇒ Object
the carets line position (counting from 1).
- .exec_env_scope ⇒ Object
-
.exec_env_selected_text ⇒ Object
full content of the selection (may not be set).
- .exec_into_new(text, command = nil) ⇒ Object
- .exec_into_void(text) ⇒ Object
- .executor(text, action = nil) ⇒ Object (also: ex)
-
.gsub(text, regexp, with) ⇒ Object
Substitute over all lines of the buffer.
- .indent_line(text, count = text.prefix_count) ⇒ Object
- .insert_at(text, motion, *count) ⇒ Object
- .insert_indented_newline_above(text) ⇒ Object
- .insert_indented_newline_below(text) ⇒ Object
- .join_line_backward(text) ⇒ Object
- .join_line_forward(text) ⇒ Object
- .leave(text, old_mode, new_mode) ⇒ Object
- .line_evaluate(text) ⇒ Object
- .open_file_under_cursor(text) ⇒ Object
-
.prepare_exec(text, command) ⇒ Object
Assigns env variables used in the given command.
- .prepare_exec_c(text) ⇒ Object
- .prepare_exec_d(text) ⇒ Object
- .prepare_exec_f(text) ⇒ Object
- .prepare_exec_F(text) ⇒ Object
- .prepare_exec_i(text) ⇒ Object
- .prepare_exec_s(text) ⇒ Object
- .repeat_command(text, count = text.prefix_count) ⇒ Object
- .smart_evaluate(text) ⇒ Object
- .source_buffer(text) ⇒ Object
- .stdout_capture_evaluate(code, file, binding = binding) ⇒ Object
-
.sub(text, regexp, with) ⇒ Object
Substitute on current line.
- .tags_at(index = :insert) ⇒ Object
-
.toggle_case(text, count = text.prefix_count) ⇒ Object
Toggle case of the character under the cursor up to
count
characters forward (count
is inclusive the first character). - .unindent_line(text, count = text.prefix_count) ⇒ Object
- .wrap_line(text) ⇒ Object
- .wrap_lines_of(content, wrap = 80) ⇒ Object
Class Method Details
.chdir(text) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/ver/methods/control.rb', line 80 def chdir(text) text.ask 'Change to: ' do |path, action| case action when :attempt path = File.(path.to_s) begin Dir.chdir(path) VER. 'Changed working directory to %s' % [path] :abort rescue Errno::ENOENT => ex VER.warn ex end end end end |
.clean_line(text, index, record = text) ⇒ Object
424 425 426 427 428 429 430 |
# File 'lib/ver/methods/control.rb', line 424 def clean_line(text, index, record = text) index = text.index(index) from, to = index.linestart, index.lineend line = text.get(from, to) = line.rstrip record.replace(from, to, ) if .empty? end |
.cursor_vertical_bottom(text) ⇒ Object
65 66 67 68 69 70 71 72 73 |
# File 'lib/ver/methods/control.rb', line 65 def cursor_vertical_bottom(text) insert = text.count('1.0', 'insert', :displaylines) + 1 last = text.count('1.0', 'end', :displaylines) shown = text.count('@0,0', "@0,#{text.winfo_height}", :displaylines) fraction = ((100.0 / last) * (insert - shown)) / 100 text.yview_moveto(fraction) end |
.cursor_vertical_bottom_sol(text) ⇒ Object
75 76 77 78 |
# File 'lib/ver/methods/control.rb', line 75 def cursor_vertical_bottom_sol(text) cursor_vertical_bottom(text) start_of_line(text) end |
.cursor_vertical_center(text) ⇒ Object
50 51 52 53 54 55 56 57 58 |
# File 'lib/ver/methods/control.rb', line 50 def cursor_vertical_center(text) insert = text.count('1.0', 'insert', :displaylines) last = text.count('1.0', 'end', :displaylines) shown = text.count('@0,0', "@0,#{text.winfo_height}", :displaylines) fraction = ((100.0 / last) * (insert - (shown / 2))) / 100 text.yview_moveto(fraction) end |
.cursor_vertical_center_sol(text) ⇒ Object
60 61 62 63 |
# File 'lib/ver/methods/control.rb', line 60 def cursor_vertical_center_sol(text) cursor_vertical_center(text) Move.start_of_line(text) end |
.cursor_vertical_top(text) ⇒ Object
36 37 38 39 40 41 42 43 |
# File 'lib/ver/methods/control.rb', line 36 def cursor_vertical_top(text) insert = text.count('1.0', 'insert', :displaylines) last = text.count('1.0', 'end', :displaylines) fraction = ((100.0 / last) * insert) / 100 text.yview_moveto(fraction) end |
.cursor_vertical_top_sol(text) ⇒ Object
45 46 47 48 |
# File 'lib/ver/methods/control.rb', line 45 def cursor_vertical_top_sol(text) cursor_vertical_top(text) Move.start_of_line(text) end |
.enter(text, old_mode, new_mode) ⇒ Object
6 7 8 |
# File 'lib/ver/methods/control.rb', line 6 def enter(text, old_mode, new_mode) clean_line(text, :insert) end |
.eval_buffer ⇒ Object
385 386 387 388 389 |
# File 'lib/ver/methods/control.rb', line 385 def eval_buffer result = eval(value, TOPLEVEL_BINDING) rescue Exception => exception VER.error(exception) end |
.exec_bundle ⇒ Object
Set up the env for a script, then execute it. For now, I only setup the env, until we figure out a good way to find bundle commands.
197 198 199 200 201 202 203 204 |
# File 'lib/ver/methods/control.rb', line 197 def exec_bundle ENV_EXPORTERS.each do |exporter| ENV["VER_#{exporter.upcase}"] = ENV["TM_#{exporter.upcase}"] = send("exec_env_#{exporter}").to_s end yield if block_given? end |
.exec_env_current_line ⇒ Object
textual content of the current line
207 208 209 |
# File 'lib/ver/methods/control.rb', line 207 def exec_env_current_line get('insert linestart', 'insert lineend') end |
.exec_env_current_word ⇒ Object
the word in which the caret is located.
212 213 214 |
# File 'lib/ver/methods/control.rb', line 212 def exec_env_current_word get('insert wordstart', 'insert wordend') end |
.exec_env_directory ⇒ Object
the folder of the current document (may not be set).
217 218 219 |
# File 'lib/ver/methods/control.rb', line 217 def exec_env_directory filename.dirname.to_s end |
.exec_env_filepath ⇒ Object
path (including file name) for the current document (may not be set).
222 223 224 |
# File 'lib/ver/methods/control.rb', line 222 def exec_env_filepath filename.to_s end |
.exec_env_line_index ⇒ Object
the index in the current line which marks the caret’s location. This index is zero-based and takes the utf-8 encoding of the line (e.g. read as TM_CURRENT_LINE) into account.
229 230 231 |
# File 'lib/ver/methods/control.rb', line 229 def exec_env_line_index index('insert').x end |
.exec_env_line_number ⇒ Object
the carets line position (counting from 1).
234 235 236 |
# File 'lib/ver/methods/control.rb', line 234 def exec_env_line_number index('insert').y end |
.exec_env_scope ⇒ Object
238 239 240 |
# File 'lib/ver/methods/control.rb', line 238 def exec_env_scope tag_names('insert').join(', ') end |
.exec_env_selected_text ⇒ Object
full content of the selection (may not be set). Note that environment variables have a size limitation of roughly 64 KB, so if the user selects more than that, this variable will not reflect the actual selection (commands that need to work with the selection should generally set this to be the standard input).
247 248 249 250 251 252 253 254 255 |
# File 'lib/ver/methods/control.rb', line 247 def exec_env_selected_text content = [] each_selected_line do |y, fx, tx| content << get("#{y}.#{fx}", "#{y}.#{tx}") end content.join("\n") end |
.exec_into_new(text, command = nil) ⇒ Object
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/ver/methods/control.rb', line 257 def exec_into_new(text, command = nil) if command target = text..home_conf_dir/'shell-result.txt' prepare_exec(command) system(command) target.open('w+'){|io| io.write(`#{command}`) } VER.find_or_create_buffer(target) else text.ask 'Command: ' do |answer, action| case action when :attempt begin exec_into_new(answer) :abort rescue => ex VER.warn(ex) end end end end end |
.exec_into_void(text) ⇒ Object
279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/ver/methods/control.rb', line 279 def exec_into_void(text) text.ask 'Command: ' do |command, action| case action when :attempt begin system(command) VER.("Exit code: #{$?}") :abort rescue => ex VER.warn(ex) end end end end |
.executor(text, action = nil) ⇒ Object Also known as: ex
336 337 338 |
# File 'lib/ver/methods/control.rb', line 336 def executor(text, action = nil) VER::Executor.new(text, action: action) end |
.gsub(text, regexp, with) ⇒ Object
Substitute over all lines of the buffer
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
# File 'lib/ver/methods/control.rb', line 308 def gsub(text, regexp, with) total = 0 Undo.record text do |record| text.index('1.0').upto(text.index('end')) do |index| lineend = index.lineend line = text.get(index, lineend) if line.gsub!(regexp, with) record.replace(index, lineend, line) total += 1 end end end VER. "Performed gsub on #{total} lines" end |
.indent_line(text, count = text.prefix_count) ⇒ Object
403 404 405 406 |
# File 'lib/ver/methods/control.rb', line 403 def indent_line(text, count = text.prefix_count) indent = (' ' * text.[:shiftwidth] * count) text.insert('insert linestart', indent) end |
.insert_at(text, motion, *count) ⇒ Object
14 15 16 17 |
# File 'lib/ver/methods/control.rb', line 14 def insert_at(text, motion, *count) Move.send(motion, text, *count) text.minor_mode(:control, :insert) end |
.insert_indented_newline_above(text) ⇒ Object
19 20 21 |
# File 'lib/ver/methods/control.rb', line 19 def insert_indented_newline_above(text) Insert.insert_indented_newline_above(text) end |
.insert_indented_newline_below(text) ⇒ Object
23 24 25 |
# File 'lib/ver/methods/control.rb', line 23 def insert_indented_newline_below(text) Insert.insert_indented_newline_below(text) end |
.join_line_backward(text) ⇒ Object
397 398 399 400 401 |
# File 'lib/ver/methods/control.rb', line 397 def join_line_backward(text) from, to = 'insert - 1 lines linestart', 'insert lineend' lines = text.get(from, to) text.replace(from, to, lines.gsub(/\s*\n\s*/, ' ')) end |
.join_line_forward(text) ⇒ Object
391 392 393 394 395 |
# File 'lib/ver/methods/control.rb', line 391 def join_line_forward(text) from, to = 'insert linestart', 'insert + 1 lines lineend' lines = text.get(from, to) text.replace(from, to, lines.gsub(/\s*\n\s*/, ' ')) end |
.leave(text, old_mode, new_mode) ⇒ Object
10 11 12 |
# File 'lib/ver/methods/control.rb', line 10 def leave(text, old_mode, new_mode) # clean_line(text, :insert) end |
.line_evaluate(text) ⇒ Object
360 361 362 363 364 365 |
# File 'lib/ver/methods/control.rb', line 360 def line_evaluate(text) content = text.get('insert linestart', 'insert lineend') stdout_capture_evaluate(content, text.filename, binding) do |res,out| text.insert("insert lineend", "\n%s%p" % [out, res] ) end end |
.open_file_under_cursor(text) ⇒ Object
27 28 29 |
# File 'lib/ver/methods/control.rb', line 27 def open_file_under_cursor(text) Open.open_file_under_cursor(text) end |
.prepare_exec(text, command) ⇒ Object
Assigns env variables used in the given command.
-
$f: The current buffer’s filename
-
$d: The current buffer’s directory
-
$F: A space-separated list of all buffer filenames
-
$i: A string acquired from the user with a prompt
-
$c: The current clipboard text
-
$s: The currently selected text
150 151 152 153 154 155 156 157 |
# File 'lib/ver/methods/control.rb', line 150 def prepare_exec(text, command) prepare_exec_f(text) if command =~ /\$f/ prepare_exec_d(text) if command =~ /\$d/ prepare_exec_F(text) if command =~ /\$F/ prepare_exec_i(text) if command =~ /\$i/ prepare_exec_c(text) if command =~ /\$c/ prepare_exec_s(text) if command =~ /\$s/ end |
.prepare_exec_c(text) ⇒ Object
175 176 177 |
# File 'lib/ver/methods/control.rb', line 175 def prepare_exec_c(text) p c: (ENV['c'] = clipboard_get) end |
.prepare_exec_d(text) ⇒ Object
163 164 165 |
# File 'lib/ver/methods/control.rb', line 163 def prepare_exec_d(text) p d: (ENV['d'] = filename.directory.to_s) end |
.prepare_exec_f(text) ⇒ Object
159 160 161 |
# File 'lib/ver/methods/control.rb', line 159 def prepare_exec_f(text) p f: (ENV['f'] = filename.to_s) end |
.prepare_exec_F(text) ⇒ Object
167 168 169 |
# File 'lib/ver/methods/control.rb', line 167 def prepare_exec_F(text) p F: (ENV['F'] = VER.buffers.map{|key, buffer| buffer.filename }.join(' ')) end |
.prepare_exec_i(text) ⇒ Object
171 172 173 |
# File 'lib/ver/methods/control.rb', line 171 def prepare_exec_i(text) raise NotImplementedError end |
.prepare_exec_s(text) ⇒ Object
179 180 181 182 183 184 185 186 187 |
# File 'lib/ver/methods/control.rb', line 179 def prepare_exec_s(text) content = [] each_selected_line do |y, fx, tx| content << get("#{y}.#{fx}", "#{y}.#{tx}") end ENV['s'] = content.join("\n") end |
.repeat_command(text, count = text.prefix_count) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/ver/methods/control.rb', line 118 def repeat_command(text, count = text.prefix_count) actions = [] text.major_mode.action_history.reverse_each do |event, mode, action| if actions.empty? next if REPEAT_BREAK_CMD.include?(action.method) next if REPEAT_BREAK_MODE.include?(mode.name) else break if REPEAT_BREAK_CMD.include?(action.method) break if REPEAT_BREAK_MODE.include?(mode.name) end actions << [action, event] end actions.reverse! actions.each do |action, event| event.prefix_arg = count action.call(event) end end |
.smart_evaluate(text) ⇒ Object
351 352 353 354 355 356 357 358 |
# File 'lib/ver/methods/control.rb', line 351 def smart_evaluate(text) if sel = text.tag_ranges(:sel) from, to = sel.first return Selection.evaluate(text) if from && to end line_evaluate(text) end |
.source_buffer(text) ⇒ Object
31 32 33 34 |
# File 'lib/ver/methods/control.rb', line 31 def source_buffer(text) VER.("Source #{text.filename}") load(text.filename.to_s) end |
.stdout_capture_evaluate(code, file, binding = binding) ⇒ Object
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 |
# File 'lib/ver/methods/control.rb', line 367 def stdout_capture_evaluate(code, file, binding = binding) begin old_stdout = $stdout.dup rd, wr = IO.pipe $stdout.reopen(wr) result = eval(code, binding, file.to_s) $stdout.reopen old_stdout; wr.close stdout = rd.read yield(result, stdout) rescue Exception => exception yield(exception, '') ensure wr.closed? || $stdout.reopen(old_stdout) && wr.close rd.closed? || rd.close end end |
.sub(text, regexp, with) ⇒ Object
Substitute on current line
326 327 328 329 330 331 332 333 334 |
# File 'lib/ver/methods/control.rb', line 326 def sub(text, regexp, with) linestart = text.index('insert linestart') lineend = linestart.lineend line = text.get(linestart, lineend) if line.sub!(regexp, with) text.replace(linestart, lineend, line) end end |
.tags_at(index = :insert) ⇒ Object
294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/ver/methods/control.rb', line 294 def (index = :insert) index = index(index) = tag_names(index) VER. .inspect require 'ver/tooltip' tooltip = Tk::Tooltip.new(.inspect) tooltip.show_on(self) Tk::After.ms(5000){ tooltip.destroy } end |
.toggle_case(text, count = text.prefix_count) ⇒ Object
Toggle case of the character under the cursor up to count
characters forward (count
is inclusive the first character). This only works for alphabetic ASCII characters, no other encodings.
100 101 102 103 104 105 |
# File 'lib/ver/methods/control.rb', line 100 def toggle_case(text, count = text.prefix_count) from, to = 'insert', "insert + #{count} chars" chunk = text.get(from, to) chunk.tr!('a-zA-Z', 'A-Za-z') text.replace(from, to, chunk) end |
.unindent_line(text, count = text.prefix_count) ⇒ Object
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 |
# File 'lib/ver/methods/control.rb', line 408 def unindent_line(text, count = text.prefix_count) indent = ' ' * text.[:shiftwidth] replace_from = 'insert linestart' replace_to = "insert linestart + #{indent.size} chars" Undo.record text do |record| count.times do line = text.get('insert linestart', 'insert lineend') return unless line.start_with?(indent) record.replace(replace_from, replace_to, '') end end end |
.wrap_line(text) ⇒ Object
342 343 344 345 346 347 348 349 |
# File 'lib/ver/methods/control.rb', line 342 def wrap_line(text) content = text.get('insert linestart', 'insert lineend') textwidth = text..textwidth lines = wrap_lines_of(content, textwidth).join("\n") lines.rstrip! text.replace('insert linestart', 'insert lineend', lines) end |
.wrap_lines_of(content, wrap = 80) ⇒ Object
432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 |
# File 'lib/ver/methods/control.rb', line 432 def wrap_lines_of(content, wrap = 80) Kernel.raise ArgumentError, "+wrap+ must be > 1" unless wrap > 1 wrap -= 1 indent = content[/^\s+/] || '' indent_size = indent.size lines = [indent.dup] content.scan(/\S+/) do |chunk| last = lines.last last_size = last.size chunk_size = chunk.size if last_size + chunk_size > wrap lines << indent + chunk elsif last_size == indent_size last << chunk elsif chunk =~ /\.$/ last << ' ' << chunk lines << indent.dup else last << ' ' << chunk end end lines end |