こころちゃんの展開図を描いた。
久しぶりに展開図を描いたのでメモ。
約80cm四方のカラぺで64等分蛇腹、制作時間12時間くらいです。
. @supermomonga さんのアイコンことこころちゃんを折ってみた。 pic.twitter.com/RJkvgdAVy4
— Vimうさぎさん(電脳化したい) (@rbtnn) 2015, 8月 10
※ 左右対称です。
msysgit/git をビルドしてみた。
まず、なぜmsysgit/gitをビルドしてみたかというと、 msysgit/msysgitがビルド済みのgit.exeを含んでおらず、 msysgit/gitをsubmoduleしていてmakeを手動で行わないといけなかったからです。
で、以下がビルド手順です。
setup-msysgit.bat
rem git.exeを含むパスを環境変数PATHに追加する。 rem 一度ビルドしてしまえば".\msysgit\git"でOK。 set PATH=C:\Git\bin git clone https://github.com/msysgit/msysgit.git pushd msysgit git submodule init git submodule update set PATH=.\bin;.\mingw\bin;.\git call msys.bat popd pause
このリポジトリ、git.exeやsvn.exeやmingwなどが含まれていてとてもオールインワンパッケージ感がありました!msysgit/msysgit便利!
Anti-pattern of vimrc
file encoding
In Vim script, :scriptencoding
exists to specify a file encoding.
Generally it should define :scriptencoding
when you use multibyte character.
When you don't use multibyte character, you don't have to define :scriptencoding
.
Therefore you have to use :scriptencoding
at the head of your vimrc.
Bad pattern
" use multibyte charactor. let g:indentLine_char = '|'
Good pattern
scriptencoding utf-8 let g:indentLine_char = '|'
:scriptencoding
and :set encoding
Vim can not recognize the character code of your vimrc when :scriptencoding
is defined before :set encoding
.
When writing :set encoding
, it should be described before :scriptencoding
.
Bad pattern
scriptencoding utf-8 set encoding=utf-8
Good pattern
set encoding=utf-8 scriptencoding utf-8
Abbreviate option
I often see a vimrc using an abbreviate option and the same strict option. It's a bad coding. You should use a strict option only.
Bad pattern(1)
" 'modeline' of abbreviation. set ml
Good pattern(1)
set modeline
Bad pattern(2)
augroup vimrc " 'autocmd' of abbreviation. au! au FileType vim * :set expandtab augroup END
Good pattern(2)
augroup vimrc autocmd! autocmd FileType vim * :set expandtab augroup END
If you don't know an abbreviate option, please you try :h ml
in your Vim.
And you will know a strict name of the abbreviate option.
*'modeline'* *'ml'* *'nomodeline'* *'noml'*
Scope of variable
I often see a vimrc using g:mapleader
and mapleader
.
It's a bad coding. You should use a variable with a scope.
Bad pattern(1)
let mapleader = ' '
Good pattern(1)
let g:mapleader = ' '
Bad pattern(2)
for i in range(0,2) execute printf('source .local_%d.vim', i) endfor
Good pattern(2)
for s:i in range(0,2) execute printf('source .local_%d.vim', s:i) endfor
When you use a variable without a scope outside a function, implicitly its scope is global scope(g:
).
Generally when you use a variable outside a function, you have to define it with script scope(s:
).
:autocmd
without belonged to groups
In Vim script, :autocmd
exists. Its syntax is following syntax.
:au[tocmd] [group] {event} {pat} [nested] {cmd}
:autocmd
can omit [group]. It is a bad coding and that makes your Vim heavy.
Bad pattern
autocmd FileType cpp setlocal expandtab autocmd FileType make setlocal noexpandtab
Good pattern
" define a group `vimrc` and initialize. augroup vimrc autocmd! augroup END " register autocmds to group `vimrc`. autocmd vimrc FileType cpp setlocal expandtab autocmd vimrc FileType make setlocal noexpandtab
Why is it heavy?
If you define autocmds without a group, your Vim registers the same autocmd each :source ~/.vimrc. And your Vim executes the same autocmds each occurring a Event(e.g. FileType). In one word, it's heavy.
「zshでsource .vimrc」を対応するvimrcにする。
以前、素で以下の記事のsource
コマンドがVimのコマンドかと思ってリプライを返してしまったことがある。
@error1009 あごめんなさい、zshのsourceじゃなくてVimのsourceのことかと勘違いしてました。zshのsourceでvimrcを読み込むのは全く意味ないですね。
— V i m う さ ぎ さ ん (@rbtnn) 2014, 12月 16
なので、どうにかしてzsh上でのsource .vimrc
を防げないかなっと考えた結果、以下の1行をvimrcの先頭で書いて置けばよいことがわかった。
"return" 2>&- || "exit"
この先頭のダブルクォートがキモで、Vim script上ではコメント扱いになり、zshやbash上ではコマンドとして正常終了するという仕組みである。便利!
ちなみに、なぜわざわざreturnとexitをしているかというと、returnのみだと終了コードがエラーで終わってしまい、exitだと端末自体が終了してしまうため、これらの問題を対処した結果このようなコードとなっています。
vimrcアンチパターン
この記事はVim Advent Calendar 2014 - Qiita1日目の記事です。
今回は、もう130回も続いているvimrc読書会でよく見られるvimrcのアンチパターン、 まぁ「これは気を付けたほうがいいんじゃない」的なことを私なりにまとめてみようと思う。
vimrcの文字コード
Vim scriptにはscriptencoding
という現在のVim scriptファイルの文字コードを指定するコマンドが存在します。
一般的にscriptencoding
はマルチバイト文字を使う前に宣言します。マルチバイト文字を一切使っていない場合、特に宣言する必要はないでしょう。
なので、マルチバイト文字をvimrc内で使用する場合(コメント内でマルチバイト文字を使用する場合も含みます)、vimrcの先頭で宣言するのがいいでしょう。
悪いパターン
" ミュートにする。 set t_vb= set visualbell set noerrorbells
良いパターン
scriptencoding utf-8 " ミュートにする。 set t_vb= set visualbell set noerrorbells
scriptencoding
とset encoding
上項で「vimrcの先頭で宣言するのがいいでしょう。」と言いましたが、
scriptencoding
とset encoding
の順番には気を付けましょう。
Vimは文字コードの内部的な仕組み上、set encoding
をscriptencoding
より
あとに記述すると文字コードを上手く扱うことができません。
よって、set encoding
を書く場合にはscriptencoding
より前に記述するべきです。
悪いパターン
scriptencoding utf-8 set encoding=utf-8
良いパターン
set encoding=utf-8 scriptencoding utf-8
省略記法のオプション
たまに省略しているオプションと省略してない同じオプションをそれぞれ宣言しているのを見かけるけど、 これは同じ処理を2回も行っていてもったいない処理です。 省略しているオプションと省略してないオプションを混ぜてvimrcに記述するのは精神衛生上可読性的にも非常に悪いです。 省略しないでオプションを設定するようにするといいでしょう。
悪いパターン
" ↓modelineの省略記法 set ml
良いパターン
set modeline
もし、省略しているオプションの正式な名前がわからない場合には:h ml
のようにヘルプを引きましょう。
以下のような感じで省略名と正式な名前の両方が記載されているはずです。
*'modeline'* *'ml'* *'nomodeline'* *'noml'*
スコープのない変数(1)
vimrcに書かれるよくあるパターンして<leader>
の文字を決める変数g:mapleader
があります。
たまにg:mapleader
とmapleader
をそれぞれ宣言しているのを見かけるけど、これは全く同じ変数を参照します。
悪いパターン
let mapleader = ' '
良いパターン
let g:mapleader = ' '
関数外でスコープなし変数を宣言した場合、暗黙的にグローバル変数扱いになります。 関数外で変数を宣言するときはスコープを付けるくせをつけるといいでしょう。
スコープのない変数(2)
関数外でfor文を使う場合、一時変数(下記でいうi
)もlet文で宣言したのと同等な扱いとなります。
ということはスコープのなしでfor文を使えば当然グローバル変数扱いとなりとても邪悪です。
悪いパターン
for i in range(0,2) execute printf('source .local_%d.vim', i) endfor
良いパターン
for s:i in range(0,2) execute printf('source .local_%d.vim', s:i) endfor
let文と同じく、関数外でfor文を使うときはスコープを付けるくせをつけるといいでしょう。
基本的にvimrc内で関数外の変数を宣言する時にはスクリプト変数であるs:
をつけるといいでしょう。
グループに属していないautocmd
autocmdコマンドは以下のような構文で、[group]
を省略することができるのですが、
vimrc内で[group]
を省略すると少々厄介です。
:au[tocmd] [group] {event} {pat} [nested] {cmd}
この[group]
を指定していないautocmdをvimrc内に記述していると、vimrcを再読み込みするたびにそのautocmdが登録されてしまいます。
ということはvimrcを読み込んだ回数だけautocmdが実行されてしまいます。
要するに余計な処理が増え、段々Vimが重くなっていきます。
悪いパターン
autocmd FileType cpp setlocal expandtab autocmd FileType make setlocal noexpandtab
良いパターン
augroup vimrc autocmd! augroup END autocmd vimrc FileType cpp setlocal expandtab autocmd vimrc FileType make setlocal noexpandtab " ...
vimrcの先頭の方で
augroup vimrc autocmd! augroup END
を宣言することでグループvimrc
に属するautocmdを初期化できます。
もうちょっと詳しくいうとautocmd!
が現在のグループに属しているautocmdをすべて登録解除を行います。
その後にグループvimrc
に属したautocmdを使えばOKです。
これでvimrcを再読み込みしてもVimが重くなることもありません。
上記の方法以外にもいくつか書き方があります。
" 別解 augroup vimrc autocmd! autocmd FileType cpp setlocal expandtab autocmd FileType make setlocal noexpandtab " ... augroup END
これは初期化と登録を同時にしてしまう方法です。
毎回、autocmd
の後にグループ名を書かなくていいので若干コーディングが楽になります。
※ グループ名は好きな名前が使えます。vimrc
である必要はありません。
展開されるマップと展開されないマップ
vimrcに良く書かれるマップにはcmap
、imap
、nmap
がある。でもこれは展開されるマップです。
これらにはそれぞれcnoremap
、inoremap
、nnnoremap
と展開されないマップも存在します。
これを上手く使いこなせていないvimrcをちらほら見かけます。
悪いパターン
nmap <leader>c :<C-u>copen<cr>
良いパターン
nnoremap <leader>c :<C-u>copen<cr>
上記の悪いパターンはnmap : ;
などとコロンの挙動を変えてしまうと途端に意図しない挙動になるでしょう。
一般的に展開されるマップを使うのはプラグインが提供している<Plug>(...)
系のマッピングです。
例
smap <C-z> <Plug>(neosnippet_expand_or_jump)
その他のマッピングでは展開されないマップを使う方がよいでしょう。 当然、意図的に展開されるマップを使うなら全くもって問題ないです。
実は必要のないset nocompatible
Vimはvimrcもしくはgvimrcを発見すると自動的にset nocompatible
になります。
なので、vimrcにset nocompatible
を書く必要はありません。
また、set nocompatible
はちょっと厄介な副作用を持っていて、以下のオプションが初期化されてしまいます。
(vim-jp/vimdoc-jaから引用)
vimrc読書会でよく話題に上がる問題としてset nocompatible
するとオプションhistory
が初期化されていまうため、
履歴が削除されてしまうというものです。
オプション + Viの既定値 効果 ~ 'allowrevins' オフ コマンド CTRL-_ なし 'backupcopy' Unix: "yes" バックアップファイルがコピーになる 他: "auto" バップアップはコピーまたはリネーム 'backspace' "" 普通のバックスペース 'backup' オフ バックアップファイルなし 'cindent' オフ C言語ファイルにインデントなし 'cedit' + "" |cmdwin| を開くキーなし 'cpoptions' + (全フラグ) Vi互換のフラグ 'cscopetag' オフ ":tag" に cscope を使わない 'cscopetagorder' 0 |cscopetagorder| を参照 'cscopeverbose' オフ |cscopeverbose| を参照 'digraph' オフ ダイグラフなし 'esckeys' + オフ 挿入モードで <Esc> で始まるキーなし 'expandtab' オフ タブはスペースに展開されない 'fileformats' + "" 自動ファイルタイプ決定なし "dos,unix" (ただし DOS, Windows と OS/2 以外で) 'formatoptions' + "vt" Vi互換の文書整形 'gdefault' オフ ":s" でフラグの既定値に 'g' なし 'history' + 0 コマンドラインの履歴なし 'hkmap' オフ ヘブライ語用キーボードマップなし 'hkmapp' オフ phoneticヘブライ語用キーボードマップなし 'hlsearch' オフ 検索でマッチした文字列に強調なし 'incsearch' オフ インクリメンタル・サーチなし 'indentexpr' "" expression によるインデントなし 'insertmode' オフ 挿入モードでの開始なし 'iskeyword' + "@,48-57,_" キーワードはアルファベットと数字と '_' 'joinspaces' オン ピリオドの後ろには空白を2個挿入 'modeline' + オフ モードラインなし 'more' + オフ リスト表示が止まらない 'revins' オフ 右から左の挿入なし 'ruler' オフ ルーラなし 'scrolljump' 1 ジャンプスクロールなし 'scrolloff' 0 スクロールにオフセットなし 'shiftround' オフ インデントは shiftwidth の整数倍でない 'shortmess' + "" メッセージの短縮なし 'showcmd' + オフ コマンドの文字は表示されない 'showmode' + オフ 現在のモードは表示されない 'smartcase' オフ 大文字小文字の無視は自動にならない 'smartindent' オフ 高度なインデントなし 'smarttab' オフ 高度なタブ挿入なし 'softtabstop' 0 タブは常に 'tabstop' を基準 'startofline' オン いくつかのコマンドで行頭に移動する 'tagrelative' + オフ タグファイル名は相対的でない 'textauto' + オフ 自動改行コード決定なし 'textwidth' 0 自動行分割なし 'tildeop' オフ チルダはオペレータではない 'ttimeout' オフ ターミナルの時間切れなし 'whichwrap' + "" 左から右への移動は行を超えない 'wildchar' + CTRL-E 現在の値が <Tab> のときのみ、コマンド ライン補完に CTRL-E を使う 'writebackup' オンかオフ |+writebackup| 機能に依る
もし、なにかの理由でset nocompatible
したい場合には以下のようにすると良いでしょう。
if &compatible set nocompatible endif
syntax on
の宣言位置
ハイライトを有効にしてくれるsyntax on
(もしくはsyntax enable
)があります。
実はファイルタイプ系ハイライトプラグインを導入している場合、syntax on
の宣言位置を気を付ける必要があります。
syntax on
は現在のruntimepathに含まれている設定をもとにシンタックスを生成しようとします。
なので、runtimepathを初期化するような処理をした後にsyntax on
してもあまり意味はなく、
runtimepathをすべて設定し終えた後にsyntax on
をするべきです。
まぁ、runtimepathを初期化するような処理をvimrcに入れている人は結構まれなので心の片隅に入れとくとよいかと思います。
悪いパターン
" runtimepathを初期化するような処理 set runtimepath=$VIMRUNTIME syntax on " ファイルタイプ系ハイライトプラグイン neoBundle 'kongo2002/fsharp-vim'
良いパターン
" runtimepathを初期化するような処理 set runtimepath=$VIMRUNTIME " ファイルタイプ系ハイライトプラグイン neoBundle 'kongo2002/fsharp-vim' syntax on
同一視されるキー
Vim Advent Calendar 2012の164日目の記事ですでに説明されていますけど、まぁ一応。 Vimは以下のキーを同一視してしまいます。
<C-i>
==<Tab>
<C-m>
==<Enter>
<C-[>
==<ESC>
なので、<Tab>
キーのマッピングしたのに<C-i>
キーのマッピングで上書きしてしまったってことが起こりえます。
inoremap <expr> <Tab> MySuperTab() " ↓これは <Tab> のキーマッピングを上書きしてしまう! inoremap <C-i> <C-o><C-i>
(上記の記事のコードをそのまま引用)
g:vim_indent_cont
アンチパターンとかではないけどあまり知られていないので、g:vim_indent_cont
について説明します。
g:vim_indent_cont
は以下のように\
を入力した時のインデント量をつかさどっている変数です。
この変数はVim script(vimrc)を編集しているときにしか使われないので、まぁVim scriptをいじらない方はどうでもいいですね。
let s:hoge = [ _______\ " ↑この`\`を入力した時のインデント量をつかさどっている変数
以上、Vim Advent Calendar 2014 - Qiita1日目の記事でした。 今回、プラグイン関連のノウハウは一切載せないようにしました。 vimrc読書会ではプラグイン関連のノウハウがいろいろと発言されているのですが...まとめるとキリがない。