sublime_dsl 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +136 -0
  3. data/Rakefile +248 -0
  4. data/SYNTAX.md +927 -0
  5. data/bin/subdsl +4 -0
  6. data/lib/sublime_dsl/cli/export.rb +134 -0
  7. data/lib/sublime_dsl/cli/import.rb +143 -0
  8. data/lib/sublime_dsl/cli.rb +125 -0
  9. data/lib/sublime_dsl/core_ext/enumerable.rb +24 -0
  10. data/lib/sublime_dsl/core_ext/string.rb +129 -0
  11. data/lib/sublime_dsl/core_ext.rb +4 -0
  12. data/lib/sublime_dsl/sublime_text/command.rb +157 -0
  13. data/lib/sublime_dsl/sublime_text/command_set.rb +112 -0
  14. data/lib/sublime_dsl/sublime_text/keyboard.rb +659 -0
  15. data/lib/sublime_dsl/sublime_text/keymap/dsl_reader.rb +194 -0
  16. data/lib/sublime_dsl/sublime_text/keymap.rb +385 -0
  17. data/lib/sublime_dsl/sublime_text/macro.rb +91 -0
  18. data/lib/sublime_dsl/sublime_text/menu.rb +237 -0
  19. data/lib/sublime_dsl/sublime_text/mouse.rb +149 -0
  20. data/lib/sublime_dsl/sublime_text/mousemap.rb +185 -0
  21. data/lib/sublime_dsl/sublime_text/package/dsl_reader.rb +91 -0
  22. data/lib/sublime_dsl/sublime_text/package/exporter.rb +138 -0
  23. data/lib/sublime_dsl/sublime_text/package/importer.rb +127 -0
  24. data/lib/sublime_dsl/sublime_text/package/reader.rb +102 -0
  25. data/lib/sublime_dsl/sublime_text/package/writer.rb +112 -0
  26. data/lib/sublime_dsl/sublime_text/package.rb +96 -0
  27. data/lib/sublime_dsl/sublime_text/setting_set.rb +123 -0
  28. data/lib/sublime_dsl/sublime_text.rb +48 -0
  29. data/lib/sublime_dsl/textmate/custom_base_name.rb +45 -0
  30. data/lib/sublime_dsl/textmate/grammar/dsl_reader.rb +383 -0
  31. data/lib/sublime_dsl/textmate/grammar/dsl_writer.rb +178 -0
  32. data/lib/sublime_dsl/textmate/grammar/plist_reader.rb +163 -0
  33. data/lib/sublime_dsl/textmate/grammar/plist_writer.rb +153 -0
  34. data/lib/sublime_dsl/textmate/grammar.rb +252 -0
  35. data/lib/sublime_dsl/textmate/plist.rb +141 -0
  36. data/lib/sublime_dsl/textmate/preference.rb +301 -0
  37. data/lib/sublime_dsl/textmate/snippet.rb +437 -0
  38. data/lib/sublime_dsl/textmate/theme/dsl_reader.rb +87 -0
  39. data/lib/sublime_dsl/textmate/theme/item.rb +74 -0
  40. data/lib/sublime_dsl/textmate/theme/plist_writer.rb +53 -0
  41. data/lib/sublime_dsl/textmate/theme.rb +364 -0
  42. data/lib/sublime_dsl/textmate.rb +9 -0
  43. data/lib/sublime_dsl/tools/blank_slate.rb +49 -0
  44. data/lib/sublime_dsl/tools/console.rb +74 -0
  45. data/lib/sublime_dsl/tools/helpers.rb +152 -0
  46. data/lib/sublime_dsl/tools/regexp_wannabe.rb +154 -0
  47. data/lib/sublime_dsl/tools/stable_inspect.rb +20 -0
  48. data/lib/sublime_dsl/tools/value_equality.rb +37 -0
  49. data/lib/sublime_dsl/tools/xml.rb +66 -0
  50. data/lib/sublime_dsl/tools.rb +66 -0
  51. data/lib/sublime_dsl.rb +23 -0
  52. 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