なんとなく自分の開発環境を紹介したくなったので、書きます。
全てにコメントしているとキリがないので、独断と偏見によって選んだポイントの紹介もしていきます。
環境はTmux + Zsh + Vimです。私の三種の神器です。
リポジトリ: s4kr4/dotfiles
Vim
設定ファイル群は~/.vim
フォルダにまとめて配置しているので、.vimrc
内では、GVim/Cygwin用にruntimepath
の追加をする以外は特に何もしていません。
if has('win32')|| has('win64')|| has('win32unix')setruntimepath+=$HOME/.vimsetruntimepath+=$HOME/.vim/afterendif
runtime! init/*.vim
runtime! functions.vim
~/.vim
以下のファイル構成はこんな感じです。
~/.vim/init/*.vim
設定をなんとなく分類して管理しています。
読み込み順は、ファイル名に数字をつけることで制御しています。
10_dein.vim
Shougo/dein.vimとそのプラグインをインストールするスクリプトです。
20_general.vim
一般的な設定を記述しています。
ファイルエンコード
setencoding=utf-8" バッファ内のエンコードsetfileencoding=utf-8" ファイル書き込み時のエンコードscriptencoding utf-8" Vim Scriptで使用するエンコード
Neocompleteでの補完時、プレビューウィンドウを表示しない
デフォルトだと、completeopt
にpreview
が含まれていて、補完時に関数の説明等が表示されます。
これがうっとおしいので、menuone
のみの設定に変更しています。
setcompleteopt=menuone
split展開方向
setsplitbelow" 上下分割時に、下側にファイルを開くsetsplitright" 左右分割時に、右側にファイルを開く
バックアップファイルやスワップファイルの作成を抑制
Vimでファイルを編集していると、ディレクトリに変なファイルが勝手に作成されます。
ファイル名末尾に~
が付加されたものがバックアップファイル、.swp
が付加されたものがスワップファイル、.un~
が付加されたものがundoファイルです。
私はどれも特に必要を感じていないので、全て無効化しています。
setnobackup" バックアップファイルを作成しないsetnowritebackup" 上書き成功時にバックアップファイルを破棄setnoswapfile" スワップファイルを作成しないsetnoundofile" undoファイルを作成しない
括弧対応ジャンプを強化
Vimにはデフォルトでカーソル下の括弧に対応する括弧へジャンプする機能がありますが、Vimにデフォルトで同梱されているmatchit.vim
を読み込むことで、この機能を強化することができます。
HTMLやXMLのタグ、Rubyのdef~end等もジャンプできるようになります。
runtime macros/matchit.vim
30_edit.vim
編集時の動作に関する設定を記述しています。
ファイル選択時のタブ補完強化
setwildmenuwildmode=list:full
未保存状態のバッファを切り替え可能にする
例えばfoo.txt
を編集中、一時的にbar.txt
を閲覧したくなったとき、未保存状態で:e bar.txt
等と入力すると以下のようなメッセージが出て、バッファを切り替えることができません。
以下の設定を追加することで、バッファの切替が可能になります。
sethidden
ちなみに、裏に未保存のバッファがある状態でVimを終了しようとすると、ちゃんと警告してくれます。
40_keymap.vim
各種keymapを設定しています。
VimScriptのhas
を使って、環境ごとに設定するkeymapを変化させたりしています。
Shift + Enter でノーマル状態のまま改行挿入 (GVim)
このkeymapはGVimでしか動作しないようです。
if has("gui_running")nnoremap<silent><S-CR> :<C-u>call append(expand('.'),'')<CR>jendif
;
, :
キーの入れ替え (macOS)
英字キーボードのMacBookを使用していることと、;
よりも :
の使用頻度が高いことから、両者の入力を入れ替えています。
if has("mac")nnoremap ; :nnoremap : ;endif
90_visual.vim
見た目に関する設定を記述しています。
ステータスライン
このあたりを参考にして、色々表示しています。%{}
で括るとコマンドの結果を表示できるので、tpope/vim-fugitiveでGitのブランチを表示したり、ファイルのエンコードを表示したりしています。
setstatusline=%F%m%r%h%w%{fugitive#statusline()}%=[TYPE:%Y][FMT:%{&fileformat}][ENC:%{&fileencoding}][LINE:%l/%L]
GUIパーツの非表示化 (GVim)
以前書いた以下の記事のとおりです。
全角スペース・行末スペースの可視化
プログラマたるもの、ソースコード中の無駄なスペースや全角スペースは殲滅していかなければなりません。
以下の設定で、それらを赤くハイライトしています。
augroup highlightSpace
autocmd!
autocmd Colorscheme * hi IdeographicSpace term=underline ctermbg=DarkRed guibg=DarkRed
autocmd VimEnter,WinEnter * match IdeographicSpace / \|\s\+$/
augroup END
~/.vim/after/indent/*.vim
ファイルタイプごとのインデント設定です。
例えばRubyのインデントはスペース2つなので、ruby.vim
に以下を記述しています。tabstop
, softtabstop
, shiftwidth
が紛らわしいですが、それぞれ
- tabstop => タブ文字の表示幅
- softtabstop => TabキーやBackSpaceキー等でカーソルが動く幅
- shiftwidth => autoindentで挿入される幅
という意味です。
setlocalexpandtabsetlocaltabstop=2setlocalsofttabstop=2setlocalshiftwidth=2
~/.vim/ftdetect/*.vim
Vimはたいていのファイルタイプを自動で認識してくれますが、拡張子からファイルタイプを推測できないものはここで指定します。
例えば*.themeファイルをPHPとして読み込みたい場合、theme.vim
に以下のように記述しておきます。
autocmd BufRead,BufNewFile *.theme setfiletype php
~/.vim/{dein,dein_lazy}.toml
dein.vim
で読み込むプラグインリストです。dein.toml
には、Vim起動時に読み込むプラグインを書いています。
また、dein_lazy.toml
には、ファイルタイプなどに合わせて遅延読み込みするプラグインを書いています。
各プラグインの個別設定は~/.vim/plugins/*.vim
に配置し、こんな感じでプラグイン読み込み時のhook_add
フックを利用して読み込んでいます。
[[plugins]]repo='terryma/vim-multiple-cursors'hook_add='source$HOME/.vim/plugins/vim-multiple-cursors.vim'
dein.toml
ファイルタイプにかかわらず、必ず読み込むプラグイン
- カラースキーム
chriskempson/vim-tomorrow-theme
- カラースキーム
- カラースキーム
- 同じ名前の変数や、正規表現にマッチする複数箇所を同時編集できる便利プラグイン
" 複数箇所の同時編集時、NeoCompleteを無効にするfunction! Multiple_cursors_before()if exists(':NeoCompleteLock')==2
exe 'NeoCompleteLock'
echo 'Disabled Neocomplete'endifendfunctionfunction! Multiple_cursors_after()if exists(':NeoCompleteUnlock')==2
exe 'NeoCompleteUnlock'
echo 'Disabled Neocomplete'endifendfunction
- Vim内からgitコマンド各種を使える
- Vimに独自のmode(submode)を追加できる
" submodeから抜けるまでの時間letg:submode_timeoutlen =300" Space + >>>...等で分割ウィンドウを連続リサイズcall submode#enter_with('winsize','n','s','<Space>>','<C-w>>')call submode#enter_with('winsize','n','s','<Space><','<C-w><')call submode#enter_with('winsize','n','s','<Space>+','<C-w>-')call submode#enter_with('winsize','n','s','<Space>-','<C-w>+')call submode#map('winsize','n','s','>','<C-w>>')call submode#map('winsize','n','s','<','<C-w><')call submode#map('winsize','n','s','+','<C-w>-')call submode#map('winsize','n','s','-','<C-w>+')" Space + hhh...等で分割ウィンドウを連続移動call submode#enter_with('winmove','n','s','<Space>h','<C-w>h')call submode#enter_with('winmove','n','s','<Space>j','<C-w>j')call submode#enter_with('winmove','n','s','<Space>k','<C-w>k')call submode#enter_with('winmove','n','s','<Space>l','<C-w>l')call submode#map('winmove','n','s','h','<C-w>h')call submode#map('winmove','n','s','j','<C-w>j')call submode#map('winmove','n','s','k','<C-w>k')call submode#map('winmove','n','s','l','<C-w>l')
- %s等で一括置換するとき、どこが置換されるのかが動的にハイライトされる
- ファイルタイプを判別して自動でコメントアウト/コメントインできる
" Ctrl + Cの連続でコメントをトグル
nmap <C-c><C-c><Plug>(caw:hatpos:toggle)
vmap <C-c><C-c><Plug>(caw:hatpos:toggle)
- thinca/vim-splash
- Vim起動時に好きなAAを表示できる。
" AAが書かれているファイルを指定letg:splash#path= $HOME."/.vim/splash/helloworld.txt"
_ _ _ _ _ _ _|||| ___||| ___ __ _____ _ __|| __||||||_||/ _ \ | |/ _ \ \ \ /\ // _ \| '__| |/ _ |||| _ | __/ | | (_) | _ \ V V /(_)||||(_|||_||_||_|\___|_|_|\___/ | ) \_/\_/ \___/|_||_|\__,_|(_)|/
s4kr4
github : github.com/s4kr4
qiita : qiita.com/s4kr4
twitter : @s4kr4m4
dein_lazy.toml
状況に応じて読み込むプラグイン
- pug編集用
- json編集用
" JSONファイルでダブルクォーテーションを表示letg:vim_json_syntax_conceal =0
- CSS3シンタックス強化
- TypeScript編集用
- HTMLを超楽に入力できる
- JSX編集用
" 拡張子が.jsのファイルでもJSXシンタックスを有効にするletg:jsx_ext_required =0
- Twig編集用
- HTML5シンタックス強化
- JavaScriptシンタックス強化
" flowの文法対応letg:javascript_plugin_flow =1
- Vue.js開発用
- 言わずと知れた補完プラグイン
" Use neocompleteletg:neocomplete#enable_at_startup =1" Use smartcaseletg:neocomplete#enable_smart_case =1" Start completion with 2 charsletg:neocomplete#auto_completion_start_length =2" Not ignore underbarsletg:neocomplete#enable_underbar_completion =1" Number of completion listletg:neocomplete#max_list =30if!exists('g:neocomplete#keyword_patterns')letg:neocomplete#keyword_patterns = {}endif" Ignore Japaneseletg:neocomplete#keyword_patterns['default'] ='\h\w*'" Use <TAB> to move listinoremap<expr><TAB> pumvisible() ? "\<C-n>" : "\<TAB>"inoremap<expr><S-TAB> pumvisible() ? "\<C-p>" : "\<S-TAB>"" Enable omni completion.
augroup SetOmniCompletionSetting
autocmd FileType css setlocalomnifunc=csscomplete#CompleteCSS
autocmd FileType html,markdown setlocalomnifunc=htmlcomplete#CompleteTags
autocmd FileType javascript setlocalomnifunc=javascriptcomplete#CompleteJS
autocmd FileType python setlocalomnifunc=pythoncomplete#Complete
autocmd FileType php setlocalomnifunc=phpcomplete#CompletePHP
autocmd FileTyperubysetlocalomnifunc=rubycomplete#Complete
autocmd FileType xml setlocalomnifunc=xmlcomplete#CompleteTags
augroup END" Enable heavy omni completion.if!exists('g:neocomplete#sources#omni#input_patterns')letg:neocomplete#sources#omni#input_patterns = {}endif
- netcomplete.vimでスニペットを扱える
- netsnippetに便利スニペット追加
- Slim編集用
Zsh
Zshの設定ファイル群は~/.zsh
に配置しています。
Vimと同様に、~/.zshrc
を起点に順次読み込みます。
if[ -z "${DOTPATH:-}"];thenDOTPATH=~/.dotfiles;export DOTPATHfi# 設定ファイル順次読み込みfor file in "${HOME}"/.zsh/init/*.zsh;do
. "$file"done# zplugはTmux内でだけ読み込むif[[ -n "$TMUX"]];then
. "${HOME}"/.zsh/zplug.zshfi# Tmux起動if has tmux;then
tmuxxfi
Zshのプラグイン管理には zplulg/zplugを使用していますが、Tmux外でプラグインを読み込むのは時間の無駄なので、Tmux内でZshを起動したときのみプラグインを読み込むようにしています。
~/.zsh/init/*.zsh
~/.zsh/init/10_env.zsh
環境変数の設定を行います。
自作スクリプトのPATHを通す
自分で書いたスクリプトは~/bin
に置くようにしているので、そこにPATHを通します。
exportPATH=$PATH:$HOME/bin
anyenvのPATHを通す
各envの管理に riywo/anyenvを使っているので、こちらのPATHを通します。
Tmuxと併用すると問題があるようなので、公式のREADME通りではなく下記のようにしています。
if[[ -d ${HOME}/.anyenv ]];thenPATH="$HOME/.anyenv/bin:$PATH"eval"$(anyenv init -)"for d in `ls $HOME/.anyenv/envs`;doexportPATH="$HOME/.anyenv/envs/$d/shims:$PATH"donefi
ローカル設定用のPATHを通す
どんな環境でも使うようなスクリプトや環境変数はdotfilesで管理していますが、会社や家だけで使う設定まで管理下に入れると気持ち悪いので、そうしたものは管理下から外しています。
以下の設定により、ローカル限定のスクリプトを~/bin_local
に配置、環境変数設定を~/.env_local.zsh
に書くことで、それぞれが存在するときだけ読み込ませることができます。
if[[ -e ${HOME}/bin_local ]];thenPATH="$HOME/bin_local:$PATH"fiif[[ -e ${HOME}/.env_local.zsh ]];thensource${HOME}/.env_local.zshfi
~/.zsh/init/20_functions.zsh
Zsh内で使いたい関数をまとめて書いています。
例えば、作ったディレクトリにそのまま移動できるmkcd
関数があります。
...
mkcd(){
mkdir -p "$1"[$? -eq 0]&&cd"$1"}
...
~/.zsh/init/30_aliases.zsh
エイリアスを登録します。
ls
のカラー設定(OS別)
ls
コマンドの結果に色を付けます。
macOSとそれ以外ではls
に色を付けるためのオプションが異なるため、OS別に分岐しています。
case"${OSTYPE}" in
darwin*)aliasls='ls -G';;
*)aliasls='ls --color=auto';;esac
ローカル設定を読み込む
~/.zsh/init/10_env.zsh
と同様に、特定の環境でのみ使用したいエイリアスを~/.local_aliases
に登録し、ここで読み込みます。
if[[ -e ${HOME}/.local_aliases ]];thensource${HOME}/.local_aliasesfi
~/.zsh/init/40_keybinds.zsh
Zshのキーバインド設定です。
vi
風のキーバインドを基本に、emacs
風の操作を多少混ぜた感じにしています。
bindkey -d
bindkey -v
bindkey '^A' beginning-of-line
bindkey '^E' end-of-line
bindkey '^N' down-line-or-history
bindkey '^P' up-line-or-history
bindkey -M viins '^B' backward-char
bindkey -M viins '^F' forward-char
~/.zsh/init/80_others.zsh
その他の雑多な設定を詰め込んでいます。
ls
の色設定
ls
で表示されるファイルの色設定です。
環境変数によって設定できますが、GNU系とBSD系で参照する環境変数が違うので、同じ色になるようにしています。
また、ls
のTAB補完で表示されるファイルにも色を付けるよう、zstyleを設定しています。
# GNU系exportLS_COLORS='no=00:fi=00:di=01;36:ln=36:pi=31:so=33:bd=44;37:cd=44;37:ex=01;32:mi=00:or=36'# BSD系exportLSCOLORS=GxgxdxbxCxegedabagacad# TAB補完時に色表示
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
ここにあるテストスクリプトで確認すると、こんな感じの色になります。
TAB補完強化
TAB補完の強化設定です。
# ファイル名補完時、大文字/小文字を区別しない
zstyle ':completion:*' matcher-list '''m:{a-z}={A-Z}''+m:{a-z}={A-Z}'
# "kill [TAB]" でプロセスIDを補完する
zstyle ':completion:*:processes'command"ps au"
zstyle ':completion:*:processes' menu yes select=2
# オプション補完時の、オプション/説明のセパレータ
zstyle ':completion:*' list-separator '-->'
区切り文字設定
Ctrl+Wで単語を消すとき等の区切り文字を設定します。
zstyle ':zle:*' word-chars ' /=;@:{}[]()<>,|.'
zstyle ':zle:*' word-style unspecified
cd
コマンド省略
ディレクトリ移動のたびにcd
なんて打ってられないので、auto_cd
を有効にして、ディレクトリ名のみで移動できるようにします。
上記のファイル名補完と合わせると、かなり楽になります。
setopt auto_cd
Shell内のVimで Ctrl + S
、Ctrl + Q
を使用可能にする
GVimでは問題ないのですが、Shell内でVimを立ち上げるとCtrl + S
、Ctrl + Q
等のキーバインドがShellに食われて使用できなくなります。
以下の設定でそれを抑制できます。
stty -ixon
zmv有効化
解説は他サイトに譲りますが、mv
コマンドをzshで拡張したzmv
が超便利なので有効化しておきます。
autoload -Uz zmv
参考: zsh の zmv を使って簡単に複数ファイルを一括リネームする
~/.zsh/init/90_visual.zsh
見た目の設定を書いています。
プロンプト
状況に応じて、プロンプトを出し分けています。
法則は以下のとおりです。
- ユーザー名
- 一般ユーザ => 緑
- root => 赤
- ホスト名+カレントディレクトリ
- ローカル => 青
- リモート => オレンジ
- 末尾記号
- 挿入(通常)モード =>
>
- コマンドモード =>
|
- 挿入(通常)モード =>
- カレントディレクトリの深さ
- 5より浅い場合 => そのまま表示
- 5以上深い場合 => 末尾の3つのみ表示、それ以前は
...
で省略
color_red="%{^[[38;5;196m%}"color_green="%{^[[38;5;046m%}"color_blue="%{^[[38;5;045m%}"color_orange="%{^[[38;5;202m%}"color_gray="%{^[[38;5;242m%}"color_end="%{^[[0m%}"case${UID} in# root0)PROMPT_USER="${color_red}%n${color_end}";;# other
*)PROMPT_USER="${color_green}%n${color_end}";;esacif[ -n "${REMOTEHOST}${SSH_CONNECTION}"];then# remote connectionPROMPT_PATH_COLOR="${color_orange}"else# localPROMPT_PATH_COLOR="${color_blue}"fiPROMPT_PATH="%(5~,.../%3~,%~)"PROMPT_STRING="${PROMPT_USER}@${PROMPT_PATH_COLOR}%m:${PROMPT_PATH}${color_end}"function zle-line-init zle-keymap-select {case$KEYMAP in
vicmd|visual)SUFFIX="|";;
*)SUFFIX=">";;esacPROMPT=$'\n'"${PROMPT_STRING}${SUFFIX} "
zle reset-prompt}
zle -N zle-line-init
zle -N zle-keymap-select
右プロンプト表示
ターミナル番号と時間を表示しています。
RPROMPT="${color_gray}%y [%D{%m/%d} %*]${color_end}"
~/.zsh/zplug.zsh
zplulg/zplugで管理するプラグインのリストです。
if[[ ! -e ~/.zplug/init.zsh ]];then
git clone https://github.com/zplug/zplug ~/.zplugfisource ~/.zplug/init.zsh
zplug "zplug/zplug"# コマンドに色をつける
zplug "zsh-users/zsh-syntax-highlighting", \
defer:2# cd便利化
zplug "b4b4r07/enhancd", \
use:init.sh# HTTPステータスコードの確認に便利
zplug "b4b4r07/http_code"# インタラクティブフィルタ
zplug "jhawthorn/fzy", \
as:command, \
rename-to:fzy, \
hook-build:"make && sudo make install"# historyからコマンドをサジェストさせる
zplug "zsh-users/zsh-autosuggestions"if[[$OSTYPE== *darwin* ]];then# GitHub 操作をshellから可能にする
zplug "github/hub", \
from:gh-r, \
as:command, \
use:"*darwin*amd64*"fi
auto_cd 時も enhancd の候補に追加する
b4b4r07/enhancdは、過去に移動したディレクトリの候補リストからインタラクティブに選択し、移動できるプラグインです。
大変便利なのですが、上述のauto_cd
を使ってディレクトリ移動した際は候補リストに挿入されないようなので、zsh-hook
を使用して無理やり突っ込んでいます。
if zplug check --verbose "b4b4r07/enhancd";then
add-zsh-hook chpwd __enhancd::cd::afterfi
Tmux
~/.tmux.conf
よくローカル/リモートでTmux
を2重に立ち上げて作業をしているのですが、設定ファイル内で条件分岐等を行う術が無いようなので、ローカル用とリモート用でファイルを分けています。
実際に使うときは、~/.tmux.conf
をそれぞれに対するSymlinkとすることで、リネームの手間を省いています。
# ローカル
~/.tmux.conf -> ~/.dotfiles/.tmux.conf# リモート
~/.tmux.conf -> ~/.dotfiles/.tmux.remote.conf
下の画像は、ローカルTmuxのウィンドウでタブを3つ開き、そのうち1つのタブでサーバにsshして、サーバ内のTmuxでまたタブを3つ開いている様子です。
キーバインド
ローカル/リモートでプレフィックスキーが被らないようにしています。
set-option -g prefix C-x
bind-key C-x send-prefix
set-option -g prefix C-r
bind-key C-r send-prefix
ローカル/リモートでステータスバーの色変更
zsh
のプロンプトと同様に、Tmux
のステータスバーも色分けをしています。
色味も統一して、青系とオレンジ系にしています。
set-option -g status-left " #[bg=colour021,fg=white] Host:#h #[bg=colour027,fg=white] Session:#S #[bg=colour033,fg=black] Window:#W(#P) #[bg=default,fg=default]"
set-option -g status-right "#(tmux-network)#[bg=colour021,fg=white] %Y-%m-%d (%a) %H:%M:%S #[bg=default,fg=default]"
set-option -g status-left " #[bg=colour202,fg=black] Host:#h #[bg=colour208,fg=black] Session:#S #[bg=colour172,fg=black] Window:#W(#P) #[bg=default,fg=default]"
set-option -g status-right "#(tmux-network)#[bg=colour202,fg=black] %Y-%m-%d (%a) %H:%M:%S #[bg=default,fg=default]"
ネットワーク状況を表示 (ローカル/リモート共通)
以前 Cygwinでネットワーク状況を表示する記事を書きましたが、その後macOSにも対応しています。OSで分岐させて、こちらを参考にスクリプト(tmux-network)を修正しました。
set-option -g status-left-length 60
set-option -g status-right-length 60
set-option -g status-left " #[bg=colour202,fg=black] Host:#h #[bg=colour208,fg=black] Session:#S #[bg=colour172,fg=black] Window:#W(#P) #[bg=default,fg=default]"
set-option -g status-right "#(tmux-network)#[bg=colour202,fg=black] %Y-%m-%d (%a) %H:%M:%S #[bg=default,fg=default]"
おわり
記事を書くにあたって、自分でも忘れていた設定を思い出したり、不要な設定を削除する等、いろいろ整理できてよかったです。