MacOS10.11環境構築: AnacondaとDein.vimでPowerline

  • 27
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

春、新しいiMac

久しぶりにEl Capitanをゼロから環境構築したのでメモ。

想定ユーザ

  • Macにはそこそこ慣れてる
  • そこそこトレンドに乗れてれば超最新でなくてもOK
  • Pythonをサクッと使いたい
    • pyenvとかVirtualenvは面倒だけどPySideJupyterは使いたい、的な
  • Zsh派
  • Vim派

基本方針

  • アプリケーションのインストールはなるべくHomebrew+Caskで
  • Vimのパッケージ管理は話題のDein.vim
  • Python周りはAnacondaに任せた
  • 統合されたPowerlineで見た目も綺麗に
  • dotfilesを他のマシンで使いまわしても手間がなるべく増えないように心がける

手順

Homebrew+Caskのインストール

散々既出なので詳細割愛。

$ xcode-select --install
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

今回はまっさらなEl Capitanへのインストールだったので、何も考えずに公式通り。
Yosemiteからのアップデート時にはシステム保護機能"Rootless"に要注意。

Zshのインストール

散々既出なので(rya

$ brew install zsh --without-etcdir
$ brew install z zsh-completions zsh-history-substring-search zsh-syntax-highlighting
$ sudo echo "/usr/local/bin/zsh" >> /etc/shells
$ chsh -s /usr/local/bin/zsh

iTerm2のインストール

Beta版で使える"Shell Integration"が素敵だけど、
基本方針1「アプリケーションのインストールはなるべくHomebrew+Caskで」に遵守。

$ brew cask install iTerm2

pyenvとAnacondaのインストール(2016/03/24追記)

そもそも、ゼロから環境構築しようと思ったのはこの記事を読んだから。
データサイエンティストを目指す人のpython環境構築 2016 - Qiita

AnacondaがHomebrewの環境を壊す可能性があるので、pyenvをかませる。
以後の仮想環境はAnacondaで設定するので、pyenvするのはこの1回きり。

$ brew install pyenv
$ pyenv install anaconda3-2.5.0
$ pyenv global anaconda3-2.5.0
$ pyenv rehash

MacBookAirなどで容量逼迫してるならMinicondaでも良いかも。

Vimのインストール

Dein.vimは7.4以上(またはNeoVim)でなければいけないので入れ直す。

$ brew install lua luajit
$ brew install vim --override-system-vi --with-lua --with-luajit --with-python3

途中、依存するpythonが勝手にインストールされるが、AnacondaのPythonを優先参照するように.zshrcを書き換えるので問題なし。
※ 記事末に.zshrcを全文晒します。
それまでは下記を実行しておく。不安な人は都度python -Vして確かめながら進めてください。

$ export PATH=~/anaconda3/bin:"$PATH"

Dein.vimのインストール

Shougoさんに感謝しつつ、下記を実行。

$ curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh
$ sh ./installer.sh ~/.vim/dein

慣例がないのでなんとなく~/.vim/deinにインストール。
続きは.vimrcで。

Powerlineのインストール

公式Doc通り。

$ pip install --user powerline-status

Anaconda環境でインストールするとpowerlineコマンド群は~/.local/binにインストールされるようだ。
ということで、こんな感じに追記。
※ 記事末に.zshrcを全文晒します。

## Powerline
# https://powerline.readthedocs.org/en/master/
if [ -d ~/.local/bin ]; then
  export PATH="$PATH":~/.local/bin
  powerline-daemon -q
  . ~/.local/lib/python3.5/site-packages/powerline/bindings/zsh/powerline.zsh
fi

基本方針5「dotfilesを他のマシンで使いまわしても手間がなるべく増えないように心がける」的にはまだ不十分だけど、とりあえず。

Powerline用フォントのインストール

パッチを当てるのは面倒なのでパッチ済みのフォントをGitHubからダウンロード。
https://github.com/powerline/fonts
解凍してinstall.shを実行すればまとめて全部インストールされる。

dotfiles

準備が整ったので、設定ファイルをガッと。

.zshrc

OSに依存しない設定を.zshrc、OS依存する設定を.zshrc.mine.(osx|ubuntu|cent)、マシン依存する設定(職場のproxy設定など)を.zshrc.machineとして記述分け。

.zshrc
# LastModified: 2016/02/04

## Zsh launch Time measurement START
#
#zmodload zsh/zprof

## Environment variable configuration
#
# LANG
#
export LANG=ja_JP.UTF-8
export LC_ALL='ja_JP.UTF-8'
case ${UID} in
0)
  LANG=C
  ;;
