最近の更新

関連


その他いろいろ

MODxでつくる! 最強のCMSサイト カバー
MODxでつくる! 最強のCMSサイト

はやくMODx 2.0でないかなあ

長らく更新をさぼっていました。忙しい…
久しぶりに.vimrcに手を加えたので、その話です。

vimでは頻繁に先頭に移動するggコマンドを使います。しかし、ちょっとまともな(?)ソースコードなどは先頭に大量のコメントがついていて、ggだけではコードの一片も見えず、さらに<C-F>を連打…ということをしがちです。

連打… これはvimmerとして敏感になるワードです。もっと効率よく、本来の目的である「最初の非コメント行」にたどり着けるはず。

そこで、早速ちょっとした関数を書いてみました。

function! GotoFirstEffectiveLine()
  normal gg
  while line(".")<line("$") && (
        \ getline(".") =~ '^\s*$'
        \ || synIDattr(synID(line("."), col("."), 0), "name") =~ ".*Comment$"
        \ )
    normal j0
  endwhile
  exe "normal z\<CR>"
endfunction
nnoremap <silent> gG :<C-U>call GotoFirstEffectiveLine()<CR>

このGotoFirstEffectiveLine()をコールすると、最初の「非空白かつ非コメント行」に移動することができます。vimではgGが空いているので、これに割り当てると覚えやすいでしょう。

LinuxのWiiリモコン(Wiimote)用ライブラリ、CWiidを用いて、音楽プレーヤSongbirdをコントロールするスクリプトを書いてみました。

操作方法

操作はきわめて単純です。

python wiimote-songbird-*.py

とすると監視プログラムがforkされるので、あとは1+2同時押しで接続し、適当にボタンを押して操作するだけ。電源ボタンを長押し(4秒くらい?)で切断し、再び接続待ちに入ります。

ボタンと動作の対応表

キー 動作
上/下 音量 +/-
左/右 次の曲/前の曲
B 再生・停止トグル

スクリプトのダウンロードはこちらから: wiimote-songbird-20090907.py
MIT Licence. Python 2.5.2, CWiid 0.6.00で動作確認しています。

~/.vim/template にあるテンプレートを(複数あればリストアップし)ロードするか否か選択できるプラグイン、qtmplsel.vimに式展開機能を追加し、v1.1.0として公開しました。

式展開

テンプレートファイルに含まれる@{@@}@で囲まれた部分をvimの式として評価し、置換します。

例えば、

// \file @{@expand('%:t')@}@
// \date @{@strftime('%Y-%m-%d')@}@
class @{@expand('%:t:r')@}@ {
};

のようなcpp用テンプレートをtestclass.cppの作成時に適用すると、以下のように展開されます。

// \file testclass.cpp
// \date 2009-09-07
class testclass {
};

入手方法

http://www.vim.org/scripts/script.php?script_id=2761から最新版をダウンロードし、~/.vim/pluginか$VIMRUNTIME/pluginに置いてください。

なお、1.0.0の説明はこちらにあります: vimでファイル作成時にテンプレートを選択 qtmplsel.vim

vimでファイルを新規作成する際、ファイルタイプに応じてテンプレート(orスケルトン)を自動的にロードするためには、.vimrcに以下のような設定を加えることが多いと思います。

autocmd BufNewFile *.py 0r ~/.vim/template/template.py

しかし、決まり切った内容を拡張子ごとに用意するのも芸がなく、
またテンプレートを使いたくない場合や、複数のテンプレートから選びたい場合に対応できません。

そこで、~/.vim/template にあるテンプレートを(複数あればリストアップし)
ロードするか否か選択できるプラグイン、qtmplsel.vimを書いてみました。

インストール

  1. qtmplsel.vim - Quick Template Selector : vim online から最新版をダウンロード
  2. ダウンロードしたスクリプトを $VIMRUNTIME/plugin か ~/.vim/plugin に入れます。

使い方

:e コマンドや vim の起動時に存在しないファイル名を入力して新規作成すると、

