vim-users.jp

Hack #133: バイナリファイルを編集する

Posted at 2010/03/21
このエントリーをはてなブックマークに追加

Vim はテキストエディタですが、バイナリファイルの簡単な編集もできます。

xxd

xxd は Vim に付属しているプログラムで、バイナリファイルを16進数のテキスト形式に変換、および、そのテキスト形式のファイルをバイナリファイルに逆変換することのできるプログラムです。Vim 付属のため Windows でも利用できます。 バイナリファイルを Vim に読み込む際と書き込む際にこのプログラムを使うことでテキストエディタ上でバイナリファイルの編集が可能になります。

ただし、xxd の逆変換機能はそこまで優れていないため、できるのは値の書き換え程度で、値の挿入や削除はできません。

設定

設定方法は :help hex-editing に載っているのでこちらを参照してもよいのですが、せっかくなので本 hack では少し違った設定方法を紹介します。

以下のファイルを ~/.vim/ftplugin/xxd.vim (Windows の場合は ~/vimfiles/ftplugin/xxd.vim) に置きます。

if !executable('xxd')
  finish
endif

let b:undo_ftplugin = (exists('b:undo_ftplugin') ? b:undo_ftplugin . ' | ' : '')
\ . 'setl bin< eol< | execute "au! ftplugin-xxd * <buffer>" | execute "silent %!xxd -r"'

setlocal binary noendofline
silent %!xxd -g 1
%s/\r$//e
augroup ftplugin-xxd
  autocmd! * <buffer>
  autocmd BufWritePre <buffer> let b:xxd_cursor = getpos('.')
  autocmd BufWritePre <buffer> silent %!xxd -r
  autocmd BufWritePost <buffer> silent %!xxd -g 1
  autocmd BufWritePost <buffer> %s/\r$//
  autocmd BufWritePost <buffer> setlocal nomodified
  autocmd BufWritePost <buffer> call setpos('.', b:xxd_cursor) | unlet b:xxd_cursor
augroup END

特定の拡張子に対して自動でバイナリ編集モードにしたい場合は、~/.vim/ftdetect/xxd.vim (Windows の場合は ~/vimfiles/ftdetect/xxd.vim) に以下のように書きます。

autocmd BufReadPost,BufNewFile *.bin,*.exe,*.dll setlocal filetype=xxd

この例では、bin, exe, dll の拡張子のファイルを開いた際にバイナリ編集モードになります。

解説

基本的な仕組みは :help hex-editing に載っているものと同じです。

バイナリ編集モードに移行した際、バッファ全体を xxd コマンドで変換して見やすい形式にします。 保存する際には、xxd -r で一旦バイナリ形式に戻してから保存し、保存後に再び xxd で見やすい形式に戻します。

加えて、変換時に移動してしまうカーソルの位置を保存、復元しています。

この方法の利点は、どんなファイルでも開いた後から

:setf xxd

とするだけでバイナリ編集モードへ移行できることです。ファイルタイプを設定するだけなので、特定のファイルをバイナリ編集モードに対応させるのも簡単です。

例えば、バイナリモードのファイル(vim -b file で開いた場合など)を自動的にバイナリ編集モードにするには vimrc で以下のようにします。

augroup xxd
  autocmd!
  autocmd BufReadPost * if &l:binary | setlocal filetype=xxd | endif
augroup END
thinca

もどる
blog comments powered by Disqus