Hatena::Groupsubtech

NaN days

ブログを移転しています。最新の記事は motemen.hatenablog.com へどうぞ

2011-08-17

Vim: コード読んでるとき、カーソルのあるブロックを確認する

| 19:31 | Vim: コード読んでるとき、カーソルのあるブロックを確認する - NaN days を含むブックマーク はてなブックマーク - Vim: コード読んでるとき、カーソルのあるブロックを確認する - NaN days

コードを読んでいるとき、いま自分がどのメソッド内にいるのか、どのブロックの中にいるのかがパッと分からなくて困ることがあり、そういう時は [{ で今いる { ... } の先頭までジャンプできるのでそれを使っていますが、いちいちジャンプするのが面倒なのでその場で確認したい。というわけで Preview window というのを使って実現してみます。

Preview window は名前の通り他のファイルをプレビューするための代物で、ウィンドウにフォーカスしなくとも <C-W> z で閉じられるのが便利 (な気がする)。

nnoremap <buffer> <silent> ( :<C-U>call PreviewOpenBrace()<CR>

if !exists('*PreviewOpenBrace')
    function PreviewOpenBrace()
        let l:pos = getpos('.')
        if l:pos == get(s:, 'last_pos', [])
            let l:count = s:last_count + 1
        else
            let l:count = v:count1
        endif
        pclose
        pedit
        wincmd p
        execute 'normal!' l:count . '[{'
        setlocal cursorline
        wincmd p
        let s:last_count = l:count
        let s:last_pos   = l:pos
    endfunction
endif

コード中で ( を押すと Preview window が開いて、カーソルのあるブロックの先頭部分を見せてくれます。さらに外側のブロックを見たい場合は同じ場所で ( を押すと、もうひとつ外側に行きます。カウントにも対応しているので 99( で一気にいちばん外側のブロックを見るというのもできる。

  • スコープのプレフィックスは辞書型の変数になっているということなので、その時点で定義されているかどうか分からない変数にアクセスしたいときは get(s:, 'last_pos', []) と書けます
  • 関数の上書きをしないようにしてるのは ftplugin に入れることを想定しているから (この関数中で Preview window を開く時に ftplugin が実行されて同じ関数が上書きされようとすると、エラーになる)

2011-03-30

今日の .vimrc: Git における最後の変更をハイライトする

| 20:29 | 今日の .vimrc: Git における最後の変更をハイライトする - NaN days を含むブックマーク はてなブックマーク - 今日の .vimrc: Git における最後の変更をハイライトする - NaN days

ざっと、ファイルどの辺を変更してたか知りたいときに便利です。

http://gyazo.com/926b0af7210395472b208a1e9746d91d.png

metarw-git (と metarw) が必要です。

https://gist.github.com/894232

2011-02-08

Vim: Perl ファイル上での "gf"

| 14:21 | Vim: Perl ファイル上での "gf" - NaN days を含むブックマーク はてなブックマーク - Vim: Perl ファイル上での "gf" - NaN days

gf でのジャンプは便利だけど

Foo::Bar->baz;
use base qw/Foo::Bar/;

なときに "Foo/Bar-.pm" や "qw/Foo/Bar/.pm" に誤爆してしまうので .vim/after/ftplugin/perl.vim に書く。これでより便利

setlocal includeexpr=substitute(substitute(substitute(v:fname,'::','/','g'),'[-/]\\?$','.pm',''),'^q[qw]\\?/','','')

Vim にバンドルされてるらしいリポジトリがあったので pull request もしてみました。

cjgactukcjgactuk2011/02/20 05:17aA1suZ <a href="http://hevofeypgxda.com/">hevofeypgxda</a>, [url=http://hebvgaiqolrk.com/]hebvgaiqolrk[/url], [link=http://yvtymgnhgcnh.com/]yvtymgnhgcnh[/link], http://fcfadkrxqgjf.com/

2010-12-15

"FBB" をその場で "Foo::Bar::Baz" や "foo_bar_baz" に展開する Vim プラグイン

| 21:02 | "FBB" をその場で "Foo::Bar::Baz" や "foo_bar_baz" に展開する Vim プラグイン - NaN days を含むブックマーク はてなブックマーク - "FBB" をその場で "Foo::Bar::Baz" や "foo_bar_baz" に展開する Vim プラグイン - NaN days

を書きました。

https://github.com/motemen/vim-guess-abbrev

コードを書いているとモジュール名や識別子を入力するのが面倒で、よく使うものに関しては :iabbrev を使って "FB" が "Foo::Bar" に展開されるように……というのをいちいち登録していたのですが、まあそこは自動でできたらいいんじゃないの、ということで書いていたものです。

例えば ftplugin/perl.vim

setlocal iskeyword+=:
inoremap <buffer> <silent> <expr> <C-]> gabbrev#i_start()
setlocal completefunc=gabbrev#complete " これはなくても動きます

と書いておき、Perl のバッファで "SM" に続けて ^] を入力すると、バッファを検索して最初に見つかったそれっぽいもの、例えば "Some::Module" や "super_method" に展開してくれます。これが気に入らなかった場合には もう一度 ^] を入力すれば全ての候補をサジェストします。

gabbrev.vim の中では、展開が要求されたときカーソル前にある単語を大文字で区切り、それを記号でつなげた正規表現を作って全てのバッファを検索しています。この場合は、/S[[:alnum:]]*/ と /M[[:alnum:]]*/ を /\([[:alnum:]]\@!\k\)\+/ (iskeyword だけど alnum ではない) でつないだような正規表現になります。

設定項目はあまりありませんが、g:gabbrev#abbrev_ch_pattern, g:gabbrev#keyword_ch_pattern を設定することでそれぞれ入力にマッチする正規表現 (デフォルト '[[:alnum:]]')、展開される語のための正規表現 (デフォルト '\k') を指定できるようになっています。

2010-11-29

fuf.vim でタブ選択

| 19:36 | fuf.vim でタブ選択 - NaN days を含むブックマーク はてなブックマーク - fuf.vim でタブ選択 - NaN days

自分は無意識にタブひらきまくるのですがどうも素の fuf には存在しないっぽい?ので自作です。

  • g:fuf_tab_format_item_line に、タブ番号を引数にとる関数の名前を渡すとフォーマットをカスタマイズできると思います (試してない)
  • タブごとに作業ディレクトリを変えている場合が多いと思うので、t:cwd をみるようになっています。デフォルトでは設定されてないはずなので適宜設定しておくと便利です

gist でもいいんだけどまあ他の人が探しやすいように。

https://github.com/motemen/vim-fuzzyfinder-tab

今日の .vimrc

| 18:30 | 今日の .vimrc  - NaN days を含むブックマーク はてなブックマーク - 今日の .vimrc  - NaN days

cnoremap <silent> <expr> <C-S> getcmdtype() =~ '[/?]' ? "<C-C>:FufLine! " . getcmdline() . "<CR>" : ''

/ でインクリメンタルサーチしていて、うまいこと辿り着けないので全体を俯瞰したいという時に C-S で即座に :FufLine する。正規表現のメタ文字みたいなのは効かないけどわりと便利っぽいです。

2009-03-17

autocomplpop.vim 下で iabbrev

| 21:14 | autocomplpop.vim 下で iabbrev - NaN days を含むブックマーク はてなブックマーク - autocomplpop.vim 下で iabbrev - NaN days

iabbrev shfit shift

普通に書くと補完が大暴れする。

こうすればいいのです。

set pastetoggle=<F10>
iabbrev shfit <F10>shift<F10>
iabbrev sfhit <F10>shift<F10>
iabbrev sefl  <F10>self<F10>

さらに、デフォルトだとスペースの入力で abbrev が発動しない件については g:AutoComplPop_MapList から ' ' を除く。

2008-11-21

いまの :Perldoc

| 21:02 | いまの :Perldoc - NaN days を含むブックマーク はてなブックマーク - いまの :Perldoc - NaN days

command! -nargs=+ -complete=file Perldoc call <SID>Perldoc(<q-args>)

function! s:Perldoc(args)
    tabnew
    if bufexists('perldoc ' . a:args)
        execute 'buffer' bufnr('perldoc ' . a:args)
    else
        silent execute '0read!LANG=C perldoc -otext -T' a:args
        if v:shell_error
            echoerr getline(1)
            quit!
        else
            file `='perldoc ' . a:args`
            setlocal buftype=nofile noswapfile
            if a:args =~ '\v(<|^)-m>'
                setfiletype perl
            else
                setfiletype man
            endif
            0
        endif
    endif
endfunction

2008-07-27

エスケープシーケンス による色付けを Vim のバッファで再現する

| 20:00 | エスケープシーケンス による色付けを Vim のバッファで再現する - NaN days を含むブックマーク はてなブックマーク - エスケープシーケンス による色付けを Vim のバッファで再現する - NaN days

PAGER='vim -R -' git show などとすると

^[[33mcommit ff47b11b42ebfc9095d8c212dd5a0b1c27518535^[[m
...

とコンソールコード (って言うのかな?) がそのまま表示されて汚い。こういうの対応してないの?と id:secondlife に聞かれ、自分も知らず、 vim.org でスクリプトをざっと探してみたけど無い気がする (AnsiEsc.vim というのがあったけどパッチを当てるみたい?試してない) ので簡単なものを書いてみた。手抜きだけどわりと使える!

f:id:motemen:20080727200724p:image

以下のコード中の "^[" は実際にはエスケープ文字なので <C-V><C-[> で置き換えて下さい。

function! HighlightConsoleCodes()
    0
    let register_save = @"
    while search('^[\[[0-9;]*m', 'c')
        normal! dfm

        let [lnum, col] = getpos('.')[1:2]
        if len(getline('.')) == col
            let col += 1
        endif
        let syntax_name = 'ConsoleCodeAt_' . bufnr('%') . '_' . lnum . '_' . col
        execute 'syntax region' syntax_name 'start=+\%' . lnum . 'l\%' . col . 'c+ end=+\%$+' 'contains=ALL'

        let highlight = ''
        for color_code in split(matchstr(@", '[0-9;]\+'), ';')
            if color_code == 0
                let highlight .= ' ctermfg=NONE ctermbg=NONE'
            elseif color_code == 1
                let highlight .= ' cterm=bold'
            elseif 30 <= color_code && color_code <= 37
                let highlight .= ' ctermfg=' . (color_code - 30)
            elseif color_code == 38
                " TODO
            elseif color_code == 39
                " TODO
            elseif 40 <= color_code && color_code <= 47
                let highlight .= ' ctermbg=' . (color_code - 40)
            elseif color_code == 49
                " TODO
            endif
        endfor
        if len(highlight)
            execute 'highlight' syntax_name highlight
        endif
    endwhile
    let @" = register_save
    0
endfunction

autocmd BufRead,StdinReadPost * if search('^[[\d*m', 'n') | call HighlightConsoleCodes() | set buftype=nofile nomodifiable | endif
" `:set modifiable | undo | syntax clear' to revert

ka-nachtka-nacht2008/07/28 18:55×コンソールコード
○エスケープシーケンス

そもそもPAGERを使うのが不味いです。パイプすれば良いじゃないですか。PAGERにするとそれがエスケープシーケンスを解釈できるものとしてエスケープシーケンスがそのままPAGERに渡されます。パイプにしたらエスケープシーケンスは渡されませんよ。
最近(Vim 7.2b以降)ならgit関係のsyntaxが含まれているのでパイプにしても問題ないはずです。

motemenmotemen2008/07/28 19:04や、折角エスケープシーケンスが吐かれているので、それをハイライトに使いたいという趣旨です。
あと「コンソールコード」は console_codes(4) から取ったのですがエスケープシーケンスと呼んだほうが正しいですかね。