ホーム > タグ > lv1

lv1

Hack #216: 消してしまった直前のメッセージを再表示する

Vim でプラグインなどが下部に表示されたメッセージを読まずに消してしまった場合はどうすればいいでしょう。:echomsg で表示されていた場合は履歴に記録されているので、:messages を実行すれば表示できます。しかし、常に :echomsg が使われているとは限りません。

g<

g< を使うことで、最後に表示されたメッセージを再表示させることができます。ただし、本当に最後に表示されたものしか表示できないので注意してください。例えば、:messages を1度実行してしまうと、g< を押しても :messages の結果が表示されてしまいます。

また、メッセージを途中で q で閉じていた場合は、g< を使っても表示されたところまでしか表示されません。

thinca

Hack #214: 括弧までを消したり置き換えたりする

問題

プログラミングを行うということは、それすなわち括弧と友達になるということです。

現在のカーソル位置から次の閉じ括弧までの文字を一気に置き換えたい、というシーンは多々あると思います。

let l:lines = getbufline(buf■r(a:filename), 1, '$')

例えば上記のようなコードを記述しており、カーソル位置は■とし、この位置からa:filenameの直後の閉じ括弧までをまとめて削除し、bufnrのかわりにbufloadedと記述したいというケースを考えてみましょう。直後に開き括弧が存在し、これらは1トークンではないため、weなどをそのまま使うことはできません。文字数を正確に数えることも困難です。おそらくt)feの二択となるでしょう。ただし後者を使う場合、正確にeがそれまで存在しないことを確認する必要があるため、より非存在性を確認しやすい括弧を用いて指定することになると思います。

こういった操作をする機会は、ほとんど意識されないものの、かなり多いことが最近の研究で明らかになっています。(*1)

解決

文単位モーションの()の使用をやめ、これにt(などを割り当てましょう。~/.vimrcに以下を記述します。

onoremap ) t)
onoremap ( t(
vnoremap ) t)
vnoremap ( t(

あとはt)などを使用するかわりにたんに)などと打鍵します。上記設定のおかげで、あなたのソフトウェア開発にかかる時間の50%が短縮できます。

参考

  • (*1) 要出典
  • :h )
  • :h t
ujihisa

Hack #212: コマンドライン引数を活用する

今回は Vim 起動後のあれこれや、Plugin のあれこれではなく、便利なコマンドライン引数を紹介します。

紹介するもの以外にも沢山のコマンドライン引数が用意されています。さらに知るには :help vim-arguments を参照してください。

–startuptime {fname}
{fname} で指定したファイルに、起動に要した時間が記録されます。
.vimrc の読み込みに何秒というように細かく出ますので、起動が遅い時の原因調査に利用出来ます。
–noplugin
Plugin を読み込まずに起動します
+[num]
起動直後に [num] 行目に移動します。
+/{pattern}
起動直後に {pattern} に最初にマッチする箇所に移動します。
-c {command}
起動直後に {command} を実行します。
-S {fname}
起動直後に {fname} を :source {fname} で読み込みます。
-R
Readonly モードで起動します。このモードではファイルへの書き込みを禁止します。
-Z
Restricted モードで起動します。このモードでは外部シェルの実行 (:shell など) を禁止します。
-b
Binary モードで起動します。
-l
Lisp モードで起動します
-C
Compatible モードで起動します。
-n
:set updatecount=0 として、Swap ファイルの生成を禁止した状態となります。
-o[n]
水平に 分割した状態で起動します。
-p[n]
[n] 個のタブを開いた状態で起動します。
-d
Diff モードで起動します。
-x
ファイルを暗号化したうえに、パスワードでロックします。

参照資料

Sixeight

Hack #210: Vim のイースターエッグを見る

Vim は長い歴史があるソフトウェアであり、そのためか多くのイースターエッグが見られます。

イースターエッグとは

ソフトウェアで見られる隠しメッセージなどのことです。詳しくは Wikipedia を参照してください。

Vim で見られるイースターエッグ

以下は筆者が知っている限りの Vim で見られるイースターエッグの一覧です。何が起こるかはあなた自身の目で確かめてください。

  • :help!
  • :help 42
  • :help holy-grail
  • :help map-modes
    • 表の下にコメントがあります。
  • :help UserGettingBored
  • :help spoon
  • :help showmatch
    • Note を参照してください。
  • :Ni!
  • :hi!
thinca

Hack #207: <C-g>, g<C-g>で選択されたテキストの情報を表示する

問題

