Friday, April 16, 2021

僕がどうしてもvimにこだわる理由

 vim、ときくと「は?何この老害」というリアクションをする諸兄も多いのではないだろうか。

このIDEとか自動補完とかが充実した21世紀にvim?お前正気か???と。

たしかに君たちの言いたいことはわかる。

しかしそれでも私は言い続けたい。vimが最強のエディタであると。

これはとくに、Unix系のOS、macとかlinuxで特に顕著である。

なぜvimが最強かというと、

1. モードの概念によりエイリアス(可動操作域)が3倍になる

2. OSと合体していて、OSをIDEにできる

3. コンパイルなど、自分がやっていることをより正確に理解できる

4. 速い

5. 言語に依存しない

6. shellを使う癖がつく

7. 自分でエディタを作る、という習慣がみにつく

------------------------------------------------------------------------

一つ一つ解説していこう。

1. モードの概念によりエイリアス(可動操作域)が3倍になる

まずこれがでかい。というより、vim敬遠者のほぼ多くが日本語入力に依存している。そもそも高等教育までやっていれば英語の読み書きができない、は言い訳にならない。英語でコメントを読み書きするのがデフォルトであればそもそもvimの操作で引っかかることはなくなる。

その前提で、モード切り替えができるということはショートカットがコンテクストごとにあるので総計で3倍になる、ということだ。例えば、

f d というキーの組み合わせは「今いる行のうちはじめに見つけたdという文字まで移動しろ」、ということで

v f d であれば選択モードなので現在位置からはじめにみつけたdまでの領域を選択する

i f d であればインサートモードなので fdという文字列が入力されている... というようなことである。

vi自体がマウスなしで操作すること前提で作られているのでこのモードにより操作の種類が3倍に圧縮されており、できる操作のレベルがマウスを使うのとは遥かに違う。

これは、結局vimのキーバインディングを学習しなければできないので、結局ここでヘタレエンジニアどもがつまづき、自己正当化しはじめる.... ちまたできくvimへの悪口雑言というのは負け犬の遠吠えなのである。

2. OSと合体していて、OSをIDEにできる

これもよく知られているが、vimがコマンドラインで編集できるエディタである以上それはコマンドラインの上に乗っかっているのである。vimではシェル実行モードあり、それはノーマルモードにおいて

:! [command]

で実行するか、もしくは

:.! [command]

を実行するかのどちらかで、前者と後者の決定的な違いは後者はコマンド実行結果をそのままバッファ(バッファというのは今編集している画面という意味)に貼り付けることができるのである。

3. コンパイルなど、自分がやっていることをより正確に理解できる

そもそもIDEなどでボタンポチしてコンパイル、とか、変なGUIにいろいろパラメータ入れて... みたいにしている過程が愚かである。はっきり言ってIDEでの開発はコンドームを20枚装着して性行為をしているのと同じである。そんなの、ないほうがいいに・・・・(女性の方、当方アスペなんどす、すんまへん・・・・)

まあ余談は置いておいて、「自分がいま何をやっているのかを」より直接的に把握するには、結局一番直接的なのはコマンドラインなのであるか、そこに何枚も絵を噛ませるのがナンセンスなのである。それでも確かに業務は回るが、応用が効くという意味ではやはりvim/emacsなどのコマンドラインエディタを使うべきだと思う。(あなたの大好きな Linus TorvaldsもRichard Stallmanも emacs使い)

4. 速い

結局IDE使いはマウスぐりぐりやってばかりになるので開発速度としてはどうしてもvimが有利になる。IDEのより良い点としてはデバッグモードが〜などとのたもううつけものありしが、斯様なたわけにつける薬あらずして、デバッグを要するやうなコードをしたためること自体間違いであり、すべてコンソールで書くこと能わずや。あないみじ。

5. 言語に依存しない

「そうだ!COBOLやってみよう!」と思ったときあなたのIDEはサポートしてますか?また、だとしてもいちいちちまちまプラグインとか入れんの?は?意味なくね?つかなんでそんなコマンドライン開発ならただ apt/brewとかでエンジンいれてそのままコード書いてコンパイルすべきところをそんな大作業になるのかわからん、そこまでしてコード自動補完ありがたいか?ドキュメントに全部書いてあるやろ?だるいねん!!!!!びしぃぃぃぃぃ!

ということです。

6. shellを使う癖がつく

刃牙の環境利用闘法じゃないですがコマンドライン派は基本コマンドラインに引きこもって一生過ごせるわけです。そしてそのときの母国語が、unixならshellなんですな。ですから、当然vimの上でもshellをべらべらべらべらしゃべるわけです。まあインターネッツいじるときはブラウザも使いますけど、まあlynx/w2mもありますしねぇ・・・・(遠い目)

7. 自分でエディタを作る、という習慣がみにつく