esac

## Default shell configuration
#
# set prompt
#
autoload -Uz add-zsh-hook
autoload -Uz colors
colors
autoload -Uz vcs_info
zstyle ':vcs_info:*' enable git svn hg bzr
# %s: vcs name, %b: branch name, %a: action name
zstyle ':vcs_info:*' formats '[%s - %b]'
zstyle ':vcs_info:*' actionformats '[%s - %b|%a]'
function _update_vcs_info {
  psvar=()
  LANG=en_US.UTF-8 vcs_info
  [[ -n "$vcs_info_msg_0_" ]] && psvar[1]="$vcs_info_msg_0_"
  RPROMPT="%1(v|%F{green}%1v%f|)"
}
add-zsh-hook precmd _update_vcs_info

case ${UID} in
0)
  PROMPT="%{${fg[cyan]}%}$(echo ${HOST%%.*} | tr '[a-z]' '[A-Z]') %B%{${fg[red]}%}%/#%{${reset_color}%}%b "
  PROMPT2="%B%{${fg[red]}%}%_#%{${reset_color}%}%b "
  SPROMPT="%B%{${fg[red]}%}%r is correct? [No,Yes,Abort,Edit]:%{${reset_color}%}%b "
  ;;
*)
  PROMPT="%{${fg[red]}%}%/%%%{${reset_color}%} "
  PROMPT2="%{${fg[red]}%}%_%%%{${reset_color}%} "
  SPROMPT="%{${fg[red]}%}%r is correct? [No,Yes,Abort,Edit]:%{${reset_color}%} "
  [ -n "${REMOTEHOST}${SSH_CONNECTION}" ] && PROMPT="%{${fg[cyan]}%}$(echo ${HOST%%.*} | tr '[a-z]' '[A-Z]') ${PROMPT}"
  ;;
esac

# Don't logoff when pushed C-d
#
setopt ignore_eof

# auto change directory
#
setopt auto_cd

# auto directory pushd that you can get dirs list by cd -[tab]
#
setopt auto_pushd

## cdr
autoload -Uz is-at-least
if is-at-least 4.3.11
then
  autoload -Uz chpwd_recent_dirs cdr add-zsh-hook
  add-zsh-hook chpwd chpwd_recent_dirs
  zstyle ':chpwd:*' recent-dirs-max 5000
  zstyle ':chpwd:*' recent-dirs-default yes
  zstyle ':completion:*' recent-dirs-insert both
fi

# command correct edition before each completion attempt
#
setopt correct

# compacked complete list display
#
setopt list_packed

# no remove postfix slash of command line
#
setopt noautoremoveslash

# no beep sound when complete list displayed
#
setopt nolistbeep

# no nomatch
#
setopt nonomatch

# print eight bit
setopt print_eight_bit

## Keybind configuration
#
# emacs like keybind (e.x. Ctrl-a gets to line head and Ctrl-e gets
#   to end) and something additions
#
bindkey -e
bindkey "^[[1~" beginning-of-line # Home gets to line head
bindkey "^[[4~" end-of-line # End gets to line end
bindkey "^[[3~" delete-char # Del

# historical backward/forward search with linehead string binded to ^P/^N
#
autoload -Uz history-search-end
zle -N history-beginning-search-backward-end history-search-end
zle -N history-beginning-search-forward-end history-search-end
bindkey "^p" history-beginning-search-backward-end
bindkey "^n" history-beginning-search-forward-end
bindkey "\\ep" history-beginning-search-backward-end
bindkey "\\en" history-beginning-search-forward-end

