⌨️

Mac修理でデータ消えたのでターミナル環境を整えた(2022年)#zsh #modern-cli

2022/08/16に公開

Macのコマンドライン環境をモダンツールインストールしつつ整えました。とりあえずzsh環境ができたのでまとめてみます。

https://github.com/arkbig/my-mac-setup

前半はzshの設定回りを紹介し、後半にインストールしたModern CLI Toolsをスクショ付きで紹介しています。

参考文献:

しばらくターミナル環境とは離れていましたが、最近はdockerやkubernetesを触ってたりIDEではなくVSCodeを使ってたりという状況でターミナルを使う機会が増えてきました。
そこで、久しぶりにターミナル環境を設定してみます。Mac標準のターミナルアプリを使いデフォルトのシェルであるzshをカスタマイズしてみました。
M1 mac miniですが、スペックは申し分なくいい感じに設定できました。かなり昔はzshを使ってみると重すぎて使いものにならなかった記憶があります。今回はもうそのイメージを覆してくれて安心しました。(最近のbashを知らないのでzshの優位性は語れません)

かっこいいスクリーンショット

かっこいいスクショ

カスタマイズ方針

  1. 標準のターミナルアプリを使う
    • iTermが有名ですが、わざわざ置き換える程使いこなせてません
  2. 標準のzshを使う
    • bashが有名ですが、zshは最強のシェルらしいのでのっかてみます
  3. プラグインマネージャーは使わない
    • プラグインを使いすぎると重くなるらしいし、そんなに使わないなら必要なし
  4. モダンなCLIコマンドを使っていく
    • 標準環境とかけ離れてしまうけど、普段の作業効率を優先します

Karabinerの設定

一部のキー操作に影響するので、Karabinerの設定も抜粋します。

https://github.com/arkbig/my-mac-setup/blob/main/config/karabiner/assets/complex_modifications/windows-like.json

