ver 2009.10.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/CHANGELOG +1404 -0
- data/MANIFEST +187 -0
- data/Rakefile +30 -0
- data/TODO +169 -0
- data/bin/ver +19 -0
- data/config/detect.rb +109 -0
- data/config/keymap/vim.rb +239 -0
- data/config/rc.rb +0 -0
- data/config/scratch +3 -0
- data/config/syntax/ANTLR.json +275 -0
- data/config/syntax/ASP VB.net.json +228 -0
- data/config/syntax/ASP.json +135 -0
- data/config/syntax/ActionScript.json +168 -0
- data/config/syntax/Ada.json +108 -0
- data/config/syntax/Apache.json +342 -0
- data/config/syntax/AppleScript.json +721 -0
- data/config/syntax/Bibtex.json +253 -0
- data/config/syntax/Blog (HTML).json +47 -0
- data/config/syntax/Blog (Markdown).json +50 -0
- data/config/syntax/Blog (Text).json +45 -0
- data/config/syntax/Blog (Textile).json +45 -0
- data/config/syntax/Bulletin Board.json +428 -0
- data/config/syntax/C++.json +323 -0
- data/config/syntax/C.json +694 -0
- data/config/syntax/CSS.json +346 -0
- data/config/syntax/DOT.json +79 -0
- data/config/syntax/Diff.json +136 -0
- data/config/syntax/Dylan.json +104 -0
- data/config/syntax/Eiffel.json +128 -0
- data/config/syntax/Erlang.json +1636 -0
- data/config/syntax/F-Script.json +137 -0
- data/config/syntax/FXScript.json +260 -0
- data/config/syntax/Gri.json +141 -0
- data/config/syntax/HTML (Mason).json +207 -0
- data/config/syntax/HTML (Rails).json +52 -0
- data/config/syntax/HTML (Tcl).json +42 -0
- data/config/syntax/HTML for ASP.net.json +736 -0
- data/config/syntax/HTML-ASP.json +45 -0
- data/config/syntax/HTML.json +614 -0
- data/config/syntax/Haskell.json +407 -0
- data/config/syntax/Inform.json +80 -0
- data/config/syntax/Ini.json +91 -0
- data/config/syntax/Io.json +142 -0
- data/config/syntax/Java.json +745 -0
- data/config/syntax/JavaProperties.json +42 -0
- data/config/syntax/JavaScript.json +446 -0
- data/config/syntax/LaTeX Beamer.json +65 -0
- data/config/syntax/LaTeX Log.json +88 -0
- data/config/syntax/LaTeX.json +962 -0
- data/config/syntax/Lighttpd.json +93 -0
- data/config/syntax/Lisp.json +101 -0
- data/config/syntax/Literate Haskell.json +55 -0
- data/config/syntax/Logtalk.json +289 -0
- data/config/syntax/Lua.json +146 -0
- data/config/syntax/M.json +744 -0
- data/config/syntax/MEL.json +161 -0
- data/config/syntax/MIPS.json +114 -0
- data/config/syntax/Mail.json +224 -0
- data/config/syntax/Makefile.json +66 -0
- data/config/syntax/Markdown.json +644 -0
- data/config/syntax/Modula-3.json +80 -0
- data/config/syntax/Movable Type.json +348 -0
- data/config/syntax/OCaml.json +1391 -0
- data/config/syntax/Objective-C++.json +21 -0
- data/config/syntax/OpenGL.json +24 -0
- data/config/syntax/PHP.json +2184 -0
- data/config/syntax/Pascal.json +128 -0
- data/config/syntax/Perl.json +2091 -0
- data/config/syntax/Plain text.json +49 -0
- data/config/syntax/Processing.json +188 -0
- data/config/syntax/Quake3 Config.json +54 -0
- data/config/syntax/R.json +157 -0
- data/config/syntax/Rez.json +137 -0
- data/config/syntax/Ruby on Rails.json +170 -0
- data/config/syntax/Ruby.json +1753 -0
- data/config/syntax/SQL (Rails).json +31 -0
- data/config/syntax/SQL.json +435 -0
- data/config/syntax/SWIG.json +96 -0
- data/config/syntax/Scheme.json +359 -0
- data/config/syntax/Shell-Unix-Generic.json +1198 -0
- data/config/syntax/Slate.json +265 -0
- data/config/syntax/Smarty.json +110 -0
- data/config/syntax/Standard ML.json +322 -0
- data/config/syntax/Subversion commit message.json +62 -0
- data/config/syntax/Tcl.json +278 -0
- data/config/syntax/TeX Math.json +83 -0
- data/config/syntax/TeX.json +157 -0
- data/config/syntax/Textile.json +273 -0
- data/config/syntax/Twiki.json +436 -0
- data/config/syntax/Vectorscript.json +97 -0
- data/config/syntax/XML strict.json +148 -0
- data/config/syntax/XML.json +301 -0
- data/config/syntax/XSL.json +96 -0
- data/config/syntax/YAML.json +293 -0
- data/config/syntax/iCalendar.json +51 -0
- data/config/syntax/reStructuredText.json +403 -0
- data/config/theme/Active4D.json +260 -0
- data/config/theme/All Hallow's Eve.json +171 -0
- data/config/theme/Amy.json +359 -0
- data/config/theme/BBEdit.json +269 -0
- data/config/theme/Bespin.json +322 -0
- data/config/theme/Blackboard.json +215 -0
- data/config/theme/BoysAndGirls01.json +156 -0
- data/config/theme/Brilliance Black.json +1695 -0
- data/config/theme/Brilliance Dull.json +1451 -0
- data/config/theme/Classic Modified.json +288 -0
- data/config/theme/Cobalt.json +345 -0
- data/config/theme/Cool Glow.json +215 -0
- data/config/theme/Dawn.json +258 -0
- data/config/theme/Eiffel.json +270 -0
- data/config/theme/Espresso Libre.json +247 -0
- data/config/theme/Fluidvision.json +272 -0
- data/config/theme/IDLE.json +159 -0
- data/config/theme/LAZY.json +178 -0
- data/config/theme/Mac Classic.json +277 -0
- data/config/theme/MagicWB (Amiga).json +231 -0
- data/config/theme/Merbivore Soft.json +181 -0
- data/config/theme/Merbivore.json +181 -0
- data/config/theme/Monokai.json +177 -0
- data/config/theme/Notepad2.json +166 -0
- data/config/theme/Pastels on Dark.json +437 -0
- data/config/theme/RubyBlue.json +226 -0
- data/config/theme/Sin City 2.json +361 -0
- data/config/theme/Slate.json +270 -0
- data/config/theme/Slush & Poppies.json +232 -0
- data/config/theme/SpaceCadet.json +143 -0
- data/config/theme/Sunburst.json +415 -0
- data/config/theme/Twilight BG FG.json +633 -0
- data/config/theme/Twilight.json +321 -0
- data/config/theme/Whys Poignant.json +119 -0
- data/config/theme/Zenburnesque.json +237 -0
- data/config/theme/barf.json +155 -0
- data/config/theme/fake.json +418 -0
- data/config/theme/happydeluxe.json +114 -0
- data/config/theme/iLife 05.json +393 -0
- data/config/theme/iPlastic.json +177 -0
- data/config/theme/mintBlue Dark.json +414 -0
- data/config/theme/mintBlue.json +415 -0
- data/config/theme/monoindustrial.json +276 -0
- data/config/theme/starlight.json +67 -0
- data/config/tutorial +74 -0
- data/config/welcome +115 -0
- data/help/index.verh +14 -0
- data/lib/ver.rb +156 -0
- data/lib/ver/entry.rb +97 -0
- data/lib/ver/keymap.rb +96 -0
- data/lib/ver/layout.rb +107 -0
- data/lib/ver/methods.rb +19 -0
- data/lib/ver/methods/completion.rb +116 -0
- data/lib/ver/methods/control.rb +340 -0
- data/lib/ver/methods/insert.rb +6 -0
- data/lib/ver/methods/move.rb +65 -0
- data/lib/ver/methods/search.rb +33 -0
- data/lib/ver/methods/select.rb +145 -0
- data/lib/ver/methods/views.rb +21 -0
- data/lib/ver/mode.rb +160 -0
- data/lib/ver/options.rb +207 -0
- data/lib/ver/plist.rb +106 -0
- data/lib/ver/status.rb +67 -0
- data/lib/ver/syntax.rb +68 -0
- data/lib/ver/syntax/detector.rb +53 -0
- data/lib/ver/syntax/processor.rb +48 -0
- data/lib/ver/text.rb +374 -0
- data/lib/ver/textpow.rb +357 -0
- data/lib/ver/theme.rb +162 -0
- data/lib/ver/vendor/fuzzy_file_finder.rb +340 -0
- data/lib/ver/view.rb +163 -0
- data/lib/ver/view/entry.rb +28 -0
- data/lib/ver/view/list.rb +137 -0
- data/lib/ver/view/list/buffer.rb +27 -0
- data/lib/ver/view/list/fuzzy_file_finder.rb +44 -0
- data/lib/ver/view/list/syntax.rb +13 -0
- data/lib/ver/view/list/theme.rb +13 -0
- data/spec/keymap.rb +224 -0
- data/tasks/bacon.rake +49 -0
- data/tasks/changelog.rake +18 -0
- data/tasks/gem.rake +22 -0
- data/tasks/gem_installer.rake +76 -0
- data/tasks/grancher.rake +12 -0
- data/tasks/install_dependencies.rake +6 -0
- data/tasks/manifest.rake +4 -0
- data/tasks/plist2json.rake +35 -0
- data/tasks/rcov.rake +18 -0
- data/tasks/release.rake +12 -0
- data/tasks/reversion.rake +8 -0
- data/tasks/syntax_list.rake +31 -0
- data/ver.gemspec +29 -0
- metadata +241 -0
data/lib/ver/textpow.rb
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
# (The MIT License)
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2007 Dizan Vasquez
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
# a copy of this software and associated documentation files (the
|
|
7
|
+
# 'Software'), to deal in the Software without restriction, including
|
|
8
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
# the following conditions:
|
|
12
|
+
#
|
|
13
|
+
# The above copyright notice and this permission notice shall be
|
|
14
|
+
# included in all copies or substantial portions of the Software.
|
|
15
|
+
#
|
|
16
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
20
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
+
|
|
24
|
+
# Copyright (c) 2009 Michael Fellinger
|
|
25
|
+
#
|
|
26
|
+
# Textpow is the underlying library for the UltraViolet syntax-highlighting engine.
|
|
27
|
+
# It appears to be under MIT license, at least that is the only license I could find.
|
|
28
|
+
#
|
|
29
|
+
# So I simply included it into VER and modified it to:
|
|
30
|
+
# * Work faster and more efficient
|
|
31
|
+
# * Use the builtin Nokogiri capabilities of Ruby 1.9
|
|
32
|
+
# * Parse Plists with Nokogiri.
|
|
33
|
+
#
|
|
34
|
+
# There is no dependency on Nokogiri in VER itself, as we ship the converted
|
|
35
|
+
# files as JSON, which is in Ruby stdlib and suited very well for transporting
|
|
36
|
+
# and processing Plists compared to XML or YAML.
|
|
37
|
+
|
|
38
|
+
module Textpow
|
|
39
|
+
class Processor
|
|
40
|
+
def start_parsing(name)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def end_parsing(name)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def new_line(line)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def open_tag(name, pos)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def close_tag(name, mark)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
class SyntaxProxy
|
|
57
|
+
def initialize proxy, syntax
|
|
58
|
+
@proxy, @syntax = proxy, syntax
|
|
59
|
+
@proxy_value = nil
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def method_missing(method, *args, &block)
|
|
63
|
+
if @proxy
|
|
64
|
+
@proxy_value ||= proxy
|
|
65
|
+
|
|
66
|
+
if @proxy_value
|
|
67
|
+
@proxy_value.send(method, *args, &block)
|
|
68
|
+
else
|
|
69
|
+
# warn "Failed proxying #{@proxy}.#{method}(#{args.join(', ')})"
|
|
70
|
+
end
|
|
71
|
+
else
|
|
72
|
+
super
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def proxy
|
|
77
|
+
case @proxy
|
|
78
|
+
when /^#(?<proxy>.+)/
|
|
79
|
+
return unless @syntax.repository
|
|
80
|
+
@syntax.repository[$~[:proxy]]
|
|
81
|
+
when "$self", "$base"
|
|
82
|
+
@syntax
|
|
83
|
+
else
|
|
84
|
+
@syntax.syntaxes[@proxy]
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
class SyntaxNode
|
|
90
|
+
OPTIONS = {} #:options => Oniguruma::OPTION_CAPTURE_GROUP}
|
|
91
|
+
|
|
92
|
+
@@syntaxes = {}
|
|
93
|
+
|
|
94
|
+
attr_accessor :processor, :syntax, :firstLineMatch, :foldingStartMarker,
|
|
95
|
+
:foldingStopMarker, :match, :begin, :content, :fileTypes, :name,
|
|
96
|
+
:contentName, :end, :scopeName, :keyEquivalent, :captures,
|
|
97
|
+
:beginCaptures, :endCaptures, :repository, :patterns
|
|
98
|
+
|
|
99
|
+
def self.load(filename, name_space = :default)
|
|
100
|
+
filename = filename.to_s
|
|
101
|
+
|
|
102
|
+
table =
|
|
103
|
+
case filename
|
|
104
|
+
when /(\.tmSyntax|\.plist)$/
|
|
105
|
+
Plist::parse_xml(filename)
|
|
106
|
+
when /\.json$/i
|
|
107
|
+
JSON.load(File.read(filename))
|
|
108
|
+
when /\.ya?ml$/i
|
|
109
|
+
YAML.load_file(filename)
|
|
110
|
+
else
|
|
111
|
+
raise ArgumentError, "Unknown filename extension"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
SyntaxNode.new(table, nil, name_space) if table
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def initialize(hash, syntax = nil, name_space = :default)
|
|
118
|
+
@name_space = name_space
|
|
119
|
+
|
|
120
|
+
prepare_scope_name(hash['scopeName'])
|
|
121
|
+
|
|
122
|
+
@syntax = syntax || self
|
|
123
|
+
|
|
124
|
+
hash.each do |key, value|
|
|
125
|
+
case key
|
|
126
|
+
when "firstLineMatch", "foldingStartMarker", "foldingStopMarker", "match", "begin"
|
|
127
|
+
begin
|
|
128
|
+
send("#{key}=", Regexp.new(value))
|
|
129
|
+
rescue ArgumentError => exception
|
|
130
|
+
raise ParsingError, "Parsing error in #{value}: #{exception}"
|
|
131
|
+
end
|
|
132
|
+
when "content", "fileTypes", "name", "contentName", "end", "scopeName", "keyEquivalent"
|
|
133
|
+
send("#{key}=", value)
|
|
134
|
+
when "captures", "beginCaptures", "endCaptures"
|
|
135
|
+
send("#{key}=", value.sort)
|
|
136
|
+
when "repository"
|
|
137
|
+
parse_repository value
|
|
138
|
+
when "patterns"
|
|
139
|
+
create_children value
|
|
140
|
+
else
|
|
141
|
+
STDERR.puts "Ignoring: #{key} => #{value.gsub("\n", "\n>>")}" if $DEBUG
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def prepare_scope_name(scopeName)
|
|
147
|
+
@@syntaxes[@name_space] ||= {}
|
|
148
|
+
|
|
149
|
+
return unless scopeName
|
|
150
|
+
|
|
151
|
+
@@syntaxes[@name_space][scopeName] = self
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def syntaxes
|
|
155
|
+
@@syntaxes[@name_space]
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def parse(string, processor = Processor.new)
|
|
159
|
+
processor.start_parsing scopeName
|
|
160
|
+
|
|
161
|
+
stack = [[self, nil]]
|
|
162
|
+
string.each_line do |line|
|
|
163
|
+
parse_line(stack, line, processor)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
processor.end_parsing self.scopeName
|
|
167
|
+
processor
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def parse_repository(repository)
|
|
171
|
+
@repository = {}
|
|
172
|
+
|
|
173
|
+
repository.each do |key, value|
|
|
174
|
+
if include = value["include"]
|
|
175
|
+
@repository[key] = SyntaxProxy.new(include, self.syntax)
|
|
176
|
+
else
|
|
177
|
+
@repository[key] = SyntaxNode.new(value, self.syntax, @name_space)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def create_children(patterns)
|
|
183
|
+
@patterns = []
|
|
184
|
+
syntax = self.syntax
|
|
185
|
+
|
|
186
|
+
patterns.each do |pattern|
|
|
187
|
+
if include = pattern["include"]
|
|
188
|
+
@patterns << SyntaxProxy.new(include, syntax)
|
|
189
|
+
else
|
|
190
|
+
@patterns << SyntaxNode.new(pattern, syntax, @name_space)
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def parse_captures(name, pattern, match, processor)
|
|
196
|
+
all_starts = []
|
|
197
|
+
all_ends = []
|
|
198
|
+
|
|
199
|
+
pattern.match_captures(name, match).each do |group, range, match_name|
|
|
200
|
+
range_first = range.first
|
|
201
|
+
next unless range_first
|
|
202
|
+
|
|
203
|
+
range_last = range.last
|
|
204
|
+
next if range_first == range_last
|
|
205
|
+
|
|
206
|
+
all_starts << [range_first, group, match_name]
|
|
207
|
+
all_ends << [range_last, -group, match_name]
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
starts = all_starts.sort.reverse
|
|
211
|
+
ends = all_ends.sort.reverse
|
|
212
|
+
|
|
213
|
+
until starts.empty? && ends.empty?
|
|
214
|
+
if starts.empty?
|
|
215
|
+
pos, key, name = ends.pop
|
|
216
|
+
processor.close_tag name, pos
|
|
217
|
+
elsif ends.empty?
|
|
218
|
+
pos, key, name = starts.pop
|
|
219
|
+
processor.open_tag name, pos
|
|
220
|
+
elsif ends.last[1].abs < starts.last[1]
|
|
221
|
+
pos, key, name = ends.pop
|
|
222
|
+
processor.close_tag name, pos
|
|
223
|
+
else
|
|
224
|
+
pos, key, name = starts.pop
|
|
225
|
+
processor.open_tag name, pos
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def match_captures(name, match)
|
|
231
|
+
matches = []
|
|
232
|
+
|
|
233
|
+
if captures = send(name)
|
|
234
|
+
captures.each do |key, value|
|
|
235
|
+
if key =~ /^\d*$/
|
|
236
|
+
key = key.to_i
|
|
237
|
+
matches << [key, match.offset(key), value["name"]] if key < match.size
|
|
238
|
+
else
|
|
239
|
+
key = key.to_sym
|
|
240
|
+
match_to_key = match.to_index(key)
|
|
241
|
+
matches << [match_to_key, match.offset(key), value["name"]] if match_to_key
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
matches
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def match_first(string, position)
|
|
250
|
+
if self.match
|
|
251
|
+
if match = self.match.match(string, position)
|
|
252
|
+
return [self, match]
|
|
253
|
+
end
|
|
254
|
+
elsif self_begin = self.begin
|
|
255
|
+
if match = self_begin.match(string, position)
|
|
256
|
+
return [self, match]
|
|
257
|
+
end
|
|
258
|
+
elsif self.end
|
|
259
|
+
else
|
|
260
|
+
return match_first_son(string, position)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
nil
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def match_end(string, match, position)
|
|
267
|
+
regstring = self.end.clone
|
|
268
|
+
regstring.gsub!(/\\([1-9])/){ match[$1.to_i] }
|
|
269
|
+
regstring.gsub!(/\\k<(.*?)>/){ match[$1.to_sym] }
|
|
270
|
+
Regexp.new(regstring).match(string, position)
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def match_first_son(string, position)
|
|
274
|
+
match = nil
|
|
275
|
+
|
|
276
|
+
if patterns
|
|
277
|
+
patterns.each do |pattern|
|
|
278
|
+
tmatch = pattern.match_first(string, position)
|
|
279
|
+
next unless tmatch
|
|
280
|
+
if !match || match[1].offset(0).first > tmatch[1].offset(0).first
|
|
281
|
+
match = tmatch
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
match
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def parse_line(stack, line, processor)
|
|
290
|
+
processor.new_line(line)
|
|
291
|
+
top, match = stack.last
|
|
292
|
+
position = 0
|
|
293
|
+
|
|
294
|
+
while true
|
|
295
|
+
if top.patterns
|
|
296
|
+
pattern, pattern_match = top.match_first_son(line, position)
|
|
297
|
+
else
|
|
298
|
+
pattern, pattern_match = nil
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
end_match = nil
|
|
302
|
+
|
|
303
|
+
if top.end
|
|
304
|
+
end_match = top.match_end( line, match, position)
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
if end_match && ( !pattern_match || pattern_match.offset(0).first >= end_match.offset(0).first )
|
|
308
|
+
pattern_match = end_match
|
|
309
|
+
pattern_match_first_offset = pattern_match.offset(0)
|
|
310
|
+
start_pos = pattern_match_first_offset.first
|
|
311
|
+
end_pos = pattern_match_first_offset.last
|
|
312
|
+
|
|
313
|
+
if processor
|
|
314
|
+
top_contentName = top.contentName
|
|
315
|
+
processor.close_tag top_contentName, start_pos if top_contentName
|
|
316
|
+
|
|
317
|
+
parse_captures "captures", top, pattern_match, processor
|
|
318
|
+
parse_captures "endCaptures", top, pattern_match, processor
|
|
319
|
+
|
|
320
|
+
top_name = top.name
|
|
321
|
+
processor.close_tag top_name, end_pos if top_name
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
stack.pop
|
|
325
|
+
top, match = stack.last
|
|
326
|
+
else
|
|
327
|
+
break unless pattern
|
|
328
|
+
|
|
329
|
+
start_pos = pattern_match.offset(0).first
|
|
330
|
+
end_pos = pattern_match.offset(0).last
|
|
331
|
+
pattern_name = pattern.name
|
|
332
|
+
|
|
333
|
+
if pattern.begin
|
|
334
|
+
if processor
|
|
335
|
+
processor.open_tag pattern_name, start_pos if pattern_name
|
|
336
|
+
parse_captures "captures", pattern, pattern_match, processor
|
|
337
|
+
parse_captures "beginCaptures", pattern, pattern_match, processor
|
|
338
|
+
|
|
339
|
+
pattern_contentName = pattern.contentName
|
|
340
|
+
processor.open_tag pattern_contentName, end_pos if pattern_contentName
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
top = pattern
|
|
344
|
+
match = pattern_match
|
|
345
|
+
stack << [top, match]
|
|
346
|
+
elsif pattern.match and processor
|
|
347
|
+
processor.open_tag pattern_name, start_pos if pattern_name
|
|
348
|
+
parse_captures "captures", pattern, pattern_match, processor
|
|
349
|
+
processor.close_tag pattern_name, end_pos if pattern_name
|
|
350
|
+
end
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
position = end_pos
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
end
|
data/lib/ver/theme.rb
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
module VER
|
|
2
|
+
class Theme < Struct.new(:name, :uuid, :default, :colors)
|
|
3
|
+
def self.list
|
|
4
|
+
VER.loadpath.map{|path| Dir[(path/'theme/*.json').to_s] }.flatten
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def self.find(theme_name)
|
|
8
|
+
VER.find_in_loadpath("theme/#{theme_name}.json")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.load(filename)
|
|
12
|
+
raise(ArgumentError, "No path to theme file given") unless filename
|
|
13
|
+
|
|
14
|
+
json = JSON.load(File.read(filename.to_s))
|
|
15
|
+
|
|
16
|
+
instance = new
|
|
17
|
+
instance.name = json['name']
|
|
18
|
+
instance.uuid = json['uuid']
|
|
19
|
+
|
|
20
|
+
json['settings'].each do |hash|
|
|
21
|
+
next unless settings = hash['settings']
|
|
22
|
+
|
|
23
|
+
if scope_names = hash['scope']
|
|
24
|
+
# specific settings
|
|
25
|
+
scope_names.split(/\s*,\s*/).each do |scope_name|
|
|
26
|
+
instance.set(scope_name, settings)
|
|
27
|
+
end
|
|
28
|
+
else
|
|
29
|
+
# general settings
|
|
30
|
+
instance.default = settings
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
instance
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.find_and_load(theme_name)
|
|
38
|
+
load(find(theme_name))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def initialize(colors = {}, &block)
|
|
42
|
+
self.colors = colors
|
|
43
|
+
instance_eval(&block) if block_given?
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def set(match, options)
|
|
47
|
+
match = normalize(match)
|
|
48
|
+
colors[match] = (colors[match] || {}).merge(sanitize_settings(options))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def get(name)
|
|
52
|
+
name = normalize(name)
|
|
53
|
+
colors.each do |syntax_name, options|
|
|
54
|
+
return syntax_name if name.start_with?(syntax_name)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
nil
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def default=(settings)
|
|
61
|
+
self[:default] = sanitize_settings(settings)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def sanitize_settings(given_settings)
|
|
65
|
+
settings = given_settings.dup
|
|
66
|
+
|
|
67
|
+
settings.keys.each do |key|
|
|
68
|
+
next unless value = settings.delete(key)
|
|
69
|
+
next if value.empty?
|
|
70
|
+
|
|
71
|
+
if value =~ /^(#\h{6})/
|
|
72
|
+
settings[key] = $1
|
|
73
|
+
elsif key.downcase == 'fontstyle'
|
|
74
|
+
styles = value.split
|
|
75
|
+
settings['font'] = TkFont.create_copy(self.font)
|
|
76
|
+
font.configure underline: styles.include?('underline')
|
|
77
|
+
font.configure slant: 'italic' if styles.include?('italic')
|
|
78
|
+
else
|
|
79
|
+
settings[key] = value
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
settings
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def font
|
|
87
|
+
@font ||= VER.options[:font].dup
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def normalize(keyname)
|
|
91
|
+
keyname.tr(' ', '-')
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# -background or -bg, background, Background
|
|
95
|
+
# -borderwidth or -bd, borderWidth, BorderWidth
|
|
96
|
+
# -cursor, cursor, Cursor
|
|
97
|
+
# -font, font, Font
|
|
98
|
+
# -foreground or -fg, foreground, Foreground
|
|
99
|
+
#
|
|
100
|
+
# -highlightbackground, highlightBackground, HighlightBackground
|
|
101
|
+
# -highlightcolor, highlightColor, HighlightColor
|
|
102
|
+
# -highlightthickness, highlightThickness, HighlightThickness
|
|
103
|
+
#
|
|
104
|
+
# -insertbackground, insertBackground, Foreground
|
|
105
|
+
# -insertborderwidth, insertBorderWidth, BorderWidth
|
|
106
|
+
#
|
|
107
|
+
# -insertofftime, insertOffTime, OffTime
|
|
108
|
+
# -insertontime, insertOnTime, OnTime
|
|
109
|
+
#
|
|
110
|
+
# -selectbackground, selectBackground, Foreground
|
|
111
|
+
# -selectborderwidth, selectBorderWidth, BorderWidth
|
|
112
|
+
# -selectforeground, selectForeground, Background
|
|
113
|
+
#
|
|
114
|
+
# -inactiveselectbackground, inactiveSelectBackground, Foreground
|
|
115
|
+
#
|
|
116
|
+
# -spacing1, spacing1, Spacing1
|
|
117
|
+
# -spacing2, spacing2, Spacing2
|
|
118
|
+
# -spacing3, spacing3, Spacing3
|
|
119
|
+
|
|
120
|
+
def apply_default_on(widget)
|
|
121
|
+
default.each do |key, value|
|
|
122
|
+
case key.downcase
|
|
123
|
+
when 'background'
|
|
124
|
+
widget.configure background: value
|
|
125
|
+
when 'caret'
|
|
126
|
+
widget.configure insertbackground: value
|
|
127
|
+
when 'foreground', 'fg'
|
|
128
|
+
widget.configure foreground: value
|
|
129
|
+
when 'invisibles'
|
|
130
|
+
# TODO
|
|
131
|
+
# widget.configure key => value
|
|
132
|
+
when 'linehighlight'
|
|
133
|
+
# TODO
|
|
134
|
+
# widget.configure key => value
|
|
135
|
+
when 'selection'
|
|
136
|
+
widget.configure selectbackground: value
|
|
137
|
+
else
|
|
138
|
+
warn key => value
|
|
139
|
+
widget.configure(key => value)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def create_tags_on(widget)
|
|
145
|
+
colors.each do |name, options|
|
|
146
|
+
TktNamedTag.new(widget, name.to_s, options)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def remove_tags_on(widget)
|
|
151
|
+
colors.each do |name, options|
|
|
152
|
+
widget.tag_remove(name.to_s, '0.0', 'end')
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def delete_tags_on(widget)
|
|
157
|
+
colors.each do |name, option|
|
|
158
|
+
widget.tag_delete(name.to_s)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|