griffin-stewieの日記

2010-10-16

[]XcodeのUserScript

Cocoaの日々: Xcode のマクロ定義

こちらの記事をみて、昔 cocoa 勉強会でちょこっと紹介した内容に似たようなのがあったのを思い出しました。

久しぶりなのでブログに書いてみようかと思いました。

Objective-C 2.0プロパティ定義文を挿入する UserScript

さきの記事ではテキストマクロとしてプロパティ定義文を挿入して実際のプロパティ名は自分入力するような形をとっていました。

私はもっと怠け者なので文字入力なしで済ましたいと思ったので UserScript にしました。

UserScript とは

f:id:griffin-stewie:20101016144310p:image

これ。

ちょっとしたことができる仕組みです。

デフォルトで入っているのものでおそらくみんながお世話になっているだろう

コメントアウトショートカット Cmd+/ は実は Perl で書かれた UserScript が実行されています。

何ができる?

こんなのが実行できます。

入力としては以下のものを受けられます。

出力はこんな感じ。

メニューから " Edit User Scrippts ..." を選べば編集画面が表示されます。

ショートカットキーもここでわりあてられます。

UserScript でプロパティ定義文を挿入する

やりたいことは

以下の2パターン作ったことがありますが、今回はクリップボード拡張を導入していない人向け。

@property を挿入する UserScript
#!/usr/bin/env ruby

lines = `pbpaste`
lines.each { |line|
  if line.match(/([_A-Za-z][_A-Za-z0-9]*\s*)+([\s\*]+)([_A-Za-z][_A-Za-z0-9]*);/)
  
    klas = $1
    star = $2
    ivar = $3  
  
    if klas != nil
      if /\ANSString/ =~ klas
        print "@property (nonatomic, copy) #{klas.strip} #{star.strip}#{ivar};\n"
      elsif /\Aid/ =~ klas
        if /delegate/ =~ ivar
          print "@property (assign) #{klas.strip} #{star.strip}#{ivar};\n"          
        else
          print "@property (nonatomic, retain) #{klas.strip} #{star.strip}#{ivar};\n"
        end
      elsif /\*/ =~ star
        print "@property (nonatomic, retain) #{klas.strip} #{star.strip}#{ivar};\n"
      else
        print "@property (assign) #{klas.strip} #{star.strip}#{ivar};\n"
      end
    elsif star == nil
      
    end
  end
}

使い方は

インスタンス変数定義部分をまとめてコピーして挿入したい場所でこのスクリプトを実行。

すると

として挿入します。

@synthesize を挿入する UserScript
#!/usr/bin/env ruby
lines = `pbpaste`
lines.each { |line|
  if line.match(/([_A-Za-z][_A-Za-z0-9]*\s*)+([\s\*]+)([_A-Za-z][_A-Za-z0-9]*);/)
  
    klas = $1
    star = $2
    ivar = $3
    print "@synthesize #{ivar};\n"
  end
}

使い方は

インスタンス変数定義部分をまとめてコピーして挿入したい場所でこのスクリプトを実行。

release を挿入する UserScript
#!/usr/bin/env ruby

lines = `pbpaste`

def releaseAndNil(variable)
  print "[#{variable} release], #{variable} = nil;\n"
end

lines.each { |line|
  if line.match(/([_A-Za-z][_A-Za-z0-9]*\s*)+([\s\*]+)([_A-Za-z][_A-Za-z0-9]*);/)
  
    klas = $1
    star = $2
    ivar = $3  
  
    if klas != nil
      if /\ANSString/ =~ klas
        releaseAndNil(ivar)
      elsif /\Aid/ =~ klas
        if /delegate/ =~ ivar
          print "delegate = nil;"          
        else
          releaseAndNil(ivar)
        end
      elsif /\*/ =~ star
        releaseAndNil(ivar)
      end
    end    
  end
}

使い方は

インスタンス変数定義部分をまとめてコピーして挿入したい場所でこのスクリプトを実行。

すると

として挿入します。

保存方法

今回紹介したスクリプトは Output を ”Insert after Selection” として保存してください。

f:id:griffin-stewie:20101016153602p:image

使い方の流れとしてはこんな感じで使うとインスタンス変数のリリース漏れなどを起こしにくいと思います。

  1. インスタンス変数をずらっと定義
  2. 定義部分をコピー
  3. プロパティ定義を挿入したい箇所で「@property を挿入する UserScript」を実行
  4. 実行ファイルを開いて@synthesize を挿入したい箇所で「@synthesize を挿入する UserScript」を実行
  5. dealloc メソッド内で「release を挿入する UserScript」を実行

その他

今回のスクリプトは普段使っていて特に問題はありませんでしたが、結構適当なのでコーディングスタイルが違う人は使えない代物かもしれません。ご利用は自己責任でお願いします。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/griffin-stewie/20101016/p1
プロフィール

griffin-stewie

griffin-stewie

遂にプログラマの端くれに。ここで述べられていることは私の個人的な意見に基づくものであり、私の雇用者には一切関係ありません。