vimコマンド
コマンド | 引数 | 説明 |
---|---|---|
:vim[grep] | 検索文字 | ""や''でくくらなくていい。/検索と同じ記法。 |
ファイルパス | **/*.xml とすると、子フォルダのxmlも見に行く。 | |
:cn | :vimの検索結果の次に進む。map gn :cnとかする。 | |
xmledit
<tag|
の状態で>
を打つと<tag>|</tag>
としてくれて、- さらに
>
を打つと、
<tag>
|
</tag>
としてくれる。
それ以外のコマンド説明は、名無しのvim使い参照。
コマンド | 引数 | 説明 |
---|---|---|
:vim[grep] | 検索文字 | ""や''でくくらなくていい。/検索と同じ記法。 |
ファイルパス | **/*.xml とすると、子フォルダのxmlも見に行く。 | |
:cn | :vimの検索結果の次に進む。map gn :cnとかする。 | |
<tag|
の状態で>
を打つと<tag>|</tag>
としてくれて、>
を打つと、<tag>
|
</tag>
としてくれる。
それ以外のコマンド説明は、名無しのvim使い参照。
Vim scriptをパースしてASTを作り、高速化を図ります。リポジトリはこちら→wholekeik/vim
Vim script は実行のたびにコマンドをパースしているので非常に遅い言語です。コマンドをパースしておいてASTとし、それを実行すれば高速化が見込めます。しかし、Vim scriptでは引数の解釈が各コマンドによって全く異なるため、共通のパーサーを書くのは不可能です。したがって事前にパースするのではなく実際に実行しながら並行してASTを作っていきます。なおVim scriptの実行はユーザーの入力(コマンドモード)やオートコマンド、関数などがありますが、ASTとなるのは関数内のみです。また、AST化は行単位で行われます。
AST化されているか確認するには、:function 関数の名前
を入力してください。
" AST化されていないfunction! F()1return1endfunction" 1行目がAST化されているfunction! F()1return1endfunction
AST化された行が他の行より深くインデントされます。元々はoptimized: return 1
のように表示していたのですが、Vimのテスト(make test
)でこの:function
コマンドの出力をパースするため、見づらい意味を変えない表記にしました。
Vimのソースコードについているテスト(make test
)はすべて通ります。しかし、同じ関数を二度以上実行してみないとAST化がうまくいっているかはわかりませんので、あまり信用はできません。
TODO // あとで調べて書く
一点のみ、互換性を破壊する箇所があります。具体的にいうと次のスクリプトが動きません(ソース元はこちら→本当にキモい Vim script - . 演算子編)。
function! s:func(time)let time =a:time
let suffix ='min'return1000-time.suffix
endfunction
echo s:func(50)" => 950min
echo s:func({'suffix': 'sec'})" => 1000 (これまでの動作)" => エラー (新しい動作)
このように、「関数内でドット演算子を使っているとき、ドット演算子の意味が途中で変化する」とエラーになるようになります。
以下はAST化できません。
|
を含む行var{'iab'}le
)AST化できない式を含むコマンドも連鎖的にAST化できなくなります。
関数についてですが、len('abc')
といったビルトイン関数、s:func(123)
といったユーザー定義関数はASTにできます。しかし、dict.func(0)
や、function('f', [42])(1)
というような複雑な関数はASTにできません。詳細はソースコードを参照してください。
もう一つ、ドット演算子の条件について説明します。Vimのドット演算子は左辺の型が決定しないと優先順位すら定まりません。ここで、x ? a.b : c.d
のような式を考えてみます。x
が真の時はa
が評価されるので一つ目のドット演算子が文字列結合か辞書アクセスかが決定します。しかしその時、c
は評価されませんので、二つ目のドット演算子はどちらの意味なのかがわかりません。そのためc.d
をASTにできず、連鎖的にx ? a.b : c.d
全体がASTにできなくなります。x
が偽の時も同様のことが起こるため、結局この式は絶対にASTにはできません。「右側に空白が一つ以上あればそのドット演算子を文字列結合とみなす」というルールがあればこの問題を(部分的に)解決できるのではないかと思っています(左側だと行継続の関係で辞書のアクセスでもスペースがある可能性があります)。ただ互換性が壊れる危険があるのでこれについては既存のスクリプトを調査する必要があります。
記事投稿時点での目下の課題は:let
と:call
のAST化です。この二つを実装すればかなりの行がAST化できるようになるのではないでしょうか。
$ git clone https://github.com/wholekeik/vim
$cd vim
$ git checkout feature/vimscript-optimization
$ ./configure && make && make test# 注: 私は引数なしのconfigure,makeしか試していません
大規模な変更でありどのようなバグがあるかわかりませんので、-u NONE -i NONE
のフラグ付きで起動するか、.vimrc等のバックアップをとった状態で起動してください。ファイル消失など、何が起こっても責任は負えません。
ブランチはfeature/vimscript-optimization
に切り替えてください。
FEAT_OPTIMIZATION
を有効にする必要があります。今はsrc/feature.h
に#define FEAT_OPTIMIZATION
が直書きされているので何もする必要はありません(あとでこれはちゃんとfeatureを定義します)。逆に、その行をコメントアウトすればFEAT_OPTIMIZATION
が有効になっていない状態でのテストが可能になります。
開発中の利便性のためsrc/Makefile
が直接変更されており、デバッグ用のフラグがいくつかオンになっています。ベンチマークを取っていただける場合は、それらを切ってコンパイラの最適化オプションを有効にした状態でお願いします。
この量の変更を一人でテストするのは難しいので、バグ報告だけでも非常に助かります。
最近の私のエディタ事情の話。
私が業務上編集するテキストファイルは9割がPython。
宗教上の理由からVIMをずっと使い続けていたが、やはり今どきのエディタとして使用するならそこそこの数のプラグインを入れる必要があった。
んで、あまりプラグインの管理がよろしくないのか、プラグインを追加したい更新したりすると高確率で動かなくなる。
ガチャガチャと書いてるうちに安定したから設定ファイルがものすごいことになってる。動かなくなるのが怖くて整理できない。
ちょこっとneovim試したけど設定ファイルの書き方が変わってて早々に心が折れた。
もう疲れたので、そろそろ脱VIMしようとしてます。
「いいからPyCharm使っておけ」なので、JetBrain謹製のVIMプラグインを導入。
意外と平気。exコマンドつかえないのだけど、そういや俺ほとんど使ってなかったわ。
hkjlの移動さえあればいい。
PyCharm ネ申
調べてたら、気づくと、Visual Studio Codeがとても良くなってた。
ATOM、Bracketはcp932の自動認識が簡単にはできない。俺だってそんなファイル編集したくないけどバッチファイルはcp932じゃないとダメなんだよチクショウ
Visual Studio Codeもデフォルトではオフなんだけど、設定に1行追加することで自動認識してくれる。
"files.autoGuessEncoding": true, // 文字コードの自動認識
エクスプローラもあるし、シンタックスの色分けも良い。
今でも十分便利なんだけど、どんどんデフォルトの設定が更新されてて、みるみる便利になってきている。
Sublime Textみたいなやつが追加された!熱い!(minimapという機能で、今まではデフォルトで無効になってたのが有効になったらしい)
てことで、非プログラマから「エディタって何使えばいいですか?」と聞かれたら今は普通にVisual Studio Codeと答えます。
さらに、拡張(エクステンション)が良い。多くはATOMやSublime Textの拡張の移植な気がする。先人に感謝。
VIMエクステンション。PyCharmと同様。結構平気。
設定もヤンクのこれくらい。
"vim.useSystemClipboard": true, // クリップボードにヤンク
どうやらneovimと連携してexコマンドが使えるようになるらしい。熱い。(でも怖いからしばらくは手を出さない)
Pythonエクステンションを入れるとPython開発もすいすい。
Visual Studio Codeはデバッガインターフェイスも組み込まれているので、簡単なスクリプトならコーディングから実行までVisual Studio Code内で完結できる。
リモートデバッグは出来ないのかな?そこまで調べてないです。宗教上の理由でPyCharmを選択できない場合は強力な選択肢になると思います。
MELエクステンションを入れればMELも色分けしてくれるよ
Visual Studio Codeは初心者にもお勧めできるエディタとなっていた。
進化のスピードが速く感じる。素晴らしいエコシステムがあるからでしょう。マイクロソフトは本当にいい会社になった。
今気持ち悪いと思ってるのは下記の通り。
この記事はVimmerな人たちでかつCommonLisp始めてみたいという方向けです。
Lisp開発用のVimプラグインであるslimvを使った環境構築をしていきます。
Emacsな人たちはLispBoxで調べると幸せになれるかもしれません。
以前書いたslimv導入という記事の内容の焼き直し版です。
Linuxな人たちだけでなくWindowsな人たちの環境構築についても書いていこうかとおもいます。
普通にGitをインストールします。
バージョンは2017/06/11現在(以降現在と言う)のデフォルトで 2.7.4を使っています。sudo apt-get install git
今回は処理系にSteel Bank Common Lispを使います。
これもGit同様普通にインストールします。
バージョンは現在のデフォルトで 1.3.1.debianを使っています。sudo apt-get install sbcl
今回使用するプラグインのslimvですが、python2サポートのあるVimでないと使えません。
sudo apt-get install vimでインストールできるVimは現在python2をサポートしていませんので、vim-nox-py2というパッケージをつかいます。sudo apt-get install vim-nox-py2
今まではVimのプラグイン管理にNeoBundleを使っていた方が多いのではないかと思います。
今回はNeoBundleの後継であるdeinを使用します。
まず、deinの導入についてはこの記事がとても参考になります。
ディレクトリを作成してdeinをクローンして、設定ファイルは以下のようにします。
if&compatiblesetnocompatibleendifsetruntimepath+=~/.vim/dein/repos/github.com/Shougo/dein.vimcall dein#begin(expand('~/.vim/dein'))call dein#add('Shougo/dein.vim')call dein#add('kovisoft/slimv')call dein#end()
設定ファイルを書いたらVimを立ち上げて以下のコマンドを実行します。
:call dein#install()
これでslimvがインストールされます。
Vimを再起動して、以下のファイルを作成してみます。
(defungreeting()(print"Welcome to the world of CommonLisp!"))
保存してから,c
を押すとREPLが立ち上がります。
test.lispを開いているバッファに戻って,b
を押すとバッファ全体が評価されます。
この記事はVS Code(Version 1.13.0)と、その拡張機能であるVimなどのよく使うショートカットキーに関する逆引きチートシートとなっております。拡張機能でカスタマイズされたショートカットの他に、独自のキーボードショートカットを登録している部分もあるので、該当箇所は斜体にしておきたいと思います。当方の環境としては、Macを使用しておりますので、Windowsの方には分かりにくい部分も多いかもしれません。ご了承ください。また、英語でも問題ない方は公式でMac対応のショートカット表が出ているのでそちらを見ても良いと思います(公式の表)。
このチートシートを効率良く確認する推奨環境の紹介です。まずディスプレイが二枚以上あると、常にチートシートを表示させながらエディタを操作することができるのでオススメです。また、スクロールを行わずに効率的に作業を進めながらチートシートを確認するために、チートシートのページを普段使いのブラウザ以外で文字を小さくして複数ウィンドウに表示させることをオススメします。「Spectacle」というアプリをPCに入れるとショートカットキーの押下でウィンドウを簡単に上寄せ半分表示、斜め右上1/4表示などの表示が可能なので、是非使用してみて下さい。この逆引きチートシートでは、キーを特殊文字で表すので、特殊文字なんて覚えていないという方は、覚えるまではキーボードビューアーを画面のどこかに表示させておいて下さい。(キーボードビューアの表示方法は「Macで記号や特殊文字を入力したい時は「キーボードビューア」と「文字ビューア」を使うと便利!」を参考にして下さい。)
⌘ Cmd
⌥ Option
⇧ Shift
^ Ctrl
キー | 動作 | 備考 |
---|---|---|
[⌘]+[X] | 行の切り取り | 未選択状態の行全体を切り取り |
[⌘]+[C] | 行のコピー | 未選択状態の行全体をコピー |
[⌘]+[⇧]+[K] | カーソル行を削除 | 行全体を削除(複数行を選択中は全ての行) |
[⌘]+[↩︎] | 現在のカーソル行の下に空行を追加 | カーソルは行頭に移動する |
[⌘]+[⇧]+[↩︎] | 現在のカーソル行の上に空行を追加 | カーソルは行頭に移動する |
[⇧]+[⌥]+[Down] | カーソル行を下にコピー | 複数行を選択中はその行数分 |
[⌘]+[']'] | 行をインデント | |
[⌘]+['['] | 行をアンインデント |
キー | 動作 | 備考 |
---|---|---|
[⌥]+[Down] | カーソルをインデントレベルで下に移動する | Indentation Level Movementの機能 |
[⌥]+[Up] | カーソルをインデントレベルで上に移動する | Indentation Level Movementの機能 |
キー | 動作 | 備考 |
---|---|---|
[⇧]+[⌥]+ドラッグ | 矩形選択 |
キー | 動作 | 備考 |
---|---|---|
[⌘]+[/] | 行コメント記号をトグル | 複数行を選択中はその行数分 |
[⇧]+[⌥]+[A] | ブロックコメント記号をトグル | 選択中は選択部分 |
キー | 動作 | 備考 |
---|---|---|
[^]+[Tab] | 開いたファイルの履歴を表示 | 開いた後は^を押下したままTabで切り替えられる |
[⌘]+[K],[O] | 現在アクティブなファイルを新規ウィンドウで開く |
キー | 動作 | 備考 |
---|---|---|
[⌘]+[N] | 新規ファイル作成 | |
[⌘]+[K],[P] | 現在アクティブなファイルのパスをコピー |
キー | 動作 | 備考 |
---|---|---|
[⌘]+[P] | ファイルを検索して開く | '>'でgitなどのコマンド操作、'@'でシンボル検索が可能 |
[⌘]+[F] | 検索ポップアップ表示 | カーソル位置のワードがマッチされていればその単語を使用する |
[⌘]+[⇧]+[F] | 全ファイルにまたがってキーワード検索をする | |
[⌘]+[H] | 置換ポップアップ表示 | 同上 |
[F3] | 次を検索 | マッチワードがあればその単語で検索 |
[⇧]+[F3] | 前を検索 | 同上 |
キー | 動作 | 備考 |
---|---|---|
[⌘]+[⇧]+[N] | 新しいVS Codeを起動 | |
[⌘]+[⇧]+[P] | コマンドパレットを開く | |
[F1] | コマンドパレットを開く | こっちの方が楽かも |
[⌘]+[⇧]+[D] | デバッグ画面の表示 | |
[⌘]+[⇧]+[E] | エクスプローラー画面の表示 | |
[⌘]+[⇧]+[F] | 検索画面の表示 | |
[^]+[⇧]+[G] | Git画面の表示 | |
[⌘]+[,] | Preference画面の表示 |
キー | 動作 | 備考 |
---|---|---|
[⌘]+[W] | 現在の開いているエディタタブを閉じる | |
[⌘]+[1] | LEFTエディタにフォーカス移動 | |
[⌘]+[2 or 3] | LIGHTエディタにフォーカス移動 | なければ同じファイルで新たに右にエディタウィンドウ作成。 |
[⌘]+[B] | サイドパネルの表示切り替え |
キー | 動作 | 備考 |
---|---|---|
[⌘]+[⇧]+[Light] | 右タブに移動 | 左もLightをLeftにすれば同様 |
[^]+[G] | 指定した行番号に移動 | |
[^]+[-] | 前に表示していた箇所に戻る | |
[^]+[⇧]+[-] | 次の箇所に進む |
キー | 動作 | 備考 |
---|---|---|
[⌘]+[⇧]+[M] | 警告やエラーのリスト表示 | |
[⌘]+[⇧]+[U] | アウトプット画面の表示 |
キー | 動作 | 備考 |
---|---|---|
[F8] | 次のエラーと警告に移動 | |
[⇧]+[F8] | 前のエラーと警告に移動 |
キー | 動作 | 備考 |
---|---|---|
[⌥]+[^]+[A] | 全ての変更をstaged | 独自ショートカット |
[⌥]+[^]+[Up] | Push | 独自ショートカット |
[⌥]+[^]+[Down] | Pull | 独自ショートカット |
キー | 動作 | 備考 |
---|---|---|
[⌥]+[M],[1] | ローカルの変更を優先する | Better Mergeの機能 |
[⌥]+[M],[2] | リモートの変更を優先する | Better Mergeの機能 |
[⌥]+[M],[3] | 両方の変更を入れる | Better Mergeの機能 |
[⌥]+[M],[↩︎] | カーソルがある範囲の変更を入れる | Better Mergeの機能 |
[⌥]+[M],[Down] | 次の競合部分に移動する | Better Mergeの機能 |
キー | 動作 | 備考 |
---|---|---|
[⌘]+[クリック] | シンボルの定義を表示 | シンボルは変数名、メソッド名のこと |
[F12] | シンボルの定義を表示 | 基本はこっちの方が使い勝手が良い |
[⌘]+[T] | 全ファイルにまたがって参照検索しファイルを開く | |
[F2] | シンボルのリネーム | |
[⇧]+[F12] | シンボル参照箇所のインライン表示 | [esc]で消せる |
[⌥]+[F12] | シンボル定義箇所のインライン表示 | [esc]で消せる |
キー | 動作 | 備考 |
---|---|---|
[F9] | ブレークポイントの切り替え | |
[F5] | デバッグスタート又はコンティニュー | |
[⇧]+[F5] | ストップ | |
[F6] | ポーズ | |
[F10] | ステップオーバー | |
[F11] | ステップイン | |
[⇧]+[F11] | ステップアウト |
キー | 動作 | 備考 |
---|---|---|
* [⌥]+[⇧]+[f]* | テーブルのフォーマットを整形する | Table Formatterの機能 |
キー | 動作 | 備考 |
---|---|---|
[⌘]+[B] | 文字を太字にする | Markdown All in Oneの機能 |
[⌘]+[I] | 文字を斜体にする | Markdown All in Oneの機能 |
[⌘]+[⌥]+[@] | 選択範囲をコードとして表示する | Markdown All in Oneの機能 |
[⌘]+[⌥]+['['] | ヘッダーを一つ上の設定に切り替える | Markdown All in Oneの機能 |
[⌘]+[⌥]+[']'] | ヘッダーを一つ下の設定に切り替える | Markdown All in Oneの機能 |
キー | 動作 | 備考 |
---|---|---|
[i] | 挿入モード | カーソル位置から |
[a] | 挿入モード | カーソルの後から |
[:] | コマンドラインモード | |
[v] | ビジュアルモード | |
[esc] | ノーマルモード |
キー | 動作 | 備考 |
---|---|---|
[:]+[e] | 開いてるファイルで右にエディタウィンドウ作成 | |
[:]+[q] | 開いているファイルを閉じる | エディタウィンドウが複数なら右から順番に |
キー | 動作 | 備考 |
---|---|---|
[dd] | カーソルがある行を切り取り | [dd]の前に数値を入れて切り取る行数の指定が可能 |
[yy] | カーソルがある行のコピー | [yy]の前に数値を入れてコピーする行数の指定が可能 |
[P] | カーソルがある行にペースト | |
[p] | カーソルの下の行にペースト | |
[u] | Undo | |
[^]+[r] | Redo | |
[U] | 行に対して行った変更の全てを取り消す | |
[v] | 選択開始 | |
[V] | 行選択 | |
[^]+[v] | 矩形選択 | |
[gv] | 直前の選択範囲を再選択 |
キー | 動作 | 備考 |
---|---|---|
[/]+[文字列] | 前方検索 | |
[?]+[文字列] | 後方検索 | |
[#] | カーソル位置の単語を前方検索 | |
[*] | カーソル位置の単語を後方検索 | |
[n] | 次の候補 | |
[N] | 前の候補 | |
[gd] | カーソル位置のローカル宣言を検索 | |
[gD] | カーソル位置のグローバル宣言を検索 | |
[:]+[%s/from/to/g] | ページ全体で置換 | fromが検索語句,toが置換語句 |
[:]+[32,50s/from/to/g] | 32〜50行目まで置換 | gは繰り返し、cなら一回毎に確認 |
キー | 動作 | 備考 |
---|---|---|
[x] | 1文字削除 | Deleteキーと同じ |
[X] | 1文字削除 | BSキーと同じ |
[D] | カーソル位置から行末まで削除 | |
[s] | 1文字削除して挿入モードへ切り替え | |
[S] | 現在の行を削除して挿入モードへ切り替え | |
[r] | カーソル位置の一文字だけ置換 | |
[R] | 置換モードに切り替え | |
[J] | 現在の行と下の行をスペースありで連結 | |
[gJ] | 現在の行と下の行をスペースなしで連結 | |
[~] | 大文字/小文字に変換 | |
[^]+[a] | カーソル位置の数字をインクリメント | |
[^]+[x] | カーソル位置の数字をデクリメント | |
[^]+[p] | (挿入モード時)単語を後方向に検索し、補完する | |
[^]+[n] | (挿入モード時)単語を前方向に検索し、補完する |
キー | 動作 | 備考 |
---|---|---|
[==] | 現在行のインデント | |
[=]+[数値] | 指定範囲のインデント | |
[=]+[G] | 現在の行から最終行までインデントする | |
[>] | 現在の行をインデント | |
[<] | 現在の行を逆インデント |
キー | 動作 | 備考 |
---|---|---|
[:]+[sp]or[vsp] | エディタウィンドウ作成 | |
[:]+[q] | エディタウィンドウを閉じる | |
[:]+[qall] | 全てのエディタウィンドウを閉じる | |
[^]+[ww] | エディタウィンドウを右に移動 | |
[^]+[hjkl] | VS code内のウィンドウを移動 |
キー | 動作 | 備考 |
---|---|---|
[gg] | 最初の行へ | |
[G] | 最後の行へ | |
[数値]+[G] | 指定した行へ | |
[0] | 行の最初へ | インデント無視 |
[^(Ctrlではない)] | 現在の行の最初へ | テキストの最初 |
[$] | 行の末尾へ | |
[-] | 前の行の最初へ | |
[+] | 次の行の最初へ | |
[%] | カーソル位置にある括弧に対応する括弧へ | |
[H] | エディタの上端へ移動 | Hの前に数値で上から数えた行へ |
[M] | エディタの中央行へ移動 | |
[L] | エディタの下端へ移動 | Lの前に数値で上から数えた行へ |
[gm] | エディタ中央へ移動 | 行中の横移動 |
[^]+[o] | 前回のジャンプ位置へ戻る | |
[^]+[i] | 次回のジャンプ位置へ戻る | |
[z]+[↩︎] | 現在の行の最初へ | テキストの最初 |
[w] | 次の単語に移動 | |
[b] | 前の単語に移動 | |
[e] | 単語の末尾に移動 | |
[W] | 次の単語に移動 | 記号は無視 |
[B] | 前の単語に移動 | 記号は無視 |
[E] | 単語の末尾に移動 | 記号は無視 |
[f]+[一文字] | カーソルを指定した文字まで移動 | 3fiで3つ目のiまで移動 |
[t]+[一文字] | カーソルを指定した文字の左端まで移動 | 3tiで3つ目のiの左側まで移動 |
キー | 動作 | 備考 |
---|---|---|
[^]+[b] | 1画面上に移動 | |
[^]+[u] | 半画面上に移動 | |
[^]+[y] | 1行上に移動 | |
[^]+[f] | 1画面下に移動 | |
[^]+[d] | 半画面下に移動 | |
[^]+[e] | 1行下に移動 | |
[z]+[l] | n文字ずつ右に移動 | コードの折り返し設定してたらいらなそう |
[z]+[L] | 半画面右に移動 | コードの折り返し設定してたらいらなそう |
[z]+[h] | n文字ずつ左に移動 | コードの折り返し設定してたらいらなそう |
[z]+[H] | 半画面左に移動 | コードの折り返し設定してたらいらなそう |
vimキーバインドを利用するアプリケーションでは、エディットモード中に日本語入力を行った場合、
Escしても日本語入力モードのままの状態になりすぐにコマンドモードが利用できない。
その都度英数入力に切り替える必要のないように、特定アプリケーションのみEscを押下した際に、日本語入力がOFFになるように設定を行う。
設定にはキーバインドをカスタマイズするアプリKarabinerを利用する。
Escキーが押下されると、日本語入力をOFFにしつつ(英数キーを押下した挙動)、エディットモードから抜ける(Escキーを単体で押下した挙動)為の動作を定義する。
Karabinerには様々な挙動がデフォルトで用意されているが、独自の定義を行うためには個別にxmlで定義を行う必要がある。
この個別の設定はprivate.xmlファイルとして行う。private.xmlは以下で指定して読み込む。
Preference > Misc&Uninstall > Open private.xml
例としてターミナルアプリ(Mac標準TerminalやiTermなど)MarkdownエディタのBoostnoteを対象として設定する。
<?xml version="1.0"?>
<root>
<appdef>
<appname>BOOSTNOTE</appname>
<equal>com.maisin.boost</equal>
</appdef>
<item>
<name>Escape to EISUU+Escape only terminal</name>
<identifier>private.remap.jis_escape2eisuuAndEscape_terminal</identifier>
<only>TERMINAL, BOOSTNOTE</only>
<autogen>
--KeyOverlaidModifier--
KeyCode::ESCAPE,
KeyCode::JIS_EISUU,
KeyCode::ESCAPE
</autogen>
</item>
</root>
設定のポイントは以下の3つ
アプリケーション名は <appdef>
タグで定義する。<appname>
タグにアプリケーション名、 <equal>
タグにアプリののBundle Identifierを指定する。
複数のBundle Identifireを指定する場合は <equal>
タグを複数追記する。
Bundle Identifierの確認方法は以下を参照する。
http://harafuji0613.hatenablog.com/entry/2015/03/22/002953
該当のアプリケーションに対応するものがあれば、プリセットのアプリケーション名を利用できる。
プリセットのアプリケーション名は以下を参照。
https://github.com/tekezo/Karabiner/blob/version_10.22.0/src/core/server/Resources/appdef.xml
設定例においてターミナルアプリ(TERMINAL)をアプリケーション名として定義(<appdef>
タグ内の設定)してないのはプリセットにリソース名が登録済みであるため。
参考までにTERMINALのプリセット定義は以下の通り。
<appdef>
<appname>TERMINAL</appname>
<equal>com.apple.Terminal</equal>
<equal>iTerm</equal>
<equal>net.sourceforge.iTerm</equal>
<equal>com.googlecode.iterm2</equal>
<equal>co.zeit.hyperterm</equal>
<equal>co.zeit.hyper</equal>
</appdef>
<only>
タグに適用したいアプリケーション名を指定する。
ここで述べるアプリケーション名は単一のアプリケーションではなく、カテゴライズした複数のアプリの総称として利用する。
<autogen>
タグの中にあるKeyCodeは上から、
を定義する。
<name>
タグで設定に名前をつける。Preference上ではこの名前で設定を確認できる。<identifier>
タグで設定に固有のIDをつける。システム内でユニークになるような命名規則を自分で考える。
https://pqrs.org/osx/karabiner/xml.html.ja#prepared-appdef
https://pqrs.org/osx/karabiner/xml.html.ja#syntax-__KeyOverlaidModifier__
githubのtpmからリポジトリをcloneして設置する。
% git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
~/.tmux.confというdotfileを作って下記の手順通りに使いたいpluginを記述する。
# List of pluginsset -g @plugin 'tmux-plugins/tpm'set -g @plugin 'tmux-plugins/tmux-sensible'# Other examples:# set -g @plugin 'github_username/plugin_name'# set -g @plugin 'git@github.com/user/plugin'# set -g @plugin 'git@bitbucket.com/user/plugin'# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run '~/.tmux/plugins/tpm/tpm'
大事なのは一番下のところで、
tpmの起動書式は~/.tmux.confの一番下に書く必要がある。
そうではないとせっかく設置したプラグインが使えない。
のちほど説明する。
% tmux source-file ~/.tmux.conf
キー入力 | 説明 |
---|---|
prefix + I | 新しいpluginを設置する |
prefix + U | pluginをアップデートする |
prefix + alt + u | pluginのリストにないものをアンインストールする |
設置方法にも言及しているが、tpmを起動(run)する部分が一番下に書かれてないと設置したpluginを正常に使えない。
最初検索で引っかかった誰かさんの.tmux.confファイルを参考にしたが、これがハマる落とし穴になってしまった。
そのときに参考にしたサイトがここだが.tmux.confの一番下にステータスバーの設定を読み込んでる。
tmuxのステータスバーにバッテリーやCPU使用率などの情報を表示したくて、tpmを利用して関連pluginを設置したが、正常に表示されなかった。
tmux source-file .tmux.confで設定ファイルをリロードするときにちょっとだけ正常に表示され、すぐ消えてしまう。
いろいろ設定ファイルを弄ってみたけどダメだったので、pluginではないコマンドで実行して表示する方法に変更した。
(pluginもスクリプト形式で書かれているからコマンドと同様だろうな。)
これらも結構気に入ったので、諦めていたが、どうにも気になり、もう一度調べた。
そこで見つけたのが設定ファイルの一番下にtpmをrunする部分を記入しないといけないと言う内容だった。
ネットで探した内容は参考にするだけで、githubや本家のサイトのreadmeとかをちゃんと読んだ方がいい。
英語が苦ってだからといて避けてしまうと痛い目に会う。
書き方がとても面倒だし、せっかくマニュアルを参考にして書いてもあまり格好良くない。
vimのpowerlineやairline、lightlineのようなステータスバーを見たことがあったので、ググったらtmuxline.vimという宝物を見つけた。
tmuxline.vimはtmuxのステータスバーを作るためのgeneratorである。
tmuxline.vimを使えば、tmuxのマニューアルを見ながら書き方を学ばなくてもいい。
tmuxline.vimを設置する。
ここではvim plugin managerとしてvim-plugを使っている。
作りたいステータスバーのpresetとthemeを指定する。
下記の設定はtmuxline.vimのreadmeから持ってきたものだ。
vim~/.vimrc
Plug 'edkolev/tmuxline.vim'letg:tmuxline_preset = {
\'a' : '#S',
\'c' : ['#(whoami)','#(uptime | cud -d " " -f 1,2,3)'],
\'win' : ['#I','#W'],
\'cwin' : ['#I','#W','#F'],
\'x' : '#(date)',
\'y' : ['%R','%a','%Y'],
\'z' : '#H'}
letg:tmuxline_theme ='papercolor'
tmuxのステータスバーは左側と右側に別れて設定を行う。
presetの'a', 'b', 'c'が左側の設定で、'x', 'y', 'z'が右側の設定である。
'win', 'cwin'はウィンドウ名を表示する設定だ。
vimのコマンドモードでTmuxlineSnapshot 「ファイル名」を実行してみよう。
ここでのファイル名はtmuxline.confにする。
:TmuxlineSnapshot tmuxline.conf
tmuxline.confというtmuxステータスバーを表示するための設定ファイルが作られる。
.tmux.confファイルからtmuxline.confファイルを読み込む設定を追加する。
tmuxline.vimで生成された設定ファイルは、.tmuxというディレクトリを生成してその配下で管理することを推奨する。
tpmを使っている場合はすでに生成されている。
# tmuxline.vim
source-file~/.tmux/tmuxline.conf
リロードする前にtmuxline.vimから生成されたtmuxline.confの下記の行を修正する。
- set -g status-utf8 "on"+ set -gq status-utf8 "on"
.tmux.confファイルリロードすれば、新しいステータスバーが表示される。
tmux source-file .tmux.conf
リロードするたびにコマンドを実行するのは面倒な作業なので、バインディングを追加する。
「prefix + r」を押すことで設定ファイルをリロードする。
bind r source-file ~/.tmux.conf\; display "Reloaded!"
おまけに設定も入れて置いたので、必要な方は参考にしていただければと思う。
" tmuxlineletg:tmuxline_preset = {
\'a' : '#S',
\'c' : ['#(whoami)'],
\'win' : ['#I','#W'],
\'cwin' : ['#I','#W','#F'],
\'x' : ['#{battery_percentage} #{battery_icon}','#{cpu_percentage} #{cpu_icon}'],
\'y' : ['%a','%R','#(ansiweather -l tokyo -w false -h false -p false -a false | cut -d " " -f7,8,9)'],
\'z' : '#H',
\'options' : {'status-justify':'left'}}
letg:tmuxline_theme ='papercolor'
右側にバッテリーとCPUの使用率、天気情報を表示しているのが見えるだろうか。
バッテリーやCPUはtmuxのpluginを設置して表示しているもので、天気情報はansiweatherというコマンドで表示している。
tmuxのpluginを設置するためにはtpmというplugin managerが必要だ。
tpmの使い方については別途の記事を作成したので、ご参考にしていただければと思う。
ちなみに僕はvim-airlineを使っていてthemeもvim-airlineのものを共有して使っている。
vim-airlineのthemeの中で好みのthemeを探してみよう。
こちらで確認ができる。
powerlineからairline、そしてlightlineへ切り替えたと思うがその経緯については全く覚えてない。
vim設定の見直しを検討していてなるべく設定の記述が少ない方がいいと思いairlineに変更した。
注意:vimだけを使うことであればこの設定でも問題がないが、tmuxと一緒に使う場合はやめた方がいい。powerline系のステータスバーが崩れてしまう。
powerlineのフォントが設置されてない場合は正常に表示されない。
rictyについてはこちらを参考にしていただければと思う。
結果としては下記のように設定すれば丁度見栄えがいい感じになった。
" ○や□の文字が崩れる問題を回避setambiwidth=double
... snip ...
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
... snip ...
" Powerline系フォントを利用するsetlaststatus=2letg:airline_powerline_fonts =1letg:airline#extensions#tabline#enabled =1letg:airline#extensions#tabline#buffer_idx_mode =1letg:airline#extensions#whitespace#mixed_indent_algo =1letg:airline_theme ='papercolor'if!exists('g:airline_symbols')letg:airline_symbols = {}
endif" unicode symbolsletg:airline_left_sep ='»'letg:airline_left_sep ='▶'letg:airline_right_sep ='«'letg:airline_right_sep ='◀'letg:airline_symbols.crypt ='🔒'letg:airline_symbols.linenr ='␊'letg:airline_symbols.linenr =''letg:airline_symbols.linenr ='¶'letg:airline_symbols.maxlinenr ='☰'letg:airline_symbols.maxlinenr =''letg:airline_symbols.branch ='⎇'letg:airline_symbols.paste='ρ'letg:airline_symbols.paste='Þ'letg:airline_symbols.paste='∥'letg:airline_symbols.spell='Ꞩ'letg:airline_symbols.notexists ='∄'letg:airline_symbols.whitespace ='Ξ'" powerline symbolsletg:airline_left_sep =''letg:airline_left_alt_sep =''letg:airline_right_sep =''letg:airline_right_alt_sep =''letg:airline_symbols.branch =''letg:airline_symbols.readonly=''letg:airline_symbols.linenr =''" old vim-powerline symbols" let g:airline_left_sep = '⮀'" let g:airline_left_alt_sep = '⮁'letg:airline_right_sep ='⮂'letg:airline_right_alt_sep ='⮃'" let g:airline_symbols.branch = '⭠'" let g:airline_symbols.readonly = '⭤'" let g:airline_symbols.linenr = '⭡'
tmuxline.vimはtmuxのステータスバーを作るためのgeneratorだ。
ここが問題だが、iterm2のambiguous-widthやvimrcのambiwidth=doubleがある場合、tmuxのステータスバーが崩れてしまう。
一部の絵文字を正常に表示させる対価としては失ってしまうのが大きい。
そもそも使うのも推奨されていなかったし、powerlineを使っている場合は画面崩れの障害ポイントになる可能性が高い。
twitvim/twitvim: Twitter client for Vimでプロキシを設定するときは .vimrc
に以下のように書いたりします。
let s:twitvim_proxy ="proxyserver:proxyport"let s:twitvim_proxy_login ="proxyuser:proxypassword"
詳しくは以下を参照
:help twitvim_proxy
:help twitvim_proxy_login
それを環境変数 HTTP_PROXY
の値から自動設定するようにしてみました。
if exists('$HTTP_PROXY')let s:proxy_url_pattern =
\ '^\%(\([^:]*\):\/\/\)\='
\ . '\%(\([^:@]*\)\(:[^@]*\)\=@\)\='
\ . '\([^:]*\)\%(:\(\d*\)\)\=/\=$'letg:twitvim_proxy = substitute($HTTP_PROXY,
\ s:proxy_url_pattern,'\4:\5','')let s:proxy_login = substitute($HTTP_PROXY,
\ s:proxy_url_pattern,'\2','')let s:proxy_pass = substitute($HTTP_PROXY,
\ s:proxy_url_pattern,'\3','')letg:twitvim_proxy_login = s:proxy_login . s:proxy_pass
endif
Vim patchダイジェスト [2017/06] (仮)
(8.0.0607~ 8.0.0642)
&sw
の代わりにshiftwidth()
を使用するようにしました。QuickFixLine
を追加しました。getqflist()
とsetqflist()
の引数nr
に$
(最後のquickfix list)を指定出来るようにしました。:global
を再帰的に使用できるようにしました。例えば、:g/found/v/notfound/{cmd}
で「found
を含みかつnotfound
を含まない行に{cmd}
を実行」出来るようになりました。:stag
のバッファを切り替えるときの動作を'switchbuf'
の値によって変えるようにしました。Vim
、コマンド名はvim
とgvim
に統一しました。feedkeys()
を使用すると、イベント待ち状態のままになる件を修正しました。[0-z]
を正しく扱えない件を修正しました。:setfiletype
にFALLBACK
引数を追加しました。(confファイルタイプの検出が、パッケージ機能のftdetectスクリプトの前に行われてしまう件を修正しました)runtimepath
への追加タイミングが遅い(非パ
ッケージプラグインのロード後になっている)件を修正しました。CTRL-C
押下時にコマンドラインに表示されるVimの終了方法をより分かり易い文言に修正しました。表記 | 意味 |
---|---|
![]() | 新機能 |
'hoge' | オプション (:h options 参照) |
:hoge | Exコマンド (:h :index 参照) |
hoge() | 組み込み関数 (:h functions 参照) |
v:hoge | Vim定義済変数 (:h v: 参照) |
こちらを参照。
暑くなって来ましたね。
今度はたまに使うけど緊要なvim機能(pluinから提供している機能を含めて)について整理する。
物覚えが悪い自分のための記事だ。
そんなわけでどんどん更新する。
キー | 説明 |
---|---|
ctrl + u | 半画面分上へ |
ctrl + d | 半画面分下へ |
ctrl + b | 一画面分上へ |
ctrl + f | 一画面分下へ |
vimの設定ファイル(.vimrc)にてmappingをするときfiletype別に設定する場合がある。
該当ファイルのタイプを誤ってしまうと正常に動作しない。
ファイルのタイプを確認したい場合はこうする。
:setfiletype?
" erbの場合、出力結果filetype=eruby
デザインさんが作業したhtmlファイルを開くとたまに長い行があってその時vimがめちゃ重くなる症状があった。
それを防ぐための設定で、値は200~300程度で設定する。
:setsynmaxcol=200
:setwrap
:setnowrap
:setpaste
:setnopaste
nopasteになっている場合でもvisualモードでペーストした部分を選んで、「=」を入力すればindentなしで貼ってくれる。
sudo権限が必要なファイルをsudoなしで開いて修正した場合、セーブができない。
そのとき、有用なpluginがsudo.vimというpluginだ。
Plug 'sudo.vim'
:w sudo:%
Password: <パスワードを入力>
Plug 'junegunn/vim-easy-align'
... snip ...
vmap <CR><Plug>(EasyAlign)
以下のキーはvisualモードで範囲を指定して<Enter>キーを押した後に入力する。
キー | 説明 |
---|---|
= | 最初の=に合わせて整列 |
3= | 三つ目の=に合わせて整列 |
*= | すべての=に合わせて整列 |
**= | =を基準として左・右で整列 |
=は例として上げただけであって、他の演算子でも使える。
主にmarkdownのテーブルを整形するときに使う。
Vimのコマンドをまとめた記事はよく見かけますが、丸暗記しようとすると余計大変です。
3行コピーペーストするのは、3yyp
で、"
の中を消すのはdi"
で、ファイル全選択はggVG
・・・って複雑化してくると困ります。
丸暗記する前に、基本的な考え方を覚えて、効率よくコマンドを覚えましょう。
コマンドを丸暗記する前に、2つの考え方を意識すると、コマンドを覚えやすくなり、応用も効くと思います。(個人の感想です)
Vimのコマンドはざっくり以下のような形になっています。
(回数) + (命令) + (回数) + (範囲)
例えば、文字を削除するコマンドはd
を使います。これをオペレータといいます。上の(命令)部分です。
次の単語の先頭に移動するコマンドはw
です。これを範囲として使ってみましょう。
コマンドは、dw
となりますね。
現在の地点から、次の単語の先頭まで文字が削除されました。
文字を選択し、ビジュアルモードに入るコマンドはv
です。
次の単語の先頭に移動するのはw
でした。
ではvw
というコマンドの結果は…?
こんな感じで、セットで覚えるというよりもあくまで組み合わせなんだよっていうのを最初に意識してほしいです。
コマンドや範囲の前には数字を付けることができます。
数字分だけの後ろの行動を繰り返すイメージです。
w
は1単語移動するコマンドでした。3w
とすると、3単語移動できます。
では、3つ後ろの単語までを削除するコマンドは?d3w
です。
さらにそれを5回繰り返したければ、5d3w
となります。
こんな感じで、数字は様々なコマンドに応用できるんだよってことです。
あるキーで出来ることを大文字にすると、同じ動作の範囲が異なるコマンドになることが多いです。
なので、両方を覚えるというよりは、まずは小文字のコマンドを覚え、徐々に大文字と使い分けるといいと思います。
以下は、小文字コマンドを大文字にした時のパターン例です。
d
というコマンドは、削除を行うt前のコマンドですが、D
とすると、1行削除になります。
同様のものに、I
,A
,V
,C
などがあります。
「末尾までになる」と解釈するならば、G
も含まれるかもしれません。
w
は次の単語の先頭まで移動します。ハイフンやカンマなども単語の区切りとみなします。W
となると、単語の定義が代わり、空白が来るまでは1単語となります。B
やE
が同様です。
検索後にn
を押すと、次の候補を検索することができます。N
とすると、逆方向です。
同様に、F
,X
,O
,P
などは、前後が逆になっていると感じます。
上記3パターンに当てはまりませんが、R
も同じ動作の亜種のようなコマンドだと思います。
もちろん、すべての大文字に当てはまるわけではなく、大文字が小文字の動作と無関係に独立しているものもあります。J
や、H
,M
,L
などが該当します。
個別に覚えましょう。
二つの異なるコマンドをくっつけて覚えるより、別々で覚えたほうが応用効くと思う!
「Vimを覚えたい、でもコマンド多すぎて一気に覚えられないし、手が出せない」みたいな人がいるような気がします。
そこで、独断と偏見で3段階くらいに分けてみました。
もちろん、これで全部ではないので、いろいろ調べてみてください。
あと、覚える前に少しこっちも意識してほしいです。
Vimを丸暗記する前に
ちょっと便利なテキストエディタとして、簡単なファイル編集や、サーバー上の設定変更などをスムーズにできる程度
作業効率はおいておいて、カーソルキーを使わずに、最低限編集できる程度を目指します。
基本移動と基本的なモードに慣れましょう。
カーソルキーは使わないことを目標にしましょう。
基本となる移動です。そのうち慣れます。
指定の行まで移動するコマンドです。
ggは先頭行、Gは最終行に移動します。
ちなみに、サーバー上などでvi実行し、行番号が表示されていなかったら、:set number
(nuまででも可)で出せます。
ページ単位の移動です。
検索しようとしてCTRL + f
を押して、画面が進んでも驚かないように。f
はforward
で進む、b
はback
で戻る、です。
大まかにファイルを移動するときは大体これで移動してます。
インサートモードに慣れましょう。
なるべく、インサートモード中の移動や削除は行わないことを心がけ、ノーマルモードで移動しましょう。
現在のカーソル位置の手前でインサートモードに切り替えます。
ノーマルモードに戻ります。
よくわからなくなったら、押してノーマルに戻りましょう。
文字を選択できるモードです。
選択後いろいろなコマンドと組み合わせられますが、最初は、コピー・削除と組み合わせるところからでいいと思います。
vキーを押してから、移動をすると選択できるのがわかると思います。
もう一度押すと選択解除されます。
1行丸ごと選択します。
そのままj
などで複数行選択です。
文字の削除はノーマルモードから、コマンドで行う癖をつけましょう。
削除というより、切り取りといった方が正しいかもしれません。
カーソル下の文字を1文字消します。
他のエディタのDelete
に近い動きです。
1文字以上消したいときは、v
で複数の文字を選択してから、d
で消してみましょう。
後述のp
で貼り付けられます。
1行丸ごと削除です。
もちろん貼り付けられます。
削除と同様ノーマルモードから、コマンドで出来ます。
v
で選択後、y
でコピーできます。後述のp
で貼り付けられます。
1行丸ごとコピーです。
もちろん貼り付けられます。
直前のx
,d
,y
を実行した結果を貼り付けることができます。
※「レジスタ」と組み合わせると、直前の結果だけでなく貼り付けたり保存しておけるので、興味のある方は調べてください。
x
やd
などで削除したものを貼り付けます。
貼り付ける位置は、カーソルの後ろです。
やり直し所謂(CTRL + z
)や再実行(CTRL + SHIFT + z
?)に当たる操作を覚えておくと、おぼつかない操作で間違えても安心です。
やり直しです。
インサートモードで1行入力してからu
を押すと、1行入力一気に戻れるのが普通と違うかもしれません。
やり直した結果を再実行します。
CTRL + f
は使えません。/
で検索します。
正規表現は覚えたほうがいいでしょう。
※正規表現のエスケープが少し独特なので、戸惑う場合はvery magicでググってください
/
で後方に検索
ちなみに/
の後、カーソル上下(CTRL + n
,CTRL + p
)を押すと、過去に検索した履歴を呼び出せます。
(bashで↑押したときのような感じ)
検索後、次の候補に行くにはn
,前の候補に行くにはN
です。
:
の後に様々なコマンドを実行できます。
最初は保存だけかもしれませんが、便利なものもあるので探してみるといいと思います。
:
のあとにw
で保存ができます。
:
のあとにq
でファイルを閉じます。w
と合わせて、:wq
で保存して終了です。ZZ
も:wq
と同様です。
最初は操作がおぼつかないので、間違えて編集してしまうこともあるでしょう。
慌てずに保存せずに閉じる、がq!
です。
組み合わせの移動や、複数のインサートモードへの切り替えを覚えて、もう少し効率的に編集できる状態を目指します。
レベル1で覚えたコマンドの派生形も覚えましょう。
単語やテキストオブジェクトの概念は最初はなじみがないかもしれませんが、覚えると移動や編集が楽になります。
それらに限った話ではありませんが、d
やy
などと組み合わせることもできます。
f
のあとに文字を入力すると、行内のその文字(1文字)の場所まで移動します。F
は行内の前方方向に検索します。Hello World
という一文で、f
W
とかd
f
W
などをやってみると動きがわかると思います。
f
と同様に後に入力した文字を基準に移動します。f
との違いは、t
はその手前の文字まで移動します。T
は前方検索です。Hello World
という一文で、t
W
とかd
t
W
などをやってみるとf
との違いがわかるでしょうか。
f
,t
,F
,T
で検索した後、再度同じ検索を繰り返したいとき、;
,,
で、それぞれ後方、前方に繰り返します。
単語を基準に移動します。w
を押すと、次の単語の先頭に移動します。b
は前方の単語の先頭、e
は現在の単語の末尾です。abc def ghi
などの文章で、様々な位置で押してみたり、d
と組み合わせると動きがわかると思います。
行頭や行末に移動します。0は
行頭、^
は空白を含まない行頭です。$
は行末です。
i
と同様にインサートモードに入るコマンドですが、移動してからインサートモードに入るコマンドを覚えるとタイプ数が少なくなります。
最初は無くても十分に思えるかもしれませんが、慣れると違いが実感できると思います。
i
だけでは、現在のカーソル位置の手前からしか編集を開始できません。a
でカーソルの後ろから編集を開始できます。l
i
(もしくは、i
→
とか)と入力しているところがa
でできるようになります。I
を使うと、現在の行の頭にカーソルが移動したうえで、編集を開始します。^
i
と同じ動きです。A
を使うと、現在の行の末尾に移動したうえで、編集を開始します。$
a
と同じ動きです。
よりスムーズに削除しましょう。
上でも述べましたが、d
w
とか、d
t
=
とか、d0
とか、移動コマンドと合わせると、v
で指定しなくても一気に消せます。/
なんかも使えます。
つまり、移動をいろいろ覚えれば削除が自在になり、結果編集速度があがります。
もちろん、削除した内容はp
でペーストできます。
現在位置から、末尾までを削除します。d
$
と同様です。
d
と同様にコピーも移動と組み合わせで可能です。
例えば、y$
で行末までコピーです。
p
と異なりカーソル位置の手前にペーストです。
/
は後方検索でしたが、?
で前方に検索します。
当然、n
, N
も/
とは逆向きに検索が進みます。
その他、個人的に使いそうなコマンドを列挙します。
普通のエディタよりVim使うほうが編集早いじゃん!ってなったらいいなぁ。
レベル3だからあまり使わないということはなく、むしろよく使うけど、他の操作で代替効くから泣く泣く3に書いたものもあります。
この内容のほかに今までのコマンドの前に、数字を付けて、回数を指定することも試してみてください。
(例えば、100p
で100行ペーストとか。)
直前に編集していた部分に移動します。
コードを編集中、上の方を見に行って、もとの編集してたところに戻りたいときとか重宝します。
対のかっこへ移動します。
インデントが崩れた長いメソッドとか、長いjsonとかに出くわして、対応した閉じかっこの場所がわからなくなっても安心です。
段落の先頭、末尾まで移動します。
段落は、改行のみの行が区切りです。
長い1行が折り返されているとき、j
では次の行に行ってしまいます。
見た目上の上下や先頭に移動するには、g
と組み合わせます。
半画面上下に移動します。CTRL + f
よりもう少し細かく移動したいときに。
画面の上部、中央、下部に移動します。
マーカーという機能です。
例えば、m
a
で、現在の位置をa
というところに保存します。
`a と押すと、そこへジャンプします。
d
とi
が組み合わさったようなコマンドです。c
で削除しながら、インサートモードに入ります。
削除してから入力するよりもタイプ数も少なくなるし、アンドゥや繰り返しもその単位で出来るので、慣れてきたらよく使います。w
とかテキストオブジェクトなどと組み合わせることが多い気がします。
1文字だけ修正したいときは、r
の後に文字を入力すると、カーソル下の文字をノーマルモードのままでその文字で置換します。
前後に行を追加してインサートモードに入ります。
同様のコマンドを再現するのであれば、$
a
Enter
や、0
i
Enter
ようになるので、面倒です。
自然と使うようになると思います。
現在の行と、次の行を半角スペース区切りで連結します。
私が最初に vimすげーって思った操作の一つだった気がします。
現在いる部分を囲んでいるものを範囲に取ることができます。
例えば、(aaa bb|b ccc)
(|
はカーソル)の位置にいるときに、()
の中だけをすべて削除したりできます。
オペレータとは、d
とかc
とかy
のような、入力後に範囲を待ち受けるコマンドです。i
をその後に入力すると、指定した記号の内部を選択することができます。(aaa bb|b ccc)
のとき、、v
i
)
などと入力するとイメージできるかと。
i
の代わりにa
だと、囲んでいる記号を含めた状態で選択します。"aaa bb|b ccc"
で、d
a
"
とかでイメージできるでしょうか。
例えば、q
a
で、a
というマクロの記録を開始します。
好きなだけ操作を行ったあと、q
を押すと停止します。
その後、任意のタイミングで@a
と実行すると、a
が実行されます。
100回繰り返したければ、100@a
です。
.
で直前の動作を繰り返します。
例えば、直前に30文字入力してインサートモードを抜けた場合、同じ30文字を入力します。
移動は「直前の動作」に含まれないため、お好きなところに移動して実行してください。
削除やペーストも同様に繰り返します。
数字での繰り返しも対応してます。
矩形選択モードです。
矩形選択を利用したテクニックとしては、矩形選択で複数行を選択した状態で、I
を押して何か入力し、ノーマルモードに戻ると、選択した複数行の矩形の先頭に同じ入力を行うことができます。
矩形の後方に入力したい場合には、A
です。
置換コマンドはよく使うので覚えておきましょう。
今回は割愛しますが、ファイルを開いたり、画面を分割したり、コマンドを実行したりいろいろとできることは多いので、ぜひ調べてください。
とりあえず、一番使うであろう、ファイル内全文の全文字を置換するコマンドです。
詳しい説明はググったりヘルプを見ていただきたいですが、少しだけ解説します。
s
の前には置換対象範囲が入力できます。
上のコマンドの%
は現在のファイル全文を指しています。%
なしだと、現在行についての置換になります。
他にも、1,10s
であれば1行目から10行目を選択できますし、ビジュアルモードで選択している状態で:
を押すと、:'<,'>
という状態になりますが、そのあとにs
と続けると、選択している範囲に対してのみ置換実行できます。
g
は、同じ行に複数の置換対象文字がある場合に、すべてを置換するオプションです。g
なしだと、最初にマッチした文字のみ置換されます。
他にも、置換するかどうか確認を求めるc
とか、置換は行わずに件数を教えてくれるn
とかあります。
/
などで検索中であれば、正規表現部分を空白にすることで、現在検索中の正規表現を対象にすることができます。/
と置換コマンドの/
が競合するため、URLをエスケープしなくてはなりません。実は、置換の/
は;
とか@
とか適当な記号でも代用できるので、:%s;http://before;https://after;g
とか出来たりします。結局詰め込みすぎたし、でもやっぱり詰め込みきれてないし、レベル順も適正かどうかわからないしって感じですが、頑張ってください。
記事書いてみましたが、チートシートの方が見やすいと思います。
タイトルにも書きましたがVim初心者です。覚え書きです。
サーバ上でファイルを編集するときはVimを使用していたものの、全く使いこなせていませんでした。
ですが、さくらのVPSでUbuntu16.04を建てたにて開発をサーバ上で行うようになってから普段使っているSublime Text3が使えない...
(もちろんSFTPプラグインはありますが...)
結局自分のPCで開発してるじゃないか...俺が求めていたのはこうじゃない!(たぶん)
というわけで、とりあえずVimでの操作方法を覚える初手として、個人的に覚えやすいなと感じたカーソル移動コマンドをまとめてみました。
h
: キー一つのみで動作するコマンドc-f
: ctrlキーと同時押しで動作するコマンド{num}G
: 数{num}を入力して動作するコマンドf{char}
: コマンドの後に一文字入力して動作するコマンド/{pattern}
: コマンドの後に{pattern}を入力して動作するコマンド
{pattern}についておそらくVimを初めて触った際に 厨二心をくすぐられる覚えるコマンドだと思います。
キーが横一列に並んでいるので押しやすく、矢印キーを押すためにホームポジションを崩さなくて済みます。
- h
: 左に移動
- j
: 下に移動
- k
: 上に移動
- l
: 右に移動
h, l
よりもよく使う気がする。
w
: 単語分先へ移動b
: 単語分前へ移動e
: 単語の末尾へ移動W
: 空白区切りの単語分先へ移動B
: 空白区切りの単語分前へ移動E
: 空白区切りの単語の末尾へ移動0
: 行頭へ移動^
: 空白以外の行頭へ移動(インデントとか)$
: 行末へ移動)
: 文分上に移動(
: 文分下に移動}
: 段落分上に移動{
: 段落分下に移動[(
: ])
: a{num}G
: {num}行目に移動:{num}
: {num}行目に移動gg
: 1行目に移動G
: 最後の行に移動c-b
: 画面分上に移動c-f
: 画面分下に移動c-u
: 画面の半分上に移動c-d
: 画面の半分下に移動H
: 画面内の最初の行に移動M
: 画面の中央の行に移動L
: 画面内の最後の行に移動厳密にはカーソル移動ではない...かも。
f{char}
: 右方向にある{char}に移動F{char}
: 左方向にある{char}に移動;
: 直前の同一行内検索を繰り返す,
: 直前の同一行内検索を逆方向に繰り返す%
: 対応する括弧類に移動*
: カーソル位置の単語を下方向に検索#
: カーソル位置の単語を上方向に検索g*
: カーソル位置の単語(部分一致)を下方向に検索g#
: カーソル位置の単語(部分一致)を上方向に検索/{pattern}
: {pattern}を含む個所を下方向に検索
{pattern}について?{pattern}
: {pattern}を含む個所を上方向に検索n
: 直前のファイル内検索を繰り返すN
: 直前のファイル内検索を逆方向に繰り返す次は編集系をまとめる予定です。
- インサードモードへの入り方
- ビジュアルモード、矩形ビジュアルモード
- デリート、コピー、カット、ペースト
な感じで。
今回はカーソル移動を扱いましたが、便利なコマンドやプラグインも覚えていこうと思っています。
(surround.vimとか...)
また、今回の内容についてのアドバイス、ご意見等ありましたらコメント等頂けると嬉しいです。
create-react-appでreact-studyというプロジェクトを生成してみよう。
% create-react-app react-study
babelやbrowserifyと組んだコマンドを実行したり、webpackの設定ファイルを書く必要もない。
create-react-appが全部やってくれる。
もちろん隠させているがwebpackを使っているので、カスタマイズするためにはwebpackの知識が必要になる。
生成されたプロジェクトをブラウザーで確認してみよう。
% cd react-study
% yarn start
自動でデフォルトブラウザーが開き、「Welcome to React」と言う挨拶が見える。
.
├── README.md
├── node_modules # Installed by Create React App├── package.json # The only app config file├── public
│ ├── favicon.ico
│ ├── index.html # Default page template│ └── manifest.json
├── src # App source lives here│ ├── App.css # Component specific CSS│ ├── App.js # Custom component definition│ ├── App.test.js
│ ├── index.css
│ ├── index.js # Root component definition│ ├── logo.svg # Import image│ └── registerServiceWorker.js
└── yarn.lock
スタイルガイドとは
コーディングのルールで大体こんな感じでコーディングしたら、読みやすい綺麗なコードになるという規約の集まりだ。
Airbnbはreactで開発している大手会社で自分たちが使っているスタイルガイドを公開している。
和駅されたものもqiitaにあったので、紹介する。
必ず読んでみよう。
Airbnbは、スタイルガイドの通りにしたのかチェックするライブラリも提供している。
eslint-config-airbnbと言う。これを使うためには下記のようなものが必要だ。
使い方や設置方法はeslint-config-airbnbのreadmeに詳細に書いている。
eslint-config-airbnbを使うためには依存関係にあるパッケージも一緒に設置しなければならない。
次は、eslint-config-airbnbのreadmeからそのまま持ってきた。
% npm info "eslint-config-airbnb@latest" peerDependencies
{ eslint: '^3.19.0',
'eslint-plugin-jsx-a11y': '^5.0.1',
'eslint-plugin-import': '^2.2.0',
'eslint-plugin-react': '^7.0.1'}
eslintの実行速度を上げるためのeslint_dというパッケージもある。
eslintとeslint_dはvimなどのEDITORでも使えるので、グローバルで設置しよう。
eslintはv3.19.0で設置することを忘れずに!
% yarn global add eslint@3.19.0
% yarn global add eslint_d
Linux又はmacOSでは下記のコマンドを使えばいいだろう。
依存関係にあるパッケージすべてが設置される。
開発に関わるパッケージなので、npmなら--save-dev、yarnなら--devオプションを付ける。
cd react-study
exportPKG=eslint-config-airbnb;
npm info "$PKG@latest" peerDependencies --json |command sed 's/[\{\},]//g ; s/: /@/g'| xargs npm install --save-dev "$PKG@latest"
cd react-study
exportPKG=eslint-config-airbnb;
npm info "$PKG@latest" peerDependencies --json |command sed 's/[\{\},]//g ; s/: /@/g'| xargs yarn add --dev "$PKG@latest"
ウィンドウの場合、eslint-config-airbnbのreadmeを参考。
~/.eslintrcファイルを用意して次を追加する。
"extends": "airbnb"
vimには文法チェックのためsyntasticという優れたpluginが存在する。(ここでは割愛する。)
Airbnbのスタイルガイドを適用するためには下記のように設定する。
Plug 'scrooloose/syntastic'
... snip ...
letg:syntastic_javascript_checkers = ['eslint']
letg:syntastic_javascript_eslint_exec ='eslint_d'
エラーメッセージはこうなる。
src/App.js|5 col 1 error| Component should be written as a pure function (react/prefer-stateless-function)
src/App.js|8 col 7 error| JSX not allowed in files with extension '.js' (react/jsx-filename-extension)
これらはeslint-plugin-reactから表示されるものだ。
各ruleとその内容を確認したい場合は下記のリンクを参考にしよう。
注意:ただのメモ
brewでズン
$ brew install global --with-exuberant-ctags --with-pygments
設定ファイルをデフォルトからコピー
cp /usr/local/Cellar/global/6.5.7/share/gtags/gtags.conf ~/.globalrc
globalのビルトインのファイル形式以外をpygmentで処理するように修正
これを
default:\:tc=native:
こう
default:\:tc=native:tc=pygments:
GNU GLOBALの対応言語を大幅に増やすPygmentsパーサーを導入する
ソースコードを快適に読むための GNU GLOBAL 入門
カーソル下の文字列に対して定義、参照をそれぞれquickfixで表示。
deinでズン。ちなみにgithubリポジトリに、公式プラグインの最新版が公開されてなかったので、リポジトリ作っといた。
[[plugins]]
repo ='lighttiger2505/gtags.vim'
hook_add ='''
" Optionsletg:Gtags_Auto_Map =0letg:Gtags_OpenQuickfixWindow =1 " Keymap " Show definetion of function cousor word on quickfix
nmap <silent> K :<C-u>exe("Gtags ".expand('<cword>'))<CR> " Show reference of cousor word on quickfix
nmap <silent> R :<C-u>exe("Gtags -r ".expand('<cword>'))<CR>'''
gtagsを非同期で自動更新してくれる。
deinでズン。
[[plugins]]
repo ='jsfaint/gen_tags.vim'
hook_add ='''
letg:gen_tags#gtags_auto_gen =1'''
denite表示用のソース。
deinでズン。期待した挙動をしてくれなかったので暇があったらプラグイン作りたい。
[[plugins]]
repo ='ozelentok/denite-gtags'
hook_add ='''
" Prefix key
nmap [denite] <Nop>
map <C-j> [denite]
" Keymap
nmap <silent> [denite]<C-D> :Denite -buffer-name=gtags_completion gtags_completion<cr>'''
昔はvimのプラグインをよく使用していました。
しかし、プラグインを入れるたびにコマンドを学習するのが面倒になってきました。
プラグインがないとできないことは当然ありますが、プラグインを使えない環境で作業をすることがありますので、最近はプラグイン武装することよりもvim機能をもっと知ることに注力しています。
ファイル操作で便利な機能やプラグインに頼らなくてもできることなどをまとめていこうと思います。
個人的に便利だと思う移動機能。
キーバインド | 挙動 |
---|---|
% | 対応する括弧に移動 |
[m | (上方向に移動)関数を定義している箇所に移動する |
]m | (下方向に移動)関数を定義している箇所に移動する |
m <任意のキー> ex) ma | 現在のカーソル箇所にマークをつける |
` <マークをつけたキー> ex) `a | マークをつけた場所に移動する |
g, | 最後に修正した場所への移動 |
普通のエディタと同じくvimにもvimgrepと呼ばれるgrep機能が備わっています。
私はtaglistプラグインが使えない環境でメソッドの一覧をみたい時に下記のようにvimgrepをよく使います。
:vimgrep /public function/ % | cw
ちなみに%は現在開いているファイル名のことを指します。
vimにはレジスタ編集中のファイル名やヤンク(コピー)した文字列の情報などをためこむ収納庫のようなものがあり、%はファイル名が保存されています。
興味のある方は:reg
で確認してみてください。
vimgrepに関しては下記の記事が参考になると思います。
vimgrepとQuickfix知らないVimmerはちょっとこっち来い
vimコマンドはパイプで組み合わせて使うことが出来るので、:tabnew | edit /home/xxx/xxx.txt
とeditコマンドで新しいタブでファイルをしたり、:tabnew | b 1
新しいタブにバッファーに展開されているファイルを流し込んだりできます。
Tabの切り替えコマンドは沢山存在しますが、下記のコマンドで大体のことが代用できると思います。
キーバインド | 挙動 | Link |
---|---|---|
gt | Tabを次のタブに切り替える | http://vim-jp.org/vimdoc-ja/tabpage.html |
{Tab番号}gt | Tabを指定したTab番号のタブに切り替える |
{Tab番号}gt
を使うのならTab内にTab番号が表示されていたほうが分かりやすいかもしれませんね。
.vimrcファイルに下記のように設定するとTab番号が表示されます。
Tab番号 : [ファイル名] のフォーマットになるような設定です。
colo desert
" カレントタブをハイライトhi TabLineSel ctermbg=1" タブにフルパスでなく、ファイル名のみを表示する settabline=%!MyTabLine()" 常にタブラインを表示 setshowtabline=2function! MyTabLine()let s =''foriin range(tabpagenr('$')) " ラベルは MyTabLabel() で作成するlet my_tab_label ='%{MyTabLabel(' . (i+1) . ')}' " 強調表示グループの選択ifi+1== tabpagenr()let s .='%#TabLineSel#'elselet s .='%#TabLine#'endif " タブ番号 : [ファイル名] のフォーマットになるように設定let s .=(i+1) . ':[' . my_tab_label .'] 'endfor " 最後のタブページの後は TabLineFill で埋め、タブページ番号をリセットするlet s .='%#TabLineFill#%T'return s
endfunctionfunction! MyTabLabel(n)let buflist = tabpagebuflist(a:n)let winnr = tabpagewinnr(a:n)return fnamemodify(bufname(buflist[winnr -1]),":t")endfunction
下記のようにファイルにパスが記載されているとします。
...
$filepath = '/usr/local/log/error.log';
...
カーソルをパスの上に合わせて下記のコマンドを実行すると:e /usr/local/log/error.log
などしなくてもerror.logファイルを開くことができます。
キーバインド | 挙動 | Link |
---|---|---|
gf | カレントウィンドウ上でファイルを開く | http://vim-jp.org/vimdoc-ja/usr_22.html |
<Ctrl>w gf | 新しくタブを開いてファイルを開く | http://vim-jp.org/vimdoc-ja/windows.html#CTRL-W_gf |
ファイルを編集している時にuを連打してファイルを元の状態に戻した経験はありませんか?
Undoブランチを理解すればuをひたすら連打するよりももっとスマートにファイルを戻せます。
http://vim-jp.org/vimdoc-ja/undo.html#undo-branches
http://vim-jp.org/vimdoc-ja/usr_32.html
ファイルの編集中は書いたり消したりという作業を繰り返するのでUndoブランチの分岐点がたくさん出来ます。
u連打でもいいですが、
:earlier {N}f
など様々な戻し方を知っていると便利なこともあるので知っておいて損はないと思います。
ちなみに戻しすぎた場合は、
:later {N}f
で調整してください。
Windowsのエクスプローラーの様にディレクトリをツリー表示させるのに
Vimのプラグインnerdtreeを使用している方は多いのではないかと思います。
標準のvimでも同じようなことが:edit .
で出来ます。ちなみにこのように表示されます。
" ============================================================================
" Netrw Directory Listing (netrw v109)
" Sorted by name
" Sort sequence: [\/]$,\.h$,\.c$,\.cpp$,*,\.info$,\.swp$,\.o$\.obj$,\.bak$
" Quick Help: <F1>:help -:go up dir D:delete R:rename s:sort-by x:exec
" ============================================================================
../
./
check/
Makefile
autocmd.txt
change.txt
eval.txt~
filetype.txt~
help.txt.info
キーバインド | 挙動 |
---|---|
Enter | ディレクトリを開く |
-(マイナス) | 親ディレクトリに移動 |
d | ディレクトリを作成する |
D | ファイル / ディレクトリを削除する |
R | ファイル / ディレクトリをリネームする |
などなど他にも機能がたくさんあります。
詳しくは下記を参照してください。
キーバンドのリファレンス : http://vim-jp.org/vimdoc-ja/pi_netrw.html#netrw-quickmap
標準のvimでもnerdtreeのようにディレクトリにブックマークをつけることも出来るので結構便利。
:ol[dfiles]で最近開いたファイルの一覧を表示することが出来ます。
:ol[dfiles]
ただし、oldfilesコマンドは最近開いたファイルの一覧を表示するだけです。
VimプラグインのMRUのように
過去に開いたファイルの一覧を表示 → 開きたいファイルを選択し移動
という事がしたいのであれば、:bro[wse]と組み合わせて下さい。
:bro[wse] ol[dfiles]
仕組みに興味のある方はhelpのリンクを貼っておきますので、読んでみてください。
viminfo : http://vim-jp.org/vimdoc-ja/usr_21.html#21.3
v:oldfiles変数 : http://vim-jp.org/vimdoc-ja/eval.html#v:oldfiles
vimはファイルを開いた状態でも:![コマンド]
で外部(OS)コマンドを実行することが出来ます。
私はPHPのファイルを編集する際、編集の合間でちょこちょこプログラムを実行しながらデバッグします。
:!php -l %
こんな感じ。
今後もちょこちょこ編集していきます。
vimでjavascriptのsyntax highlightingやindetationのために使っていたのは「vim-javascript」というものだった。
以前まではこれで十分だったが、reactなどには対応されていない部分があり、「yajs.vim」で乗り換えた。
syntax highlightingの比較画面をみればどっちがいいのかわかると思う。
ECMAScript(ES)で開発するので、同じ人が作った「es.next.syntax.vim」も入れる。
「javascript-libraries-syntax.vim」を使えばjQueryやAngularJSなど他のライブラリにも綺麗に表示される。
Plug 'othree/yajs.vim', { 'for': ['javascript','javascript.jsx'] }
Plug 'othree/es.next.syntax.vim', { 'for': ['javascript','javascript.jsx'] }
Plug 'othree/javascript-libraries-syntax.vim', { 'for': ['javascript','javascript.jsx'] }
javascript-libraries-syntaxは使いたいライブラリを指定する必要がある。
functionを作って.jsファイルを開くときに呼び出せばいい。
function! EnableJavascript() " Allow JSX in normal JS filesletg:jsx_ext_required =0 " Setup used librariesletg:used_javascript_libs ='jquery,underscore,react,flux,jasmine,d3'letb:javascript_lib_use_jquery =1letb:javascript_lib_use_underscore =1letb:javascript_lib_use_react =1letb:javascript_lib_use_flux =1letb:javascript_lib_use_jasmine =1letb:javascript_lib_use_d3 =1endfunction
autocmd MyVimrc FileType javascript,javascript.jsx call EnableJavascript()
これは僕の設定で、他のJavaScriptライブラリを有効にする必要がある方はreadmeを参考にしていただければと思う。
ちなみに、MyVimrcはautocmd!をやってくれるものだ。
augroup MyVimrc
autocmd!
augroup END
jsxのSyntaxフラグインとして「mxw/vim-jsx」を使っていたが、
閉じる"}"で警告の表示になっていて「vim-jsx-pretty」に変更した。
readmeにDemo画面が出ているので、どっちがいいのか確認してみよう。
Plug 'maxmellon/vim-jsx-pretty', { 'for': ['javascript','javascript.jsx'] }
ternjsを使えばpowerfulなコード補完が可能だ。
いろんなEDITORに対応されていてvim pluginも提供している。
npmが設置されている必要がある。
Plug 'ternjs/tern_for_vim', { 'for': ['javascript','javascript.jsx'],'do': 'npm install' }
ternjsの公式サイトのドキュメントよりatomのドキュメントがもっと参考になった。
次は、atomのドキュメントを参考にして作成した。
% vim ~/.tern-project
.tern-projectファイルを次のように作成する。
{"ecmaVersion":6,"libs":["browser","ecma5","ecma6","ecma7"],"loadEagerly":["node_modules/react-dom/**/*.js","node_modules/react/**/*.js","node_modules/whatwg-fetch/fetch.js","src/**/*.js"],"plugins":{"es_modules":{},"node":{},"doc_comment":{"fullDocs":true,"strong":true}}}
プロパティ | 説明 |
---|---|
ecmaVersion | デフォルトで使うecmaを指定 |
libs | 入力補完に使うlibraryを指定 |
loadEagerly | libs以外に入力補完に使えたいlibraryを指定 |
dontLoad | 入力補完に使えたくないlibraryを指定 |
plugins | サーバープラグインを指定 |
loadEagerly
名前の通りeager loadなので、使う場合はそれなりにコストが高い。
node_modules以下を全部読み込むのはやめた方がいい。
dontLoad
確実に使えたくないものを指定するとき使う。
plugins
もっと多いが、詳細はternjsの公式マニュアルを参考していただければと思う。
ここでは設定ファイルに書かれているものだけ説明する。
プラグイン | 説明 |
---|---|
es_modules | ES6のimportとexportに対応 |
node | nodeで使う変数やプラグインのloadに対応 |
doc_comment | jsdocスタイルのコメントに対応 |
詳細が知りたい場合は下記のリンクを参考にしよう。
% vim ~/.eslintrc
.eslintrcファイルを次のように作成する。
{"parser":"babel-eslint","env":{"browser":true,"node":true},"settings":{"ecmascript":6,"jsx":true},"plugins":["react","import"],"rules":{"react/prefer-stateless-function":0,"react/jsx-filename-extension":[1,{"extensions":[".js",".jsx"]}],},"extends":"airbnb"}
設定ファイルをみれば大体わかる。
詳細は次の記事を参考にしよう。
これはあくまで、スタイルガイドやコードの補完、スニペットに関するプラグインだけだ。
Vimを使っている開発者であればこのくらいは使いこなした方がいいと思う。
このほかにも開発に役立つプラグインは盛りだくさんあるが、次の機会にね。
主にJavaScriptのコーディング用としてVimを使い始めたのですが、当初夢見ていたようには使いこなせておらず、挫折しそうになりました。使いこなせていない原因を考えてみると、基本的な操作は覚えたものの、それらを組み合わせてチャチャッと編集する方法が瞬時に思い浮かばず、その都度う~んと考え込んでしまっているからだと思います。
そこで、コーディング中によく出てくる場面をお題にして、自分用の練習ドリルを作ることにしました。これを納得のいくスピードでクリアできるようになるまで、ひたすら繰り返そうと思います。その前に、あわよくばベテランVimmerの方々からアドバイスを頂いてもっと改善できないか、と考えて投稿した次第です。
ドリルの解法例は、必ずしも効率的な操作にはなっていません。というより、むしろ全体的に非効率です。なぜなら、各解法は以下のような個人的な事情を踏まえて考えたものだからです。
%
とか数字とか)は極力使わない(例えば %
は [{
や ]}
で代用する、など)上記の1つめや2つめ、特に2つめは、まずそこを練習しろという話ですが…。
まずは練習に入る前に、私の操作のクセを矯正する目的で、いくつかの便利なキーを使えないようにしています。
f
を徹底するf
や t
で横移動する方法が効率よいと分かってはいるのですが、つい無意識に h
や l
を押しっぱなしにして移動してしまいます。
これを矯正するために、h
と l
での移動を禁止しました。
nnoremaph<nop>nnoremapl<nop>
ついでに、単語単位での移動も禁止しました。
nnoremapw<nop>nnoremapb<nop>nnoremape<nop>nnoremap ge <nop>vnoremapw<nop>vnoremapb<nop>vnoremape<nop>vnoremap ge <nop>
最初の頃は「横移動は全て単語移動でやってしまおう、それが一番シンプルで覚えやすい」と意気込んでいました。ですが、実際にやってみると、プログラムの一行の中には様々な記号が混じっているのでガッツガッツと引っかかってしまい、いっそのことしばらくは使わないことに決めました。
ちなみに大文字での移動はもともと使いこなせていなかったので、そのままです。英文ならともかく、プログラミングでは利用場面も少ないと思います。またカーソルキーは、そもそもカーソルキーを使うのが面倒だという理由でVimに乗り換えたため使っておらず、そのままです。
これでもう f
で移動するしかなくなりました。
(ただ、日本語で書かれた行だと身動きが取れなくなりますが…)
<ESC>o
を徹底する1回の挿入モードの中で何行もコードを書いてノーマルモードに戻り、最後の1行だけ元に戻そうとして u
したら全部消えた、という失敗を繰り返してしまったので、挿入モード中の <CR>
を禁止することにしました。
inoremap<CR><nop>
なお、挿入モード中にどうしても必要な場合は <C-j>
します。
つい最近まで jj
をエスケープキーに割り当てていましたが、いつもと違う環境で操作した時や、コメント文を日本語で入力した後などにアッとなってしまうため、やめました。
ここから本題です。
プログラミング中によくある場面をお題として挙げ、その解法を示し、最後に練習用のサンプルコード、という構造になっています。
なお、言い訳がましく繰り返しになりますが、解法はあくまで私個人の低レベルな事情を考慮したものであり、最適な解ではありません。
cw{chars}<ESC>
変数名を変更したい、という場面です。
例えば、hoge
という変数がいくつかあって、名前が気に入らないのでそれら全てを piyo
に変えたいような場合です。hoge
の先頭にカーソル位置がある前提で、cwpiyo<ESC>
とします。
開始カーソル位置は、1行目の先頭です。
私は、fh*Ncwpiyo<ESC>n.
で練習しています。
consthoge=1;console.log(hoge);
constpiyo=1;console.log(piyo);
cw<C-r>0<ESC>
変数名を変更したい、という場面です。ただしお題1とは少し条件が異なり、あらかじめ変更後の変数名をヤンクしておいて、それをプットしたいという場合です。
例えば hoge
という変数がいくつかあり、それらをヤンク済みの piyo
に変えたい場合には、hoge
の先頭にカーソル位置がある前提で、cw<C-r>0<ESC>
とします。わざわざ <C-r>0
とするのが面倒ですが、.
で繰り返し可能にするには仕方ありません。
このパターン、私はよく、一般的なエディタのノリで viwp
して次の単語でまた viwp
してアッとなってしまいます。
開始カーソル位置は、1行目の先頭です。
私は、fpyejFh*Ncw<C-r>0<ESC>n.
で練習しています。
constpiyo=1;hoge+=1;console.log(hoge);
constpiyo=1;piyo+=1;console.log(piyo);
f_qmxgUlq
スネークケースにしていた変数をキャメルケースに変更したい、という場面です。あまり遭遇しない場面ですが、つい最近あったので。
例えば、hoge_hoge
で先頭にカーソルがある前提で、f_qmxgUlq
とすれば hogeHoge
となります。マクロに登録しているのは、繰り返しを簡単にするためです。私はマクロやマークはなんでもかんでも m
に登録することにしています。
なお、gUl
は ~
としたほうが手っ取り早いですが、~
はめったに使わないキーなので敬遠しています。
開始カーソル位置は、1行目の先頭です。
私は、fh*Nf_qmxgUlq;@myiwncw<C-r>0<ESC>n.
で練習しています。なお、途中から(cw
以降)はお題2と同じ操作です。
consthoge_piyo_fuga=1;hoge_piyo_fuga+=1;console.log(hoge_piyo_fuga);
consthogePiyoFuga=1;hogePiyoFuga+=1;console.log(hogePiyoFuga);
cw{chars}<C-r><C-o>"{chars}<ESC>
変数を、記号や関数などで囲いたい、という場面です。これはよくあるかと思います。
例えば、hoge
を "hoge"
とするような場合、現在のカーソル位置が hoge の先頭にある前提で、cw"<C-r><C-o>""<ESC>
とします。
その後に、別の変数に対しても同じ編集を行いたい場合には .
で繰り返すことができるのですが、もし <C-r><C-o>"
を <C-r>"
と手抜きしていると失敗します。
開始カーソル位置は、1行目の先頭です。
私は、fhcwparseInt(<C-r><C-o>", 10)<ESC>jFp.
で練習しています。
consta=hoge;constb=piyo;
consta=parseInt(hoge,10);constb=parseInt(piyo,10);
vf{]}
以下のような関数をまるごと選択したい、という場面です。
functioncompare(a,b){returna-b;}
現在のカーソル位置が function の先頭にある前提で、vf{]}
で選択状態にできます。
なお、]}
は %
としたほうが手っ取り早いですが、%
キーは遠いので敬遠しています。
開始カーソル位置は、1行目の先頭です。
私は、fc*Nffvf{]}dnviwpNdj
で練習しています。
constcompare=function(a,b){returna-b;};array1.sort(compare);
array1.sort(function(a,b){returna-b;});
demmf{char}viwp`mP
「隣り合った」単語を入れ替える方法を私は早い段階で覚えたのですが、そもそもプログラミングでは隣り合った単語の順序が違っていたら文法エラーになるケースが多いのでその状況に出会う機会が少なく、せっかく覚えた方法を活用できていませんでした。
しかし、「離れた」単語同士を入れ替えたい場面ならあります。
例えば以下の変数 hoge と piyo を入れ替えるような場合です。
hoge-piyo;
現在のカーソル位置が hoge の先頭である前提で、demmfpviwp`mP
で入れ替えられます。
開始カーソル位置は、行の先頭です。
私は、fhdemmfpviwp`mP
で練習しています。
consta=hoge-piyo;
consta=piyo-hoge;
V>O{chars}<ESC>`>o{chars}<ESC>
いくつかの行をif文などのブロックで囲いたい、という場面です。
方法はいくつも考えられますが、個人的には、まずはブロックで囲いたい部分をビジュアルモードで選択することから始めるのが視覚的に分かりやすかったので、それを生かす方法にしました。
開始カーソル位置は、行の先頭です。
私は、jVj>Oif (fuga) {<ESC>`>o}<ESC>
で練習しています。
hoge=1;piyo=1;foo=1;bar=1;
hoge=1;if(fuga){piyo=1;foo=1;}bar=1;
f{vaBygPI else <ESC>
もともとif文があり、中身が似たようなelseを追加したい、という場面です。
開始カーソル位置は、行の先頭です。
私は、f{vaBygPI else <ESC>j<C-a>
で練習しています。
if(fuga){hoge=0;}
if(fuga){hoge=0;}else{hoge=1;}
f,a<C-j><ESC>viBs<C-j><C-r>"<C-j><ESC>
正しい用語が分からないのですが、JavaScriptのオブジェクトリテラルの書き方を、
a={hoge:1,piyo:2};
から
a={hoge:1,piyo:2};
にしたい、という場面です。
上記のような単純な形であれば、f,a<C-j><ESC>viBs<C-j><C-r>"<C-j><ESC>
とします。階層が深い場合でも、この操作の組み合わせでなんとかなります。
開始カーソル位置は、行の先頭です。
私は、f,a<C-j><ESC>;.viBs<C-j><C-r>"<C-j><ESC>
で練習しています。
constuser={name:"hoge",age:20,address:"fuga"};
constuser={name:"hoge",age:20,address:"fuga"};
では、一ヶ月くらい毎日練習してみます。