TextMate 2 下 Ctag 和 Git Bundle 同时工作

最近再使用 TextMate 2 的 Bundle:Ctag 和 Git 的时候经过了一番周折才勉强可以让这两个 Bundle 同时工作。写出来帮助遇到同样问题的朋友。避免浪费时间。

问题现象:

使用 TM2、 ruby 1.9.3 或 ruby 2.0.1

Git Bundle 可以正常工作。

安装 TM Ctag Bundle 之后 ^ + Command + P 报异常大概如下:

1
2
3
4
5
6
7
8
 ui.rb:308: in `to_plist': An object in the argument tree could not be converted (ArgumentError)
     from ~/Library/Application Support/TextMate/Managed/Bundles/Bundle Support.tmbundle/Support/shared/lib/ui.rb:308:in `block in initialize'
     from ~/Library/Application Support/TextMate/Managed/Bundles/Bundle Support.tmbundle/Support/shared/lib/ui.rb:307:in `popen'
      from /Library/Application Support/TextMate/Managed/Bundles/Bundle Support.tmbundle/Support/shared/lib/ui.rb:307:in `initialize'
     from ~/Library/Application Support/TextMate/Managed/Bundles/Bundle Support.tmbundle/Support/shared/lib/ui.rb:20:in `new'
     from ~/Library/Application Support/TextMate/Managed/Bundles/Bundle Support.tmbundle/Support/shared/lib/ui.rb:20:in `dialog'
      from /Library/Application Support/TextMate/Managed/Bundles/Bundle Support.tmbundle/Support/shared/lib/progress.rb:42:in `call_with_progress'
     from ~/_test_tm.rb:12:in `<main>'

其中关键是: ui.rb:308: in `to_plist’: An object in the argument tree could not be converted 如果你的异常是这个那么可以肯定的时候和我的情况一直。下面是我的一个临时解决方案。

这个 bug 的解决有争议,TextMate 社区认为是 Ruby 的 bug,但网络上另一个解决方案认为是 TextMate 的 bug。

1
2
3
4
5
6
7
cd ~/Library/Application Support/TextMate/Managed/Bundles/Bundle Support.tmbundle/Support/shared/lib/osx
git clone git://github.com/kballard/osx-plist.git
cd osx-plist/ext/plist
ruby extconf.rb && make
cd ../../../
mv plist.bundle plist.bundle.old
cp osx-plist/ext/plist/plist.bundle ./plist.bundle

这样Ctag是可以正常运行的,但是会导致 Git Bundle 报错:

1
2
dyld: lazy symbol binding failed: Symbol not found: _rb_intern2 Referenced from: ~/Library/Application Support/TextMate/Managed/Bundles/Bundle Support.tmbundle/Support/shared/lib/osx/plist.bundle Expected in: flat namespace
dyld: Symbol not found: _rb_intern2 Referenced from: ~/Library/Application Support/TextMate/Managed/Bundles/Bundle Support.tmbundle/Support/shared/lib/osx/plist.bundle Expected in: flat namespace

我的一个临时解决方案是:

1
2
3
cd ~/Library/Application Support/TextMate/Managed/Bundles/Bundle Support.tmbundle/Support/shared/lib/osx
git clone git://github.com/kballard/osx-plist.git
cd osx-plist/ext/plist

打开 osx-plist/ext/plist 下的 plist.c 找到:

1
2
3
4
5
6
/*
 * Document-class: OSX::PropertyListError
 */
void Init_plist() {
  mOSX = rb_define_module("OSX");
  mPlist = rb_define_module_under(mOSX, "PropertyList");

void Init_plist() { 改为 void Init_plist2() { 后执行:

1
2
3
4
ruby extconf.rb && make
cd ../../../
mv plist.bundle.old plist.bundle
cp osx-plist/ext/plist/plist.bundle ./plist2.bundle

找到 TM Ctag 的安装目录,我的是: ~/Library/Application Support/Avian/Pristine Copy/Bundles/tm-ctags.tmbundle/Support/bin 修改 tmctags.rb 和 update_ctags.rb 分别在 require ENV['TM_SUPPORT_PATH'] + '/lib/ui.rb' 前增加:

require ENV['TM_SUPPORT_PATH'] + '/lib/osx/plist2'

这样就可以同时工作了 但是还是会有一个警告消息。

完美的解决方案是修改 原版的 plist.bundle 或者 完善 git://github.com/kballard/osx-plist.git

简单研究了一下 TM2的源码 目前我还不会修改 plist.bundle 所以只能使用这个临时不完美的解决方案。

这个方案的原理是: 先载入新版本的 plist2 ,之后原版的plist就无法加载。但是会有一个警告消息。

Comments