仕様
・DSL向けを想定しているため単純なメソッド名+引数名(複数)で構成されるクラスマクロのみを対象とします。
・ブロックは未対応。
・DSL定義部、DSL利用部、DSL呼出部、Snippetテンプレートの4ファイルから構成され、全て同一フォルダに配置する
・出力結果はカレント配下にsnippetsフォルダを作成し、その配下にメソッド名+「.」+sublme-snippetで出力する。
・DSL利用部は下記のようにメソッド名、引き数名をシンボルで指定する。引数は順序通りにタブ順が決まる。
・DSL呼出部はDSL利用部のテンプレート生成機能を持つ。initを指定して呼び出すこと。
・DSL呼出部をコンソールから引数無しで呼び出しするとSnippetを生成する。
・作成が成功したらSublime Text2のPackages\Userフォルダ配下にコピーすれば利用可能です。
・RubyのDSL向けに作ったのでテンプレートのscopeは「source.ruby」固定にしてあります。
DSL記述イメージ
add :method_name, :args_name1, :args_name1・・・ add :method_name
ソース
DSL定義部ソース
snippetter.rb
# encoding: utf-8 require "pp" require "erb" class TargetMethod attr_accessor :method_name, :args def initialize(&block) instance_eval do block.call(self) end end end module Kernel attr_accessor :_methods SNIPPETS_OUTPUT = "./snippets" def add(method_name, *args) return if method_name.nil? return if method_name.empty? return if args.each.include?(nil) return if args.each.include?("") @_methods ||= [] @_methods << TargetMethod.new do |t| t.method_name = method_name t.args = args end end def generate base_template = File.open("template", "r") {|f|f.read} @_methods.each do |m| template = base_template output(m.method_name, get_snippet(template, m.method_name, get_args_names(m))) end if @_methods end private def get_args_names(_method) args = _method.args args_names = " " args.each_with_index do |a, i| args_names << "${#{i + 1}:#{a}}, " end args_names.chop!.chop! unless args.empty? end def get_snippet(template, method_name, args_names) erb = ERB.new(template) snippet = erb.result(binding) snippet end def output(method_name, snippet) Dir::mkdir(SNIPPETS_OUTPUT) unless FileTest.exist?(SNIPPETS_OUTPUT) file_name = "#{SNIPPETS_OUTPUT}/#{method_name}.sublime-snippet" File::open(file_name, "w") do |f| f.puts snippet end puts "create for #{method_name} method snippet => #{file_name}" end end
DSL利用部設定サンプル
Snippet.rb
# encoding: utf-8 require_relative "./snippetter" add :click, :action, :model, :tag add :data, :key, :value add :submit
DSL呼出部ソース
se.rb
# encoding: utf-8 if $*.size == 1 && $*[0] == "init" File::open("./Snippet.rb", "w") do |f| f.puts <<-EOS # encoding: utf-8 require_relative "./snippetter" # add :method1, :args1, :args2, :args3 # add :method2 EOS end puts "create Snippet.rb template file" exit end unless FileTest.exist?("./Snippet.rb") puts "please create Snippet.rb" puts "you can use 'ruby se.rb init'. then you get Snippet.rb template." exit end require_relative "./snippetter" require_relative "./Snippet" generate
template
<snippet> <content><![CDATA[ <%= method_name %><%= args_names %> ]]></content> <tabTrigger><%= method_name %></tabTrigger> <scope>source.ruby</scope> <description><%= method_name %> method</description> </snippet>
サンプル
実行コマンド
$ruby se.rb create for click method snippet => ./snippets/click.sublime-snippet create for data method snippet => ./snippets/data.sublime-snippet create for submit method snippet => ./snippets/submit.sublime-snippet
出力例
<snippet> <content><![CDATA[ click ${1:action}, ${2:model}, ${3:tag} ]]></content> <tabTrigger>click</tabTrigger> <scope>source.ruby</scope> <description>click method</description> </snippet>
出力も含めたファイル構成
│ se.rb │ Snippet.rb │ snippetter.rb │ template │ └─snippets click.sublime-snippet data.sublime-snippet submit.sublime-snippet