これも重要で、vimそのものってあれ自体で完成しているわけではなくvimscriptたくさんかましたり /usr/local/bin配下にいっぱい自分のエイリアススクリプトとかパイソンスクリプトとかいれてそれをvimに呼び出していろいろなことをやるわけでやんす。とくに1000回繰り返しそうな動作であれば確実にそうやって省力化するわけです。(emacsだとマクロですね)

まあそんなかんじで、vimを嗜むとメリットしかないです。

有料エディタ?お主うつけものか?叩っ斬る!控えおろう!!!!!

by 井原西鶴

ってかんじです。

まあ煽りとか抜きにして例えば、こんなユースケースを想像しましょう。

「ワイ、ソースコード鑑賞して技術力をみがくンゴ〜っ。そうンゴね・・・・ワイ意識高いからLinuxのソースコードでも読むンゴ?ンゴ?」

みたいなことを思ったとしましょう。そんなときにIDEでどうやってランダムにソースコードよみますか?

検索して、なんかプラグインとか落とすんですか????(侮)

nnoremap * :Randopen<CR>  
...
nnoremap _ :Prevfile<CR>
nnoremap + :Nextfile<CR>
 
:command! -nargs=? Randopen :call Randopen(<f-args>)
function! Randopen(...)
   if a:0 >= 1
       let result = system(g:script_dir . "randomfile " . a:1)
   else
       let result = system(g:script_dir . "randomfile ")
   endif
   execute "edit " . result
endfunction

:command! -nargs=0 Nextfile :call Nextfile()
function Nextfile() 
 let result = system("navi -n " . @%)
 execute "edit " . result
endfunction

:command! -nargs=0 Prevfile :call Prevfile()
function Prevfile() 
 let result = system("navi -p " . @%)
 execute "edit " . result
endfunction

ちなみにここで呼ばれてる randomfileってのが

#!/usr/bin/env bash
if [ "$1" == "-b" ]; then
   files=$(find . -perm +111 -type f | grep -v .git)
   len=$(echo $files | tr -s ' ' '\n' | wc -l)
else
   files=$(find . -type f -not -empty | grep -v git | grep -v .class | grep -v .png | grep -v .ico | grep -v .jpg | grep -v .PNG | grep -v .gif)
   len=$(echo $files | tr -s ' ' '\n' | wc -l)
fi
#idx=$(echo $((1 + RANDOM % $len)))
idx=$(echo $((RANDOM % $len)))
i=0
target_file=$file
for file in $files; do
   if [ "$i" == "$idx" ]; then
       target_file=$file
   fi
   i=$((i+1))
done
echo $target_file

こちらがnaviスクリプト

#!/usr/bin/env bash
action=$1
if [[ "$action" != "-n" && "$action" != "-p" ]]; then
   printf "\naction missing (-n|-p)\n\n"
   exit
fi
current_path=$(basename $2)
if [ -z $current_path ]; then
   current_dir=$(pwd)
else
   dirname2=$(dirname $2)
   if [[ $dirname2 != $pwd* ]]; then
       dirname2="$(pwd)/$dirname2"
   fi
   current_dir=$dirname2
fi
i=0
pointer=-1
list=$(ls -lt -r $current_dir | awk '{print $9}')
current_dir=$(echo $current_dir | sed 's/\/\.//g')
for x in $list;do
   if [[ -f $x || -f $current_dir/$x ]]; then
       base_cp=$(basename $current_path)
       base_x=$(basename $x)
       if [[ $base_cp == $base_x ]];then
           pointer=$i
       fi
       i=$((i+1))
   fi
done
i=0
for x in $list;do
   file=$x 
   if [[ -f $current_dir/$x ]]; then
       file=$current_dir/$x
   fi
   if [[ -f $file ]]; then
       if [[ $i == $((pointer+1)) && $action == "-n" ]];then
           echo $file
       fi
       if [[ $i == $((pointer-1)) && $action == "-p" ]];then
           echo $file
       fi
       i=$((i+1))
   fi
done

まあようは ボタンの8とシフトキー同時に押すと現在のディレクトリの中のファイルを一覧して、その一覧サイズがマックスの乱数を生成してその乱数のインデックスのファイルをとってくる、つまりランダムにファイルをとってくるんですな。

こういうのは、まあファイル数が膨大で何から読んでいいかわかんないし、とりあえずなんでもいいから出してほしい、というときには便利なアプローチになります。

また、上記エイリアスでは+, _ ボタンで同じディレクトリ上で右のファイル、左のファイルに移動することができます(バッファの呼び出し履歴じゃないんで C-i, C-oとは違う)

まあそんなかんじで自分でエディタを拡張していく、しかもそれも bash/pythonとかでちゃっちゃかつくれるから楽ちんですな?

てなわけで みなさん、vimを使いましょう!(真顔)

はじめは手こずるかもだけど、てだれてくるとすごいことになります!!!!!

twitter: @keisuganodev

あ、あと手前味噌ですがエンジニア?に関係する漫画を描いてます、もしよければ

https://www.amazon.co.jp/dp/B092JFQVF9

No comments:

Post a Comment