lib/ver/text.rb in ver-2009.11.29 vs lib/ver/text.rb in ver-2009.12.14

- old
+ new

@@ -40,29 +40,31 @@ MATCH_WORD_RIGHT = /[^a-zA-Z0-9]+[a-zA-Z0-9'"{}\[\]\n-]/ MATCH_WORD_LEFT = /(^|\b)\S+(\b|$)/ attr_accessor :keymap, :view, :status - attr_reader :filename, :encoding, :pristine, :syntax + attr_reader :filename, :encoding, :pristine, :syntax, :undoer # attributes for diverse functionality attr_accessor :selection_mode, :selection_start def initialize(view, options = {}) super self.view = view + @options = Options.new(:text, VER.options) - keymap_name = VER.options.keymap + keymap_name = @options.keymap self.keymap = Keymap.get(name: keymap_name, receiver: self) apply_mode_style(keymap.mode) # for startup setup_tags + @undoer = VER::Undo::Tree.new(self) + self.selection_start = nil @pristine = true @syntax = nil - @options = Options.new(:text, VER.options) @encoding = Encoding.default_internal @dirty_indices = [] self.mode = keymap.mode end @@ -89,38 +91,24 @@ def layout view.layout end - # lines start from 1 - # end is maximum lines + 1 def status_projection(into) - format = "%s %s %s [%s]" + format = options.statusline.dup - top, bot = yview + format.gsub!(/%([[:alpha:]]+)/, '#{\1()}') + format.gsub!(/%_([[:alpha:]]+)/, '#{(_ = \1()) ? " #{_}" : ""}') + format.gsub!(/%([+-]?\d+)([[:alpha:]]+)/, '#{\2(\1)}') + format = "%{#{format}}" - if top < 0.5 - percent = '[top]' - elsif bot > 99.5 - percent = '[bot]' - else - percent = "#{bot.to_i}%" - end + context = Status::Context.new(self) + line = context.instance_eval(format) - additional = [keymap.mode] - syntax_name = syntax.name if syntax - additional << syntax_name if syntax_name - additional << @encoding - - values = [ - short_filename, - index(:insert).idx, - percent, - additional.join(' | '), - ] - - into.value = format % values + into.value = line + rescue => ex + puts ex, ex.backtrace end TAG_ALL_MATCHING_OPTIONS = { from: '1.0', to: 'end - 1 chars' } def tag_all_matching(name, regexp, options = {}) @@ -181,55 +169,18 @@ super return unless mark_name == :insert Tk::Event.generate(self, '<<Movement>>') end - def refresh_selection - return unless start = selection_start + def insert(index, string) + index = index(index) unless index.respond_to?(:to_index) - now = index(:insert) - left, right = [start, now].sort - tag_remove :sel, '1.0', 'end' - - case selection_mode - when :select_char - tag_add :sel, left, "#{right} + 1 chars" - when :select_line - tag_add :sel, "#{left} linestart", "#{right} lineend" - when :select_block - ly, lx = left.split - ry, rx = right.split - - from_y, to_y = [ly, ry].sort - from_x, to_x = [lx, rx].sort - - from_y.upto to_y do |y| - tag_add :sel, "#{y}.#{from_x}", "#{y}.#{to_x + 1}" - end + undo_record do |record| + record.insert(index, string) end end - # fix the ruby definition of delete, Tk allows more than 2 indices - def delete(*args) - if args.size > 2 - deleted = args.each_slice(2).map{|left, right| get(left, right) } - else - deleted = get(*args) - end - - copy(deleted) - - execute('delete', *args) - - touch!(*args) - end - - def insert(*args) - super - touch!(args.first) - end - # Replaces the range of characters between index1 and index2 with the given # characters and tags. # See the section on [insert] for an explanation of the handling of the # tag_list arguments, and the section on [delete] for an explanation # of the handling of the indices. @@ -239,13 +190,18 @@ # of the window or movement of insertion cursor occurs. # In addition the undo/redo stack are correctly modified, if undo operations # are active in the text widget. # # replace index1 index2 chars ?tagList chars tagList ...? - def replace(index1, index2, *rest) - super - touch!(*index(index1).upto(index(index2)).to_a) + def replace(index1, index2, string) + index1 = index(index1) unless index1.respond_to?(:to_index) + index2 = index(index2) unless index2.respond_to?(:to_index) + return if index1 == index2 + + undo_record do |record| + record.replace(index1, index2, string) + end end def focus super Tk::Event.generate(self, '<<Focus>>') @@ -280,10 +236,11 @@ return unless filename return if @encoding == Encoding::BINARY if @syntax = Syntax.from_filename(filename) defer{ syntax.highlight(self, value) } + status_projection(status) if status end end def schedule_line_highlight(raw_index) return unless @syntax @@ -294,10 +251,17 @@ def schedule_highlight(options = {}) return unless @syntax schedule_highlight! end + # TODO: maybe we can make this one faster when many lines are going to be + # highlighted at once by bundling them. + def touch!(*args) + args.each{|arg| schedule_line_highlight(arg) } if @syntax + Tk::Event.generate(self, '<<Modified>>') + end + private def schedule_highlight!(*args) defer do syntax.highlight(self, value) @@ -313,26 +277,20 @@ tag_all_trailing_whitespace(from: from, to: to) tag_all_uris(from: from, to: to) end end - # TODO: maybe we can make this one faster when many lines are going to be - # highlighted at once by bundling them. - def touch!(*args) - args.each{|arg| schedule_line_highlight(arg) } if @syntax - Tk::Event.generate(self, '<<Modified>>') - end - def mode=(name) keymap.mode = mode = name.to_sym - edit_separator + undo_separator apply_mode_style(mode) status_projection(status) if status end def apply_mode_style(mode) cursor = MODE_CURSOR[mode] + return unless cursor configure cursor return unless status && color = cursor[:insertbackground] style = status.style Tk::Tile::Style.configure style, fieldbackground: color @@ -424,10 +382,14 @@ VER.error(ex) end end end - def font(options) - VER.options[:font].configure options + def font(given_options = nil) + if given_options + options.font.configure(given_options) + else + options.font + end end end end