lib/textbringer/commands/buffers.rb in textbringer-0.1.8 vs lib/textbringer/commands/buffers.rb in textbringer-0.1.9

- old
+ new

@@ -1,97 +1,241 @@ # frozen_string_literal: true module Textbringer module Commands - [ - :forward_char, - :backward_char, - :forward_word, - :backward_word, - :next_line, - :previous_line, - :delete_char, - :backward_delete_char, - ].each do |name| - define_command(name) do |n = number_prefix_arg| - Buffer.current.send(name, n) - end + define_command(:forward_char, + doc: "Move point n characters forward.") do + |n = number_prefix_arg| + Buffer.current.forward_char(n) end + + define_command(:backward_char, + doc: "Move point n characters backward.") do + |n = number_prefix_arg| + Buffer.current.backward_char(n) + end - [ - :beginning_of_line, - :end_of_line, - :beginning_of_buffer, - :end_of_buffer, - :exchange_point_and_mark, - :copy_region, - :kill_region, - :yank, - :newline, - :delete_region, - :transpose_chars - ].each do |name| - define_command(name) do - Buffer.current.send(name) - end + define_command(:forward_word, + doc: "Move point n words forward.") do + |n = number_prefix_arg| + Buffer.current.forward_word(n) end - define_command(:set_mark_command) do - Buffer.current.set_mark - message("Mark set") + define_command(:backward_word, + doc: "Move point n words backward.") do + |n = number_prefix_arg| + Buffer.current.backward_word(n) end + - define_command(:goto_char) do - |n = read_from_minibuffer("Go to char: ")| - Buffer.current.goto_char(n.to_i) + define_command(:next_line, + doc: "Move point n lines forward.") do + |n = number_prefix_arg| + Buffer.current.next_line(n) + end + + define_command(:previous_line, + doc: "Move point n lines backward.") do + |n = number_prefix_arg| + Buffer.current.previous_line(n) + end + + define_command(:delete_char, + doc: "Delete n characters forward.") do + |n = number_prefix_arg| + Buffer.current.delete_char(n) + end + + define_command(:backward_delete_char, + doc: "Delete n characters backward.") do + |n = number_prefix_arg| + Buffer.current.backward_delete_char(n) + end + + define_command(:beginning_of_line, + doc: "Move point to the beginning of the current line.") do + Buffer.current.beginning_of_line + end + + define_command(:end_of_line, + doc: "Move point to the end of the current line.") do + Buffer.current.end_of_line + end + + define_command(:beginning_of_buffer, + doc: "Move point to the beginning of the buffer.") do + Buffer.current.beginning_of_buffer + end + + define_command(:end_of_buffer, + doc: "Move point to the end of the buffer.") do + Buffer.current.end_of_buffer + end + + define_command(:push_mark, + doc: <<~EOD) do + Set mark at pos, and push the mark on the mark ring. + Unlike Emacs, the new mark is pushed on the mark ring instead of + the old one. + EOD + |pos = Buffer.current.point| + Buffer.current.push_mark(pos) + end + + define_command(:pop_mark, + doc: "Pop the mark from the mark ring.") do + Buffer.current.pop_mark + end + + define_command(:pop_to_mark, + doc: <<~EOD) do + Move point to where the mark is, and pop the mark from + the mark ring. + EOD + Buffer.current.pop_to_mark + end + + define_command(:exchange_point_and_mark, + doc: "Exchange the positions of point and mark.") do + Buffer.current.exchange_point_and_mark + end + + define_command(:copy_region, + doc: "Copy the region to the kill ring.") do + Buffer.current.copy_region + end + + define_command(:kill_region, + doc: "Copy and delete the region.") do + Buffer.current.kill_region + end + + define_command(:yank, + doc: "Insert the last text copied in the kill ring.") do + Buffer.current.yank + end + + define_command(:newline, + doc: "Insert a newline.") do + Buffer.current.newline + end + + define_command(:delete_region, + doc: "Delete the region without copying.") do + Buffer.current.delete_region + end + + define_command(:transpose_chars, + doc: "Transpose characters.") do + Buffer.current.transpose_chars + end + + define_command(:set_mark_command, + doc: <<~EOD) do + Set the mark at point. + + With C-u, move point to where the mark is, and pop the mark from + the mark ring. + EOD + |arg = current_prefix_arg| + buffer = Buffer.current + if arg + buffer.pop_to_mark + else + buffer.push_mark + message("Mark set") + end + end + + define_command(:goto_char, + doc: "Move point to pos.") do + |pos = read_from_minibuffer("Go to char: ")| + Buffer.current.goto_char(pos.to_i) Window.current.recenter_if_needed end - define_command(:goto_line) do + define_command(:goto_line, + doc: "Move point to line n.") do |n = read_from_minibuffer("Go to line: ")| Buffer.current.goto_line(n.to_i) Window.current.recenter_if_needed end - define_command(:self_insert) do |n = number_prefix_arg| + define_command(:self_insert, + doc: "Insert the character typed.") do + |n = number_prefix_arg| c = Controller.current.last_key merge_undo = Controller.current.last_command == :self_insert Buffer.current.insert(c * n, merge_undo) end - define_command(:quoted_insert) do |n = number_prefix_arg| + define_command(:quoted_insert, + doc: "Read a character, and insert it.") do + |n = number_prefix_arg| c = Controller.current.read_char if !c.is_a?(String) raise EditorError, "Invalid key" end Buffer.current.insert(c * n) end - define_command(:kill_line) do + define_command(:kill_line, + doc: "Kill the rest of the current line.") do Buffer.current.kill_line(Controller.current.last_command == :kill_region) Controller.current.this_command = :kill_region end - define_command(:kill_word) do + define_command(:kill_word, + doc: "Kill a word.") do Buffer.current.kill_word(Controller.current.last_command == :kill_region) Controller.current.this_command = :kill_region end - define_command(:yank_pop) do + define_command(:yank_pop, + doc: <<~EOD) do + Rotate the kill ring, and replace the yanked text. + EOD if Controller.current.last_command != :yank raise EditorError, "Previous command was not a yank" end Buffer.current.yank_pop Controller.current.this_command = :yank end - define_command(:undo) do + define_command(:undo, + doc: "Undo changes.") do Buffer.current.undo message("Undo!") unless Window.echo_area.current? end - define_command(:redo) do + define_command(:redo_command, + doc: "Redo changes reverted by undo.") do Buffer.current.redo message("Redo!") unless Window.echo_area.current? + end + + define_command(:back_to_indentation, + doc: "Move point to the first non-space character.") do + buffer = Buffer.current + buffer.beginning_of_line + while /[ \t]/ =~ buffer.char_after + buffer.forward_char + end + end + + define_command(:delete_indentation, + doc: <<~EOD) do + Delete indentation and join the current line to the previous line. + EOD + buffer = Buffer.current + back_to_indentation + pos = buffer.point + buffer.skip_re_backward(/[^\n]/) + return if buffer.beginning_of_buffer? + buffer.backward_char + buffer.skip_re_backward(/[ \t]/) + buffer.delete_region(buffer.point, pos) + buffer.insert(" ") + buffer.backward_char end end end