vimwikiすごい

投稿者 nanki 2010-10-05 03:13:00 GMT

紹介しようと思ったのですが、こちらにて詳細にまとめられていたので参照してください。

すごいポイントはいくつかありますが、特にテーブル編集中に自動でセルサイズが再計算されるのが感動です。ただ、pre中でも再レイアウトされるのは残念。

なお、現在のバージョンはいくつか相違点がありました。 * tableのsyntaxがちょっと違う * Vim7.3のconcealに対応している

関係ないけど、作者のMaxim KimさんはVim好きそうな名前ですね。

参考:

Objective-JおよびCappuccinoとそのvim補完 2

投稿者 nanki 2010-07-10 13:15:00 GMT

前回のエントリから早一年半。

Atlasのベータプログラムもいつの間にかスタートして、心躍るネタを提供してくれるObjective-J/Cappuccino.

一方僕はVimScriptを改良した。

主な改善点は、

  • []を自動で追加
  • 代入による変数の型推測
  • 定数を補完データベースに追加

Objective-CやObjective-Jでは、メッセージを続けて送る場合、[]を入れ子に書かないといけなくて、かなり苦痛なのだが、直前の対応する[の前に[を自動挿入することで、

  [CPView alloc] init
  // ☟
  [[CPView alloc] init]

という補完が行われるようになった。


MacOSXで最強のTerminal環境を構築するには

投稿者 nanki 2010-02-11 04:00:00 GMT

screenshot

大それたタイトルだが、Terminal.app(以下Terminal)のタブ機能を快適に使う話である。

Terminalを使い倒している皆様なら、当然のことながら、5~10の端末が開いていると思うが、僕は今までタブを使ってこなかった。

これは大体次のような理由によるものである。

  1. 切替が面倒くさい
  2. 中身が分からない
  3. タブの分狭くなる

今回は、この三つの問題を解決して、タブを快適に使おうじゃありませんか。

問題: 切替が面倒くさい

これはTerminal.app が、次のタブ/前のタブ、という操作しか用意していないことに起因する。 2~3つなら問題ないが、5~10のタブを切り替えるには機能不足。

これを terminaltabswitchingを使って解決する。

terminaltabswitching はTerminal.appのタブの切替を⌘0-9 で行えるようにするSIMBLプラグイン。 本家からforkされ、いくつかSnowLeopard関連の変更などがあたっていそうな niw’s terminaltabswitching at master - GitHub に、このコミットをマージしたものを使っている。

ビルド方法は

$ xcodebuild -configuration Release build

buildするだけで勝手にinstallされる。

これで、タブの切替が楽になった。

問題: 中身が分からない

タブの切替は出来るようになったが、タブの中身は切り替えるまでわからない。 プロセス名が書いてあったりするが、全部zshじゃあどれがどれだかわからないし、vimを終了すると、”Thanks for flying Vim”とかに書換えられて鬱陶しい。 ここでは、zsh と vim について掘り下げる。他の環境の人は各自深追いしてください。

# ~/.zshrc
function title {
  print -n "\e]0;$@\a"
  export TITLE="${(pj: :)@}"
}

chpwd() {
  title $(basename "$(pwd)")
}

cd .

まず、便利な関数titleを用意する。 $ title hello terminal! でタブのタイトルが設定できる。 また、現在のタブのタイトルを簡単に得る方法がたぶんないので、環境変数に保存する。

chpwd は、カレントディレクトリが変化した時に呼び出され、現在のディレクトリ名をタイトルに設定する。 これで、どのタブが何か一目瞭然となる。わからないのは、ディレクトリ名をつける人のセンスの問題に帰着する。

# ~/.vimrc
execute ":set titleold:".fnameescape($TITLE)
execute ":set titlestring:".fnameescape($TITLE." - %t")

vimは終了時に、titleoldをタイトルとして設定するので、それを、環境変数$TITLEにしておく。 さらに、ファイル編集中は、ファイル名が表示されるようになった。

問題: タブの分狭くなる

MacOSXの画面はただでさへ、Dockやメニューバー、タイトルバーで狭くなっているのに、この期に及んでタブバーでさらにせまくなるなんて許せない。 もう、画面を90度回転させて使いたい。

回転は首が痛くなりそうなのであきらめて、アプリケーションをフルスクリーンで使う方法ならある。 megazoomerがそれ。これもSIMBLプラグイン。SIMBL様さま。 使い方は、ここぞという時に⌘Enter

どうせ、タブとか考慮されてないから、変な事になるんでしょ、と思いきや、Dockもメニューバーもタイトルバーもきれいに消えて、すごい快適。

難点は、

  • そのアプリケーションがアクティブな間Spotlightが使えなくなる
  • マウスで履歴などを選択する時に、ウィンドウ下端に行っても、自動でスクロールしない

ついでにSafariでも使ってみたけど、たまに変になる。

数々の苦難を乗り越えて

当初の問題を解決したので、次いってみよう。

Marc Liyanage - Blog - Mac OS X - Terminal Tricks: “term” revisited, with tabs で公開されているスクリプトでは、AppleScriptを通して、Terminalを操作し、コマンドラインからタブを開く事ができる。

これを、~/bin/term などに保存すると、$ term -t ~/work でタブを開く事ができる。 コマンドの実行などもできる。 さらに、こんな感じのコマンドも用意した。zshのaliasでいい人はそっちの方がいいと思う。

#!/bin/sh
# ~/bin/tab
term -t "$@"

僕の場合、今手を付けている作業を、ブラウザのタブやTerminalのカレントディレクトリなどを外部記憶として保存しているので、OSの再起動はとても避けたい作業のひとつだが、 次のようなコマンドを実行することで、zshが開いているタブ群を再現できるスクリプトが得られるのでとてもよい。

$ lsof -a -c zsh -d cwd  | tail +2 | awk '{print "tab " $9}' | sort | uniq
tab /Users/nanki/*******/****
tab /Users/nanki/*******/*********/****/**********
tab /Users/nanki/*******/********************
tab /Users/nanki/****/*********/****/****/****
tab /Users/nanki/****/****/*********

(あ、エスケープしてない)

疑問点まとめ

  • 10を超えるタブはどうするのかしらん
  • screen はどうしよう
  • AppleScript使ったらタブのタイトルとれるかな?
参考:

treetop.vim

投稿者 nanki 2009-03-17 09:28:00 GMT

syntax

TreetopというRubyで書かれたpackrat parserがある。

その文法ファイルをsyntax highlightするvim. これがなきゃ始まらない。

参考:

vimで実行されたautocmdを知りたい

投稿者 nanki 2008-05-28 19:21:00 GMT

$ vim -V9 filename

とすればいいらしい。

あるいは、

:set verbose=9


英数を英数+ESCに - KeyRemap4MacBook

投稿者 nanki 2008-04-28 23:38:00 GMT

vimで日本語を入力していると、ESC押しても日本語が解除されない。

そもそも、ESC遠すぎる。

以前使っていたThinkpadでは、半角/全角、無変換、F1が全てESCで便利だったのに。

DefaultKeyBindings.dictでなんとかなると思ったけど、ならなさそうなので、KeyRemap4MacBookを導入してみた。

英数をESCにする設定はあるが、英数を英数+ESCにする設定はないようだ。 というわけで、しばしの格闘の末…よくわかってないけど動いているっぽい。

たまに、英数にしようとして、検索ボックスの文字列を消したりする。 英数x2を英数+ESCにしたほうがいいかもしれないけど、取りあえずしばらく使ってみる。

diff -r 7af393f8e690 files/prefpane/checkbox.xml
--- a/files/prefpane/checkbox.xml Mon Apr 28 06:27:59 2008 +0900
+++ b/files/prefpane/checkbox.xml Mon Apr 28 23:37:57 2008 +0900
@@ -1053,6 +1053,10 @@
               <sysctl>remap.jis_eisuu2escape</sysctl>
             </item>
             <item>
+              <name>EISUU to EISUU &amp; Escape</name>
+              <sysctl>remap.jis_eisuu2jis_eisuu_escape</sysctl>
+            </item>
+            <item>
               <name>EISUU to Tab</name>
               <sysctl>remap.jis_eisuu2tab</sysctl>
             </item>
diff -r 7af393f8e690 src/kext/RemapUtil.cpp
--- a/src/kext/RemapUtil.cpp  Mon Apr 28 06:27:59 2008 +0900
+++ b/src/kext/RemapUtil.cpp  Mon Apr 28 23:37:57 2008 +0900
@@ -749,6 +749,15 @@
   }

   void
+  FireFunc::firefunc_jis_eisuu_escape(const RemapParams &params) {
+    unsigned int flags = allFlagStatus.makeFlags(params);
+    listFireExtraKey.add(FireExtraKey::TYPE_AFTER, KeyEvent::DOWN, 0, KeyCode::JIS_EISUU, CharCode::JIS_EISUU);
+    listFireExtraKey.add(FireExtraKey::TYPE_AFTER, KeyEvent::UP, 0, KeyCode::JIS_EISUU, CharCode::JIS_EISUU);
+    listFireExtraKey.add(FireExtraKey::TYPE_AFTER, KeyEvent::DOWN, flags, KeyCode::ESCAPE, CharCode::ESCAPE);
+    listFireExtraKey.add(FireExtraKey::TYPE_AFTER, KeyEvent::UP, flags, KeyCode::ESCAPE, CharCode::ESCAPE);
+  }
+
+  void
   FireFunc::firefunc_space(const RemapParams &params) {
     unsigned int flags = allFlagStatus.makeFlags(params);
     listFireExtraKey.add(FireExtraKey::TYPE_AFTER, KeyEvent::DOWN, flags, KeyCode::SPACE, CharCode::SPACE);
diff -r 7af393f8e690 src/kext/RemapUtil.hpp
--- a/src/kext/RemapUtil.hpp  Mon Apr 28 06:27:59 2008 +0900
+++ b/src/kext/RemapUtil.hpp  Mon Apr 28 23:37:57 2008 +0900
@@ -178,6 +178,7 @@
     void firefunc_commandSpace(const RemapParams &params);
     void firefunc_enter(const RemapParams &params);
     void firefunc_escape(const RemapParams &params);
+    void firefunc_jis_eisuu_escape(const RemapParams &params);
     void firefunc_space(const RemapParams &params);
     void firefunc_jis_kana(const RemapParams &params);
     void firefunc_jis_kana_x2(const RemapParams &params);
diff -r 7af393f8e690 src/kext/remap.cpp
--- a/src/kext/remap.cpp  Mon Apr 28 06:27:59 2008 +0900
+++ b/src/kext/remap.cpp  Mon Apr 28 23:37:57 2008 +0900
@@ -1589,6 +1589,15 @@
   }

   void
+  remap_jis_eisuu2jis_eisuu_escape(const RemapParams &params)
+  {
+    if (! config.remap_jis_eisuu2jis_eisuu_escape) return;
+
+    static KeyOverlayedModifier kom;
+    kom.remap(params, KeyCode::JIS_EISUU, ModifierFlag::NONE, FireFunc::firefunc_jis_eisuu_escape);
+  }
+
+  void
   remap_jis_eisuu2tab(const RemapParams &params)
   {
     if (! config.remap_jis_eisuu2tab) return;
@@ -2122,6 +2131,7 @@
   remap_jis_eisuu2optionL(params);
   remap_jis_eisuu2shiftL(params);
   remap_jis_eisuu2escape(params);
+  remap_jis_eisuu2jis_eisuu_escape(params);
   remap_jis_eisuu2tab(params);
   remap_jis_eisuu2middleclick(params);
   remap_jis_eisuu2rightclick(params);
参考:

" in ~/.vimrc
au BufWritePost */bin/* :silent !chmod a+x <afile>
au BufEnter */bin/* if getline(1) == "" | :call setline(1, "#!/usr/bin/env ruby") | endif
参考:

Simple creation of scripts - Vim Tips Wiki - a Wikia wiki


Re: netswitch! | vim/rubyのための部分最適化

投稿者 nanki 2008-01-26 21:39:00 GMT

Re: netswitch! | vim/rubyのための部分最適化

今はこんな風になっている。

function SymbolUnderCursor(tran)
  return synIDattr(synID(line("."),col("."), a:tran),"name")
endfunction

function SmartSemicolon()
  execute "normal a "
  try
    throw SymbolUnderCursor(1)
  catch /rubyString\|rubyRegexp/
    execute "normal r;"
  catch /.*/
    execute "normal xo \<BS>"
  endtry
endfunction

function SmartEnd()
  execute "normal a1"
  try
    throw SymbolUnderCursor(0)
  catch /rubyString\|rubyRegexp\|rubyLocalVariableOrMethod/
    execute "normal xae\<Esc>and"
  catch
    execute "normal xae\<Esc>and\<Enter> \<BS>"
  endtry
endfunction
  
    
function SmartDefine()
  try
    throw SymbolUnderCursor(1)
  catch /rubyDefine/
    execute "normal oe\<Esc>and\<Esc>k"
  catch
  endtry 
endfunction
    
au FileType ruby imap <buffer> begin begin<Enter>
au FileType ruby imap <buffer> end  <Esc>:call SmartEnd()<CR>a
au FileType ruby imap <buffer> then then<Enter>
au FileType ruby imap <buffer> ensure ensure<Enter>
au FileType ruby imap <buffer> else else<Enter>
au FileType ruby imap <buffer> elsif elsif<Enter>
au FileType ruby imap <buffer> ; <Esc>:call SmartSemicolon()<CR>a
au FileType ruby imap <buffer> def def<Esc>:call SmartDefine()<CR>a
追記:
  • rubyRepeat追加

vim/rubyのための部分最適化

投稿者 nanki 2006-01-21 19:06:00 GMT

この辺 を読んで思い出した。

数年前、Javaコードのメトリクス(というか、文字別タイプ量)を調べた時、もっとも多かったのは;と()だった。

考えてみれば、このセミコロン、ほとんどすべての行末に現れて、しかも、ほぼ100% ;+Enter の形で出現、右小指を二回連続消耗するというあり得ないほど無駄にタイピングの苦痛を増やしている奴なのだ。いくらStrong Typingと言ったって・・・

当時はvimでJavaのコードを書いていたので、早速;を;+Enter に置き換え、なんとか快適な環境を作ることに成功したのだった。

その時の経験からか、あまりタイピングが苦痛にならないruby でも、次のような部分的な最適化をしている。

  • ; で改行
  • 文字列中の;では反応しない
  • end も自動で改行
  • begin,else,then,ensureなどの予約語で改行
  • rails 向けに、Ctrl+=,Ctrl+eでerbのタグ
" ~/.vimrc
au BufNewFile,BufRead *.rhtml setf eruby

autocmd FileType html imap <buffer> <C-_> <%=  %><Esc>2hi
autocmd FileType html imap <buffer> <C-E> <%  %><Esc>2hi
autocmd FileType ruby imap <buffer> <C-L> RAILS_DEFAULT_LOGGER.debug()<Esc>i

function SmartSemicolon()
  let s = synIDattr(synID(line("."),col("."),0),"name")
  if s == "rubyString"
    execute "normal a \<Esc>vr;"
  else
    execute "normal a\<Enter> \<BS>"
  endif
endfunction

function SmartEnd()
  let s = synIDattr(synID(line("."),col("."),0),"name")
  if s == "" || s == "rubyNoDoBlock"
    execute "normal ae\<Esc>and\<Enter> \<BS>"
  else
    execute "normal ae\<Esc>and"
  endif
endfunction

autocmd FileType ruby imap <buffer> begin begin<Enter>
autocmd FileType ruby imap <buffer> end  <Esc>:call SmartEnd()<CR>a
autocmd FileType ruby imap <buffer> then then<Enter>
autocmd FileType ruby imap <buffer> ensure ensure<Enter>
autocmd FileType ruby imap <buffer> else else<Enter>
autocmd FileType ruby inoremap <buffer> ; <Esc>:call SmartSemicolon()<CR>a

コード補完も含めコーディング時の最適化というのは、タイプ量当たりの情報量をいかに増やすかというところにある。

コード中に頻出するパターンを見つけ出して、一つずつつぶしていくのが、部分最適化が好きな人間にはたまらない。

次にやるとしたら「閉じるキー」。 begin-end,(),{},||,”“,” などを区別せず、閉じるキーを押すと一番近くの括弧を閉じてくれる、というやつ。 スペース近くの使わないキーに割り当ててやりたい。

誰か作りませんか?or既にある奴をご存知ないですか?