lib/ver/methods/insert.rb in ver-2010.02 vs lib/ver/methods/insert.rb in ver-2010.08
- old
+ new
@@ -1,45 +1,35 @@
module VER
+ Buffer.def_delegator(:@at_insert, :tab, :insert_tab)
+ Buffer.def_delegator(:@at_insert, :newline, :insert_newline)
+ Buffer.def_delegator(:@at_insert, :selection, :insert_selection)
+
module Methods
module Insert
module_function
+ def tab(buffer) buffer.insert_tab end
+ def newline(buffer) buffer.insert_newline end
+ def selection(buffer) buffer.insert_selection end
+
def file_contents(filename)
content = read_file(filename)
insert :insert, content
rescue Errno::ENOENT => ex
VER.error(ex)
end
- def selection(text)
- text.insert(:insert, Tk::Selection.get)
- end
-
- def tab(text)
- text.insert(:insert, "\t")
- end
-
- def newline(text)
- if text.options.autoindent
- indented_newline(text)
- else
- text.insert(:insert, "\n")
- end
- end
-
def newline_below(text)
Undo.record text do |record|
if text.options.autoindent
- # text.mark_set('insert', 'insert lineend')
- # Indent.insert_newline(text, record)
line = text.get('insert linestart', 'insert lineend')
indent = line[/^\s*/]
- text.mark_set(:insert, 'insert lineend')
+ text.insert = 'insert lineend'
record.insert(:insert, "\n#{indent}")
else
- text.mark_set(:insert, 'insert lineend')
+ text.insert = 'insert lineend'
record.insert(:insert, "\n")
end
Control.clean_line(text, 'insert - 1 line', record)
end
@@ -86,26 +76,48 @@
# it's what Tk can handle best.
def string(text)
common_string(text, text.event.unicode)
end
- def replace_string(text, replacement = text.event.unicode)
- Undo.record text do |record|
- record.delete(:insert, 'insert + 1 chars')
- common_string(text, replacement, record)
+ def enter_replace(buffer, old_mode, new_mode)
+ # store count argument for later repetition
+ buffer.store(self, :replace_count, buffer.prefix_count(0))
+ buffer.store(self, :replace_chars, '')
+ end
+
+ def leave_replace(buffer, old_mode, new_mode)
+ # repeat replacment
+ count = buffer.store(self, :replace_count)
+ chars = buffer.store(self, :replace_chars).dup
+
+ buffer.undo_record do |record|
+ count.times do
+ common_string(buffer, chars, record)
+ end
end
end
- def replace_char(text, replacement = text.event.unicode)
- Undo.record text do |record|
+ def replace_string(buffer, replacement = buffer.event.unicode)
+ buffer.undo_record do |record|
record.delete(:insert, 'insert + 1 chars')
- common_string(text, replacement, record)
+ buffer.store(self, :replace_chars) << replacement
+ common_string(buffer, replacement, record)
end
- text.mark_set(:insert, 'insert - 1 chars')
- text.minor_mode(:replace_char, :control)
end
+ def replace_char(buffer, replacement = buffer.event.unicode, count = buffer.prefix_count)
+ buffer.undo_record do |record|
+ count.times do
+ record.delete(:insert, 'insert + 1 chars')
+ common_string(buffer, replacement, record)
+ end
+ end
+ buffer.skip_prefix_count_once = replacement =~ /^\d+$/
+ buffer.mark_set(:insert, 'insert - 1 chars')
+ buffer.minor_mode(:replace_char, :control)
+ end
+
def common_string(text, string, record = text)
return if string.empty?
if !string.frozen? && string.encoding == Encoding::ASCII_8BIT
begin
@@ -115,9 +127,69 @@
end
end
# puts "Insert %p in mode %p" % [string, keymap.mode]
record.insert(:insert, string)
+ end
+
+ # Insert characters literally, or enter decimal byte value (3 digits).
+ # This means we try to get up to 3 digits, but possibly don't get any.
+ #
+ # This code is less than elegant, but so is the behaviour we try to
+ # achieve.
+ #
+ # (none) decimal 3 255
+ # o or O octal 3 377 (255)
+ # x or X hexadecimal 2 ff (255)
+ # u hexadecimal 4 ffff (65535)
+ # U hexadecimal 8 7fffffff (2147483647)
+ def literal(buffer)
+ reader = ->(string = ''){
+ buffer.major_mode.read(1) do |event|
+ if unicode = event.unicode
+ string += unicode # copy
+ buffer.message string.inspect
+
+ case result = literal_handle(buffer, string)
+ when nil
+ reader.call(string)
+ when String
+ literal_insert(buffer, result)
+ end
+ else
+ return # Unverrichteter Dinge
+ end
+ end
+ }
+
+ reader.call
+ end
+
+ # returning nil means read next char
+ # returning a String means you're done and want the result inserted.
+ # returning anything else means you're giving up.
+ def literal_handle(buffer, string)
+ case string
+ when /^\d{,3}$/
+ return if string.size < 3
+ [string.to_i].pack('U')
+ when /^o([0-7]{,3})$/i
+ return if $1.size < 3
+ [Integer("0#$1")].pack('U')
+ when /^x(\h{,2})$/i
+ return if $1.size < 2
+ [Integer("0x#$1")].pack('U')
+ when /^u(\h{,4})$/
+ return if $1.size < 4
+ [Integer("0x#$1")].pack('U')
+ when /^U(\h{,8})$/
+ return if $1.size < 8
+ [Integer("0x#$1")].pack('U')
+ end
+ end
+
+ def literal_insert(buffer, char)
+ buffer.at_insert.insert(char)
end
end
end
end