# reverse menu completion binded to Shift-Tab
#
bindkey "\e[Z" reverse-menu-complete

## Command history configuration
#
HISTFILE=${HOME}/.zsh_history
HISTSIZE=50000
SAVEHIST=50000
setopt hist_ignore_all_dups
setopt hist_ignore_dups
setopt hist_expand
setopt hist_ignore_space
setopt extended_history
setopt share_history

## zsh editor
#
autoload -Uz zed

## Alias configuration
#
# expand aliases before completing
setopt complete_aliases

alias where="command -v"
alias jobs="jobs -l"

alias la="ls -aF"
alias ll="ls -la"

alias du="du -H"
alias df="df -H"

alias rm="rm -i"
alias mv="mv -i"
alias cp="cp -i"

alias su="su -l"

alias vi='vim'

alias g='git'

alias -s rb="ruby"
alias -s py="python"
alias -s php="php -f"
alias -s go="go"

# delete unwanted files
alias duf="find . \( -name '.DS_Store' -o -name '._*' -o -name '.apdisk' -o -name 'Thumbs.db' -o -name 'Desktop.ini' \) -delete -print"

## terminal configuration
#
case "${TERM}" in
screen)
  TERM=xterm-256color
  ;;
esac

case "${TERM}" in
xterm|xterm-color)
  export LSCOLORS=exfxcxdxbxegedabagacad
  export LS_COLORS='di=34:ln=35:so=32:pi=33:ex=31:bd=46;34:cd=43;34:su=41;30:sg=46;30:tw=42;30:ow=43;30'
  zstyle ':completion:*' list-colors 'di=34' 'ln=35' 'so=32' 'ex=31' 'bd=46;34' 'cd=43;34'
  ;;
esac

## auto ls
#
function chpwd() { ls -aF }

# zsh-syntax-highlighting
#
if [ -f /usr/local/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh ]; then
  source /usr/local/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
fi

## SSH
#
bindkey "^?" backward-delete-char
export MANPATH=/usr/local/man:/usr/share/man:$MANPATH

## load user .zshrc configuration file
#
if [[ -f ~/.zshrc.mine ]]; then
  source ~/.zshrc.mine
fi
.zshrc.mine
# LastModified: 2016/03/22

################################################
# for MacOS X
################################################

## HomeBrew
#
export PATH=/usr/local/bin:/usr/local/sbin:$PATH
# HomeBrew Man
export MANPATH=/usr/local/man:/usr/share/man:$MANPATH

## rbenv
##
export RBENV_ROOT="/usr/local/var/rbenv"
if [ -d $RBENV_ROOT ]; then
  export PATH="$RBENV_ROOT/bin:$PATH"
  if which rbenv > /dev/null; then eval "$(rbenv init - zsh)"; fi
fi

## pyenv
#
export PYENV_ROOT=/usr/local/var/pyenv
export PATH=/usr/local/bin:/usr/local/share/python:$PATH
if which pyenv > /dev/null; then eval "$(pyenv init -)"; fi
if which pyenv-virtualenv-init > /dev/null; then eval "$(pyenv virtualenv-init -)"; fi

## Gemfile
##
RUBYGEMS_GEMDEPS=-
# -: search Gemfile from current directory to ancestor

## nodebrew
##
nodebrew=$HOME/.nodebrew/current/bin
if [ -d "$nodebrew" ]; then
  export PATH=$nodebrew:$PATH
  nodebrew use stable > /dev/null
fi

## Alias
#
if [ -e /usr/local/bin/gls ]; then
  alias ls="gls --color=auto -F"
else
  alias ls="ls -GF"
fi

if [ -x "`which vim`" ]; then
  alias vim="/usr/local/bin/vim"
fi

alias b='brew'
alias bi='brew info'
alias bl='brew list'
alias bs='brew -S'
alias bug='brew update && brew upgrade'

alias gibol='gibo -l | sed "/=/d" | tr "\t", "\n" | sed "/^$/d" | sort | peco | xargs gibo'
alias subl='/Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl'

