bashrc/vimrc再び。

.bashrcはじめ設定ファイルのたぐいはちょくちょく書き加えるので少しずつカオスになっていく。
ということで、整理しつつ、いくつかtips的なアレコレをまとめてみた。

.bashrc編

まずは.bashrcから

環境変数をいじる糖衣function in .bashrc

.bashrcを見てみるとやたら目に付くのが"export HOGEHOGE=hoge:${HOGEHOGE}"という記述。
単に環境変数を拡張しているだけなのだが、何を追加しているのか分かりづらいし、なにより環境変数が空だったときに余分な":"がつくのが嫌い。
ということで書いてみたのがこんな。

function AddPathPre()
{
	if [ -z "${!1}" ]; then
		eval "export ${1}=${2}"
	else
		eval "export ${1}=${2}:\${${1}}"
	fi
}

function AddPathPost()
{
	if [ -z "${!1}" ]; then
		eval "export ${1}=${2}"
	else
		eval "export ${1}=\${${1}}:${2}"
	fi
}

${!HOGE}はHOGEを二重展開(?)するらしい。つまり、HOGE="FUGA" FUGA="PIYO"なとき、${HOGE}は当然"FUGA"なわけだが、${!HOGE}は${FUGA}つまりPIYOになるらしい。
今回は${1}に"PATH"とか文字列が入ってるので、それを展開して空かどうかチェックしてます。
あとは適当にeval。ほげほげ。

OS/アーキテクチャによってPATHを振り分ける。in .bashrc

どこ行っても同じ設定/ソフトを使いたい!のにOS/アーキテクチャが違うので動かない!
というのはよくある話(だと思う)。


非常に個人的な話になってしまうのだが、うちの大学はlinuxMacで同じホームを共有するようになっている。
加えて、当然ではあるが、root権限を持っていない。
するとどうなるか?というと、使いたいソフトはホーム以下にインストールしてPATHを通すということになる。
なるのだけど、ホームはlinuxでもMacでも同じなので同じバイナリは使えない。


まぁ、そんなこんなな背景があって、書いちゃいました的なスクリプト

if [ $(uname -p | wc -c) -le $(uname -m | wc -c) ]; then
	processor=$(uname -p);
else
	processor=$(uname -m);
fi
kernel=$(uname -s | tr "[A-Z]" "[a-z]")
export ARCH="${HOME}/arch/${kernel}-${processor}/"