ノーマルモードでは<C-g>g<C-g>などバッファの情報を表示するコマンドがあるのに、ヴィジュアルモードではありません。
選択されたテキストの情報を見たいというのはよくあるパターンです。
どうすればいいでしょうか?

解決

visualctrlg.vimを使います。
visualctrlg.vimはヴィジュアルモードで選択されたテキストの情報を表示してくれる本稿にぴったりのプラグインです。
インストールすれば自動的に<C-g>g<C-g>がヴィジュアルモードで使えるようになっているはずです。

tyru

Hack #206: 外部で変更のあったファイルを自動的に読み直す

ツール等で出力されたファイルを開いている場合や、VCS で更新した場合など、Vim で開いているファイルが外部で変更されることは割とよくあることでしょう。そういった場合、Vim は自動的に読み直すことができます。

'autoread' オプション

'autoread' オプションを有効にすると、元のファイルの変更を Vim が検知し、かつバッファが変更されていなかった場合、バッファは自動的に再読み込みされます。 これはグローバルまたはバッファについてローカルなオプションであり、バッファ毎に設定が可能です。

変更のチェックを強化する

'autoread' で Vim が変更に気付いたときに読み直されるわけですが、Vim はそこまで頻繁に変更をチェックするわけではありません。もっと頻繁にチェックして欲しい場合、以下のコマンドでチェックを行うことができます。

:checktime

これを autocmd を使って自動的に実行するようにすれば、再読み込みが発生する頻度が上がります。

augroup vimrc-checktime
  autocmd!
  autocmd WinEnter * checktime
augroup END

この設定ではウィンドウを移動する度にチェックを行います。

thinca

Hack #205: 複数行をコメントアウトする

問題

普段のコーディングにおいて、ある程度のコードの塊をまとめてコメントアウトしたくなることがありせんか。 コメントアウトしたコードは大抵不要となり捨てることになるのですが、一時的にリファクタリング前のコードを残したり、デバッグなどの際に止めを得ずコメントの付け外しを行うことがあるかと思います。

コードのコメントアウトと聞いてすぐに思い浮ぶのは, Hack #12: 条件にマッチする行を削除する にあるような I# <Esc> とする方法です。 しかしながら、この方法では複数行をコメントアウトするのに時間がかかり、気がつけば Fibonacci 数列を求めるコードを 3 パターンほど記述出来る程度の時間を浪費していることもあります。

別解として ^<C-v>jjjI# <Esc> などとして、コメントアウトする方法もありますが、行頭がずれていたりすると大変面倒です。

解決方法

もっとも手頃な方法として commentout.vim を使用する方法が挙げられます。 これは vim online Tip #271: easy (un)commenting out of source code として掲載されていたもので 参照資料1 に詳しい解説があります。

また Tip 1570 Commenting with opfunc で紹介されているスクリプトを利用する方法もあります。 オリジナルは Ruby に対応していなかったため、一部修正を加えています。

" Comment or uncomment lines from mark a to mark b.
function! CommentMark(docomment, a, b)
  if !exists('b:comment')
    let b:comment = CommentStr() . ' '
  endif
  if a:docomment
    exe "normal! '" . a:a . "_\<C-V>'" . a:b . 'I' . b:comment
  else
    exe "'".a:a.",'".a:b . 's/^\(\s*\)' . escape(b:comment,'/') . '/\1/e'
  endif
endfunction

" Comment lines in marks set by g@ operator.
function! DoCommentOp(type)
  call CommentMark(1, '[', ']')
endfunction

" Uncomment lines in marks set by g@ operator.
function! UnCommentOp(type)
  call CommentMark(0, '[', ']')
endfunction

" Return string used to comment line for current filetype.
function! CommentStr()
  if &ft == 'cpp' || &ft == 'java' || &ft == 'javascript'
    return '//'
  elseif &ft == 'vim'
    return '"'
  elseif &ft == 'python' || &ft == 'perl' || &ft == 'sh' || &ft == 'R' || &ft == 'ruby'
    return '#'
  elseif &ft == 'lisp'
    return ';'
  endif
  return ''
endfunction

nnoremap <Leader>c <Esc>:set opfunc=DoCommentOp<CR>g@
nnoremap <Leader>C <Esc>:set opfunc=UnCommentOp<CR>g@
vnoremap <Leader>c <Esc>:call CommentMark(1,'<','>')<CR>
vnoremap <Leader>C <Esc>:call CommentMark(0,'<','>')<CR>

コメントアウトしたい箇所を Visual mode で選択し、<leader>c を打鍵することで Filetype に沿ってコメントアウトされます。 逆に、コメントアウトされた箇所を Visual mode で選択し <leader>C を打鍵することでコメントを外すことも出来ます。

