sublime_dsl 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +136 -0
- data/Rakefile +248 -0
- data/SYNTAX.md +927 -0
- data/bin/subdsl +4 -0
- data/lib/sublime_dsl/cli/export.rb +134 -0
- data/lib/sublime_dsl/cli/import.rb +143 -0
- data/lib/sublime_dsl/cli.rb +125 -0
- data/lib/sublime_dsl/core_ext/enumerable.rb +24 -0
- data/lib/sublime_dsl/core_ext/string.rb +129 -0
- data/lib/sublime_dsl/core_ext.rb +4 -0
- data/lib/sublime_dsl/sublime_text/command.rb +157 -0
- data/lib/sublime_dsl/sublime_text/command_set.rb +112 -0
- data/lib/sublime_dsl/sublime_text/keyboard.rb +659 -0
- data/lib/sublime_dsl/sublime_text/keymap/dsl_reader.rb +194 -0
- data/lib/sublime_dsl/sublime_text/keymap.rb +385 -0
- data/lib/sublime_dsl/sublime_text/macro.rb +91 -0
- data/lib/sublime_dsl/sublime_text/menu.rb +237 -0
- data/lib/sublime_dsl/sublime_text/mouse.rb +149 -0
- data/lib/sublime_dsl/sublime_text/mousemap.rb +185 -0
- data/lib/sublime_dsl/sublime_text/package/dsl_reader.rb +91 -0
- data/lib/sublime_dsl/sublime_text/package/exporter.rb +138 -0
- data/lib/sublime_dsl/sublime_text/package/importer.rb +127 -0
- data/lib/sublime_dsl/sublime_text/package/reader.rb +102 -0
- data/lib/sublime_dsl/sublime_text/package/writer.rb +112 -0
- data/lib/sublime_dsl/sublime_text/package.rb +96 -0
- data/lib/sublime_dsl/sublime_text/setting_set.rb +123 -0
- data/lib/sublime_dsl/sublime_text.rb +48 -0
- data/lib/sublime_dsl/textmate/custom_base_name.rb +45 -0
- data/lib/sublime_dsl/textmate/grammar/dsl_reader.rb +383 -0
- data/lib/sublime_dsl/textmate/grammar/dsl_writer.rb +178 -0
- data/lib/sublime_dsl/textmate/grammar/plist_reader.rb +163 -0
- data/lib/sublime_dsl/textmate/grammar/plist_writer.rb +153 -0
- data/lib/sublime_dsl/textmate/grammar.rb +252 -0
- data/lib/sublime_dsl/textmate/plist.rb +141 -0
- data/lib/sublime_dsl/textmate/preference.rb +301 -0
- data/lib/sublime_dsl/textmate/snippet.rb +437 -0
- data/lib/sublime_dsl/textmate/theme/dsl_reader.rb +87 -0
- data/lib/sublime_dsl/textmate/theme/item.rb +74 -0
- data/lib/sublime_dsl/textmate/theme/plist_writer.rb +53 -0
- data/lib/sublime_dsl/textmate/theme.rb +364 -0
- data/lib/sublime_dsl/textmate.rb +9 -0
- data/lib/sublime_dsl/tools/blank_slate.rb +49 -0
- data/lib/sublime_dsl/tools/console.rb +74 -0
- data/lib/sublime_dsl/tools/helpers.rb +152 -0
- data/lib/sublime_dsl/tools/regexp_wannabe.rb +154 -0
- data/lib/sublime_dsl/tools/stable_inspect.rb +20 -0
- data/lib/sublime_dsl/tools/value_equality.rb +37 -0
- data/lib/sublime_dsl/tools/xml.rb +66 -0
- data/lib/sublime_dsl/tools.rb +66 -0
- data/lib/sublime_dsl.rb +23 -0
- metadata +145 -0
@@ -0,0 +1,157 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module SublimeDSL
|
4
|
+
module SublimeText
|
5
|
+
|
6
|
+
##
|
7
|
+
# A command.
|
8
|
+
|
9
|
+
class Command
|
10
|
+
|
11
|
+
def self.from_method_missing(sym, args)
|
12
|
+
method = sublime_method(sym.to_s)
|
13
|
+
last_word = method.split('_').last
|
14
|
+
case args.length
|
15
|
+
when 0
|
16
|
+
when 1
|
17
|
+
args = args.first.is_a?(Hash) ? args.first : { last_word => args.first }
|
18
|
+
when 2
|
19
|
+
args.last.is_a?(Hash) or
|
20
|
+
return new(sym, args, "invalid arguments to #{method}: #{cmd.args.inspect}")
|
21
|
+
args = { last_word => args.first }.merge(args.last)
|
22
|
+
else
|
23
|
+
return new(sym, args, "invalid arguments to #{method}: #{cmd.args.inspect}")
|
24
|
+
end
|
25
|
+
new(method, args)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.dsl_method(name)
|
29
|
+
if ruby_keyword_hash[name]
|
30
|
+
'_' << name
|
31
|
+
elsif name.start_with?('$')
|
32
|
+
'_dollar_' << name[1..-1]
|
33
|
+
else
|
34
|
+
name
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.sublime_method(name)
|
39
|
+
return name unless name.start_with?('_')
|
40
|
+
m = name[1..-1]
|
41
|
+
if m.start_with?('dollar_')
|
42
|
+
'$' << m[7..-1]
|
43
|
+
elsif ruby_keyword_hash[m]
|
44
|
+
m
|
45
|
+
else
|
46
|
+
name
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.ruby_keyword_hash
|
51
|
+
@ruby_keyword_hash ||= Hash[
|
52
|
+
%w(
|
53
|
+
alias and BEGIN begin break case class def defined? do
|
54
|
+
else elsif END end ensure false for if in module
|
55
|
+
next nil not or redo rescue retry return self super
|
56
|
+
then true undef unless until when while yield
|
57
|
+
).map { |w| [w, true] }
|
58
|
+
]
|
59
|
+
end
|
60
|
+
|
61
|
+
attr_reader :name, :args, :error
|
62
|
+
|
63
|
+
def initialize(name, args, error = nil)
|
64
|
+
@name = name
|
65
|
+
@args =
|
66
|
+
if error
|
67
|
+
args
|
68
|
+
else
|
69
|
+
args ? args.to_a.map { |n,v| Argument.new(n,v) } : []
|
70
|
+
end
|
71
|
+
@error = error
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_h(command_key = 'command', args_key = 'args')
|
75
|
+
if args.empty?
|
76
|
+
{ command_key => name }
|
77
|
+
else
|
78
|
+
args_hash = {}
|
79
|
+
args.each { |a| args_hash[a.name] = a.value }
|
80
|
+
{ command_key => name, args_key => args_hash }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_dsl(statement_style = false)
|
85
|
+
method = Command.dsl_method(name)
|
86
|
+
return method if args.empty?
|
87
|
+
last = name.split('_').last
|
88
|
+
if last == args.first.name
|
89
|
+
arg_list = args.first.to_s(false)
|
90
|
+
arg_list << ', ' << args[1..-1].map(&:to_s).join(', ') if args.length > 1
|
91
|
+
else
|
92
|
+
arg_list = args.map(&:to_s).join(', ')
|
93
|
+
end
|
94
|
+
statement_style ? "#{method} #{arg_list}" : "#{method}(#{arg_list})"
|
95
|
+
end
|
96
|
+
|
97
|
+
alias to_s to_dsl
|
98
|
+
|
99
|
+
include Tools::ValueEquality
|
100
|
+
|
101
|
+
##
|
102
|
+
# A command argument.
|
103
|
+
|
104
|
+
class Argument
|
105
|
+
|
106
|
+
attr_reader :name, :value
|
107
|
+
|
108
|
+
def initialize(name, value)
|
109
|
+
@name = name
|
110
|
+
@value = value
|
111
|
+
end
|
112
|
+
|
113
|
+
def to_s(hash_style = true)
|
114
|
+
if hash_style
|
115
|
+
"#{name}: #{display(value)}"
|
116
|
+
else
|
117
|
+
display(value)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
include Tools::ValueEquality
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
def display(v)
|
126
|
+
case v
|
127
|
+
when String
|
128
|
+
v.inspect
|
129
|
+
when TrueClass, FalseClass, Numeric
|
130
|
+
v.to_s
|
131
|
+
when Array
|
132
|
+
display_array(v)
|
133
|
+
when Hash
|
134
|
+
v.inspect
|
135
|
+
when NilClass
|
136
|
+
'nil'
|
137
|
+
else
|
138
|
+
raise Error, "command argument #{name.inspect} value: #{v.inspect}"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
def display_array(a)
|
143
|
+
if a.empty?
|
144
|
+
'[]'
|
145
|
+
elsif a.all? { |e| e.is_a?(String) && e =~ /\A(\S+)\z/ }
|
146
|
+
"%w(#{a.join(' ')})"
|
147
|
+
else
|
148
|
+
a.inspect
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module SublimeDSL
|
4
|
+
module SublimeText
|
5
|
+
|
6
|
+
class CommandSet
|
7
|
+
|
8
|
+
def self.import(file)
|
9
|
+
name = File.basename(file, File.extname(file))
|
10
|
+
set = new(name)
|
11
|
+
list = JSON[File.read(file, encoding: 'utf-8')]
|
12
|
+
begin
|
13
|
+
set.items.concat list.map { |h| Item.from_json(h) }
|
14
|
+
rescue => ex
|
15
|
+
Console.error "file: #{file}"
|
16
|
+
raise ex
|
17
|
+
end
|
18
|
+
set
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :name, :items
|
22
|
+
|
23
|
+
def initialize(name)
|
24
|
+
@name = name
|
25
|
+
@items = []
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_dsl
|
29
|
+
dsl = "commands #{name.to_source} do\n\n"
|
30
|
+
items.each { |i| dsl << " #{i.to_dsl}\n" }
|
31
|
+
dsl << "\nend"
|
32
|
+
end
|
33
|
+
|
34
|
+
def export(dir)
|
35
|
+
file = "#{dir}/#{name}.sublime-commands"
|
36
|
+
File.open(file, 'wb:utf-8') { |f| f.write to_json }
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_json
|
40
|
+
"[\n" <<
|
41
|
+
items.map { |i| JSON.generate(i.to_h) }.join(",\n").indent(2) <<
|
42
|
+
"\n]"
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
class Item
|
47
|
+
|
48
|
+
def self.from_json(json_hash)
|
49
|
+
h = json_hash.dup
|
50
|
+
cap = h.delete('caption') or raise Error, "no caption: #{json_hash.inspect}"
|
51
|
+
cmd = h.delete('command') or raise Error, "no command: #{json_hash.inspect}"
|
52
|
+
args = h.delete('args')
|
53
|
+
h.empty? or warn "unkown keys ignored: #{h.inspect}"
|
54
|
+
new(cap, Command.new(cmd, args))
|
55
|
+
end
|
56
|
+
|
57
|
+
attr_reader :caption, :command
|
58
|
+
|
59
|
+
def initialize(caption, command)
|
60
|
+
@caption = caption
|
61
|
+
@command = command
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_dsl
|
65
|
+
"item #{caption.to_source}, #{command.to_dsl}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_h
|
69
|
+
{ 'caption' => caption }.merge(command.to_h)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
class DSLReader < Tools::BlankSlate
|
76
|
+
|
77
|
+
def initialize(file = nil)
|
78
|
+
@command_sets = []
|
79
|
+
@current_set = nil
|
80
|
+
instance_eval File.read(file, encoding: 'utf-8'), file if file
|
81
|
+
end
|
82
|
+
|
83
|
+
def _command_sets
|
84
|
+
@command_sets
|
85
|
+
end
|
86
|
+
|
87
|
+
def commands(name, &block)
|
88
|
+
@current_set and raise Error, "'commands' blocks cannot be nested"
|
89
|
+
@current_set = CommandSet.new(name)
|
90
|
+
instance_eval(&block)
|
91
|
+
@command_sets << @current_set
|
92
|
+
@current_set = nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def item(caption, cmd)
|
96
|
+
@current_set or raise Error, "'item' is invalid outside of a 'commands' block"
|
97
|
+
cmd.error and raise Error, "item '#{caption}': #{cmd.error}"
|
98
|
+
@current_set.items << Item.new(caption, cmd)
|
99
|
+
end
|
100
|
+
|
101
|
+
def method_missing(sym, *args, &block)
|
102
|
+
@current_set or raise Error, "'#{sym}' is invalid outside of a 'commands' block"
|
103
|
+
Command.from_method_missing(sym, args)
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|