なんとなく自分の開発環境を紹介したくなったので、書きます。
全てにコメントしているとキリがないので、独断と偏見によって選んだポイントの紹介もしていきます。
環境はTmux + Zsh + Vimです。私の三種の神器です。
リポジトリ: s4kr4/dotfiles
Vim
設定ファイル群は~/.vim
フォルダにまとめて配置しているので、.vimrc
内では、GVim/Cygwin用にruntimepath
の追加をする以外は特に何もしていません。
if has('win32') || has('win64') || has('win32unix')
set runtimepath+=$HOME/.vim
set runtimepath+=$HOME/.vim/after
endif
runtime! init/*.vim
runtime! functions.vim
~/.vim
以下のファイル構成はこんな感じです。
~/.vim/init/*.vim
設定をなんとなく分類して管理しています。
読み込み順は、ファイル名に数字をつけることで制御しています。
10_dein.vim
Shougo/dein.vim とそのプラグインをインストールするスクリプトです。
20_general.vim
一般的な設定を記述しています。
ファイルエンコード
set encoding=utf-8 " バッファ内のエンコード
set fileencoding=utf-8 " ファイル書き込み時のエンコード
scriptencoding utf-8 " Vim Scriptで使用するエンコード
Neocompleteでの補完時、プレビューウィンドウを表示しない
デフォルトだと、completeopt
にpreview
が含まれていて、補完時に関数の説明等が表示されます。
これがうっとおしいので、menuone
のみの設定に変更しています。
set completeopt=menuone
split展開方向
set splitbelow " 上下分割時に、下側にファイルを開く
set splitright " 左右分割時に、右側にファイルを開く
バックアップファイルやスワップファイルの作成を抑制
Vimでファイルを編集していると、ディレクトリに変なファイルが勝手に作成されます。
ファイル名末尾に~
が付加されたものがバックアップファイル、
.swp
が付加されたものがスワップファイル、
.un~
が付加されたものがundoファイルです。
私はどれも特に必要を感じていないので、全て無効化しています。
set nobackup " バックアップファイルを作成しない
set nowritebackup " 上書き成功時にバックアップファイルを破棄
set noswapfile " スワップファイルを作成しない
set noundofile " undoファイルを作成しない
括弧対応ジャンプを強化
Vimにはデフォルトでカーソル下の括弧に対応する括弧へジャンプする機能がありますが、Vimにデフォルトで同梱されているmatchit.vim
を読み込むことで、この機能を強化することができます。
HTMLやXMLのタグ、Rubyのdef~end等もジャンプできるようになります。
runtime macros/matchit.vim
30_edit.vim
編集時の動作に関する設定を記述しています。
ファイル選択時のタブ補完強化
set wildmenu wildmode=list:full
未保存状態のバッファを切り替え可能にする
例えばfoo.txt
を編集中、一時的にbar.txt
を閲覧したくなったとき、未保存状態で:e bar.txt
等と入力すると以下のようなメッセージが出て、バッファを切り替えることができません。
以下の設定を追加することで、バッファの切替が可能になります。
set hidden
ちなみに、裏に未保存のバッファがある状態で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>j
endif
;
, :
キーの入れ替え (macOS)
英字キーボードのMacBookを使用していることと、;
よりも :
の使用頻度が高いことから、両者の入力を入れ替えています。
if has("mac")
nnoremap ; :
nnoremap : ;
endif
90_visual.vim
見た目に関する設定を記述しています。
ステータスライン
このあたりを参考にして、色々表示しています。
%{}
で括るとコマンドの結果を表示できるので、tpope/vim-fugitive でGitのブランチを表示したり、ファイルのエンコードを表示したりしています。
set statusline=%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で挿入される幅
という意味です。
setlocal expandtab
setlocal tabstop=2
setlocal softtabstop=2
setlocal shiftwidth=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'
endif
endfunction
function! Multiple_cursors_after()
if exists(':NeoCompleteUnlock')==2
exe 'NeoCompleteUnlock'
echo 'Disabled Neocomplete'
endif
endfunction
-
- Vim内からgitコマンド各種を使える
-
- Vimに独自のmode(submode)を追加できる
" submodeから抜けるまでの時間
let g: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が書かれているファイルを指定
let g: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ファイルでダブルクォーテーションを表示
let g:vim_json_syntax_conceal = 0
-
- CSS3シンタックス強化
-
- TypeScript編集用
-
- HTMLを超楽に入力できる
-
- JSX編集用
" 拡張子が.jsのファイルでもJSXシンタックスを有効にする
let g:jsx_ext_required = 0
-
- Twig編集用
-
- HTML5シンタックス強化
-
- JavaScriptシンタックス強化
" flowの文法対応
let g:javascript_plugin_flow = 1
-
- Vue.js開発用
-
- 言わずと知れた補完プラグイン
" Use neocomplete
let g:neocomplete#enable_at_startup = 1
" Use smartcase
let g:neocomplete#enable_smart_case = 1
" Start completion with 2 chars
let g:neocomplete#auto_completion_start_length = 2
" Not ignore underbars
let g:neocomplete#enable_underbar_completion = 1
" Number of completion list
let g:neocomplete#max_list = 30
if !exists('g:neocomplete#keyword_patterns')
let g:neocomplete#keyword_patterns = {}
endif
" Ignore Japanese
let g:neocomplete#keyword_patterns['default'] = '\h\w*'
" Use <TAB> to move list
inoremap <expr><TAB> pumvisible() ? "\<C-n>" : "\<TAB>"
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<S-TAB>"
" Enable omni completion.
augroup SetOmniCompletionSetting
autocmd FileType css setlocal omnifunc=csscomplete#CompleteCSS
autocmd FileType html,markdown setlocal omnifunc=htmlcomplete#CompleteTags
autocmd FileType javascript setlocal omnifunc=javascriptcomplete#CompleteJS
autocmd FileType python setlocal omnifunc=pythoncomplete#Complete
autocmd FileType php setlocal omnifunc=phpcomplete#CompletePHP
autocmd FileType ruby setlocal omnifunc=rubycomplete#Complete
autocmd FileType xml setlocal omnifunc=xmlcomplete#CompleteTags
augroup END
" Enable heavy omni completion.
if !exists('g:neocomplete#sources#omni#input_patterns')
let g:neocomplete#sources#omni#input_patterns = {}
endif
-
- netcomplete.vimでスニペットを扱える
-
- netsnippetに便利スニペット追加
-
- Slim編集用
Zsh
Zshの設定ファイル群は~/.zsh
に配置しています。
Vimと同様に、~/.zshrc
を起点に順次読み込みます。
if [ -z "${DOTPATH:-}" ]; then
DOTPATH=~/.dotfiles; export DOTPATH
fi
# 設定ファイル順次読み込み
for file in "${HOME}"/.zsh/init/*.zsh; do
. "$file"
done
# zplugはTmux内でだけ読み込む
if [[ -n "$TMUX" ]]; then
. "${HOME}"/.zsh/zplug.zsh
fi
# Tmux起動
if has tmux; then
tmuxx
fi
Zshのプラグイン管理には zplulg/zplug を使用していますが、Tmux外でプラグインを読み込むのは時間の無駄なので、Tmux内でZshを起動したときのみプラグインを読み込むようにしています。
~/.zsh/init/*.zsh
~/.zsh/init/10_env.zsh
環境変数の設定を行います。
自作スクリプトのPATHを通す
自分で書いたスクリプトは~/bin
に置くようにしているので、そこにPATHを通します。
export PATH=$PATH:$HOME/bin
anyenvのPATHを通す
各envの管理に riywo/anyenv を使っているので、こちらのPATHを通します。
Tmuxと併用すると問題があるようなので、公式のREADME通りではなく下記のようにしています。
if [[ -d ${HOME}/.anyenv ]]; then
PATH="$HOME/.anyenv/bin:$PATH"
eval "$(anyenv init -)"
for d in `ls $HOME/.anyenv/envs`; do
export PATH="$HOME/.anyenv/envs/$d/shims:$PATH"
done
fi
ローカル設定用のPATHを通す
どんな環境でも使うようなスクリプトや環境変数はdotfilesで管理していますが、会社や家だけで使う設定まで管理下に入れると気持ち悪いので、そうしたものは管理下から外しています。
以下の設定により、ローカル限定のスクリプトを~/bin_local
に配置、環境変数設定を~/.env_local.zsh
に書くことで、それぞれが存在するときだけ読み込ませることができます。
if [[ -e ${HOME}/bin_local ]]; then
PATH="$HOME/bin_local:$PATH"
fi
if [[ -e ${HOME}/.env_local.zsh ]]; then
source ${HOME}/.env_local.zsh
fi
~/.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*)
alias ls='ls -G'
;;
*)
alias ls='ls --color=auto'
;;
esac
ローカル設定を読み込む
~/.zsh/init/10_env.zsh
と同様に、特定の環境でのみ使用したいエイリアスを~/.local_aliases
に登録し、ここで読み込みます。
if [[ -e ${HOME}/.local_aliases ]]; then
source ${HOME}/.local_aliases
fi
~/.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系
export LS_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系
export LSCOLORS=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
# root
0)
PROMPT_USER="${color_red}%n${color_end}"
;;
# other
*)
PROMPT_USER="${color_green}%n${color_end}"
;;
esac
if [ -n "${REMOTEHOST}${SSH_CONNECTION}" ]; then
# remote connection
PROMPT_PATH_COLOR="${color_orange}"
else
# local
PROMPT_PATH_COLOR="${color_blue}"
fi
PROMPT_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=">"
;;
esac
PROMPT=$'\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 ~/.zplug
fi
source ~/.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::after
fi
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]"
おわり
記事を書くにあたって、自分でも忘れていた設定を思い出したり、不要な設定を削除する等、いろいろ整理できてよかったです。