また、<leader>cip などと打鍵することで、text-objects の単位でのコメントアウトも可能です。コメントを外す際は <leader>Cip と打鍵します。

参照資料

Sixeight

Hack #204: Vimに望み通りの新機能を搭載してもらう

問題

Vim scriptを書いたり、あるいはVimを用いて他の言語でプログラミングを行う日々を通して、Vimに対して様々な要望がでてくることと思います。Vim本体にこんな機能があればこういう目的を実現するのが容易になるのに、あるいはVim scriptのこの変な挙動が修正されたらプラギン開発がずっと容易になるのに、などなど。

解決

寄付をします。

http://www.vim.org/sponsor/index.php

Vimの開発者であるBramさんは、このように語っています。

Since Bram is back to a paid job the money will now be used to help children in Uganda. (snip) But at the same time donations increase Bram’s motivation to keep working on Vim!

寄付をすることによって間接的にVimの開発を支援することができます。

クレジットカードや郵便を用いて送金することができます。最小単位が10ユーロです。ユーロ安の今が大チャンスです。

また別の解決策として、自分でVim本体へのパッチを書いてvim_devに投稿する方法もあります。これに関しては、vim-users.jpに掲載されているReal Vim Hacks Projectというページに役に立つ情報がたくさん掲載されていますので、ご参照ください。

補足

vim.orgにて寄付をした人の一覧を見ることができます。

http://www.vim.org/sponsor/hall_of_honour.php

2011年3月現在、公表されている寄付金額の合計は13336ユーロです。

参考

寄付に関する情報もVimに添付されています。:help sponsorしてみましょう。

ujihisa

Hack #201: バックアップを作成する

バックアップには 2 種類あります。 1 つは編集中のファイルのバックアップ、これをスワップファイルと呼びます。 もう 1 つは既に存在しているファイルを上書きする際に作成されるものです。

スワップファイル

スワップファイルを作成するには ‘swapfile’ をオンにします。 オフにするとスワップファイルは作成されなくなります。

スワップファイルは ‘directory’ で指定したディレクトリに作成されます。 全てのプラットフォームでの規定値は Unix の場合 ‘.,~/tmp,/var/tmp,/tmp’ と指定れているため、 カレントディレクトリ、つまり編集中のファイルと同じディレクトリに作成されます。

スワップファイルは ‘updatecount’ で指定している文字数を入力することで書き込まれます。 ‘updatecount’ を 0 に指定するとスワップファイルは作成されなくなります。

設定例

保存場所からカレントディレクトリを除き、~/tmp にして、更新の間隔を 500 文字にするには以下の様に指定します。

set swapfile
set directory-=.
set updatecount=500

バックアップ

同名のファイルを上書きする前にバックアップを取るには、’backup’ もしくは ‘writebackup’ をオンにします。

‘backup’ をオンにしておくと、上書きに成功した場合にもバックアップを残します。 ‘backup’ をオフにしておくと ‘writebackup’ をオンしておくと上書きが成功した場合はバックアップを破棄するようになります。 どちらもオフにした場合にはバックアップを取らなくなります。

バックアップ先を指定するには ‘backupdir’ を指定します。既定値ではカレントディレクトリにバックアップが作成されます。 ‘backupext’ を指定すると、バックアップファイル名の最後に指定した文字列を追加することが出来ます。 例えば、ファイル名の最後にタイムスタンプを追加するには、以下のように指定します。(HELP からの引用)

