ver 2009.11.29 → 2009.12.14
Sign up to get free protection for your applications and to get access to all the features.
- 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
|