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.
- 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,237 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module SublimeDSL
         
     | 
| 
      
 4 
     | 
    
         
            +
            module SublimeText
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              class Menu
         
     | 
| 
      
 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 
     | 
    
         
            +
                  set.items.concat list.map { |h| Item.from_json(h) }
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  set
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                attr_reader :name, :items
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def initialize(name)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @name = name
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @items = []
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def to_dsl
         
     | 
| 
      
 25 
     | 
    
         
            +
                  dsl = "menu #{name.to_source} do\n\n"
         
     | 
| 
      
 26 
     | 
    
         
            +
                  items.each { |i| dsl << "#{i.to_dsl}\n" }
         
     | 
| 
      
 27 
     | 
    
         
            +
                  dsl << "\nend"
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def write(dir)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  file = "#{dir}/#{name}.menu.rb"
         
     | 
| 
      
 32 
     | 
    
         
            +
                  File.open(file, 'wb:utf-8') do |f|
         
     | 
| 
      
 33 
     | 
    
         
            +
                    f.puts '# encoding: utf-8'
         
     | 
| 
      
 34 
     | 
    
         
            +
                    f.puts "\n#{to_dsl}"
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                def export(dir)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  file = "#{dir}/#{name}.sublime-menu"
         
     | 
| 
      
 40 
     | 
    
         
            +
                  File.open(file, 'wb:utf-8') { |f| f.write to_json }
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                def to_json
         
     | 
| 
      
 44 
     | 
    
         
            +
                  "[\n" <<
         
     | 
| 
      
 45 
     | 
    
         
            +
                    items.map { |i| i.to_json('  ') }.join(",\n") <<
         
     | 
| 
      
 46 
     | 
    
         
            +
                  "\n]"
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                class Item
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  def self.from_json(json_hash)
         
     | 
| 
      
 53 
     | 
    
         
            +
                    h = json_hash.dup
         
     | 
| 
      
 54 
     | 
    
         
            +
                    item = Item.new.tap do |i|
         
     | 
| 
      
 55 
     | 
    
         
            +
                      i.caption = h.delete('caption')
         
     | 
| 
      
 56 
     | 
    
         
            +
                      i.mnemonic = h.delete('mnemonic')
         
     | 
| 
      
 57 
     | 
    
         
            +
                      cmd = h.delete('command')
         
     | 
| 
      
 58 
     | 
    
         
            +
                      args = h.delete('args')
         
     | 
| 
      
 59 
     | 
    
         
            +
                      i.command = Command.new(cmd, args) if cmd
         
     | 
| 
      
 60 
     | 
    
         
            +
                      i.id = h.delete('id')
         
     | 
| 
      
 61 
     | 
    
         
            +
                      i.checkbox = h.delete('checkbox')
         
     | 
| 
      
 62 
     | 
    
         
            +
                      i.platform = h.delete('platform')
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
                    children = h.delete('children') || []
         
     | 
| 
      
 65 
     | 
    
         
            +
                    children.each do |c|
         
     | 
| 
      
 66 
     | 
    
         
            +
                      item.items << Item.from_json(c)
         
     | 
| 
      
 67 
     | 
    
         
            +
                    end
         
     | 
| 
      
 68 
     | 
    
         
            +
                    h.empty? or warn "unkown keys ignored: #{h.inspect}"
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                    item
         
     | 
| 
      
 71 
     | 
    
         
            +
                  end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                  attr_accessor :command, :caption, :mnemonic, :id, :checkbox, :platform
         
     | 
| 
      
 74 
     | 
    
         
            +
                  attr_reader :items
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                  def initialize()
         
     | 
| 
      
 77 
     | 
    
         
            +
                    @command = nil
         
     | 
| 
      
 78 
     | 
    
         
            +
                    @caption = nil
         
     | 
| 
      
 79 
     | 
    
         
            +
                    @mnemonic = nil
         
     | 
| 
      
 80 
     | 
    
         
            +
                    @id = nil
         
     | 
| 
      
 81 
     | 
    
         
            +
                    @checkbox = nil
         
     | 
| 
      
 82 
     | 
    
         
            +
                    @platform = nil
         
     | 
| 
      
 83 
     | 
    
         
            +
                    @items = []
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                  def to_dsl(indent = '  ')
         
     | 
| 
      
 87 
     | 
    
         
            +
                    args = ''
         
     | 
| 
      
 88 
     | 
    
         
            +
                    options = []
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                    if caption
         
     | 
| 
      
 91 
     | 
    
         
            +
                      cap = caption.gsub('&', '&&')
         
     | 
| 
      
 92 
     | 
    
         
            +
                      if mnemonic
         
     | 