:au BufWritePre * let &bex = '-' . strftime("%Y%b%d%X") . '~'`

また、バックアップを作成しないファイル名のパターンを ‘backupskip’ に指定することが出来ます。

参照資料

Sixeight

Hack #200: 候補を選択し、実行する

200番目のHackです。これまであなたは199ものHackを習得してきました。さらなる高みを目指して、日々修練を怠らないようにしましょう。

概要

Vimでは多くの操作が「何を行うか決め、その後候補を指定する」というものになっています。たとえばファイルa.txtを別のバッファに開くならば、:new a.txtなどというコマンドを実行することになります。まず先に:newを打鍵し、つまり「別のバッファに開く」という動作を決め、その後対象となるファイルを入力します。このとき、Vim組み込みの補完は、:newという先立つ入力をもとに、後に入力されるものはファイル名と分かりきっていることから、ファイル名のための補完を行ってくれます。かゆいところに手が届く支援もあり、また無駄な操作が存在せず、非常に効率的かつ快適です。

一方、近年Vim業界で幅を利かせつつあるuniteというプラギンが存在します。全てを統合し破壊するフレームワークなどと呼ばれていて、なんのことかよくわからずとりあえず見送っている方も多いのではないでしょうか。

uniteはこのような視点で見てみることで理解が容易になるかもしれません。従来のVimの多くの操作とと違い、「候補を選択し、それから実行する」ための機能を提供するためのフレームワークだ、という見方です。

uniteコアは枠組みを提供するのみで、実際にユーザが触れるのは個別のuniteプラギンでしょう。uniteというとuniteコアを指し、unite-fileというとuniteのfileプラギンのことを指します。uniteコアをインストールすると、特に意識することなく標準添付のプラギンがいくつか何の設定もなしに動作します。

以下の各セクションで、対象の種類に大雑把にわけてuniteプラギンの使い方について説明します。

ファイルを操作するuniteプラギン

標準添付のunite-fileというプラギンがあります。

:edit a.txt

のかわりに、まず以下のコマンドでunite窓を開きます。

:Unite file

カレントディレクトリのファイル一覧がでてきます。

つづいて、jkで項目間を移動し、今回対象として取り扱いたいa.txtのところにカーソルを移動します。つづいて、<tab>を打鍵します。

そのファイルに対して「何ができるか」の一覧がでてきました。今回行いたいのはそのファイルを開くことですので、openと打鍵して<cr>します。なお、他のコマンドとかぶらない程度に省略することができます。oで十分です。

以上でunite上でファイルの操作を行うことができることがわかりました。この説明だけを聞くと、「単に手順が増えただけじゃないか」と思うかもしれません。著者もそうでした。

また、j, kで項目間を移動するだけでなく、iを打鍵してInsert mode(*1)に入ってから適当な文字列を入力することで、その文字列で候補を絞り込むことができます。今回対象はa.txtb.txtの二つのみですので、aと一文字打鍵するだけで候補が完全にa.txtのみに絞られます。

カレントディレクトリにあるファイルを:Unite fileで開くだけならば、:editの方が良いでしょう。しかし、もうすこし複雑な例になると、uniteの優位性がじわじわと上回ってきます。

標準添付にunite-file_recというプラギンがあります。これはカレントディレクトリ以下のファイルを再帰的にすべて探索するという点を除いてunite-fileとほぼ全く同等です。

unite-file_recはかなり強力で、筆者は一日に少なくとも1000回は使用しています。:editでいちいち深いディレクトリをもぐってファイルを開く必要はありません。また、カレントディレクトリ以下のファイル数が非常に多くとも、探索が非同期で行われるため、Vimが固まることはありません。

さらに、previewモードというものが存在します。:Uniteコマンド時に-auto-previewというオプションを指定すると、カーソルを移動するたびにunite窓の少ししたに小さなウインドウが現れ、そこにファイルの中身の一部が表示されます。

ファイル以外のものを操作するuniteプラギン

筆者が頻繁に使うものの例はunite-colorschemeです。これについて詳しくは Hack #196: カラースキームは開発支援ツール を参照ください。なお、-auto-previewオプション付きで起動することにより、カーソル移動するたびに実際にそのVimのcolorschemeがチラチラ変わります。(キャンセルすると元のcolorschemeに戻ります)

また、unite-refを用いることで、ruby, haskell, perl, python, php, erlang, clojureのドキュメントをひくことができます。英和辞書、manもついていてお買い得です(*2)。これはref.vimというVimプラギンが既に存在し、そのプラギンがuniteで利用可能になっているという構造になっています。以下の図は例としてrefで>>=で検索してみたところです。Haskellの例がいくつか見つかっていますね。

他にも参考になるプラギンと対応する記事を羅列します。

  • unite-help Hack #199: :helpに慣れ親しむ
    • :helpコマンドの説明をしていますが、:helpそのものを使わずとも、unite-helpで気楽にhelpをひきましょう。

類似のフレームワークとの比較

候補を選択し、何かを実行するためのフレームワークは他にもいくつかあります。これについて詳しくは Hack #189 : Emacsのプラグインに対応するVimプラグインを参照ください。uniteの作者自らによる解説があり、必見です。

新たなuniteプラギンの開発

これについて詳しくは Hack #197: unite.vim の source を作成する を参照ください。

脚注

  • (*1) 厳密にはInsert modeではなくNarrowing modeと呼ばれるunite独自の特殊な疑似モードです
  • (*2) いまなら送料無料です
ujihisa

Home > Tags > lv1

Search
Feeds
Links
  • 公式
  • 勉強会
  • 情報
  • コミュニティ
  • Meta
    Etc
    Creative Commons License
    This blog is licensed under a Creative Commons License.

    Return to page top