lib/ver.rb in ver-2009.11.29 vs lib/ver.rb in ver-2009.12.14
- old
+ new
@@ -1,7 +1,7 @@
-# Well begun is half done.
-# -- Aristotle
+# Man must shape his tools lest they shape him.
+# -- Arthur R. Miller
# lazy stdlib
autoload :Benchmark, 'benchmark'
autoload :FileUtils, 'fileutils'
@@ -12,11 +12,14 @@
require 'digest/sha1'
require 'json'
# require 'pp'
require 'securerandom'
require 'set'
+require 'pathname'
+autoload :SizedArray, 'ver/vendor/sized_array'
+
module VER
autoload :Entry, 'ver/entry'
autoload :Help, 'ver/help'
autoload :Font, 'ver/font'
autoload :HoverCompletion, 'ver/hover_completion'
@@ -29,66 +32,39 @@
autoload :Text, 'ver/text'
autoload :Textpow, 'ver/vendor/textpow'
autoload :Levenshtein, 'ver/vendor/levenshtein'
autoload :Theme, 'ver/theme'
autoload :View, 'ver/view'
+ autoload :ExceptionView, 'ver/exception_view'
+ autoload :Bookmarks, 'ver/methods/bookmark'
+ autoload :Bookmark, 'ver/methods/bookmark'
+ autoload :Undo, 'ver/undo'
require 'ver/options'
@options = Options.new(:ver)
class << self
- attr_reader :root, :layout, :status, :paths, :options
+ attr_reader(:root, :layout, :status, :paths, :options, :bookmarks,
+ :ctag_stack)
end
+ # the rest of the options are in config/rc.rb
options.dsl do
- o "Default Font for all widgets",
- :font, "TkFixedFont 10"
+ o "Fork off on startup to avoid dying with the terminal",
+ :fork, true
o "Internal:External encoding",
:encoding, "UTF-8:UTF-8"
- o "Tk Tile Theme",
- :tk_theme, 'clam'
-
- o "Syntax highlighting theme",
- :theme, "Blackboard"
-
o "Keymap used",
:keymap, 'vim'
- o "Expand all tabs into spaces",
- :expandtab, true
-
- o "Use automatic indentation",
- :autoindent, true
-
- o "Number of spaces used in autoindent",
- :shiftwidth, 2
-
- o "Number of spaces a tab stands for",
- :tabstop, 8
-
- o "Number of characters after which wrap commands will wrap",
- :textwidth, 80
-
- o "In case of a total failure, this key binding should bail you out",
- :emergency_exit, "<Control-q>"
-
- o "Fork off on startup to avoid dying with the terminal",
- :fork, true
-
- o "Milliseconds that the cursor is visible when blinking",
- :insertontime, 500
-
- o "Milliseconds that the cursor is invisible when blinking",
- :insertofftime, 0
-
o "Width of one tab in pixel",
:tabs, 10
- o "Default filetype if no matching syntax can be found",
- :filetype, "Plain Text"
+ o "Minimum size of search term to start incremental highlighting",
+ :search_incremental_min, 1
o "Location of personal configuration",
:home_conf_dir, Pathname('~/.config/ver').expand_path
o "Location of system-wide configuration",
@@ -102,43 +78,60 @@
def loadpath
options.loadpath
end
- def run(given_options = {})
- @options.merge!(given_options)
-
+ def run(given_options = {}, &block)
setup_tk
+ run_startup(given_options)
- if Tk::RUN_EVENTLOOP_ON_MAIN_THREAD
- run_aqua
- else
- run_x11
+ forking do
+ if Tk::RUN_EVENTLOOP_ON_MAIN_THREAD
+ run_aqua(&block)
+ else
+ run_x11(&block)
+ end
end
rescue => exception
VER.error(exception)
exit
end
- def run_aqua
+ def run_aqua(&block)
run_core
- EM.run{ Tk.mainloop }
+ EM.defer(&block) if block
+ Tk.mainloop
end
- def run_x11
- EM.run do
- EM.defer do
- run_core
- Tk.mainloop
+ def run_x11(&block)
+ EM.defer do
+ run_core
+ EM.defer(&block) if block
+ Tk.mainloop
+ end
+ end
+
+ def forking
+ if options.fork
+ fork do
+ trap(:HUP){ 'terminal disconnected' }
+ EM.run{ yield }
end
+ else
+ EM.run{ yield }
end
end
- def run_core
+ def run_startup(given_options)
first_startup unless options.home_conf_dir.directory?
load 'rc'
+ @options.merge!(given_options)
+ end
+
+ def run_core
sanitize_options
+ # dump_options
setup_widgets
open_argv || open_welcome
emergency_bindings
end
@@ -149,17 +142,24 @@
def setup_widgets
Tk::Tile.set_theme options.tk_theme
@paths = Set.new
+
@root = Tk.root
@root.wm_geometry = '160x80'
+
@layout = Layout.new(@root)
@layout.strategy = Layout::VerticalTiling
+
@status = Entry.new(@root, font: options.font)
@status.insert :end, 'For information about VER, type F1'
@status.pack(fill: :x)
+
+ @exception_view = nil
+ @bookmarks = Bookmarks.new
+ @ctag_stack = []
end
def sanitize_options
font = options.font
@@ -266,102 +266,56 @@
def opened_file(text)
@paths << text.filename
end
+ def dump_options
+ out = []
+
+ options.each_pair do |key, value|
+ out << [key,
+ case value
+ when Tk::Font
+ "VER::Font[%p]" % [value.actual_hash]
+ when Pathname
+ value.to_s
+ else
+ value
+ end
+ ]
+ end
+
+ out.each do |pair|
+ puts("VER.options.%s = %p" % pair)
+ end
+ end
+
def error(exception)
@status.value = exception.message if @status
- error_tree(exception) if @root
+ exception_view(exception) if @root
$stderr.puts("#{exception.class}: #{exception}", *exception.backtrace)
rescue Errno::EIO
# The original terminal has disappeared, the $stderr pipe was closed on the
# other side.
[$stderr, $stdout, $stdin].each(&:close)
rescue IOError
# Our pipes are closed, maybe put some output to a file logger here, or display
# in a nicer way, maybe let it bubble up to Tk handling.
end
- def error_tree(exception)
- @tree ||= Tk::Tile::Treeview.new(@root)
- @tree.clear
+ def exception_view(exception)
+ unless @exception_view
+ @exception_view ||= ExceptionView.new(@root)
- @tree.configure(
- columns: %w[line method],
- displaycolumns: %w[line method]
- )
- @tree.heading('#0', text: 'File')
- @tree.heading('line', text: 'Line')
- @tree.heading('method', text: 'Method')
- @tree.tag_configure('error', background: '#f88')
- @tree.tag_configure('backtrace', background: '#8f8')
+ @exception_view.bind '<<TreeviewOpen>>' do
+ @exception_view.on_treeview_open
+ end
- context_size = 7
- frames = {}
- error_tags = ['error']
- backtrace_tags = ['backtrace']
-
- # from Rack::ShowExceptions
- exception.backtrace.each do |line|
- next unless line =~ /(.*?):(\d+)(:in `(.*)')?/
- filename, lineno, function = $1, $2.to_i, $4
-
- item = @tree.insert(nil, :end,
- text: filename, values: [lineno, function], tags: error_tags)
-
- begin
- lines = ::File.readlines(filename)
- _lineno = lineno - 1
-
- first_lineno = [_lineno - context_size, 0].max
- last_lineno = [_lineno + context_size, lines.size].min
- context = lines[first_lineno..last_lineno]
-
- frames[item.id] = {
- filename: filename,
- lineno: lineno,
- function: function,
- first_lineno: first_lineno,
- last_lineno: last_lineno,
- context: context,
- }
- rescue => ex
- puts ex, ex.backtrace
+ @exception_view.bind '<Escape>' do
+ @exception_view.pack_forget
+ @layout.views.first.focus
end
end
- @tree.focus
- @tree.pack expand: true, fill: :both
-
- @tree.bind('<<TreeviewOpen>>'){|event|
- begin
- item = @tree.focus_item
- frame = frames[item.id]
-
- case frame
- when Hash
- filename, lineno, first_lineno, context =
- frame.values_at(:filename, :lineno, :first_lineno, :context)
-
- context.each_with_index{|line, idx|
- line_lineno = first_lineno + idx + 1
- tags = line_lineno == lineno ? error_tags : backtrace_tags
- line_item = item.insert(:end,
- text: line, values: [line_lineno], tags: tags)
- frames[line_item.id] = [filename, lineno]
- }
- when Array
- filename, lineno = frame
- @layout.views.first.find_or_create(filename, lineno){|view|
- @tree.pack_forget
- }
- end
- rescue => ex
- puts ex, ex.backtrace
- end
- }
- @tree.bind('<Escape>'){
- @tree.pack_forget
- @layout.views.first.focus
- }
+ @exception_view.show(exception)
end
end