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