alias mute_volume='osascript -e "set Volume 0"'
alias max_volume='osascript -e "set Volume 10"'
alias jnethack="cocot -t UTF-8 -p EUC-JP -- /usr/local/bin/jnethack"

# Pygments
if [ -x `which pygmentize` ]; then
  alias c='pygmentize -O style=monokai -f console256 -g'
fi

# with Line numbers
alias -g L='| nl -n ln -b a'

## ccze
# Robust and modular log colorizer
# https://packages.debian.org/wheezy/ccze
if [ -x "`which ccze`" ]; then
  alias -g C="| ccze -A"
fi

## Completion configuration
#
if [ -d /usr/local/share/zsh-completions ]; then
  fpath=(/usr/local/share/zsh-completions $fpath)
fi
autoload -U compinit
compinit -C

## Google Cloud SDK
# brew cask install google-cloud-sdk
#
if [ -f /opt/homebrew-cask/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/path.zsh.inc ]; then
  source /opt/homebrew-cask/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/path.zsh.inc
  source /opt/homebrew-cask/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/completion.zsh.inc
fi

## Go
#
if [ -x "`which go`" ]; then
  export GOPATH=$HOME/go/
  export GOROOT=`go env GOROOT`
  export PATH=$PATH:$GOPATHbin:$GOROOT/bin
fi

## Peco
# brew tap peco/peco
#
if [ -x "`which peco`" ]; then
  alias top='top | peco'
  alias ps='ps aux | peco'
  alias -g P='| peco'

  function peco-select-history () {
    local tac
    if which gtac > /dev/null; then
      tac="gtac"
    elif which tac > /dev/null; then
      tac="tac"
    else
      tac="tail -r"
    fi
    BUFFER=$(\history -n 1 | eval $tac | peco --query "$LBUFFER")
    CURSOR=$#BUFFER # move cursor
    #zle -R -c       # refresh
  }
  zle -N peco-select-history

  function peco-cdr () {
    local selected_dir=$(cdr -l | awk '{ print $2 }' | peco)
    if [ -n "$selected_dir" ]; then
      BUFFER="cd ${selected_dir}"
      zle accept-line
    fi
    #zle -R -c
  }
  zle -N peco-cdr

  bindkey '^r' peco-select-history
  bindkey '^j' peco-cdr
fi

## z.sh (https://github.com/rupa/z)
# brew install z
# like autojump
#
if [ -f `brew --prefix`/etc/profile.d/z.sh ]; then
  source `brew --prefix`/etc/profile.d/z.sh
  _Z_CMD=j
  compctl -U -K _z_zsh_tab_completion "$_Z_CMD"
fi

## zsh-history-substring-search
# brew install zsh-history-substring-search
#
if [ -f /usr/local/opt/zsh-history-substring-search/zsh-history-substring-search.zsh ]; then
  source /usr/local/opt/zsh-history-substring-search/zsh-history-substring-search.zsh
  bindkey '^[[A' history-substring-search-up
  bindkey '^[[B' history-substring-search-down
fi

## MObileSHell
#
compdef mosh=ssh

## Git
#
compdef g=git

## Haxe
#
export HAXE_STD_PATH="/usr/local/lib/haxe/std"

## Heroku
#
export PATH="/usr/local/heroku/bin:$PATH"

## translate-shell
# https://github.com/soimort/translate-shell
if [ -x "`which trans`" ]; then
  alias -g T='| trans :ja'
fi

## iTerm2 Shell Integration
#
test -e ${HOME}/.iterm2_shell_integration.zsh && source ${HOME}/.iterm2_shell_integration.zsh

## Powerline
# pip install --user powerline-status
if [ -d ~/.local/bin ]; then
  export PATH="$PATH":~/.local/bin
  powerline-daemon -q
  . ~/.local/lib/python3.5/site-packages/powerline/bindings/zsh/powerline.zsh
fi

## Setting of each machine
#
if [ -f ~/.zshrc.machine ]; then
  source ~/.zshrc.machine
fi

