とうとうXcode4のプレビュー版がWWDCに行けなかった開発者にも公開されました。
たかとももさっそくDLして使ってみましたが、いままでのXcodeからかなり進化していてびっくりしてしまいました。慣れるまではちょっと大変そうですが、使いこなせたらものすごい簡単に開発ができそうな気がします。
Xcode4が正式版になったときに Vim + cocoa.vim に修正が必要になったりしないといいのですが。。。。
ということで、今日はちょっとした設定の紹介です。
VimでC言語やらを書いているときに include “hogehoge” と書かれているところの上で gf とするとincludeされたファイルにジャンプできる機能があります。ただObjective-Cの場合だと include “hogehoge” ではなくて import “fugafuga” とか import <UIKit/UIKit.h> だったりしてうまくジャンプできません。
おすすめの使い方
- 編集しているファイルを :vsplit して画面分割する。
- import “hogehoge” の上で gf する
- ジャンプした先のファイルから、さらに gf もできます。
- ジャンプしすぎたときは C-o で戻る。
ウィンドウを分割することで、ジャンプした先のファイルを参考にしながら編集ができるので楽ちんですよね。
ということで以下が設定になります。
autocmd FileType objc setlocal path=.;,/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.0.sdk/System/Library/Frameworks,/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks,,
autocmd FileType objc setlocal include=^\s*#\s*import
autocmd FileType objc setlocal includeexpr=substitute(v:fname,'\/','\.framework/Headers/','g')
まず1行目はファイルを探すためディレクトリを指定してあります。SDKのバージョンが変わったときにはここを適宜 変更してください。。次に2行目でimport “” と import <> の間に書かれているところがincludeされたファイルだと指定します。最後の行は Import <UIKit/UIKit.h>の「UIKit/UIKit.h」の部分を「UIKit.framework/Headers/UIKit.h」に書き換えをしています。
この3つを設定してあげると Import <UIKit/UIKit.h> と書かれたところで gf したときに、pathで設定したディレクトリ ・ includeexprの設定が組み合わさって/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.0.sdk\
/System/Library/Frameworks/UIKit.framework/Header/UIKit.h にジャンプできるようになります。ジャンプしたところから戻るには C-o を使ってくださいね。
意外と便利なのでぜひ設定してくださいね♪
でわでわ、たかともでした。
autocmd は augroup MyObjcCmd 〜 augtoup END でくくってあげて、先頭に augroup MyObjcCmd の次の行には autocmd! なんてしてあげるのもいいかと。
昨日、記事書いたばっかりですが QuickFixとの連携もできるような設定ができたので、紹介です。
augroup MyObjcAutoCmd
autocmd!
autocmd FileType objc setlocal makeprg=xcodebuild -activetarget -activeconfiguration \| grep -e "^/.*" \| sort -u
autocmd FileType objc nnoremap <buffer> <C-9> :call XcodeBuildCheck()<CR>
autocmd FileType objc inoremap <buffer> <C-9> <C-o>:call XcodeBuildCheck()<CR>
function! XcodeBuildCheck() "{{{
let proj_dir = substitute(b:cocoa_proj, '(.*)/.*' , '1', '')
let current_dir = getcwd()
execute ":lcd " . escape(expand(proj_dir), " #\")
make
execute ":lcd " . escape(expand(current_dir), " #\")
endfunction
augroup END
b:cocoa_projを取得するために前回の記事の下の方の設定をもってくるか、cocoa.vimをいれるかのどちらかが必要です。
Xcodeでつくったクラスファイルを編集中にcontrol+9をすると自動でxcodeprojファイルのあるディレクトリにカレントディレクトリを移して、makeしてくれます。またmakeが終わった時点でカレントディレクトリをもとの場所に戻してくれる処理もいれてあります。

またエラー箇所をQuickfixで見られるようになっています。grepでエラー箇所を探したあとに sort -u でエラー箇所の重複の削除をしています。もしかしたら副作用があるかもしれないです。

前回の記事が嘘のような使い心地ですよ〜>< 最初からこうすればよかったと。
みなさん、ぜひぜひ設定してくださいっ!!
ちなみにVimでMacアプリケーション開発してる人、iPhoneアプリ開発してる人ってどれぐらいいるんでしょうか?
Vimにcocoa.vimを導入してからすっかりXcodeはビルド用になってます。
Vim + cocoa.vimで少し不満だったのが、エラーをみたいときにいちいちXcodeとVimとをいったりきたりしないといけないというところ。わがままなのかもしれないですが、どうせならVimだけでさくっと確認したいなぁ〜と。
そんなわけでからXcodeを使わずに文法チェック(というかビルドしてるという。。。)するための設定をしてみました。
autocmd FileType objc nnoremap <buffer> <C-9> :call XcodeBuildCheck()<CR>
autocmd FileType objc inoremap <buffer> <C-9> <C-o>:call XcodeBuildCheck()<CR>
function! XcodeBuildCheck() "{{{
let proj_dir = substitute(b:cocoa_proj, '\(.*\)\/.*' , '\1', '')
let proj_file = substitute(b:cocoa_proj, '\(.*\)\/\(.*\)', '\2', '')
let current_dir = getcwd()
execute ":lcd " . escape(expand(proj_dir), " #\\")
let error_message = system( 'xcodebuild -project ' . escape(expand(proj_file), " #\\") .' -activetarget -activeconfiguration')
echo error_message
execute ":lcd " . escape(expand(current_dir), " #\\")
endfunction
上のコードを.vimrcに追加するとXcodeプロジェクトに含まれているファイルを編集しているときにControl+9を押すとシステムのxcodebuildというコマンドを呼び出してビルドをしてくれて、ビルド結果が表示されるようになります。Xcodeをいちいち立ち上げしなくてもビルドできるので楽ちんです♪
やりたかったけど、できなかったこと
- error_messageを整形するなりして表示されるメッセージを綺麗にしたかった。
- QuickFixのウィンドウに表示して、エラー行にすぐに飛べるようにしたかった。
1つ目の「メッセージの整形」は、substitute()をつかって抽出できるかな?と試してみたのですが、うまくいかず。2つ目の「QuickFixウィンドウを使う」はできるのかどうかもわからない。そんな状態になってます。VimScriptってよくわからないんですよね。。。。そんなわけでだれか作ってくれないかなぁ〜なんて思ってしまいます。
Objective-CでVimを動かせないかな。。。。
ともあれ、Xcodeを使わずにVimだけでビルドができる & 文法エラーもチェックできるので、ぜひぜひ試してみてください。
というわけで、たかともでした。
ちなみにb:cocoa_projが取得できればcocoa.vimはいらないです。こんな感じ。
if exists('b:cocoa_proj')
finish
endif
let b:cocoa_proj = fnameescape(globpath(expand('<afile>:p:h'), '*.xcodeproj'))
" Search a few levels up to see if we can find the project file
if empty(b:cocoa_proj)
let b:cocoa_proj = fnameescape(globpath(expand('<afile>:p:h:h'), '*.xcodeproj'))
if empty(b:cocoa_proj)
let b:cocoa_proj = fnameescape(globpath(expand('<afile>:p:h:h:h'), '*.xcodeproj'))
if empty(b:cocoa_proj)
let b:cocoa_proj = fnameescape(globpath(expand('<afile>:p:h:h:h:h'), '*.xcodeproj'))
endif
endif
endif
autocmd FileType objc setlocal makeprg=xcodebuild\ -activetarget\ -activeconfiguration
をしておいて、ビルドするときに:lcdでxcodeprojがあるディレクトリにいって:makeする方法を見つけて、泣きそうです。
まぁ、いちいち:lcdしなくてもいい利点はあるものの、やってしまった感が。。。。
EmacsからVimに乗り換えるきっかけになったプラグイン。
cocoa.vim
Vimで開発するときには必須のプラグインです。
- C-x C-o or F2 = オムニ補完
- Command + Option + ↑ = ヘッダーファイルと実装ファイルの切り替え
- Command + 2 = メソッド(関数)のリスト表示
- Command + 0 = Xcodeで開く
- ノーマルモードで K = カーソルの下の単語をドキュメントから検索
このあたりはXcodeにはできるけど、Vimにはない機能をうまく補ってくれます。
が、
- Command + R = ビルドしてXcodeに移動する
- Command + B = ビルド
- Command + shift + K = クリーン
Xcodeを使って手動でビルドしてあげると問題ないプロジェクトでも、このあたりの機能を使おうとするとなぜかXcodeがエラーをはいてました。いろいろ調べていたのですが解決方法を二つほどみつけたので紹介します。
その1: AppleScriptでショートカットを直接たたく。
~/.vim/ftplugin/objc_cocoa_mappings.vimを以下の通りに変更します。
削除、もしくはコメントアウトする部分
34行目~36行目
nn <buffer> <silent> <d-r> :w<bar>cal<SID>BuildAnd('launch')<cr>
nn <buffer> <silent> <d-b> :w<bar>cal<SID>XcodeRun('build')<cr>
nn <buffer> <silent> <d-K> :w<bar>cal<SID>XcodeRun('clean')<cr>
追加する部分
最後の方にでもどうぞ。
nn <buffer> <silent> <d-r> :w<bar>cal<SID>XcodeBuildRun<cr>
nn <buffer> <silent> <d-b> :w<bar>cal<SID>XcodeBuild<cr>
nn <buffer> <silent> <d-K> :w<bar>cal<SID>XcodeClean<cr>
fun s:XcodeBuildRun() call system("open -a Xcode ".b:cocoa_proj." && osascript -e '" \ ."tell application \"Xcode\" to activate \r" \ ."tell application \"System Events\" \r" \ ."tell process \"Xcode\" \r" \ ."key code 36 using {command down} \r" \ ."end tell \r" \ ."end tell \r'")
fun s:XcodeBuild() call system("open -a Xcode ".b:cocoa_proj." && osascript -e '" \ ."tell application \"Xcode\" to activate \r" \ ."tell application \"System Events\" \r" \ ."tell process \"Xcode\" \r" \ ."key code 11 using {command down} \r" \ ."end tell \r" \ ."end tell \r'")
fun s:XcodeClean()call system("open -a Xcode ".b:cocoa_proj." && osascript -e '"\ ."tell application \"Xcode\" to activate \r"\ ."tell application \"System Events\" \r"\ ."tell process \"Xcode\" \r"\ ."key code 40 using {command down} \r"\ ."end tell \r"\ ."end tell \r'")
実際、ビルドして実行以外は試していないのですがこれでいけるはず。。。いけなかったらごめんなさい。またこの方法だとcocoa.vimの動作が少し動作が変わってしまいます。
- Command + R = ビルドして実行する(iPhoneシミュレータが起動する)
- Command + B = ビルドしてXcodeに移動する
- Command + shift + K = クリーニングをしてXcodeに移動する。
その2: Xcodeの設定を変更する。
- Xcodeでプロジェクトを右クリックして情報を見るを選択。

- ベースSDKの項目を探して、iPhoneシミュレータを選ぶ。

- アーキテクチャをNavive Architecture of Build Machineに変更する。

こちらの方法の欠点はベースSDKなどやアーキテクチャを変更してしまっているので、注意が必要だったりもします。またCommand + BするにはMakefileのあるディレクトリにあるファイルを編集している必要があるようです。
たかともは方法2の設定をしていますが、お好みにあわせてどうぞ♪
ここまで書いておもったのですが、方法1でやるなら
" ビルドして実行
autocmd! FileType objc nn <buffer><silent> <d-r> :w<bar>call<SID>XcodeCommand('36')<cr>
" ビルドするだけ
autocmd! FileType objc nn <buffer><silent> <d-b> :w<bar>call<SID>XcodeCommand('11')<cr>
" クリーニング
autocmd! FileType objc nn <buffer><silent> <d-K> :w<bar>cal<SID>XcodeCommand('40')<cr>
function! s:XcodeCommand(keycode) call system("open -a Xcode ".b:cocoa_proj." && osascript -e '" \ ."tell application \"Xcode\" to activate \r" \ ."tell application \"System Events\" \r" \ ."tell process \"Xcode\" \r" \ ."key code ".a:keycode." using {command down} \r" \ ."end tell \r" \ ."end tell \r'") endfunction
こんなコードを~/.vim/ftplugin/objc_cocoa_mappings.vimに追加してあげた方がスマートな気がします。ちゃんと動くのか不安ですが。。。。動作報告よろしくお願いします。というわけでMac & iPhoneの開発者のみなさん、iPhone4にむけてがんばりましょ~♪
でわでわ、たかともでした。
追記
上のコードだともcocoa.vimにもともとある関数が呼ばれてしまうみたいです。「autocmd! FileType ~」の部分のの部分を調節して使う。もしくは方法1で削除する部分を消したあとに、上のコードをVimの設定ファイルに追加してください。
2010/06/09:方法1の追加するコードの代わりに上のコードを使うように修正
Macが直ったのでちょうどいい機会だとSnowLeopardのクリーンインストールなど楽しんでいたんですが、あまりにも楽しくってブログの更新がかなりあいてしまいました。ごめんなさい。
今夜はとうとうWWDCですね♪どんな発表があるのかものすごい楽しみです。
Xcodeが新しくなるとか、iPhoneがでるとか。。。。
たかともはiPhone,Macの開発環境をVimで構築するのに、いそしんでいました。
というわけで、cocoa.vimにXcodeとの連携と使いやすい補完候補をつくってもらって、neocomplecache.vimで自動で補完候補をポップアップしてもらう。快適すぎますっ!!もうXcodeのエディタで作業なんてできませんっ!!
ただそのままの状態だとneocomplcacheでオムニ補完をしようとするとVimごと落ちてしまったので、cocoa.vimに手を入れました。
直すところは
~/.vim/autoload/objc/cocoacomplete.vim 90〜95行目
" Adds item to the completion menu if they match the base.
fun s:Complete(base, items)
for item in a:items
if item =~ '^'.a:base | call complete_add(item) | endif
endfor
endf
ここから上のコードのfor item in a:timesからendforまでをコメントアウトしてあげます。
あとは.vimrcにg:neocomplcache_omni_patternsを追記するだけで完成です
let g:neocomplcache_omni_patterns = {
\ 'objc' : '\h\w\+\|\%(\h\w*\|)\)\%(\.\|->\)\h\w*'
\}
ちなみに正規表現はC言語用のものをそのまま使っているので、もしかしたらまずいこともあるかもしれません。
Vimを使っている開発者の方はぜひ試してみてください。
最後に、neocomplcacheの作者の方には大変お世話になりました。ものすごい基本的な質問ばかりのVimビギナーな自分にたいして、あれほど親身になって相談にのっていただけるとは思いもしませんでした。これからもneocomplcacheのバージョンアップ楽しみにしています。
さてiPhoneのアプリつくろ〜っ♪
でわでわ、たかともでした。