| 
      
 93 
     | 
    
         
            +
                        if cap =~ /^(.*?)(#{mnemonic})(.*)$/i
         
     | 
| 
      
 94 
     | 
    
         
            +
                          args << "#{$1}&#{$2}#{$3}".to_source
         
     | 
| 
      
 95 
     | 
    
         
            +
                        else
         
     | 
| 
      
 96 
     | 
    
         
            +
                          args << cap.to_source
         
     | 
| 
      
 97 
     | 
    
         
            +
                          options << "mnemonic: #{mnemonic.to_source}"
         
     | 
| 
      
 98 
     | 
    
         
            +
                        end
         
     | 
| 
      
 99 
     | 
    
         
            +
                      else
         
     | 
| 
      
 100 
     | 
    
         
            +
                        args << cap.to_source
         
     | 
| 
      
 101 
     | 
    
         
            +
                      end
         
     | 
| 
      
 102 
     | 
    
         
            +
                    end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                    if command
         
     | 
| 
      
 105 
     | 
    
         
            +
                      args << ', ' unless args.empty?
         
     | 
| 
      
 106 
     | 
    
         
            +
                      args << command.to_dsl
         
     | 
| 
      
 107 
     | 
    
         
            +
                      options << "mnemonic: #{mnemonic.to_source}" if caption.nil? && mnemonic
         
     | 
| 
      
 108 
     | 
    
         
            +
                    end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
                    options << "id: #{id.to_source}" if id
         
     | 
| 
      
 111 
     | 
    
         
            +
                    options << "checkbox: true" if checkbox
         
     | 
| 
      
 112 
     | 
    
         
            +
                    options << "platform: #{platform.to_source}" if platform
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                    dsl = "#{indent}item #{args}"
         
     | 
| 
      
 115 
     | 
    
         
            +
                    unless options.empty?
         
     | 
| 
      
 116 
     | 
    
         
            +
                      dsl << ', ' unless args.empty?
         
     | 
| 
      
 117 
     | 
    
         
            +
                      dsl << options.join(', ')
         
     | 
| 
      
 118 
     | 
    
         
            +
                    end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                    unless items.empty?
         
     | 
| 
      
 121 
     | 
    
         
            +
                      i = indent + '  '
         
     | 
| 
      
 122 
     | 
    
         
            +
                      dsl << " do\n"
         
     | 
| 
      
 123 
     | 
    
         
            +
                      items.each do |c|
         
     | 
| 
      
 124 
     | 
    
         
            +
                        dsl << c.to_dsl(i) << "\n"
         
     | 
| 
      
 125 
     | 
    
         
            +
                      end
         
     | 
| 
      
 126 
     | 
    
         
            +
                      dsl << "#{indent}end"
         
     | 
| 
      
 127 
     | 
    
         
            +
                    end
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                    dsl
         
     | 
| 
      
 130 
     | 
    
         
            +
                  end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                  def to_h(include_items = true)
         
     | 
| 
      
 133 
     | 
    
         
            +
                    h = {}
         
     | 
| 
      
 134 
     | 
    
         
            +
                    h['caption'] = caption if caption
         
     | 
| 
      
 135 
     | 
    
         
            +
                    h['mnemonic'] = mnemonic if mnemonic
         
     | 
| 
      
 136 
     | 
    
         
            +
                    h.merge! command.to_h if command
         
     | 
| 
      
 137 
     | 
    
         
            +
                    h['id'] = id if id
         
     | 
| 
      
 138 
     | 
    
         
            +
                    h['checkbox'] = checkbox if checkbox
         
     | 
| 
      
 139 
     | 
    
         
            +
                    h['platform'] = platform if platform
         
     | 
| 
      
 140 
     | 
    
         
            +
                    h['children'] = items.map(&:to_h) if include_items && !items.empty?
         
     | 
| 
      
 141 
     | 
    
         
            +
                    h
         
     | 
| 
      
 142 
     | 
    
         
            +
                  end
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
                  def to_json(indent)
         
     | 
| 
      
 145 
     | 
    
         
            +
                    return indent + JSON.generate(to_h) if items.empty?
         
     | 
| 
      
 146 
     | 
    
         
            +
                    json = indent + JSON.pretty_generate(to_h(false))
         
     | 
| 
      
 147 
     | 
    
         
            +
                    json = json[0..-3] # remove trailing "\n}"
         
     | 
| 
      
 148 
     | 
    
         
            +
                    json.gsub!("\n", "\n#{indent}")
         
     | 
| 
      
 149 
     | 
    
         
            +
                    json << %(,\n#{indent}  "children": [\n)
         
     | 
| 
      
 150 
     | 
    
         
            +
                    ind = indent + '    '
         
     | 
| 
      
 151 
     | 
    
         
            +
                    json << items.map { |i| i.to_json(ind) }.join(",\n")
         
     | 
| 
      
 152 
     | 
    
         
            +
                    json << "\n#{indent}  ]\n#{indent}}"
         
     | 
| 
      
 153 
     | 
    
         
            +
                  end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                class DSLReader < Tools::BlankSlate
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
                  def initialize(file = nil)
         
     | 
| 
      
 161 
     | 
    
         
            +
                    @menus = []
         
     | 
| 
      
 162 
     | 
    
         
            +
                    @item_stack = []
         
     | 
| 
      
 163 
     | 
    
         
            +
                    instance_eval File.read(file, encoding: 'utf-8'), file if file
         
     | 
| 
      
 164 
     | 
    
         
            +
                  end
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                  def _menus
         
     | 
| 
      
 167 
     | 
    
         
            +
                    @menus
         
     | 
| 
      
 168 
     | 
    
         
            +
                  end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                  def menu(name, &block)
         
     | 
| 
      
 171 
     | 
    
         
            +
                    @item_stack.empty? or raise Error, "menu blocks cannot be nested"
         
     | 
| 
      
 172 
     | 
    
         
            +
                    @item_stack.push Menu.new(name)
         
     | 
| 
      
 173 
     | 
    
         
            +
                    instance_eval(&block)
         
     | 
| 
      
 174 
     | 
    
         
            +
                    @menus << @item_stack.pop
         
     | 
| 
      
 175 
     | 
    
         
            +
                  end
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                  def item(*args, &block)
         
     | 
| 
      
 178 
     | 
    
         
            +
                    @item_stack.empty? and raise Error, "'item' is invalid outside of a menu block"
         
     | 
| 
      
 179 
     | 
    
         
            +
                    item = new_item(args)
         
     | 
| 
      
 180 
     | 
    
         
            +
                    @item_stack.last.items << item
         
     | 
| 
      
 181 
     | 
    
         
            +
                    return unless block
         
     | 
| 
      
 182 
     | 
    
         
            +
                    @item_stack.push item
         
     | 
| 
      
 183 
     | 
    
         
            +
                    instance_eval(&block)
         
     | 
| 
      
 184 
     | 
    
         
            +
                    @item_stack.pop
         
     | 
| 
      
 185 
     | 
    
         
            +
                  end
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                  def method_missing(sym, *args, &block)
         
     | 
| 
      
 188 
     | 
    
         
            +
                    @item_stack.empty? and raise Error, "'#{sym}' is invalid outside of a menu block"
         
     | 
| 
      
 189 
     | 
    
         
            +
                    Command.from_method_missing(sym, args)
         
     | 
| 
      
 190 
     | 
    
         
            +
                  end
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
                  def new_item(args)
         
     | 
| 
      
 193 
     | 
    
         
            +
                    args.empty? and raise Error, "no argument for 'item'"
         
     | 
| 
      
 194 
     | 
    
         
            +
                    item = Item.new
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                    # get the caption if any
         
     | 
| 
      
 197 
     | 
    
         
            +
                    if args.first.is_a?(String)
         
     | 
| 
      
 198 
     | 
    
         
            +
                      caption = args.shift
         
     | 
| 
      
 199 
     | 
    
         
            +
                      caption =~ /&([^& ])/ and item.mnemonic = $1.upcase
         
     | 
| 
      
 200 
     | 
    
         
            +
                      item.caption = caption.gsub(/&(.)/, '\1')
         
     | 
| 
      
 201 
     | 
    
         
            +
                      return item if args.empty?
         
     | 
| 
      
 202 
     | 
    
         
            +
                    end
         
     | 
| 
      
 203 
     | 
    
         
            +
             
     | 
| 
      
 204 
     | 
    
         
            +
                    # get the command if any
         
     | 
| 
      
 205 
     | 
    
         
            +
                    cmd = args.first
         
     | 
| 
      
 206 
     | 
    
         
            +
                    if cmd.is_a?(Command)
         
     | 
| 
      
 207 
     | 
    
         
            +
                      cmd.error and raise Error, "item '#{caption}': #{cmd.error}"
         
     | 
| 
      
 208 
     | 
    
         
            +
                      item.command = cmd
         
     | 
| 
      
 209 
     | 
    
         
            +
                      args.shift
         
     | 
| 
      
 210 
     | 
    
         
            +
                      return item if args.empty?
         
     | 
| 
      
 211 
     | 
    
         
            +
                    end
         
     | 
| 
      
 212 
     | 
    
         
            +
             
     | 
| 
      
 213 
     | 
    
         
            +
                    # options
         
     | 
| 
      
 214 
     | 
    
         
            +
                    options = args.first
         
     | 
| 
      
 215 
     | 
    
         
            +
                    args.length == 1 && options.is_a?(Hash) or
         
     | 
| 
      
 216 
     | 
    
         
            +
                      raise Error, "invalid arguments for 'item': #{args.inspect}"
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
                    item.id = options.delete(:id)
         
     | 
| 
      
 219 
     | 
    
         
            +
                    item.checkbox = options.delete(:checkbox)
         
     | 
| 
      
 220 
     | 
    
         
            +
                    item.platform = options.delete(:platform)
         
     | 
| 
      
 221 
     | 
    
         
            +
                    mnemonic = options.delete(:mnemonic)
         
     | 
| 
      
 222 
     | 
    
         
            +
                    if mnemonic
         
     | 
| 
      
 223 
     | 
    
         
            +
                      item.mnemonic && mnemonic != item.mnemonic and
         
     | 
| 
      
 224 
     | 
    
         
            +
                        warn "item '#{caption}': mnemonic #{item.mnemonic} overwritten by #{mnemonic}"
         
     | 
| 
      
 225 
     | 
    
         
            +
                      item.mnemonic = mnemonic
         
     | 
| 
      
 226 
     | 
    
         
            +
                    end
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
                    item
         
     | 
| 
      
 229 
     | 
    
         
            +
                  end
         
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
      
 231 
     | 
    
         
            +
                end
         
     | 
| 
      
 232 
     | 
    
         
            +
             
     | 
| 
      
 233 
     | 
    
         
            +
             
     | 
| 
      
 234 
     | 
    
         
            +
              end
         
     | 
| 
      
 235 
     | 
    
         
            +
             
     | 
| 
      
 236 
     | 
    
         
            +
            end
         
     | 
| 
      
 237 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,149 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module SublimeDSL
         
     | 
| 
      
 4 
     | 
    
         
            +
            module SublimeText
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              class Mouse
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def self.sublime
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @sublime ||= create_sublime_mouse
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def self.create_sublime_mouse
         
     | 
| 
      
 13 
     | 
    
         
            +
                  mouse = new('Sublime Text')
         
     | 
| 
      
 14 
     | 
    
         
            +
                  (1..9).each { |i| mouse.add_button "button#{i}" }
         
     | 
| 
      
 15 
     | 
    
         
            +
                  mouse.add_button "scroll_up"
         
     | 
| 
      
 16 
     | 
    
         
            +
                  mouse.add_button "scroll_down"
         
     | 
| 
      
 17 
     | 
    
         
            +
                  %w(shift ctrl alt super).each { |m| mouse.add_modifier m }
         
     | 
| 
      
 18 
     | 
    
         
            +
                  mouse.modifiers.concat mouse.buttons
         
     | 
| 
      
 19 
     | 
    
         
            +
                  mouse
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                attr_reader :name, :buttons, :modifiers
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def initialize(name)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @name = name
         
     | 
| 
      
 26 
     | 
    
         
            +
                  @buttons = []
         
     | 
| 
      
 27 
     | 
    
         
            +
                  @modifiers = []
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @clicks = []
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                alias to_s name
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                def clone(name)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  clone = Mouse.new(name)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  buttons.each { |b| clone.add_button b.st_name, b.name }
         
     | 
| 
      
 36 
     | 
    
         
            +
                  (modifiers - buttons).each { |m| clone.add_modifier m.st_name, m.name }
         
     | 
| 
      
 37 
     | 
    
         
            +
                  clone.modifiers.concat clone.buttons
         
     | 
| 
      
 38 
     | 
    
         
            +
                  clone
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                def button(name)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  buttons.find { |b| b.name == name }
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                def modifier(name)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  modifiers.find { |b| b.name == name }
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                def add_button(st_name, name = nil)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  @buttons << Button.new(st_name, name)
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                def add_modifier(st_name, name = nil)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  @modifiers << Button.new(st_name, name)
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                def clicks_hash
         
     | 
| 
      
 58 
     | 
    
         
            +
                  @clicks_hash ||= {}
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                def modifiers_index_hash
         
     | 
| 
      
 62 
     | 
    
         
            +
                  @modifiers_index_hash ||= begin
         
     | 
| 
      
 63 
     | 
    
         
            +
                    h = {}
         
     | 
| 
      
 64 
     | 
    
         
            +
                    modifiers.each_with_index { |b,i| h[b.name] = i }
         
     | 
| 
      
 65 
     | 
    
         
            +
                    h
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                def ensure_click(spec)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  *modifier_names, button_name = spec.split('+')
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  button = button(button_name) or
         
     | 
| 
      
 73 
     | 
    
         
            +
                    raise Error, "invalid button #{button_name.inspect}"
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  # check & reorder the modifiers
         
     | 
| 
      
 76 
     | 
    
         
            +
                  unless modifier_names.empty?
         
     | 
| 
      
 77 
     | 
    
         
            +
                    sorted = []
         
     | 
| 
      
 78 
     | 
    
         
            +
                    modifier_names.each do |name|
         
     | 
| 
      
 79 
     | 
    
         
            +
                      i = modifiers_index_hash[name]
         
     | 
| 
      
 80 
     | 
    
         
            +
                      i or raise Error, "invalid modifier #{name.inspect}"
         
     | 
| 
      
 81 
     | 
    
         
            +
                      sorted[i] = name
         
     | 
| 
      
 82 
     | 
    
         
            +
                    end
         
     | 
| 
      
 83 
     | 
    
         
            +
                    modifier_names = sorted.compact
         
     | 
| 
      
 84 
     | 
    
         
            +
                  end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                  # if there is a registered click for this spec, return it
         
     | 
| 
      
 87 
     | 
    
         
            +
                  std_spec = [*modifier_names, button_name].join('+')
         
     | 
| 
      
 88 
     | 
    
         
            +
                  click = clicks_hash[std_spec]
         
     | 
| 
      
 89 
     | 
    
         
            +
                  return click if click
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                  # can't have the button in the modifiers
         
     | 
| 
      
 92 
     | 
    
         
            +
                  modifier_names.include?(button_name) and
         
     | 
| 
      
 93 
     | 
    
         
            +
                    raise Error, "can't have the button in the modifiers: #{spec.inspect}"
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
                  # create and register the click
         
     | 
| 
      
 96 
     | 
    
         
            +
                  modifiers = modifier_names.map { |n| modifier(n) }
         
     | 
| 
      
 97 
     | 
    
         
            +
                  click = Click.new(modifiers, button)
         
     | 
| 
      
 98 
     | 
    
         
            +
                  clicks_hash[click.to_spec] = click
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                  click
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
                ##
         
     | 
| 
      
 105 
     | 
    
         
            +
                # A mouse button or modifier.
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                class Button
         
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
      
 109 
     | 
    
         
            +
                  attr_reader :st_name
         
     | 
| 
      
 110 
     | 
    
         
            +
                  attr_accessor :name
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                  def initialize(st_name, name)
         
     | 
| 
      
 113 
     | 
    
         
            +
                    @st_name = st_name
         
     | 
| 
      
 114 
     | 
    
         
            +
                    @name = name || st_name
         
     | 
| 
      
 115 
     | 
    
         
            +
                  end
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                end
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                ##
         
     | 
| 
      
 121 
     | 
    
         
            +
                # A mouse click: button + modifiers.
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                class Click
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
                  attr_reader :button, :modifiers
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
                  def initialize(modifiers, button)
         
     | 
| 
      
 128 
     | 
    
         
            +
                    @modifiers = modifiers
         
     | 
| 
      
 129 
     | 
    
         
            +
                    @button = button
         
     | 
| 
      
 130 
     | 
    
         
            +
                  end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                  def to_spec
         
     | 
| 
      
 133 
     | 
    
         
            +
                    [*modifiers.map(&:name), button.name].join('+')
         
     | 
| 
      
 134 
     | 
    
         
            +
                  end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                  alias to_s to_spec
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                  def to_h
         
     | 
| 
      
 139 
     | 
    
         
            +
                    h = { 'button' => button.st_name }
         
     | 
| 
      
 140 
     | 
    
         
            +
                    h['modifiers'] = modifiers.map(&:st_name) unless modifiers.empty?
         
     | 
| 
      
 141 
     | 
    
         
            +
                    h
         
     | 
| 
      
 142 
     | 
    
         
            +
                  end
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
                end
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
              end
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            end
         
     | 
| 
      
 149 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,185 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module SublimeDSL
         
     | 
| 
      
 4 
     | 
    
         
            +
            module SublimeText
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              class MouseMap
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def self.import(file)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  name = File.basename(file, File.extname(file))
         
     | 
| 
      
 10 
     | 
    
         
            +
                  map = new(name)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  list = JSON[File.read(file, encoding: 'utf-8')]
         
     | 
| 
      
 12 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 13 
     | 
    
         
            +
                    map.bindings.concat list.map { |h| MouseBinding.from_json(h) }
         
     | 
| 
      
 14 
     | 
    
         
            +
                  rescue => ex
         
     | 
| 
      
 15 
     | 
    
         
            +
                    puts "file: #{file}"
         
     | 
| 
      
 16 
     | 
    
         
            +
                    raise ex
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  map
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                attr_reader :name, :bindings
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def initialize(name)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @name = name
         
     | 
| 
      
 26 
     | 
    
         
            +
                  @bindings = []
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def write(dir)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  file = "#{dir}/#{name}.mousemap.rb"
         
     | 
| 
      
 31 
     | 
    
         
            +
                  File.open(file, 'wb') do |f|
         
     | 
| 
      
 32 
     | 
    
         
            +
                    f.puts "\nmousemap #{name.to_source} do"
         
     | 
| 
      
 33 
     | 
    
         
            +
                    f.puts
         
     | 
| 
      
 34 
     | 
    
         
            +
                    bindings.each do |b|
         
     | 
| 
      
 35 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 36 
     | 
    
         
            +
                        f.puts '  ' << b.to_dsl
         
     | 
| 
      
 37 
     | 
    
         
            +
                      rescue => ex
         
     | 
| 
      
 38 
     | 
    
         
            +
                        puts "file: #{file}\nbinding: #{b.click}"
         
     | 
| 
      
 39 
     | 
    
         
            +
                        raise ex
         
     | 
| 
      
 40 
     | 
    
         
            +
                      end
         
     | 
| 
      
 41 
     | 
    
         
            +
                    end
         
     | 
| 
      
 42 
     | 
    
         
            +
                    f.puts "\nend"
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                def export(dir)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  file = "#{dir}/#{name}.sublime-mousemap"
         
     | 
| 
      
 48 
     | 
    
         
            +
                  File.open(file, 'wb:utf-8') { |f| f.write to_json }
         
     | 
| 
      
 49 
     | 
    
         
            +
                end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                def to_json
         
     | 
| 
      
 52 
     | 
    
         
            +
                  "[\n" <<
         
     | 
| 
      
 53 
     | 
    
         
            +
                    bindings.map { |b| JSON.generate(b.to_h) }.join(",\n").indent(2) <<
         
     | 
| 
      
 54 
     | 
    
         
            +
                  "\n]"
         
     | 
| 
      
 55 
     | 
    
         
            +
                end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                ##
         
     | 
| 
      
 59 
     | 
    
         
            +
                # A mouse binding: a click with its command(s).
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                class MouseBinding
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  def self.from_json(json_hash)
         
     | 
| 
      
 64 
     | 
    
         
            +
                    h = json_hash.dup
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                    button = h.delete('button') or raise Error, 'no button: ' << json_hash.inspect
         
     | 
| 
      
 67 
     | 
    
         
            +
                    modifiers = h.delete('modifiers')
         
     | 
| 
      
 68 
     | 
    
         
            +
                    spec = [*modifiers, button].join('+')
         
     | 
| 
      
 69 
     | 
    
         
            +
                    click = Mouse.sublime.ensure_click(spec)
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    count = h.delete('count')
         
     | 
| 
      
 72 
     | 
    
         
            +
                    count = count.to_i if count
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                    press = h.delete('press_command')
         
     | 
| 
      
 75 
     | 
    
         
            +
                    press_command = press ? Command.new(press, h.delete('press_args')) : nil
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                    cmd = h.delete('command')
         
     | 
| 
      
 78 
     | 
    
         
            +
                    command = cmd ? Command.new(cmd, h.delete('args')) : nil
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                    h.empty? or raise Error, 'unexpected JSON keys: ' << h.inspect
         
     | 
| 
      
 81 
     | 
    
         
            +
                    new(click, count, press_command, command)
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  rescue => ex
         
     | 
| 
      
 84 
     | 
    
         
            +
                    warn "error with binding #{json_hash.inspect}"
         
     | 
| 
      
 85 
     | 
    
         
            +
                    warn ex.message
         
     | 
| 
      
 86 
     | 
    
         
            +
                    raise
         
     | 
| 
      
 87 
     | 
    
         
            +
                  end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                  attr_reader :click, :count, :press_command, :command
         
     | 
| 
      
 90 
     | 
    
         
            +
                  attr_accessor :source_file
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                  def initialize(click, count, press_command, command)
         
     | 
| 
      
 93 
     | 
    
         
            +
                    @click = click
         
     | 
| 
      
 94 
     | 
    
         
            +
                    @count = count
         
     | 
| 
      
 95 
     | 
    
         
            +
                    @press_command = press_command
         
     | 
| 
      
 96 
     | 
    
         
            +
                    @command = command
         
     | 
| 
      
 97 
     | 
    
         
            +
                  end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                  def to_dsl
         
     | 
| 
      
 100 
     | 
    
         
            +
                    spec = click.to_spec
         
     | 
| 
      
 101 
     | 
    
         
            +
                    dsl = "click#{count} #{spec.to_source}"
         
     | 
| 
      
 102 
     | 
    
         
            +
                    dsl << ", down: #{press_command.to_dsl}" if press_command
         
     | 
| 
      
 103 
     | 
    
         
            +
                    dsl << ", up: #{command.to_dsl}" if command
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                    dsl
         
     | 
| 
      
 106 
     | 
    
         
            +
                  end
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                  def to_h
         
     | 
| 
      
 109 
     | 
    
         
            +
                    h = click.to_h
         
     | 
| 
      
 110 
     | 
    
         
            +
                    h['count'] = count if count
         
     | 
| 
      
 111 
     | 
    
         
            +
                    h.merge! press_command.to_h('press_command', 'press_args') if press_command
         
     | 
| 
      
 112 
     | 
    
         
            +
                    h.merge! command.to_h if command
         
     | 
| 
      
 113 
     | 
    
         
            +
                    h
         
     | 
| 
      
 114 
     | 
    
         
            +
                  end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                class DSLReader < Tools::BlankSlate
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                  def initialize(file = nil)
         
     | 
| 
      
 122 
     | 
    
         
            +
                    @mousemaps = []
         
     | 
| 
      
 123 
     | 
    
         
            +
                    @current_map = nil
         
     | 
| 
      
 124 
     | 
    
         
            +
                    @mouse = Mouse.sublime
         
     | 
| 
      
 125 
     | 
    
         
            +
                    instance_eval File.read(file, encoding: 'utf-8'), file if file
         
     | 
| 
      
 126 
     | 
    
         
            +
                  end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                  def _mousemaps
         
     | 
| 
      
 129 
     | 
    
         
            +
                    @mousemaps
         
     | 
| 
      
 130 
     | 
    
         
            +
                  end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                  def mousemap(name, &block)
         
     | 
| 
      
 133 
     | 
    
         
            +
                    @current_map and raise Error, "'mousemap' blocks cannot be nested"
         
     | 
| 
      
 134 
     | 
    
         
            +
                    @current_map = MouseMap.new(name)
         
     | 
| 
      
 135 
     | 
    
         
            +
                    instance_eval(&block)
         
     | 
| 
      
 136 
     | 
    
         
            +
                    @mousemaps << @current_map
         
     | 
| 
      
 137 
     | 
    
         
            +
                    @current_map = nil
         
     | 
| 
      
 138 
     | 
    
         
            +
                  end
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                  def button_names(maps={})
         
     | 
| 
      
 141 
     | 
    
         
            +
                    # create a copy of the Sublime mouse
         
     | 
| 
      
 142 
     | 
    
         
            +
                    @mouse = Mouse.sublime.clone('Custom Names')
         
     | 
| 
      
 143 
     | 
    
         
            +
                    maps.each_pair do |name, st_name|
         
     | 
| 
      
 144 
     | 
    
         
            +
                      b = @mouse.modifier(st_name) or
         
     | 
| 
      
 145 
     | 
    
         
            +
                        raise Error, "no button nor modifier named '#{st_name}'"
         
     | 
| 
      
 146 
     | 
    
         
            +
                      b.name = name
         
     | 
| 
      
 147 
     | 
    
         
            +
                    end
         
     | 
| 
      
 148 
     | 
    
         
            +
                  end
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                  def click1(spec, options={})
         
     | 
| 
      
 151 
     | 
    
         
            +
                    click spec, options.merge({ count: 1 })
         
     | 
| 
      
 152 
     | 
    
         
            +
                  end
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
                  def click2(spec, options={})
         
     | 
| 
      
 155 
     | 
    
         
            +
                    click spec, options.merge({ count: 2 })
         
     | 
| 
      
 156 
     | 
    
         
            +
                  end
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                  def click3(spec, options={})
         
     | 
| 
      
 159 
     | 
    
         
            +
                    click spec, options.merge({ count: 3 })
         
     | 
| 
      
 160 
     | 
    
         
            +
                  end
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                  def click(spec, options={})
         
     | 
| 
      
 163 
     | 
    
         
            +
                    @current_map or raise Error, "'click' is invalid outside of a 'mousemap' block"
         
     | 
| 
      
 164 
     | 
    
         
            +
                    click = @mouse.ensure_click(spec)
         
     | 
| 
      
 165 
     | 
    
         
            +
                    count = options.delete(:count)
         
     | 
| 
      
 166 
     | 
    
         
            +
                    press_cmd = options.delete(:down)
         
     | 
| 
      
 167 
     | 
    
         
            +
                    press_cmd && press_cmd.error and raise Error, "click '#{spec}':#{press_cmd.error}"
         
     | 
| 
      
 168 
     | 
    
         
            +
                    cmd = options.delete(:up)
         
     | 
| 
      
 169 
     | 
    
         
            +
                    cmd && cmd.error and raise Error, "click '#{spec}':#{cmd.error}"
         
     | 
| 
      
 170 
     | 
    
         
            +
                    press_cmd || cmd or
         
     | 
| 
      
 171 
     | 
    
         
            +
                      raise Error, "click '#{spec}': no 'up' nor 'down' command"
         
     | 
| 
      
 172 
     | 
    
         
            +
                    @current_map.bindings << MouseBinding.new(click, count, press_cmd, cmd)
         
     | 
| 
      
 173 
     | 
    
         
            +
                  end
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
                  def method_missing(sym, *args, &block)
         
     | 
| 
      
 176 
     | 
    
         
            +
                    @current_map or raise Error, "'#{sym}' is invalid outside of a 'mousemap' block"
         
     | 
| 
      
 177 
     | 
    
         
            +
                    Command.from_method_missing(sym, args)
         
     | 
| 
      
 178 
     | 
    
         
            +
                  end
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
                end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
              end
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
            end
         
     | 
| 
      
 185 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,91 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module SublimeDSL
         
     | 
| 
      
 4 
     | 
    
         
            +
            module SublimeText
         
     | 
| 
      
 5 
     | 
    
         
            +
            class Package
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              ##
         
     | 
| 
      
 8 
     | 
    
         
            +
              # 'Universal' DSL reader: reads any DSL block and updates its package.
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              class DSLReader
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def initialize(file, package)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @file = file
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @package = package
         
     | 
| 
      
 15 
     | 
    
         
            +
                  instance_eval File.read(file, encoding: 'utf-8'), file
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                def method_missing(sym, *args, &block)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  raise DSLError, "'#{sym}' is not a valid Package DSL statement"
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                def theme(*args, &block)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  r = TextMate::Theme::DSLReader.new
         
     | 
| 
      
 24 
     | 
    
         
            +
                  r.theme(*args, &block)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @package.themes.concat r._themes
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def language(*args, &block)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  r = TextMate::Grammar::DSLReader.new
         
     | 
| 
      
 30 
     | 
    
         
            +
                  r.language(*args, &block)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  @package.grammars.concat r._grammars
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def preferences(*args, &block)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  r = TextMate::Preference::DSLReader.new
         
     | 
| 
      
 36 
     | 
    
         
            +
                  r.preferences(*args, &block)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  @package.preferences.concat r._preferences
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def snippets(*args, &block)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  r = TextMate::Snippet::DSLReader.new
         
     | 
| 
      
 42 
     | 
    
         
            +
                  r.snippets(*args, &block)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  @package.snippets.concat r._snippets
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                def settings(*args, &block)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  r = SettingSet::DSLReader.new
         
     | 
| 
      
 48 
     | 
    
         
            +
                  r.settings(*args, &block)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  @package.setting_sets.concat r._setting_sets
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                def macro(*args, &block)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  r = Macro::DSLReader.new
         
     | 
| 
      
 54 
     | 
    
         
            +
                  r.macro(*args, &block)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  @package.macros.concat r._macros
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                def commands(*args, &block)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  r = CommandSet::DSLReader.new
         
     | 
| 
      
 60 
     | 
    
         
            +
                  r.commands(*args, &block)
         
     | 
| 
      
 61 
     | 
    
         
            +
                  @package.command_sets.concat r._command_sets
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                def menu(*args, &block)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  r = Menu::DSLReader.new
         
     | 
| 
      
 66 
     | 
    
         
            +
                  r.menu(*args, &block)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  @package.menus.concat r._menus
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                def mousemap(*args, &block)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  r = MouseMap::DSLReader.new
         
     | 
| 
      
 72 
     | 
    
         
            +
                  r.mousemap(*args, &block)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  @package.mousemaps.concat r._mousemaps
         
     | 
| 
      
 74 
     | 
    
         
            +
                end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                def keymap(*args, &block)
         
     | 
| 
      
 77 
     | 
    
         
            +
                  r = KeyMap::DSLReader.new
         
     | 
| 
      
 78 
     | 
    
         
            +
                  r._file = @file
         
     | 
| 
      
 79 
     | 
    
         
            +
                  r.keymap(*args, &block)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  @package.keymaps.concat r._keymaps
         
     | 
| 
      
 81 
     | 
    
         
            +
                end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                def keyboard(*args, &block)
         
     | 
| 
      
 84 
     | 
    
         
            +
                  raise Error, "keyboards must be defined in a separate *.keyboard.rb file"
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
              end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            end
         
     | 
| 
      
 90 
     | 
    
         
            +
            end
         
     | 
| 
      
 91 
     | 
    
         
            +
            end
         
     |