sublime_dsl 0.1.1

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.
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