ver 2009.11.29 → 2009.12.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/AUTHORS +6 -0
- data/CHANGELOG +353 -1
- data/LICENSE +18 -0
- data/MANIFEST +11 -1
- data/Rakefile +2 -1
- data/bin/ver +3 -12
- data/config/detect.rb +1 -1
- data/config/keymap/diakonos.rb +181 -0
- data/config/keymap/emacs.rb +24 -24
- data/config/keymap/vim.rb +162 -127
- data/config/rc.rb +29 -14
- data/config/syntax/Nemerle.json +3 -3
- data/lib/ver.rb +88 -134
- data/lib/ver/entry.rb +5 -0
- data/lib/ver/exception_view.rb +97 -0
- data/lib/ver/hover_completion.rb +14 -7
- data/lib/ver/keymap.rb +30 -1
- data/lib/ver/layout.rb +20 -14
- data/lib/ver/methods.rb +6 -15
- data/lib/ver/methods/bookmark.rb +189 -0
- data/lib/ver/methods/completion.rb +2 -2
- data/lib/ver/methods/control.rb +109 -26
- data/lib/ver/methods/ctags.rb +28 -4
- data/lib/ver/methods/delete.rb +85 -4
- data/lib/ver/methods/insert.rb +73 -52
- data/lib/ver/methods/move.rb +122 -35
- data/lib/ver/methods/open.rb +4 -43
- data/lib/ver/methods/search.rb +46 -17
- data/lib/ver/methods/select.rb +121 -24
- data/lib/ver/methods/undo.rb +23 -0
- data/lib/ver/methods/views.rb +5 -0
- data/lib/ver/mode.rb +18 -17
- data/lib/ver/status.rb +2 -2
- data/lib/ver/status/context.rb +166 -0
- data/lib/ver/text.rb +43 -81
- data/lib/ver/text/index.rb +24 -7
- data/lib/ver/undo.rb +289 -0
- data/lib/ver/vendor/sized_array.rb +70 -0
- data/lib/ver/vendor/textpow.rb +6 -1
- data/lib/ver/version.rb +3 -0
- data/lib/ver/view.rb +11 -8
- data/lib/ver/view/list/grep.rb +15 -4
- data/lib/ver/view/term.rb +9 -3
- data/spec/helper.rb +94 -0
- data/ver.gemspec +9 -6
- metadata +25 -5
- data/spec/keymap.rb +0 -224
data/config/rc.rb
CHANGED
@@ -1,10 +1,28 @@
|
|
1
1
|
VER.options.dsl do
|
2
|
-
o "
|
3
|
-
:
|
2
|
+
o "Use automatic indentation",
|
3
|
+
:autoindent, true
|
4
|
+
|
5
|
+
o "Sequence to comment a line, may change through file type preferences",
|
6
|
+
:comment_line, '#'
|
7
|
+
|
8
|
+
o "Start and end sequence to comment a region, may change through file type preferences",
|
9
|
+
:comment_region, ['=begin', '=end']
|
4
10
|
|
5
11
|
o "Internal:External encoding",
|
6
12
|
:encoding, "UTF-8:UTF-8"
|
7
13
|
|
14
|
+
o "Expand all tabs into spaces",
|
15
|
+
:expandtab, true
|
16
|
+
|
17
|
+
o "In case of a total failure, this key binding should bail you out",
|
18
|
+
:emergency_exit, "<Control-q>"
|
19
|
+
|
20
|
+
o "Default Font for all widgets",
|
21
|
+
:font, "TkFixedFont 10"
|
22
|
+
|
23
|
+
o "Fork off on startup to avoid dying with the terminal",
|
24
|
+
:fork, true
|
25
|
+
|
8
26
|
o "Tk Tile Theme",
|
9
27
|
:tk_theme, 'clam'
|
10
28
|
|
@@ -14,12 +32,6 @@ VER.options.dsl do
|
|
14
32
|
o "Keymap used",
|
15
33
|
:keymap, 'vim'
|
16
34
|
|
17
|
-
o "Expand all tabs into spaces",
|
18
|
-
:expandtab, true
|
19
|
-
|
20
|
-
o "Use automatic indentation",
|
21
|
-
:autoindent, true
|
22
|
-
|
23
35
|
o "Number of spaces used in autoindent",
|
24
36
|
:shiftwidth, 2
|
25
37
|
|
@@ -29,11 +41,14 @@ VER.options.dsl do
|
|
29
41
|
o "Number of characters after which wrap commands will wrap",
|
30
42
|
:textwidth, 80
|
31
43
|
|
32
|
-
o "
|
33
|
-
:
|
44
|
+
o "Minimum size of search term to start incremental highlighting",
|
45
|
+
:search_incremental_min, 1
|
34
46
|
|
35
|
-
o "
|
36
|
-
:
|
47
|
+
o "Show vertical scrollbar",
|
48
|
+
:vertical_scrollbar, false
|
49
|
+
|
50
|
+
o "Show horizontal scrollbar",
|
51
|
+
:horizontal_scrollbar, false
|
37
52
|
|
38
53
|
o "Milliseconds that the cursor is visible when blinking",
|
39
54
|
:insertontime, 500
|
@@ -41,8 +56,8 @@ VER.options.dsl do
|
|
41
56
|
o "Milliseconds that the cursor is invisible when blinking",
|
42
57
|
:insertofftime, 0
|
43
58
|
|
44
|
-
o "
|
45
|
-
:
|
59
|
+
o "Format for Statusline",
|
60
|
+
:statusline, '%r\t%4l,%c %P\t[%m%_s%_e]'
|
46
61
|
|
47
62
|
o "Default filetype if no matching syntax can be found",
|
48
63
|
:filetype, "Plain Text"
|
data/config/syntax/Nemerle.json
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
"fileTypes": [
|
3
3
|
"n"
|
4
4
|
],
|
5
|
-
"foldingStartMarker": "(\\{
|
6
|
-
"foldingStopMarker": "(\\}
|
5
|
+
"foldingStartMarker": "(\\{|\\(|<\\[)",
|
6
|
+
"foldingStopMarker": "(\\}|\\)|\\]>)",
|
7
7
|
"keyEquivalent": "^~N",
|
8
8
|
"name": "Nemerle",
|
9
9
|
"patterns": [
|
@@ -125,4 +125,4 @@
|
|
125
125
|
],
|
126
126
|
"scopeName": "source.nemerle",
|
127
127
|
"uuid": "F563968D-4CB3-11DB-9F95-00112474B8F0"
|
128
|
-
}
|
128
|
+
}
|
data/lib/ver.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
#
|
2
|
-
#
|
1
|
+
# Man must shape his tools lest they shape him.
|
2
|
+
# -- Arthur R. Miller
|
3
3
|
|
4
4
|
# lazy stdlib
|
5
5
|
autoload :Benchmark, 'benchmark'
|
@@ -14,6 +14,9 @@ require 'json'
|
|
14
14
|
# require 'pp'
|
15
15
|
require 'securerandom'
|
16
16
|
require 'set'
|
17
|
+
require 'pathname'
|
18
|
+
|
19
|
+
autoload :SizedArray, 'ver/vendor/sized_array'
|
17
20
|
|
18
21
|
module VER
|
19
22
|
autoload :Entry, 'ver/entry'
|
@@ -31,62 +34,35 @@ module VER
|
|
31
34
|
autoload :Levenshtein, 'ver/vendor/levenshtein'
|
32
35
|
autoload :Theme, 'ver/theme'
|
33
36
|
autoload :View, 'ver/view'
|
37
|
+
autoload :ExceptionView, 'ver/exception_view'
|
38
|
+
autoload :Bookmarks, 'ver/methods/bookmark'
|
39
|
+
autoload :Bookmark, 'ver/methods/bookmark'
|
40
|
+
autoload :Undo, 'ver/undo'
|
34
41
|
|
35
42
|
require 'ver/options'
|
36
43
|
@options = Options.new(:ver)
|
37
44
|
|
38
45
|
class << self
|
39
|
-
attr_reader
|
46
|
+
attr_reader(:root, :layout, :status, :paths, :options, :bookmarks,
|
47
|
+
:ctag_stack)
|
40
48
|
end
|
41
49
|
|
50
|
+
# the rest of the options are in config/rc.rb
|
42
51
|
options.dsl do
|
43
|
-
o "
|
44
|
-
:
|
52
|
+
o "Fork off on startup to avoid dying with the terminal",
|
53
|
+
:fork, true
|
45
54
|
|
46
55
|
o "Internal:External encoding",
|
47
56
|
:encoding, "UTF-8:UTF-8"
|
48
57
|
|
49
|
-
o "Tk Tile Theme",
|
50
|
-
:tk_theme, 'clam'
|
51
|
-
|
52
|
-
o "Syntax highlighting theme",
|
53
|
-
:theme, "Blackboard"
|
54
|
-
|
55
58
|
o "Keymap used",
|
56
59
|
:keymap, 'vim'
|
57
60
|
|
58
|
-
o "Expand all tabs into spaces",
|
59
|
-
:expandtab, true
|
60
|
-
|
61
|
-
o "Use automatic indentation",
|
62
|
-
:autoindent, true
|
63
|
-
|
64
|
-
o "Number of spaces used in autoindent",
|
65
|
-
:shiftwidth, 2
|
66
|
-
|
67
|
-
o "Number of spaces a tab stands for",
|
68
|
-
:tabstop, 8
|
69
|
-
|
70
|
-
o "Number of characters after which wrap commands will wrap",
|
71
|
-
:textwidth, 80
|
72
|
-
|
73
|
-
o "In case of a total failure, this key binding should bail you out",
|
74
|
-
:emergency_exit, "<Control-q>"
|
75
|
-
|
76
|
-
o "Fork off on startup to avoid dying with the terminal",
|
77
|
-
:fork, true
|
78
|
-
|
79
|
-
o "Milliseconds that the cursor is visible when blinking",
|
80
|
-
:insertontime, 500
|
81
|
-
|
82
|
-
o "Milliseconds that the cursor is invisible when blinking",
|
83
|
-
:insertofftime, 0
|
84
|
-
|
85
61
|
o "Width of one tab in pixel",
|
86
62
|
:tabs, 10
|
87
63
|
|
88
|
-
o "
|
89
|
-
:
|
64
|
+
o "Minimum size of search term to start incremental highlighting",
|
65
|
+
:search_incremental_min, 1
|
90
66
|
|
91
67
|
o "Location of personal configuration",
|
92
68
|
:home_conf_dir, Pathname('~/.config/ver').expand_path
|
@@ -104,39 +80,56 @@ module VER
|
|
104
80
|
options.loadpath
|
105
81
|
end
|
106
82
|
|
107
|
-
def run(given_options = {})
|
108
|
-
@options.merge!(given_options)
|
109
|
-
|
83
|
+
def run(given_options = {}, &block)
|
110
84
|
setup_tk
|
85
|
+
run_startup(given_options)
|
111
86
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
87
|
+
forking do
|
88
|
+
if Tk::RUN_EVENTLOOP_ON_MAIN_THREAD
|
89
|
+
run_aqua(&block)
|
90
|
+
else
|
91
|
+
run_x11(&block)
|
92
|
+
end
|
116
93
|
end
|
117
94
|
rescue => exception
|
118
95
|
VER.error(exception)
|
119
96
|
exit
|
120
97
|
end
|
121
98
|
|
122
|
-
def run_aqua
|
99
|
+
def run_aqua(&block)
|
123
100
|
run_core
|
124
|
-
EM.
|
101
|
+
EM.defer(&block) if block
|
102
|
+
Tk.mainloop
|
103
|
+
end
|
104
|
+
|
105
|
+
def run_x11(&block)
|
106
|
+
EM.defer do
|
107
|
+
run_core
|
108
|
+
EM.defer(&block) if block
|
109
|
+
Tk.mainloop
|
110
|
+
end
|
125
111
|
end
|
126
112
|
|
127
|
-
def
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
113
|
+
def forking
|
114
|
+
if options.fork
|
115
|
+
fork do
|
116
|
+
trap(:HUP){ 'terminal disconnected' }
|
117
|
+
EM.run{ yield }
|
132
118
|
end
|
119
|
+
else
|
120
|
+
EM.run{ yield }
|
133
121
|
end
|
134
122
|
end
|
135
123
|
|
136
|
-
def
|
124
|
+
def run_startup(given_options)
|
137
125
|
first_startup unless options.home_conf_dir.directory?
|
138
126
|
load 'rc'
|
127
|
+
@options.merge!(given_options)
|
128
|
+
end
|
129
|
+
|
130
|
+
def run_core
|
139
131
|
sanitize_options
|
132
|
+
# dump_options
|
140
133
|
setup_widgets
|
141
134
|
open_argv || open_welcome
|
142
135
|
emergency_bindings
|
@@ -151,13 +144,20 @@ module VER
|
|
151
144
|
Tk::Tile.set_theme options.tk_theme
|
152
145
|
|
153
146
|
@paths = Set.new
|
147
|
+
|
154
148
|
@root = Tk.root
|
155
149
|
@root.wm_geometry = '160x80'
|
150
|
+
|
156
151
|
@layout = Layout.new(@root)
|
157
152
|
@layout.strategy = Layout::VerticalTiling
|
153
|
+
|
158
154
|
@status = Entry.new(@root, font: options.font)
|
159
155
|
@status.insert :end, 'For information about VER, type F1'
|
160
156
|
@status.pack(fill: :x)
|
157
|
+
|
158
|
+
@exception_view = nil
|
159
|
+
@bookmarks = Bookmarks.new
|
160
|
+
@ctag_stack = []
|
161
161
|
end
|
162
162
|
|
163
163
|
def sanitize_options
|
@@ -268,9 +268,30 @@ module VER
|
|
268
268
|
@paths << text.filename
|
269
269
|
end
|
270
270
|
|
271
|
+
def dump_options
|
272
|
+
out = []
|
273
|
+
|
274
|
+
options.each_pair do |key, value|
|
275
|
+
out << [key,
|
276
|
+
case value
|
277
|
+
when Tk::Font
|
278
|
+
"VER::Font[%p]" % [value.actual_hash]
|
279
|
+
when Pathname
|
280
|
+
value.to_s
|
281
|
+
else
|
282
|
+
value
|
283
|
+
end
|
284
|
+
]
|
285
|
+
end
|
286
|
+
|
287
|
+
out.each do |pair|
|
288
|
+
puts("VER.options.%s = %p" % pair)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
271
292
|
def error(exception)
|
272
293
|
@status.value = exception.message if @status
|
273
|
-
|
294
|
+
exception_view(exception) if @root
|
274
295
|
$stderr.puts("#{exception.class}: #{exception}", *exception.backtrace)
|
275
296
|
rescue Errno::EIO
|
276
297
|
# The original terminal has disappeared, the $stderr pipe was closed on the
|
@@ -281,87 +302,20 @@ module VER
|
|
281
302
|
# in a nicer way, maybe let it bubble up to Tk handling.
|
282
303
|
end
|
283
304
|
|
284
|
-
def
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
@tree.configure(
|
289
|
-
columns: %w[line method],
|
290
|
-
displaycolumns: %w[line method]
|
291
|
-
)
|
292
|
-
@tree.heading('#0', text: 'File')
|
293
|
-
@tree.heading('line', text: 'Line')
|
294
|
-
@tree.heading('method', text: 'Method')
|
295
|
-
@tree.tag_configure('error', background: '#f88')
|
296
|
-
@tree.tag_configure('backtrace', background: '#8f8')
|
297
|
-
|
298
|
-
context_size = 7
|
299
|
-
frames = {}
|
300
|
-
error_tags = ['error']
|
301
|
-
backtrace_tags = ['backtrace']
|
302
|
-
|
303
|
-
# from Rack::ShowExceptions
|
304
|
-
exception.backtrace.each do |line|
|
305
|
-
next unless line =~ /(.*?):(\d+)(:in `(.*)')?/
|
306
|
-
filename, lineno, function = $1, $2.to_i, $4
|
307
|
-
|
308
|
-
item = @tree.insert(nil, :end,
|
309
|
-
text: filename, values: [lineno, function], tags: error_tags)
|
305
|
+
def exception_view(exception)
|
306
|
+
unless @exception_view
|
307
|
+
@exception_view ||= ExceptionView.new(@root)
|
310
308
|
|
311
|
-
|
312
|
-
|
313
|
-
_lineno = lineno - 1
|
314
|
-
|
315
|
-
first_lineno = [_lineno - context_size, 0].max
|
316
|
-
last_lineno = [_lineno + context_size, lines.size].min
|
317
|
-
context = lines[first_lineno..last_lineno]
|
318
|
-
|
319
|
-
frames[item.id] = {
|
320
|
-
filename: filename,
|
321
|
-
lineno: lineno,
|
322
|
-
function: function,
|
323
|
-
first_lineno: first_lineno,
|
324
|
-
last_lineno: last_lineno,
|
325
|
-
context: context,
|
326
|
-
}
|
327
|
-
rescue => ex
|
328
|
-
puts ex, ex.backtrace
|
309
|
+
@exception_view.bind '<<TreeviewOpen>>' do
|
310
|
+
@exception_view.on_treeview_open
|
329
311
|
end
|
330
|
-
end
|
331
|
-
|
332
|
-
@tree.focus
|
333
|
-
@tree.pack expand: true, fill: :both
|
334
312
|
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
frame = frames[item.id]
|
339
|
-
|
340
|
-
case frame
|
341
|
-
when Hash
|
342
|
-
filename, lineno, first_lineno, context =
|
343
|
-
frame.values_at(:filename, :lineno, :first_lineno, :context)
|
344
|
-
|
345
|
-
context.each_with_index{|line, idx|
|
346
|
-
line_lineno = first_lineno + idx + 1
|
347
|
-
tags = line_lineno == lineno ? error_tags : backtrace_tags
|
348
|
-
line_item = item.insert(:end,
|
349
|
-
text: line, values: [line_lineno], tags: tags)
|
350
|
-
frames[line_item.id] = [filename, lineno]
|
351
|
-
}
|
352
|
-
when Array
|
353
|
-
filename, lineno = frame
|
354
|
-
@layout.views.first.find_or_create(filename, lineno){|view|
|
355
|
-
@tree.pack_forget
|
356
|
-
}
|
357
|
-
end
|
358
|
-
rescue => ex
|
359
|
-
puts ex, ex.backtrace
|
313
|
+
@exception_view.bind '<Escape>' do
|
314
|
+
@exception_view.pack_forget
|
315
|
+
@layout.views.first.focus
|
360
316
|
end
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
@layout.views.first.focus
|
365
|
-
}
|
317
|
+
end
|
318
|
+
|
319
|
+
@exception_view.show(exception)
|
366
320
|
end
|
367
321
|
end
|
data/lib/ver/entry.rb
CHANGED
@@ -53,6 +53,7 @@ module VER
|
|
53
53
|
Tk::Event.generate(self, '<<Deleted>>')
|
54
54
|
Tk::Event.generate(self, '<<Modified>>')
|
55
55
|
end
|
56
|
+
alias kill delete # nobody wants to copy that way, right? ;)
|
56
57
|
|
57
58
|
def insert(*args)
|
58
59
|
super
|
@@ -198,6 +199,10 @@ module VER
|
|
198
199
|
delete(*virtual_movement(motion, count))
|
199
200
|
end
|
200
201
|
|
202
|
+
def kill_motion(motion, count = 1)
|
203
|
+
kill(*virtual_movement(motion, count))
|
204
|
+
end
|
205
|
+
|
201
206
|
private
|
202
207
|
|
203
208
|
def virtual_movement(name, count = 1)
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module VER
|
2
|
+
class ExceptionView < Tk::Tile::Treeview
|
3
|
+
OPTIONS = {
|
4
|
+
context: 7,
|
5
|
+
}
|
6
|
+
|
7
|
+
attr_reader :tree, :frames, :context_size, :error_tags, :backtrace_tags
|
8
|
+
|
9
|
+
def initialize(parent, options = {})
|
10
|
+
super
|
11
|
+
|
12
|
+
@frames = {}
|
13
|
+
@context_size = OPTIONS[:context]
|
14
|
+
@error_tags = ['error']
|
15
|
+
@backtrace_tags = ['backtrace']
|
16
|
+
|
17
|
+
setup_config
|
18
|
+
end
|
19
|
+
|
20
|
+
def setup_config
|
21
|
+
configure(
|
22
|
+
columns: %w[line method],
|
23
|
+
displaycolumns: %w[line method]
|
24
|
+
)
|
25
|
+
|
26
|
+
heading('#0', text: 'File')
|
27
|
+
heading('line', text: 'Line')
|
28
|
+
heading('method', text: 'Method')
|
29
|
+
|
30
|
+
tag_configure('error', background: '#f88')
|
31
|
+
tag_configure('backtrace', background: '#8f8')
|
32
|
+
end
|
33
|
+
|
34
|
+
def on_treeview_open
|
35
|
+
item = focus_item
|
36
|
+
frame = frames[item.id]
|
37
|
+
|
38
|
+
case frame
|
39
|
+
when Hash
|
40
|
+
filename, lineno, first_lineno, context =
|
41
|
+
frame.values_at(:filename, :lineno, :first_lineno, :context)
|
42
|
+
|
43
|
+
context.each_with_index{|line, idx|
|
44
|
+
line_lineno = first_lineno + idx + 1
|
45
|
+
tags = line_lineno == lineno ? error_tags : backtrace_tags
|
46
|
+
line_item = item.insert(:end,
|
47
|
+
text: line, values: [line_lineno], tags: tags)
|
48
|
+
frames[line_item.id] = [filename, lineno]
|
49
|
+
}
|
50
|
+
when Array
|
51
|
+
filename, lineno = frame
|
52
|
+
VER.layout.views.first.find_or_create(filename, lineno){|view|
|
53
|
+
pack_forget
|
54
|
+
}
|
55
|
+
end
|
56
|
+
rescue => ex # careful here, don't want infinite loop
|
57
|
+
puts ex, ex.backtrace
|
58
|
+
end
|
59
|
+
|
60
|
+
def show(exception)
|
61
|
+
clear
|
62
|
+
|
63
|
+
# from Rack::ShowExceptions
|
64
|
+
exception.backtrace.each do |line|
|
65
|
+
next unless line =~ /(.*?):(\d+)(:in `(.*)')?/
|
66
|
+
show_line($1, $2.to_i, $4)
|
67
|
+
end
|
68
|
+
|
69
|
+
focus
|
70
|
+
pack expand: true, fill: :both
|
71
|
+
end
|
72
|
+
|
73
|
+
def show_line(filename, lineno, function)
|
74
|
+
item = insert(nil, :end,
|
75
|
+
text: filename, values: [lineno, function], tags: error_tags)
|
76
|
+
|
77
|
+
# may fail from here on without issues.
|
78
|
+
lines = ::File.readlines(filename)
|
79
|
+
_lineno = lineno - 1
|
80
|
+
|
81
|
+
first_lineno = [_lineno - context_size, 0].max
|
82
|
+
last_lineno = [_lineno + context_size, lines.size].min
|
83
|
+
context = lines[first_lineno..last_lineno]
|
84
|
+
|
85
|
+
frames[item.id] = {
|
86
|
+
filename: filename,
|
87
|
+
lineno: lineno,
|
88
|
+
function: function,
|
89
|
+
first_lineno: first_lineno,
|
90
|
+
last_lineno: last_lineno,
|
91
|
+
context: context,
|
92
|
+
}
|
93
|
+
rescue => ex
|
94
|
+
puts ex, ex.backtrace
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|