## Login Message
#
echo "============================================================";
echo "=  =====  ==================    =====      ========   ==   =";
echo "=   ===   =================  ==  ===  ====  ========  ==  ==";
echo "=  =   =  ================  ====  ==  ====  ========  ==  ==";
echo "=  == ==  ===   ====   ===  ====  ===  ==============    ===";
echo "=  =====  ==  =  ==  =  ==  ====  =====  =============  ====";
echo "=  =====  =====  ==  =====  ====  =======  ==========    ===";
echo "=  =====  ===    ==  =====  ====  ==  ====  ========  ==  ==";
echo "=  =====  ==  =  ==  =  ===  ==  ===  ====  ========  ==  ==";
echo "=  =====  ===    ===   =====    =====      ========  ====  =";
echo "============================================================";
echo -e "\e[33m [Uptime & Who] \e[m"
w
if [ -x "`which fortune`" ]; then
  echo -e "\n\e[33m [Today's fortune] \e[m"
  fortune | trans :ja
fi

## Zsh launch Time measurement END
#
#if type zprof > /dev/null 2>&1; then
#  zprof | ccze -A
#fi
  • pygmentize
  • ccze
  • peco
  • gibo
  • mosh
  • translate-shell

といったパッケージを常用しているため、インストールされていない環境では"Not Found"と怒られるかもしれませんがあらかじめご了承ください。
いずれもHomebrewから簡単にインストールできます。

.vimrc

.vimrc
if &compatible
  set nocompatible
endif

" Required:
set runtimepath^=~/.vim/dein/repos/github.com/Shougo/dein.vim

" Required:
call dein#begin(expand('~/.vim/dein'))

" Let dein manage dein
" Required:
call dein#add('Shougo/dein.vim')
call dein#add('Shougo/vimproc.vim', {
  \ 'build': {
  \   'windows': 'tools\\update-dll-mingw',
  \   'cygwin': 'make -f make_cygwin.mak',
  \   'mac': 'make -f make_mac.mak',
  \   'linux': 'make',
  \   'unix': 'gmake',
  \  },
  \ })

" Add or remove your plugins here:
" Fundamental
call dein#add('vim-jp/vimdoc-ja')
call dein#add('Shougo/neosnippet.vim')
call dein#add('Shougo/neosnippet-snippets')
call dein#add('Shougo/unite.vim')
call dein#add('Shougo/vimshell')
call dein#add('scrooloose/nerdtree')
call dein#add('editorconfig/editorconfig-vim')

" Git
call dein#add('tpope/vim-fugitive')
call dein#add('airblade/vim-gitgutter')

" Visual
call dein#add('powerline/powerline', {'rtp': 'powerline/bindings/vim/'})

" Required:
call dein#end()
filetype plugin indent on

" If you want to install not installed plugins on startup.
if dein#check_install()
  call dein#install()
endif
" Unite
let g:unite_enable_start_insert = 1
let g:unite_enable_ignore_case = 1
let g:unite_enable_smart_case = 1

" grep
nnoremap <silent> ,g  :<C-u>Unite grep:. -buffer-name=search-buffer<CR>
" grep on cursor
nnoremap <silent> ,cg :<C-u>Unite grep:. -buffer-name=search-buffer<CR><C-R><C-W><CR>
" resume grep
nnoremap <silent> ,r  :<C-u>UniteResume search-buffer<CR>

set number
set title
set ruler
set showcmd
set showmatch
set matchtime=1
set laststatus=2
set showtabline=2
set noshowmode
set spell

set autoindent
set smartindent

set expandtab
set ts=2 sw=2 sts=0

autocmd BufReadPost * if 0 < line("'\"") && line("'\"") <= line("$") | exe "normal g`\"" | endif

set ignorecase
set smartcase
set wrapscan
set incsearch
set hlsearch

set backspace=start,eol,indent

" Highlight TrailingSpaces
augroup HighlightTrailingSpaces
  autocmd!
  autocmd VimEnter,WinEnter,ColorScheme * highlight TrailingSpaces term=underline guibg=Red ctermbg=Red
  autocmd VimEnter,WinEnter * match TrailingSpaces /\s\+$/
augroup END