すべて見たい場合はここをクリック。 GitHub埋め込みだと200行しか表示されないようです。
{
  "title": "Windows Keyboard",
  "rules": [
    {
      "description": "日本語 On/Off | 変換/無変換",
      "manipulators": [
        {
          "description": "無変換",
          "from": {
            "key_code": "japanese_pc_nfer"
          },
          "to": {
            "key_code": "japanese_eisuu"
          },
          "type": "basic"
        },
        {
          "description": "変換",
          "from": {
            "key_code": "japanese_pc_xfer"
          },
          "to": {
            "key_code": "japanese_kana"
          },
          "type": "basic"
        }
      ]
    },
    {
      "description": "左 command ⇔ control",
      "manipulators": [
        {
          "from": {
            "key_code": "left_command",
            "modifiers": {
              "optional": "any"
            }
          },
          "to": {
            "key_code": "left_control"
          },
          "type": "basic"
        },
        {
          "from": {
            "key_code": "left_control",
            "modifiers": {
              "optional": "any"
            }
          },
          "to": {
            "key_code": "left_command"
          },
          "type": "basic"
        }
      ]
    },
    {
      "description": "application ⇒ fn",
      "manipulators": [
        {
          "from": {
            "key_code": "application",
            "modifiers": {
              "optional": "any"
            }
          },
          "to": {
            "key_code": "fn"
          },
          "type": "basic"
        }
      ]
    },
    {
      "description": "単語移動 | command + ←/→",
      "manipulators": [
        {
          "from": {
            "key_code": "left_arrow",
            "modifiers": {
              "mandatory": "command",
              "optional": "any"
            }
          },
          "to": {
            "key_code": "left_arrow",
            "modifiers": ["option"]
          },
          "type": "basic"
        },
        {
          "from": {
            "key_code": "right_arrow",
            "modifiers": {
              "mandatory": "command",
              "optional": "any"
            }
          },
          "to": {
            "key_code": "right_arrow",
            "modifiers": ["option"]
          },
          "type": "basic"
        },
        {
          "from": {
            "key_code": "left_arrow",
            "modifiers": {
              "mandatory": "option",
              "optional": "any"
            }
          },
          "to": {
            "key_code": "left_arrow",
            "modifiers": ["command"]
          },
          "type": "basic"
        },
        {
          "from": {
            "key_code": "right_arrow",
            "modifiers": {
              "mandatory": "option",
              "optional": "any"
            }
          },
          "to": {
            "key_code": "right_arrow",
            "modifiers": ["command"]
          },
          "type": "basic"
        }
      ]
    },
    {
      "description": "ブラウザ 戻る/進む | mouse 4/5",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "frontmost_application_if",
              "bundle_identifiers": ["com.apple.Safari"]
            }
          ],
          "from": {
            "pointing_button": "button4"
          },
          "to": {
            "key_code": "close_bracket",
            "modifiers": ["command"]
          },
          "type": "basic"
        },
        {
          "conditions": [
            {
              "type": "frontmost_application_if",
              "bundle_identifiers": ["com.apple.Safari"]
            }
          ],
          "from": {
            "pointing_button": "button5"
          },
          "to": {
            "key_code": "non_us_pound",
            "modifiers": ["command"]
          },
          "type": "basic"
        }
      ]
    },
    {
      "description": "ウィンドウ切り替え (command + tab, option + tab)",
      "manipulators": [
        {
          "from": {
            "key_code": "tab",
            "modifiers": {
              "mandatory": ["command"],
              "optional": ["shift"]
            }
          },
          "to": {
            "key_code": "tab",
            "modifiers": ["control"]
          },
          "type": "basic"
        },
        {
          "from": {
            "key_code": "tab",
            "modifiers": {
              "mandatory": ["option"],
              "optional": ["shift"]
            }
          },
          "to": {
            "key_code": "tab",
            "modifiers": ["command"]
          },
          "type": "basic"
        }
      ]
    },
    {
      "description": "先頭、末尾 | (Ctrl+)Home/End",
      "manipulators": [
        {
          "conditions": [
            {
              "type": "frontmost_application_unless",
              "bundle_identifiers": [
                "com.apple.Terminal",
                "com.microsoft.VSCode"
              ]
            }
          ],
          "from": {
            "key_code": "home",
            "modifiers": {
              "mandatory": "command"
            }
          },
          "to": {
            "key_code": "up_arrow",
            "modifiers": ["command"]
          },
          "type": "basic"
        },
        {
          "conditions": [
            {
              "type": "frontmost_application_unless",
              "bundle_identifiers": [
                "com.apple.Terminal",
                "com.microsoft.VSCode"
              ]
            }
          ],
          "from": {
            "key_code": "end",
            "modifiers": {
              "mandatory": "command"
            }
          },
          "to": {
            "key_code": "down_arrow",
            "modifiers": ["command"]
          },
          "type": "basic"
        },
        {
          "conditions": [
            {
              "type": "frontmost_application_unless",
              "bundle_identifiers": [
                "com.apple.Terminal",
                "com.microsoft.VSCode"
              ]
            }
          ],
          "from": {
            "key_code": "home"
          },
          "to": {
            "key_code": "a",
            "modifiers": ["control"]
          },
          "type": "basic"
        },
        {
          "conditions": [
            {
              "type": "frontmost_application_unless",
              "bundle_identifiers": [
                "com.apple.Terminal",
                "com.microsoft.VSCode"
              ]
            }
          ],
          "from": {
            "key_code": "end"
          },
          "to": {
            "key_code": "e",
            "modifiers": ["control"]
          },
          "type": "basic"
        }
      ]
    }
  ]
}

Complex ModificationsからAdd ruleして使用します。

なお、私はErgoDox EZの分割&親指活用キーボードを使い、仕事ではWindows環境となります。

zshrcとか

ログインシェルのときに読み込まれる.zprofileでbrew用にパス通しと、Docker用にColimaの起動をしています。ターミナルアプリをMac起動時に自動実行しているので、Dockerの起動をここで書いています。

https://github.com/arkbig/my-mac-setup/blob/main/config/zsh/.zprofile

.zshrczshrc.zshのロードだけ書いています。今後設定を分割したくなったり、.zshrcを勝手に書き換えられても分かるようにするため分けてます。

https://github.com/arkbig/my-mac-setup/blob/main/config/zsh/.zshrc

そしてメインのzshrc.zsh

https://github.com/arkbig/my-mac-setup/blob/main/config/zsh/zshrc.zsh

すべて見たい場合はここをクリック。 GitHub埋め込みだと200行しか表示されないようです。
######################################################################
# general

# BATシンタックスハイライトでチートシート表示するため、#のコメント行を見やすくする
export BAT_THEME=zenburn
# viの代わりにKakouneを使う
export EDITOR=kak
# 補完メニューのカラー変更でも使うため、LSDのデフォルト色を設定
export LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:'

