🚉
Zshをカスタマイズしよう
AGENDA
- zsh使ってますか?
- zshellをカスタマイズすると…
- zshのカスタマイズ方法
- 私と一緒に開発しませんか? (zshianの紹介)
伝えたいこと
- 自作コマンドは気持ちいい
- 自作TUIは気持ちいい
zsh使っていますか?
- Z shell is 何?
- The Z shell (Zsh) is a Unix shell that can be used as an interactive login shell and as a command interpreter for shell scripting. Zsh is an extended Bourne shell with many improvements, including some features of Bash, ksh, and tcsh.
- 要するに対話的なログインシェルでShell Scriptのコマンドインタープリタ
- Wikipedia: https://en.wikipedia.org/wiki/Z_shell
- last edit: 4 May 2023
- Macの皆さんはご存知かもしれませんが…
-
zsh (Z シェル) は、macOS Catalina 以降で新規作成されるすべてのユーザアカウントのデフォルトシェルです。
-
bash は、macOS Mojave 以前のデフォルトのシェルです。(詳しくは下記参照)
-
Apple: zsh を Mac のデフォルトシェルとして使う November. 2 2022
-
Zshをカスタマイズしませんか?
- Zshをカスタムする理由
- 建前: 打ち込む文字数の削減, 便利機能を使いたい
- 本音: かっこいいから
Z shellをカスタマイズすると…
- 私のZ shellの画面
- gitのcommitにメッセージと絵文字を入れれます
- デフォルトの画面はwikiのように色の設定があまりされてない (白黒)
- また, terminalの入力受付状態のときに表示される文字(prompt)に情報が少ない
- Gitの情報とか時間とかを知りたい!
- 実際aliasと補完があると打ち込み回数が減り開発が楽になる
どうやって使いやすくするか
- Oh My ZshをなどのPluginを使う
- Communityで管理されていてDocumentも豊富
- https://github.com/ohmyzsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
- 自力
- 「素晴らしいプラグインはあるけど完璧に自分好みの設定のプラグインなんてないよね」
- 「ないなら作っちゃえばいいじゃん」
- 「そうか、作ればいいのか」
- 「作りたくなりましたよね...??????」
Z shellのカスタマイズの仕方
~/.zshrc
に書き込み, source
で有効化する. 簡単!
cd $HOME
touch .zshrc
echo "alias helloworld='echo Hello World'" > .zshrc
source .zshrc
helloworld // print Hello World
- aliasはshort cutのようなもので設定するとterminalが解釈・変換してくれる
- optionの設定
setopt RM_STAR_SILENT # do not confirm when run `rm *`
setopt nonomatch # enable to use ? and & in curl as literal
setopt no_beep # disable beep sound
setopt nolistbeep # disable beep sound after completion
setopt auto_cd # if command not found consider using cd
setopt share_history # share history between all zsh
setopt hist_ignore_dups # do NOT add command to history if command is same to prev command
setopt extended_glob # enable wild pattern when using glob
- pathの設定
# PATH SETTING #
# * add path path to home brew
# typeset -Ug : deal with path as set of PATH
# N-/ : add path if not exist
typeset -gU path PATH
path=(
/opt/homebrew/bin(N-/)
/opt/homebrew/sbin(N-/)
/usr/bin
/usr/sbin
/bin
/sbin
/usr/local/bin(N-/)
/usr/local/sbin(N-/)
/Library/Apple/usr/bin
)
- homebrewの設定
- promptはgitと連携したいのでここで設定している
# HOMEBREW SETTING
# * if brew has already installed, below lines will be run when reading this file
# if type brew : check wheather brew command exist
# &> : redirect both of standard output and error to /dev/null
# zsh-git-prompt/zshrc : to use for showing git branch in command prompt
# autoload -Uz : prevent from being over written by user alias. use zsh format
if type brew &>/dev/null; then
FPATH=$(brew --prefix)/share/zsh-completions:$FPATH
source $(brew --prefix)/share/zsh-autosuggestions/zsh-autosuggestions.zsh
source $(brew --prefix)/opt/zsh-git-prompt/zshrc.sh
autoload -Uz compinit && compinit
autoload -Uz colors && colors
autoload -Uz add-zsh-hook
fi
# Delete the empty character immediately before the completion entered in zsh-completion
ZLE_REMOVE_SUFFIX_CHARS=$'' # add space after completion
# PROMPT SETTING #
# alias python="python3" : add alias for git_super_status
# : if Mac OS version < 12 Monterey, you can comment out this line
# %F{color} ... %f : change color
# %n : user name
# ($(arch)) : system architecture
# %D : YYYY-mm-dd
# %T : hh:mm
# $(git_super_status) : git status
# %# : show "#" if you are root, else show %
# if brew list | grep ~ : if ~ exists, return true
# add-zsh-hook precmd : if
alias python="python3"
git_prompt() {
# if .git exists show it
if [ "$(git rev-parse --is-inside-work-tree 2> /dev/null)" = true ]; then
PROMPT="%F{green}🖱️ : %n%f 🔧: %F{cyan}($(arch))%f ⏰: %F{yellow}%D %T%f
📍: %F{blue}%~%f 🌿: $(git_super_status)
%F{green}>> %f %# "
else
PROMPT="%F{green}🖱️ : %n%f 🔧: %F{cyan}($(arch))%f ⏰: %F{yellow}%D %T%f
📍: %F{blue}%~%f
%F{green} >> %f %# "
fi
}
if brew list | grep zsh-git-prompt &> /dev/null; then
add-zsh-hook precmd git_prompt
fi
- 「複数ファイルに分割したい!」
-
.zsh
ファイルを作り, それぞれをsource
する処理を.zshrcに書く - 私は
$HOME/.zsh
の下に設定対象ごとのdir, fileを作っています
-
# Load seperated config files
for conf in "$HOME/.zsh/"*/*.zsh; do
source "${conf}"
done
unset conf
そんなにコマンド作って覚えていられるの?
- commandやaliasは基本的に覚えない
- 覚えるという発想が間違っている(過激派)
具体例
- gitのalias
-
show_git_alias
で出現するようにしている
grepとone liner perlを使って文字列整形します. 対象のファイルはaliasを設定しているファイルです.
ソースコード
# Add all changes in working directory to the staging area
alias gad='git add .'
# Amend the most recent commit
alias gamd='git commit --amend'
# List all local branches
alias gbr='git branch'
# List all remote branches
alias gbrr='git branch -r'
# Create a new branch and switch to it
alias gcb='git checkout -b '
# Remove files from the index (staging area)
alias gcr='git rm -r --cached'
# Fetch from and integrate with another repository or a local branch (short for 'git pull origin')
alias gpull='git pull origin'
# Update remote refs along with associated objects (short for 'git push origin')
alias gpush='git push origin'
# Reset current HEAD to the specified state
alias greset='git reset'
# Show the working tree status
alias gst='git status'
# Switch to another branch
alias gsw='git switch '
ソースコードからcsvを作るShell Script
#!/bin/bash
# Remove lines starting with '#'
grep -v '^#' .zsh/git/alias.zsh | \
# Remove 'alias ' at the start of each line
perl -pe 's/^alias //' | \
# Replace '=' with ','
perl -pe "s/='/,/" | \
# Remove trailing quote
perl -pe "s/'$//" | \
# Remove blank lines
grep -v '^$' > .zsh/doc/git_alias.csv
出力用のコマンド show_git_alias
の実装
# Note: line 7; doc dir is upper dir of this file
# Note: line 7; we use absolute path for git_alias
function show_git_alias() {
echo -e "Alias\tCommand\n----\t-------"
while IFS=',' read -r alias command
do
echo -e "${alias}\t${command}"
done < $HOME/.zsh/doc/git_alias.csv | column -t
}
具体例2
- gitのcommitにメッセージと絵文字を入れるとき
- `gcm what_you_did “message”` ⇒ `git commit -m ":emoji: [what_you_did] ===> message` のalias(function) を貼って実装している
- what_you_didの部分は正規表現で検索できるようにしている
gcm
と gcm_search_command
. gcm_search_commandはgcmのコマンド引数をgrepで検索する
gcm () {
# input validation
if [ $# -ne 2 ];then
echo "Error: the number of arguments must be 2. if you do not command name, please run 'gcm_searc_command' you can read file on command"
return 1
fi
case "$1" in
"add_a_dependency" ) icon=":heavy_plus_sign: [add a dependency] =>" ;;
"add_analytics" ) icon=":chart_with_upwards_trend: [add analytics] => " ;;
"add_animation" ) icon=":dizzy: [add animation] => " ;;
...
"work_in_progress" ) icon=":construction: [work in progress] =>" ;;
"work_on_responsive_design" ) icon=":iphone: [work on responsive design] => " ;;
"write_code_drunkely" ) icon=":beer: [write code drunkly] => " ;;
"h" ) vim ~/zsh_config/data/gcm_command_commit
esac
commit_message="$icon $2"
git commit -m $commit_message
}
gcm_search_command (){
if [ $# -ne 1 ];then
echo "ERROR: the number of input must be 1"
exit 1
fi
cat ~/.zsh/doc/gcm_command_name.txt | grep $1
}
私と一緒に開発しませんか?
今日紹介したものは全てOSSで公開しています. 開発に興味のあるかたは是非repositoryを訪れてみてください!
Discussion