Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

悲しみの果て

$
0
0

悲しいお知らせですが、前エントリは没となりました。

根本的な勘違い

そもそもなぜ巨大なだけのこんなスクリプトが出来上がってしまったのかを考える必要があります。

プロジェクトリーダーの理解

  1. netrw内のブックマークファイル(.netrwbook)はただのvimスクリプトなので、先にロードしておけば、netrwの変数 g:netrw_bookmarklistを使えるかもしれない
  2. ノーマルモードの gbが空いていた
  3. ディレクトリ関係を弄るのであればvim導入初期から使っていた<Leader>vから始まる設定ファイルへの移動マップもうまく組み込みたい
  4. なんか :split some/directory/:Hexplore some/directory/の挙動が違う気がする (すごく気になる)

というわけで、この辺の欲を一気にまとめるスクリプトを作ろうという発想に至ったわけです。

得られたサポート

そもそもじゃあこの差はなんなんだ?って話なんだけど…何の成果も得られませんでした。ただ :Hexploreを使うと既にあるnetrwのバッファ内でディレクトリ移動されて、 :Rexploreを使うまでウィンドウとして出てこない事があるので「これは何なんだろう」というところまでしかわかりませんでした。

プログラマのコード

…はもう前のエントリで見てもらえばいいとして、どうにもやるべきことに対して労力が見合っていません。この状態から更に捻じ伏せようという気になれなくなったところで根本的に方法が間違っている事に気が付きました。

顧客が本当に必要だったもの

そもそもnetrwはどう使われたいのでしょうか?確かに :Explorerは現在のバッファの編集状態を見ていい感じにウィンドウを開くダンディなヤツですが、「もっとカジュアルに :e some/directory/で使ってもいいよ」と言ってくれているんです。じゃあわざわざ長いコマンドを使わずに :e, :sp, :vsでいいじゃないですか。"Small is beautiful" を忘れちゃダメっすよ…

実装された運用

dirz.vim
if!exists('g:netrw_bookmarklist')try
        execute printf("source %S/%S",g:netrw_home,'.netrwbook')catch/E121/
        execute printf("source %S/%S", split(&runtimepath,',')[0],'.netrwbook')endtryendiflets:cmdDict={    \'e':'edit',    \'e!':'edit!',    \'s':'split',    \'v':'vsplit',    \'t':'tabe',    \'t!':'tabe'    \}lets:cmdDict['s!']=&splitbelow ? 'abo split':'bel split'lets:cmdDict['v!']=&splitright ? 'lefta vsplit':'rightb split'function! dirz#open(...) abort
    let path =a:1let isBang = exists('a:2') ? a:2:''let drx = exists('a:3') ? tolower(a:3[0]):''if drx ==''if getbufinfo(bufname(''))[0]['changed']let drx = isBang =='!' ? 'v':'s'elselet drx ='e'endiflet isBang =''endif

    execute printf("%s %S",s:cmdDict[drx.isBang], path)endfunctionfunction! dirz#netrwBook(...) abort
    let index = exists('a:1') ? a:1:0let isBang = exists('a:2') ? a:2:''let drx = exists('a:3') ? a:3:''if index ==0let line =1forbming:netrw_bookmarklist
            echo printf('%3d: %s', line,bm)let line +=1endforcall inputsave()let selected = input('番号と<Enter>を入力して下さい (空でキャンセル): ')call inputrestore()elselet selected = index
    endifcall dirz#open(g:netrw_bookmarklist[abs(selected)-1], isBang, drx)endfunction

noremap <Plug>(dirz_netrwBookS):<C-u>call dirz#netrwBook(v:count)<CR>
noremap <Plug>(dirz_netrwBookV):<C-u>call dirz#netrwBook(v:count,'!')<CR>
noremap <Plug>(dirz_netrwBookT):<C-u>call dirz#netrwBook(v:count,'','t')<CR>

command!-bang Bookz call dirz#netrwBook('','<bang>','')
command!-bang SBookz call dirz#netrwBook('','<bang>','s')
command!-bang VBookz call dirz#netrwBook('','<bang>','v')
command!-bang TBookz call dirz#netrwBook('','<bang>','t')

…どうしてこんな事になってしまったんだ。

さておき

やっていることは基本的に一緒で、netrwのブックマークをノーマルモードからも使うためのものです。dirz#netrwBook()関数の方で g:netrw_bookmarklistからパスを読み込んで、開き方の指定は汎用的に使える dirz#open()関数に任せています。むしろ本体は dirz#open()に見えてきます。

dirz#open()関数

:Explorerのバッファの編集状況をチェックしていい具合にウィンドウ分割するダンディな部分はぜひ実装したいということで残しました。

モード

dirz#oepn()の第三引数のモードは大体こんな感じです。

mode名称bangなし挙動bangあり挙動
(なし)ワイズモードバッファが保存されていなければ :splitバッファが保存されていなければ :vsplit
s垂直分割モード:split:splitと逆方向 (&splitbelowを参照)
v水平分割モード:vsplit:vsplitと逆方向 (&splitrightを参照)
tタブモード:tabe:tabe
e通常モード:edit:edit!

アナリストのデザイン

とりあえず汎用に使える関数にしてしまったので、netrwに入れるには適してない1ブックマークを別なスクリプトから定義して使ってもいいかなと思ってたんですけど…けど、なんですよ。このスクリプト作成前のvimのコンフィグへのリマップ「群」が「選んで」「開く」という形になっていたのは良くないんじゃないのか?という自問自答が始まってしまいました。一つの動作で一つづつ操作を定義すれば、マトリクスを書くためにすべての状態を書く必要はないわけで…というわけで現在手近にアクセスしたいファイルのパスはコマンドモードの短縮入力にしてみました。とはいえ打鍵数は多いので頑張り過ぎかなとも思っているので…弱ったなまたスクリプトが増えるぞ…?


  1. netrwのブックマークは追加するとリストの最初の要素に入るのでカウントがズレる。 


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>