######################################################################
# alias
# デフォルト環境に放り出されると戸惑いそうだけど、普段の効率を優先して
# Modern CLI Toolsに置き換える
alias .2=cd ../..
alias .3=cd ../../..
alias .4=cd ../../../..
alias .5=cd ../../../../..
alias cat='bat --paging=never'
alias cut='choose'
alias df='duf'
alias diff='delta'
alias du='dust'
alias find='fd'
alias grep='rg -S'
alias less='bat'
alias ll='lsd -Ahl --total-size --group-dirs=last'
alias lr='lsd -Ahl --total-size --tree --group-dirs=last'
alias ls='lsd -A --group-dirs=last'
alias mkdir='mkdir -p'
alias ps='procs --tree'
alias rm='trash -F'
alias time='gtime'
alias top='btm'
alias tree='lsd -A --tree --group-dirs=last'
alias vi='kak'
alias -g C='|tee >(pbcopy)'
alias -g G='|rg -S'
alias -g L='|bat --style=plain'
# チートシート表示
ch() { cheat $* | bat --style=plain -l sh }
# 直近のディレクトリをあいまい検索して移動
pop() { cd $(dirs -lp | bat -r 2: | fzf --no-sort --prompt='cd >') }
# Jsonファイルをgrep
jgrep() { gron | grep $* | gron -u }
# ディレクトリを作成&移動
mkcd() {
    if [[ -d "$1" ]]; then
        cd "$1"
    else
        mkdir -p "$1" && cd "$1"
    fi
}

######################################################################
# cd
# cd記録数の設定
DIRSTACKSIZE=50
# cd検索パスの設定
cdpath=~/proj
# ディレクトリ名のみでもcd
setopt auto_cd
# cd時にpushをする
setopt auto_pushd
# pushに同じものを登録しない
setopt pushd_ignore_dups