ファイルタイプ
ft=pythonなら サーチパス/python_*
拡張子
*.pyなら サーチパス/*.py
ファイル名
ファイル名=Makefile なら サーチパス/Makefile_*

に該当するテンプレートを ~/.vim/template から列挙し、一つ以上該当するものがあればリストを表示します。

リスト上では k(上) / j(下) で項目を選択し、 Enter で決定、 q でキャンセル(ロードしない)となります。

また、グローバル変数g:qts_templatedirを設定することで、任意の場所をテンプレートファイルのサーチパスに設定することができます。

使用例

qtmplsel.vim screenshot

リスト表示部分などQuickBufを参考にしました。

ExactAudioCopy等でCDをリッピングする際、freedbに曲情報がないとCUEのタイトルなどが空欄になってしまいます。

その後mp3に変換した後で曲名などを設定しても、元のCUEにもそれを反映させるのは結構面倒です。

mp3tocue.py は、「タグ設定済みのmp3」から「対応するタグなし/不完全なCUE」にTITLEとPERFORMER情報をコピーするためのPythonスクリプトです。

mp3tocue-0.1.1.zip をダウンロード

python mp3tocue.py -t -e utf-8 -i CDImage.cue --in-place C:\Music\test\*.mp3

のようにすると、*.mp3のタグを読み出し、トラック番号順に並べ(-tオプション)、UTF-8で(-eオプション)、CDImage.cue を更新します。

-tを指定しなければ入力mp3を指定した順に、-eを指定しなければエンコーディングは元々のCUEのエンコーディングと同じになります。

※トラック長はCUE中のものを流用する必要があり、一からCUEを作り出すことはできません。あくまで曲/奏者情報の書き換えに特化しています。

vimで{モーション}で指定された範囲を、レジスタ(デフォルト”、指定も可能)で置き換えるオペレータ<C-K>を提供するプラグイン、
regreplop.vimの説明を書きました。
ビジュアル選択中で<C-K>とすると選択範囲が置換されます。

前に直接vim scriptとしてポストしたのとだいたい同じ内容ですが、少し綺麗にしてvim.orgに載せました。

使用例

単語の上で<C-K>iw
単語全体をレジスタ(")で置換
"ayyした後、他の行で"a<C-K><C-K>
行全体を、レジスタaにヤンクした行で置換
vWの後にhlで微調整して<C-K>
選択範囲をレジスタ(")で置換

vimのfoldopenにhorが含まれる場合、閉じた折りたたみの上で右移動しようとすると自動的にzo(折りたたみを開く)してくれます。
しかし逆に、開いた折りたたみの上で左移動してもzc(閉じる)してくれません(多分)。

行頭でhすると折りたたみを閉じるようにする設定を.vimrcに加えてみました。

nnoremap <expr> h foldlevel(getpos('.')[1])>0 &&
      \(getpos('.')[2]==1 \|\|
      \getline('.')[: getpos('.')[2]-2] =~ "^[\<TAB> ]*$" )?"zch":"h"

ちょっと便利。

行単位コメントをトグル/挿入/削除するためのコマンド/オペレータを導入するvimスクリプト、commentop.vimv1.1.1をリリースしました。

1.1.0からの変更内容は、

  • range function (:h function-range-example) を用いてスクリプトを簡素化
  • virtcolを利用し、タブ/スペースが混在していても見た目の幅を考慮してコメント挿入されるように

の2点です。

2009 07 24

テンプレート

最近boost::mplに興味を持って、ちょっと色々試しています。

Base::template tmp<0>::get()

なんていう気持ち悪い場所にtemplateが書けるなんてのもここ数日で知りました。

それでテンプレートを使って、TI_0, TI_1, …, TI_n の入力型を処理してTO_0, TO_1, …, TO_m の出力型を吐くような、functionもどきを作ったりしています。

主に画像処理に使う目的(つまりTIとかTOには画像が入る)で書いていますが、
単に画像だけならvector<shared <IplImage> >+仮想関数とかでいいわけです。
ところが時々特徴点集合とか整数値とか、画像じゃないものも受け渡す必要がでてきます。

これらを全部同様に扱えるようにというひねくれた目標を掲げたら途端にテンプレートの世界へ…
だんだん慣れてきて、クソ長いコンパイルエラーもなんとか意図するところがわかるようになってきました。

ちなみにその画像処理ライブラリはテンプレートのコンパイル時inline展開の恩恵に与れているようで、結構面倒な処理を渡しても30fpsカメラで27fpsくらい出ています。

しかしcvShowImageまわりがマルチスレッドで微妙な挙動を示すのには参りました。どうやらcvNamedWindowとcvShowImageは同じスレッドで起動しなくてはならず、cvShowImageはメインスレッド(というかcvWaitKeyスレッド?)でコールしないと画像が表示されない等など。ちょっとソース見たわけではないので怪しい経験則ですが、暇があったらちゃんと読んで調べておこうと思います。
目下の所は全処理スレッドが完了するのを待った後でcvShowImageだけメインスレッドに回しています。若干汚い。

ソースコードを編集しているときにありがちな状況として、一行の先頭や末尾にはそれほど興味がないが、中央付近を編集したいというものがあります。

例えば、今次に示す行の先頭にカーソルがあるとします。

  cord.set_slot(0, boost::shared_ptr<PipelineCallback<Image> >(new PipelineCallback<Image>()));

ここでshared_ptrの中身を書き換えたい場合、ちょっと思いつくだけでも

  1. 検索する /Pi<CR>
  2. カギ括弧へ移動して右 f<l
  3. Pへ移動する fP
  4. 11番目の単語に移動する 11w
  5. カラム指定 37| (エルでもいいけどパイプ)
  6. lllllllllllllllllllllllllllllllllllll

など様々な方法がありますが、2,3,4,5は確実性・直観性に劣り、1はタイプ数に劣り、6はvim使いとして許されざる入力です。この中なら一番まっとうなのは検索でしょうか。
fやtは明らかに次に何処に行くか分かっていれば使い出がありますが、ひとたび変な場所に飛ばされると混乱するのが常です。(vim歴が浅いだけかも知れませんが)

そこで、ここは自分をはじめとする脳の緩いvimユーザのために、最後の6. lllllllllllllllllllllllllllllllllllllに活路を見出そうと思いました。

37回もlをキーリピートするかわりに、最初に行の中央に移動してからlなりhなりで目的の場所へ行こうという方法です。

幸いvimにはvirtualedit/virtcolという、見た目の文字幅を考慮する仕組みが備わっているのでこれをそのまま利用します。

noremap <expr> gm (virtcol('$')/2).'\|'

元々のgmは画面幅に対して中央になるように、カーソルを水平移動するキーですが、あまり使いそうも無いので上書きしてしまいました。

« 前のページ次のページ »