for i in ${ARCH}/*/; do
	AddPathPre PATH "${i}/bin/"
	AddPathPre PATH "${i}/sbin/"

	AddPathPre LIBDIR "${i}/lib/"
	AddPathPre LIBRARY_PATH "${i}/lib/"
	AddPathPre LD_LIBRARY_PATH "${i}/lib/"
	AddPathPre DYLD_FALLBACK_LIBRARY_PATH "${i}/lib/"
	AddPathPre DYLD_FALLBACK_FRAMEWORK_PATH "${i}/lib/"

	AddPathPre C_INCLUDE_PATH "${i}/include/"
	AddPathPre CPLUS_INCLUDE_PATH "${i}/include/"

	AddPathPre MANPATH "${i}/share/man/"
	AddPathPre MANPATH "${i}/man/"
done

前半部がOS/アーキテクチャ判別。OSTYPEとかHOSTTYPEって環境変数があるようなんだけど、色々あってこうなりましたとさ。
unameはもうすこし「共通な出力」を出すようにしてほしい...orz
結局「uname -pとuname -mのうち短いほう + "-" + uname -s」のすべて小文字、に落ち着いた感じ。
あとは環境変数ARCHを使って記述すれば同じ.bashrcでもちゃんとswitchできるわけです。
具体的には"./configure --prefix=${ARCH}"でインストール、PATHに"${ARCH}/bin"を入れる...など。


最近は故あって、というほど深い理由ではないのだけど、諸事情で${ARCH}以下にもう一段ディレクトリ掘ってインストールしている。
例えばvimだと"./configure --prefix=${ARCH}/vim/"という感じ。
そのせいで後半部分にforが出てきてます。
フラットでいいなら単に"${PATH}/bin/"とかを使えばokです。
あと、設定している環境変数は思いつく限りのすべて。
ライブラリでもないのにLD_LIBRARY_PATHに通したり、とか結経無駄。
あと、やたら環境変数が長くなる。
普通に--prefix=${ARCH}がいいと思います。


あと、ここまでできたらいっそ、~/arch/以下をヴァージョン管理システムで自鯖に上げておくと、どこでもmy環境!みたいな感じでいいかも。
アーキテクチャ毎にさらに設定を書きたい場合には

if [ -f ${ARCH}/.bashrc_extra ]; then
	. ${ARCH}/.bashrc_extra
fi

とか書いて${ARCH}毎に書いておくと幸せになれるかも。

エスケープシーケンス in .bashrc

これはもう、ただ単に見てもらえれば分かると思います。

export CR="$(echo -ne '\r')"
export LF="$(echo -ne '\n')"
export TAB="$(echo -ne '\t')"
export ESC="$(echo -ne '\033')"
export COLOUR_BLACK="${ESC}[30m"
export COLOUR_RED="${ESC}[31m"
export COLOUR_GREEN="${ESC}[32m"
export COLOUR_YELLOW="${ESC}[33m"
export COLOUR_BLUE="${ESC}[34m"
export COLOUR_CYAN="${ESC}[35m"
export COLOUR_MAGENTA="${ESC}[36m"
export COLOUR_WHITE="${ESC}[37m"
export COLOUR_HIGHLIGHT_BLACK="${ESC}[30;1m"
export COLOUR_HIGHLIGHT_RED="${ESC}[31;1m"
export COLOUR_HIGHLIGHT_GREEN="${ESC}[32;1m"
export COLOUR_HIGHLIGHT_YELLOW="${ESC}[33;1m"
export COLOUR_HIGHLIGHT_BLUE="${ESC}[34;1m"
export COLOUR_HIGHLIGHT_CYAN="${ESC}[35;1m"
export COLOUR_HIGHLIGHT_MAGENTA="${ESC}[36;1m"
export COLOUR_HIGHLIGHT_WHITE="${ESC}[37;1m"
export COLOUR_DEFAULT="${ESC}[m"

わざわざ"\033"とか書くのめんどいよね、とか、33って何色?シアンって何番?みたいなプチめんどくささを減らします。
COLOURと英国式になってるのは別段深い理由があるわけではないです。
他に「COLORなんとか」みたいな環境変数があった場合には区別できて便利かも、程度。

PS1の記述 in .bashrc

PS1とか書くと、思わず我が家の最新ゲーム機である、某Play$tation のことを思い浮かべてしまうけれど、これはPrompt Stringのこと。
PS2,PS3,PSP,PS4と続くのだけど、普通はPS1ぐらいしか指定しないと思われ。
PS2は複数行入力の時の。「echo "hoge」まで打ってクォート閉じ忘れた時に出てくる"> "の部分。
PS3,PS4は存在すら覚えておく必要ないかも。


で、このPS1。凝ろうとするとやたらぐちゃぐちゃになってしまって分からなくなってくる。
加えて条件分岐までいれるともはやカオス。
そんなわけでPS1をすっきり(?)書く方法をば。

PS_USER="\[${COLOUR_YELLOW}\]\u\[${COLOUR_DEFAULT}\]"
PS_WORK="\[${COLOUR_HIGHLIGHT_WHITE}\]\W\[${COLOUR_DEFAULT}\]"

if [ -n "${PARTTY_SESSION}" ] ; then
	PS_HOST="\[${COLOUR_GREEN}\]${PARTTY_SESSION}!\[${COLOUR_DEFAULT}\]"
else
	PS_HOST="\[${COLOUR_GREEN}\]\h\[${COLOUR_DEFAULT}\]"
fi

if [ -n "${WINDOW}" ] ; then
	PS_SCREEN="\[${COLOUR_CYAN}\]#${WINDOW}\[${COLOUR_DEFAULT}\]"
else
	PS_SCREEN=""
fi

if [ -n "${SSH_CLIENT}" ] ; then
	PS_SSH="\[${COLOUR_MAGENTA}\]/$(echo ${SSH_CLIENT} | sed 's/ [0-9]\+ [0-9]\+$//g')\[${COLOUR_DEFAULT}\]"
else
	PS_SSH=""
fi

ATODE_FILE="${HOME}/.atode"
if [ -f "${ATODE_FILE}" ]; then
	PS_ATODE="\[${COLOUR_RED}\]:\$(cat ${ATODE_FILE} 2>/dev/null | wc -l)\[${COLOUR_DEFAULT}\]"
else
	PS_ATODE=""
fi

PS_HIST="\[${COLOUR_HIGHLIGHT_BLUE}\]\!\[${COLOUR_DEFAULT}\]"

export PS1="[${PS_USER}${PS_ATODE}@${PS_HOST}${PS_SCREEN}${PS_SSH} ${PS_HIST}:${PS_WORK}]\$ "

PSでの色指定はエスケープシーケンスの前後に"\["と"\]"が必要、という謎仕様で、この辺の糖衣でも書こうと思ったのですが、これで十分かな〜とか思ってそのまま書いてます。
PSはshell使いの個性なので色々いじってみるといいと思います。
上の例だと基本的には「[ (ユーザ名/黄色) @ (ホスト名/緑) (履歴番号/青) : (ワーキングディレクトリ/明るい白) ] \$ 」なのですが、

  • atodeコマンドのスタックがあるときは、その深さをユーザ名の後ろに赤で。
  • parttyのセッション中は、ホスト名の代わりにparttyのセッション名を。
  • screenを張っているときは、「#スクリーン番号」をホスト名の後ろにシアンで。
  • sshで入っているときは、アクセス元IPをさらにその後ろにマゼンダで。

という条件分岐を含んでいたりします。
なので、ssh先でscreenを張りつつparttyを開始して、かつatodeやることがたまっており、さらにやたら長い名前のディレクトリで作業をしているとひどいことになります。
まぁ、ほどほどに。
終了ステータスによって\$の色を変えてた時期があったのですが、気がついたら使えなくなりました。bash4にしたからかしら。
PSで$?を使いたいのだけどなぁ。

最後の番人 in .bashrc

いや、別に大したことではなくて、ファイル末尾に

return

って書いてあるだけなんですがね。
一時期うちの界隈では、ロックし忘れたまま席を立ったひとのマシンに、slをしこんではaliasですべてのコマンドをslにしてしまう、といういたずらがはやっていたのですが、このreturnを書くだけで.bashrcの末尾に何か追加されても大丈夫!という...。
そんな超プチ小ネタです。

.vimrc編

ここから.vimrcに入っていきます。
あまりなじみがない(であろう、と筆者が思っている)オプションを中心に紹介してみたいと思います。

vimdiffの挙動を変える in .vimrc

まずはvimdiffの挙動を変えるオプション : diffopt
デフォルトだとfiller(余剰部分がある方にあわせて空行をいれる)だけですが、

[]context
{n}[] :違いがある行の前後n行を表示して、残りをfoldする。記述なしで6行
icase
ignore case 大文字小文字を区別しない
iwhite
ignore whitespace whitespaceの数を考慮しない
horizontal
横にvimdiffる
vertical
縦にvimdiffる
[]foldcolumn
{n}[] :左側にn幅のfoldtreeを表示する。

などが指定できます。
ちなみに、一番最後のfoldcolumnはfoldの機能なのですが、(筆者の環境の場合)赤地に青などというアリエナイ配色になっているので、

highlight FoldColumn ctermbg=darkgray ctermfg=white

などという風に色を変えることをおすすめします。はい。

の挙動を変える in .vimrc

これは前にも書いたのですが再掲。
ノーマルモードコマンドのC-AとC-Xはカーソルの下の数字をインクリメント/デクリメントするのですが、0始まりの数字は8進数と認識してしまいます。
8進法なんてあまり使わない一方で、幅をそろえるために先頭に0を入れることは多々。
ということで、

set nrformats-=octal

でさっくり消してしまいましょう。
逆に、追加するとおいしいのが"alpha"。アルファベットをインクリメント/デクリメントできるようになります。
指定できるのは"alpha","octal"と16進数用の"hex"。
マクロと組み合わせるとウマウマです。

set nrformats+=alpha
カーソルの位置をわかりやすくする in .vimrc

最近ソースコード書きつつカーソルを見失うことが増えてきました...orz
そんなわけで最近お世話になっているのがcursorline。
カーソルのある行にアンダーラインを引いてくれます。
あと、同様にcursorcolumnというオプションもあります。
lineじゃなくて、column。ということでカーソルのある「列」を反転表示します。
何かには使える...かも?
あと、アンダーラインじゃいやだ、という場合には

highlight CursorLine cterm=inverse

などで、スタイルを変えられます。CursorColumnも同様。

画面分割の挙動を変える in .vimrc

自分はあまり画面分割を使わない人間なのですが、まわりでは結構使っているのを見かけます。
画面分割する際に、あたらしい窓が右に出るか左に出るか、あるいは上に出るか下に出るか。
細かいことだけど、結構気になるひともいるのでは?
ということで、splitrightオプションとsplitbelowオプション。
それぞれ分割時の新しい窓はそれぞれ、右、下に開かれます。当然noを頭につければその反対です。
能率も微妙に変わったり?


あわせていじりたいのが分割時のアクティブ/非アクティブでのステータスラインの配色。
カーソルが有るときとないときで微妙にステータスラインの文字色が変わるのですが、どうせ変わるならパッと見でわかるようにしたい。
と、いうことで

highlight StatusLine cterm=bold,reverse
highlight StatusLineNC cterm=bold

のように自由に変えることができます。
ちなみに、StatusLineとStatusLineNCで全く同じにすると、カーソルがある側のステータスラインのfillcharに"^"が使われるようになります。

インデント方法を変える in .vimrc

C言語系のインデントを変えるオプションにcinoptionsがあります。
実は筆者もこのオプションのすべてを試した訳ではないのですが、とりあえず、

set cinoptions=:0

が好き。
具体的には上の例ではswitch文における、"case HOGE:"のインデントを0にする、つまり"switch( hoge ) {"と"case HOGE:"の先頭が揃うようにインデントされるようになります。
詳しくは":help cinoptions-values"に具体例付きで書いてあるのですが、中括弧の位置とかかなり細かく指定できるようです。
vimのインデントスタイルが気にくわない!という方は一度試してみては?

全角スペースを可視化する in .vimrc

全角スペース大っ嫌い人間なので全角スペースは特別にhighlightしたい。
という場合に便利なのがこれ。

highlight ZenkakuSpace cterm=underline ctermbg=white ctermfg=blue
match ZenkakuSpace / /

という記述。ちなみに、スラッシュの間にその憎き全角スペースを書いておきます。
これは別に全角スペースだけに限らず、この文字はhighlightしたい、とか"TODO:"を目立つように、などにも使えます。
なかなか便利。

行末のスペースやタブ文字を可視化する in .vimrc

これも先ほどのと同じ方法でできないでもないですが、ここはlistchrasを使いましょう。
listchrasは行末のスペースやタブ文字のほか、行末、nbsp、nowrap時の左右に続く印を設定することができます。
個人的お気に入りな設定はこちら。

set listchars=tab:→\ ,trail:_,precedes:«,extends:»

多バイト文字ばりばり使いまくりでなんか気持ち悪いですが、その一方で、多バイト文字を使うことでソースコードに紛れてしまうことがない、というメリットもあったりします。
ついでにhighlightでNonText,SpecialKeyの配色を変えておくと吉です。
NonTextはeol(行末)、precedes(左に続く)、extends(右に続く)を、
SpecialKeyはnbsp(改行しない空白)、tab(タブ文字)、trail(行末のスペース)を、配色替えすることができます。


ちなみに多バイト文字はdigraph機能使うと楽に入力できます。
例えば"→"なら^K - >、"«"なら^K < <、ギリシャ文字なら^K a *などで入力できます。
くわしくは":help digraph"!!!

自動バックアップ in .vimrc

毎度おなじみですね。再掲か再々掲ぐらい?

set backup
set backupdir=~/.backup/vim
set viewdir=~/.backup/view
if has( "autocmd" )
	autocmd BufWritePre * call UpdateBackupFile()
	function! UpdateBackupFile()
		let dir = strftime("~/.backup/vim/%Y/%m/%d", localtime())
		if !isdirectory(dir)
			let retval = system("mkdir -p ".dir)
			let retval = system("chown goth:staff ".dir)
		endif
		exe "set backupdir=".dir
		unlet dir
		let ext = strftime("%H_%M_%S", localtime())
		exe "set backupext=.".ext
		unlet ext
	endfunction
endif

上の例では~/.backup/vim以下に年月日でディレクトリを掘って、かつバックアップファイル名の後ろに時分秒をくっつけてバックアップを作るようにします。
:wする度にバックアップファイルが増えるのが難点ですが、非常に便利です。
秒単位はさすがにやりすぎ、と言う場合には"%H_%M_%S"を"%H_%M"にするなど適宜変更できます。