# プロンプト表示時にディレクトリ内容をリストアップ
zle-line-init() {
    # TODO 色をつけたい(やり方不明)
    # TODO いい感じにwrapさせたい(ただの手抜き)
    local maxlen=$(echo $(( $COLUMNS * 2 )))
    local all=$(lsd -1FL --icon never --group-dirs first)
    local dirs=""
    for d (${(f)all}) {
        if [[ "$d" =~ "[ ]" ]]; then
            dirs="$dirs '$d'"
        else
            dirs="$dirs $d"
        fi
        if [ ${#dirs} -gt $maxlen ]; then
            dirs="${dirs:0:$maxlen-3}..."
            break
        fi
    }
    zle -M "$dirs"
}
zle -N zle-line-init

######################################################################
# history

# 履歴保存数の設定
HISTSIZE=10000
SAVEHIST=10000

# 履歴に時間も記録
setopt extended_history
# 履歴の同じ古いコマンドは削除
setopt hist_ignore_all_dups
# history (fc -l)コマンドを履歴に保存しない
setopt hist_no_store
# 履歴に余計な空白を記録しない
setopt hist_reduce_blanks
# 他ウィンドウと履歴を共有する
setopt share_history

# 最後のワードをスマートにする
# ls /usr/share
# ls !$&  or  ls ESC-.&
# ls !$  or ls ESC-. <-- insert-last-wordだと「&」が選ばれるが、smart-insert-last-wordでは「/usr/share」が選ばれる
autoload -Uz smart-insert-last-word
zle -N insert-last-word smart-insert-last-word

# 履歴のあいまい検索
select-history() {
    LBUFFER=$(history -Dinr 1 | fzf --no-sort +m --query "$LBUFFER" --prompt="History > " | choose 3:)
}
zle -N select-history
# 履歴をあいまい検索から実行
accept-history() {
    zle select-history
    zle accept-line
}
zle -N accept-history

######################################################################
# completion
# 補完を有効
autoload -Uz compinit && compinit

# 候補が大量時にもメニュー表示の確認せず表示させる
LISTMAX=-1

# カーソル位置での単語補完を有効
setopt complete_in_word
# リスト表示をコンパクトにする
setopt list_packed
# リスト選択を縦でなく横移動
setopt list_rows_first
# 自動でのmenu表示をしない
setopt no_auto_menu
# 自動でのmenu補完をしない
setopt no_menu_complete

# 補完メニューの色設定
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
# 小文字入力でも大文字に補完一致させる
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
# 項目毎に補完メニューをグループ化
zstyle ':completion:*' group-name ''
# 補完メニューのグループ名を色設定
zstyle ':completion:*:descriptions' format '%F{yellow}# %d:%f'
# 補完メニューのグループ表示順を設定
zstyle ':completion:*' group-order local-directories named-directories path-directories
# 空白時にもタブキーで補完させる
zstyle ':completion:*' insert-tab false

# 補完メニューの明示的表示
menu-complete-and-select() {
    zle menu-complete
    zle menu-select
}
zle -N menu-complete-and-select

######################################################################
# help
# cheatを起動させる(未入力時はmy-favorite決め打ち)
run-cheat() {
    if [ -z $BUFFER ]; then
        cheat my-favorite | bat --style=plain -l sh
    else
        if [ "$BUFFER" != "${BUFFER#\\}" ]; then
            # original command
            local cmd=$(echo ${BUFFER#\\} | choose 0)
        else
            # Possible alias
            local lbuf=$LBUFFER
            local rbuf=$RBUFFER
            BUFFER=$(echo $BUFFER | choose 0)
            zle _expand_alias
            local cmd=$(echo $BUFFER | choose 0)
            LBUFFER=$lbuf
            RBUFFER=$rbuf
        fi
        cheat $cmd | bat --style=plain -l sh
    fi
}
zle -N run-cheat

######################################################################
# 入力

# Tabはメニュー補完、option-iはbashっぽい補完(連番ファイル選択時に便利)
bindkey '^i' menu-complete-and-select # Tab
bindkey 'ˆ' expand-or-complete # option-i

# 履歴操作
bindkey '^p' history-beginning-search-backward
bindkey '^n' history-beginning-search-forward
bindkey '^r' accept-history
bindkey '®' select-history # TODO: menuselectの"^j"と"^m"みたいに確定キーで切り替えたい

# Windows Like
# Terminal.appのプロファイル > キーボードで追加が必要
# Home(↖︎)→\033[H
# End(↘︎)→\033[F
bindkey '^[[H' beginning-of-line
bindkey '^[[F' end-of-line

# optionをメタキーにせずそのままとし、特殊文字に必要なショートカットを割り当てる

# 単語単位
bindkey '∫' backward-word  # option-b
bindkey 'ƒ' forward-word # option-f
bindkey '∂' kill-word # option-d
bindkey '˙' backward-kill-word # option-h

# 最後の引数を再利用
bindkey '≥' insert-last-word # option-.

# 大文字、小文字
bindkey 'ç' capitalize-word # option-c
bindkey 'ü' up-case-word # option-u
bindkey '¬' down-case-word # option-d

# ヘルプ表示
bindkey '¿' run-cheat # option-? (option-shift-/)

# タブを入力したい時などに使う
bindkey 'œ' quoted-insert # option-q # Why does not control-q work?
bindkey -r "^v" # quoted-insert # Clipy shortcut

# menuselectキーマップ
zmodload -i zsh/complist
accept-line-anywhere() {
    zle accept-line
}
zle -N accept-line-anywhere
bindkey -M menuselect '^m' accept-line-anywhere # 通常は確定、"^j"でバッファ挿入のみ
bindkey -M menuselect '^[[Z' backward-char # shift-TABで戻る

# option-bなどでいい感じに単語移動
# less /usr/local/hoge <-- 通常は「最初の/」まで戻るが、これで「最後の/」に移動
autoload -Uz select-word-style
select-word-style default
zstyle ':zle:*' word-chars " &+,/:=@{|}"
zstyle ':zle:*' word-style unspecified

# ######################################################################
# Install app
# 他の設定を書き換えることがあるので、最後に記載する。
#  select-word-styleがzsh-syntax-highlightingの後だと効かないのを確認済み。

# プロンプトカスタマイズ
eval "$(starship init zsh)"

# cd 履歴からいい感じに移動
# bindkey j hoge OR 検索 ji
# https://news.mynavi.jp/techplus/article/techp5607/
# "^[[0n"クエリステータスレポート(返答)らしいけどなんだろう?
# bindkey "^[[0n" __zoxide_z_complete_helper
eval "$(zoxide init --cmd j zsh)"

# うっすら補完を表示
# → or End accept suggestion
source /opt/homebrew/share/zsh-autosuggestions/zsh-autosuggestions.zsh

# コマンド入力中にシンタックスハイライト
source /opt/homebrew/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

説明

フォント

フォントは白源を使っています。公式サポートの方法ではないけど手軽なのでbrew install font-hackgen-nerdでインストール。

HackGen35Nerd Console Regular 12を設定しています。半角:全角が3:5比率です。

フォント設定

プロンプト

プロンプトはstarshipを使って設定しています。
starshipは各種プログラミング言語の環境(Pythonとか)が表示できますが、まだ設定していません。デフォルトの$allを使っているので、よく表示されるものは今後設定していく予定です。

https://github.com/arkbig/my-mac-setup/blob/main/config/starship.toml

starship画面

この画像のように、プロンプトで多くの情報を表示しています。左側に「パス」「Git情報」「時計」、右側に「終了ステータス」「所要時間」「環境情報」
、入力欄に「プロンプト文字」です。
右側の「環境情報」(via 🐍 v3.8.9)はまだ未設定でデフォルトの$allが表示されているだけです。

カラーはarkbig/color-coordinateをみて、決めました。和風と紫が好きですので、Deepのラインでグラデーション設定しています。

エイリアス

.数字世の中のエンジニアのalias設定を見てなるほどと思い追加しました。
catcutdfdiffdufindgreplesslspstoptreeはモダンなCLIコマンドに置き換えています。
rmはMacのゴミ箱へ移動するコマンドで置換し、もとに戻せます。viは似た操作性だけど、一貫性が上がっているkak(Kakoune)です。

グローバルエイリアスには以下を設定しています。

  • Calias -g C='|tee >(pbcopy)' でクリップボードにコピーしつつ、標準出力します。
  • Galias -g G='|rg -S' でgrep(rgでSmart case search)します。
  • Lalias -g L='|bat --style=plain'でLESSします。

関数もいくつか定義しています。

  • chcheatでチートシート表示し、batのshellシンタックスハイライトをしています。今後よく使うものは自前でMarkdownへ書き直したい。
  • popdirsで直近の移動ディレクトリを表示し、batでカレントディレクトリを除き、fzfであいまい検索しています。
  • jgrepgronを使ってjsonをgrepして、jsonに戻しています。
  • mkcdmkdir & cdです。(なおmkdirは-pオプションで親パス含めて一気に作成します)

ディレクトリ移動

cdコマンドなしでディレクトリ名だけでも移動できるようにauto_cdを有効にします。auto_pushdも有効にし、ディレクトリ移動履歴をもつようにし、前述したpop関数であいまい検索移動できるようにしています。

eval "$(zoxide init --cmd j zsh)"jjiコマンドでいい感じにディレクトリ移動ができるようになっています。

また、zle-line-init関数を使ってプロンプト表示時にディレクトリの内容を表示しています。
これはhook関数のディレクトリ移動したときのchpwdやプロンプト表示時のprecmdでも似たようなことができます。ただし、zle-line-initだとコマンド実行後には消えているのでスクロールで過去のコマンド&結果を確認するとき邪魔にならなくていいです。
zle -M "message"で色を付けたかったけど、方法がわかりませんでした。詳しい方教えてください。

ヒストリー

select-history()関数を定義して、履歴をあいまい検索できるようにしています。(control-rで実行、option-rで入力だけし編集可能状態にする)
時間があると分かりやすいので、絞り込み時は表示しバッファへ入力するときにカットしています。

search history

補完

補完はTABmenu-complete-and-selectoption-iexpand-or-completeとしています。
デフォルトのexpand-or-completeだと候補が増えるとメニュー選択になるので、no_auto_menuno_menu_completeを設定しTABキーを押したときだけメニュー表示します。これにより、連番のファイル名が並んでいる場合にTABだと探すのがたいへんですが、option-iだと一致する部分まで補完した後に数字キーを入力して再度option-iを押していくとすばやく選択できます。

TABのメニュー表示はグループごとに表示し色もつけています。そしてmenuselectキーマップにEnterキーでバッファ挿入&実行まで行うようにしています。(control-jでリストを選ぶと通常のバッファ入力だけです)

help

zshではコマンドを入力途中でESC-hを押すとそのコマンドのmanページを表示できます。cheatコマンドで同じようなことをできるようにrun-cheat関数を定義してoption-?(option-shift-/)に割り当てています。run-cheatは未入力時に固定のファイルを表示します。

入力

bindkeyでショートカットを登録していますが、optionキーにも割り当てています。ターミナルアプリだけであれば、プロファイルのキーボード設定で「メタキーとしてOptionキーを使用」にチェックを入れると^[(ESC)がoptionキーで入力できます。しかしVS Codeの統合ターミナルでは使えないのでこの設定はせず単純にoptionキーで入力される変わった文字にショートカットを割り当てることにしています。

^qとか^sとかなぜか入力を受け付けてくれないものがあるのでそれらは回避しています。 Macに詳しい方、何が悪さしているか教えてください。
理由はなぜ Control-/ がターミナルで使えないか調べたらターミナルの歴史を紐解くことになったこれかな?もともと特殊なキー入力は特別対応されていて、ターミナルエミュレータは必要なものだけ変換してくれる。なのでTerminal.appの環境設定でプロファイルのキーボードで登録したら反応するようになった。
Home/EndキーはVS Codeのターミナルだとquoted-insert^[[M/^[[F]が出るとけど、Terminal.appだと何も表示されないというようにアプリごとに挙動が違うと。

あと、fzfであいまい検索時のキーバインド設定方法ご存じの方もやり方教えてください。

ターミナル環境のバックアップ保存

ターミナルアプリのプロファイル設定をバックアップしておきたいので方法をググりました。すると Deploying Terminal profile settings using macOS configuration profiles というサイトを発見したのでこれを参考にスクリプトを作成しています。

他にもHomebrewとVS Codeの拡張機能のリストも併せて出力しています。実際使う人は適宜ファイル名を書き換えてください。

https://github.com/arkbig/my-mac-setup/blob/main/config/backup.sh

Modern CLI Tools

基本的には modern-unix - A collection of modern/faster/saner alternatives to common unix commands. を見て便利そうなものを探しました。

brew bundle --file Brewfile でインストールしています。

https://github.com/arkbig/my-mac-setup/blob/main/config/homebrew/Brewfile

これは、brew bundle dumpコマンドでBrewfileがカレントディレクトリに出力されます。

brew外でターミナル環境に関わるものはDocker(colima)KarabinerVS Codeをインストールしています。brewでインストールできるものもありますが、数が少ないので一応公式サイトから手動ダウンロードしています。

Docker(colima)はarkbig/devbaseで設定しています。

インストールしたものを簡単に説明していきます。

bat - A cat(1) clon with wings.

catコマンドの代替です。シンタックスハイライトをしてくれるのがいいです。pager機能も持っているのでlessとしても使っています。

bat画面

# BATシンタックスハイライトでチートシート表示するため、#のコメント行を見やすくする
export BAT_THEME=zenburn

alias less='bat'
# pagingを無効
alias cat='bat --paging=never'
# そのままのplain表示
alias -g L='|bat --style=plain'
# シンタックスハイライトの言語を指定
ch() { cheat $* | bat --style=plain -l sh }
# 表示範囲を指定(2行目以降)
pop() { cd $(dirs -lp | bat -r 2: | fzf --no-sort --prompt='cd >') }

lsd - The next gen ls command

lsコマンドの代替です。カラフルに表示してくれるのがいいです。階層表示もしてくれるのでtreeとしても使っています。
リストにexaもありますが、私はファイル→ディレクトリの順番で表示したくてlsdを利用しています。

lsd画面

# ファイル→ディレクトの順でほぼ全て表示(.と..は除く)
alias ls='lsd -A --group-dirs=last'
# サイズが人に優しいリスト表示で、ディレクトリのサイズは中のファイルの合計を表示
alias ll='lsd -Ahl --total-size --group-dirs=last'
# ツリー表示
alias tree='lsd -A --tree --group-dirs=last'
# ツリー形式でファイル情報も表示
alias lr='lsd -Ahl --total-size --tree --group-dirs=last'
# カレントディレクトリ情報を表示
zle-line-init() {
    # 1行でアイコンなしのディレクトリ→ファイルの順で表示
    local all=$(lsd -1FL --icon never --group-dirs first)
:

delta - A syntax-highlighting pager for git, diff, and grep output

diffコマンドの代替です。シンタックスハイライトと横並び表示してくれるのがいいです。gitのdiffとして使っていて、.gitconfigに設定を書いています。
ちなみにGUIだと有料ですがBeyond Compareが便利です。(Windowsの古いバージョンは持っているけど、最新のMac対応板はまだ未購入)

delta画面

[core]
pager=delta
[interactive]
diffFilter=delta --color-only
[add.interactive]
useBuiltin=false
[delta]
navigate=true
side-by-side=true
[merge]
conflictstyle=diff3
[diff]
colorMoved=default

gitui - Blazing 💥 fast terminal-ui for git written in rust 🦀

gitコマンドの代替です。まだGit操作に慣れてないので、TUIで操作でき便利です。

gitui画面

dust - A more intuitive version of du in rust

duコマンドの代替です。視覚的に容量比率が分かるのでいいです。

dust画面

duf - Disk Usage/Free Utility - a better 'df' alternative

dfコマンドの代替です。視覚的に使用量が分かるのでいいです。

duf画面

ripgrep - ripgrep recursively searches directories for a regex pattern while respecting your gitignore

grepコマンドの代替です。.gitignoreを認識してくれたりとても早いのがいいです。

repgrep画面

# Smart case searchを有効
alias grep='rg -S'
alias -g G='|rg -S'

fzf - 🌸 A command-line fuzzy finder

あいまい検索をしてくれます。絞り込みが楽にできるのがいいです。

fzf画面

# 並び替えなしで、プロンプトに'cd >'を表示
pop() { cd $(dirs -lp | bat -r 2: | fzf --no-sort --prompt='cd >') }
# 最初から$LBUFFERの内容で絞り込み
select-history() { LBUFFER=$(history -Dinr 1 | fzf --no-sort +m --query "$LBUFFER" --prompt="History > " | choose 3:) }

choose - A human-friendly and fast alternative to cut and (sometimes) awk

cutの代替です。指定が分かりやすいのでいいです。

choose画面

jq - Command-line JSON processor

JSONプロセッサーらしいです。全然使いこなしてませんがフォマットして表示してくれるので便利です。

jq画面

gron - Make JSON greppable!

JSONファイルをgrepしやすいようにフィールドごとにフルパスで表示してくれるので便利です。

gron画面

# Jsonファイルをgrep
jgrep() { gron | grep $* | gron -u }

cheat - cheat allows you to create and view interactive cheatsheets on the command-line. It was designed to help remind *nix system administrators of options for commands that they use frequently, but not frequently enough to remember.

manの代替です。簡単にチートシートを作って表示できるので便利です。

cheat画面

# チートシートをbatでシンタックスハイライト
ch() { cheat $* | bat --style=plain -l sh }

bottom - Yet another cross-platform graphical process/system monitor.

topの代替です。グラフィカルに表示されるのでモダンな感じがいいです。(top画面見慣れているなら、-b,--basicオプションが使えます)

bottom画面

hyperfine - A command-line benchmarking tool

timeコマンドの代替です。複数回試行して平均してくれたり、2つのコマンドの速度比較したりできるようです。(まだ使っていない)

hyperfine画面

gnutime - The `time' command runs another program, then displays information about the resources used by that program.

timeコマンドの代替です。メモリ情報も表示してくれます。(内部でgtimeを実行するhyperfineのようなものが欲しいです)

ghutime画面

procs - A modern replacement for ps written in Rust

psコマンドの代替です。ツリー表示だったり検索が楽だったりして便利です。

procs画面

# ツリー表示
alias ps='procs --tree'

zoxide - A smarter cd command. Supports all major shells.

cdコマンドの代替です。過去に移動したことあるディレクトリをいい感じに検索して移動でき便利です。

zoxide画面

# `j`、`ji`に割り当てる
eval "$(zoxide init --cmd j zsh)"

kakoune - Modal editor · Faster as in fewer keystrokes · Multiple selections · Orthogonal design

viコマンドの代替です。viに比べて操作の一貫性が増しているし、ヘルプも表示してくれて便利です。(vi使いこなしてないです。vimを華麗に操作する人を見るとカッコいい!となりますよね)

kakoune画面

starship - The minimal, blazing-fast, and infinitely customizable prompt for any shell!

プロンプトを簡単にカスタマイズできて便利です。

starship画面

trash - This is a small command-line program for OS X that moves files or folders to the trash.

rmコマンドの代替です。Macのゴミ箱に移動してもとに戻せるのが便利です。

# ゴミ箱から戻せるようにする
alias rm='trash -F'

Discussion