ついでに、Dein.vimの前にNeoBundleで使っていたvimrcも載せときます。

vimrc.neobundle
" LastModified: 2015/02/10

if has('vim_starting')
  "set nocompatible " Be iMproved
  set runtimepath+=~/.vim/bundle/neobundle.vim/
endif

call neobundle#begin(expand('~/.vim/bundle/'))

" Let NeoBundle manage NeoBundle
NeoBundleFetch 'Shougo/neobundle.vim'

NeoBundle 'Shougo/vimproc', {
  \ 'build' : {
  \ 'windows' : 'make -f make_mingw32.mak',
  \ 'cygwin' : 'make -f make_cygwin.mak',
  \ 'mac' : 'make -f make_mac.mak',
  \ 'unix' : 'make -f make_unix.mak',
  \ },
\ }

" My Bundles here:
NeoBundle 'Shougo/neocomplete'
NeoBundle 'Shougo/unite.vim'
NeoBundle 'tpope/vim-fugitive'
NeoBundle 'airblade/vim-gitgutter'
NeoBundle 'editorconfig/editorconfig-vim'
NeoBundle 'mattn/emmet-vim'
NeoBundle 'itchyny/lightline.vim'
NeoBundle 'tomasr/molokai'
NeoBundle 'vim-jp/vimdoc-ja'
NeoBundle 'rking/ag.vim'
NeoBundle 'scrooloose/nerdtree'

NeoBundleCheck

call neobundle#end()

filetype plugin indent on " Required!
filetype indent on

syntax on

" neocomplete
let g:neocomplete#enable_at_startup = 1
let g:neocomplete#enable_smart_case = 1
let g:neocomplete#force_overwrite_completefunc = 1

" Unite
let g:unite_enable_start_insert = 1
let g:unite_enable_ignore_case = 1
let g:unite_enable_smart_case = 1

" grep
nnoremap <silent> ,g  :<C-u>Unite grep:. -buffer-name=search-buffer<CR>
" grep on cursor
nnoremap <silent> ,cg :<C-u>Unite grep:. -buffer-name=search-buffer<CR><C-R><C-W><CR>
" resume grep
nnoremap <silent> ,r  :<C-u>UniteResume search-buffer<CR>

" use 'ag' instead of 'grep'
if executable('ag')
  let g:unite_source_grep_command = 'ag'
  let g:unite_source_grep_default_opts = '--nogroup --nocolor --column'
  let g:unite_source_grep_recursive_opt = ''
endif

set number
set showmode
set title
set ruler
set showcmd
set showmatch
set matchtime=1
set laststatus=2
set spell
set display=lastline

set autoindent
set smartindent

set expandtab
set ts=2 sw=2 sts=0

autocmd BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$") | exe "normal g`\"" | endif

set ignorecase
set smartcase
set wrapscan
set incsearch
set hlsearch

set backspace=start,eol,indent

" Highlight TrailingSpaces
augroup HighlightTrailingSpaces
  autocmd!
  autocmd VimEnter,WinEnter,ColorScheme * highlight TrailingSpaces term=underline guibg=Red ctermbg=Red
  autocmd VimEnter,WinEnter * match TrailingSpaces /\s\+$/
augroup END

" colorscheme
colorscheme molokai
let g:molokai_original = 1
let g:rehash256 = 1

微調整 & 諸注意

LC_ALLがないとPowerlineに怒られる

気持ち悪いけど、.zshrcにLC_ALLを書いておけば回避可能。

.zshrc
export LANG=ja_JP.UTF-8
export LC_ALL='ja_JP.UTF-8'

特にVimのステータスラインが乱れる

iTerm2のProfileにはRegular FontとNon-ASCII Fontの設定があり、三角形はNon-ASCII Fontの方で描画されているので、
どちらもpatch済みのフォントを設定し、
"Treat ambiguous-width characters as double width"のチェックは外す。
この辺はPowerlineのconfigで追い込むほうが早い。

完成

iTerm2.tiff

vim.tiff

作業時間は正味、15分ぐらい。「桜舞い散る中に忘れた記憶」とならないようメモメモ。