释放小七猫的分享欲

使用 nix-darwin 为 sonoma 配置一个简洁高效的 zsh

tags: 终端, 编辑器
@ 29/04/2024

更新原因:用了很久的 homebrew,感觉不是很完美,就尝试切换到了 nix,挺香的。

不过本文仅适合入门,nix 也仅配置了 flake 和 configuration,不包括 home-manager(macos 上问题太多)。


游戏本 xxxx

macbook ++++

自己拿一台游戏本,整天折腾 linux,消磨了我很多时光。遂重新审视自己的需求,发现其实游戏玩的不多,故卖之,换 macbook。

但是终端不像 Arch 那么好配置了,所以还是记录一下吧。

安装 Darwin-nix

一行代码解决

sh <(curl -L https://nixos.org/nix/install)

终端输入 nix,有输出则说明成功,使用 nix 必须使用科学上网工具,如果没有请滑走。

nix 基本方案说明

本人仅使用 nix 配置终端工具,且不包括 python(我使用自带 python+pdm,更方便,nix 先天不善于处理 python)

nix 简单配置

在 ~/.zprofile 中添加

export NIX_PATH=darwin-config=$HOME/.nixpkgs/darwin-configuration.nix:/nix/var/nix/profiles/per-user/root/channels:$HOME/.nix-defexpr/channels:nixpkgs-overlays=$HOME/.nixpkgs/overlays/:nixpkgs-overlays=$HOME/.nixpkgs/overlays/

然后 clone 我的模板仓库https://github.com/songguokunsgg/nixos-darwin-config

将 clone 下来的文件夹移动为 ~/.nixpkgs

将 flake.nix 中的主机名修改为你自己的主机名

然后 cd 到~/.nixpkgs, 使用以下命令进行第一次安装

nix run nix-darwin --extra-experimental-features nix-command --extra-experimental-features flakes -- switch --flake .

后续使用这两行命令进行升级

nix flake update ~/.nixpkgs
darwin-rebuild switch --flake ~/.nixpkgs

如果没有找到 darwin-rebuild,检查环境变量。

仓库的 README 有一些其他说明,可酌情查看。

zsh 配置

配置思路

主要用到 4 个插件:

  • zsh-autosuggestions
  • zsh-syntax-highlighting
  • zsh-completions(可选)
  • zsh-theme-powerlevel10k(可选)

前三个是功能性插件,最后一个是主题插件,如果对美观要求不高的话,可以不装最后一个

拉取功能插件

# 建议补全
git clone --depth=1 https://github.com/zsh-users/zsh-autosuggestions ~/.zsh/plugins/zsh-autosuggestions

# 语法高亮
git clone --depth=1 https://github.com/zsh-users/zsh-syntax-highlighting ~/.zsh/plugins/zsh-syntax-highlighting

# 自动补全
git clone --depth=1 https://github.com/zsh-users/zsh-completions ~/.zsh/plugins/zsh-completions

# p10k 主题
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/.zsh/plugins/powerlevel10k

将 zsh 的插件统一放置在 ~/.zsh/plugins/ 下

安装字体

推荐使用 nerd-fonts-hack 字体作为终端字体

编写 zsh 配置文件

环境变量存放位置为 ~/.zprofile,配置文件在 ~/.zshrc,主要编写 ~/. zshrc 文件

将以下代码加入 .zshrc 以使用插件

fpath=(~/.zsh/plugins/zsh-completions/src $fpath)
autoload -Uz compinit
if [[ -n ~/.zcompdump(#qN.mh+168) ]]; then
  compinit
else
  compinit -C
fi
# ========== zsh-completions 常用配置 ==========
# 1. 基础核心(必须)
zstyle ':completion:*' menu select                    # 菜单选择补全
zstyle ':completion:*' rehash true                    # 新命令立即生效(必加)
zstyle ':completion:*' use-cache on                   # 补全缓存(提速)
zstyle ':completion:*' cache-path ~/.zsh/cache        # 缓存路径

# 2. 智能匹配 + 模糊补全(体验神器)
zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
zstyle ':completion:*' max-errors 2                   # 允许输错 2 个字符仍补全

# 3. 交互体验优化(必开)
setopt ALWAYS_TO_END                                  # 补全后光标跳到末尾
setopt COMPLETE_IN_WORD                               # 单词中间也能正常补全

# 4. 显示美化(清晰好看)
zstyle ':completion:*' group-name ''                  # 自动分组显示
zstyle ':completion:*:descriptions' format '%B--- %d ---%b'  # 分组标题
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS} # 彩色补全
zstyle ':completion:*:default' list-prompt '%S%M matches%s'  # 显示匹配数
zstyle ':completion:*' file-sort modification         # 文件按修改时间排序(最近优先)

# 5. 路径补全优化
zstyle ':completion:*' expand yes                     # 展开路径
zstyle ':completion:*' squeeze-slashes yes            # 合并 // 为 /

# 6. kill 进程补全(实用必备)
zstyle ':completion:*:*:kill:*' menu yes select
zstyle ':completion:*:processes' command 'ps -au$USER'

source ~/.zsh/plugins/powerlevel10k/powerlevel10k.zsh-theme
source ~/.zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh
source ~/.zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

然后进行功能配置,直接复制粘贴下面代码即可

### 常用命令别名 {{{
alias cp='cp -i'
alias mv='mv -i'
alias rm='rm -i'
alias ls='ls -a --color=auto'
alias ll='ls -al --color=auto'
alias grep='grep --color=auto'
# alias nvim="nvim -u ~/.config/nvim/init-plugin.lua"
# }}}

### 个性化功能配置 {{{
# 容器相关
pm_ls()         { podman ps -a; }
pm_ls_net()     { podman network ls; }
pm_ls_pod()     { podman pod ls; }
pm_stop_all()   { podman stop $(podman ps -q); }
pm_start_all()  { podman start $(podman ps -aq); }
pm_rm_all()     { pm_stop_all; podman rm $(podman ps -q); }
pm_rm_pod_all() { pm_stop_all; podman pod rm $(podman pod list -q); }
pm_clean()      { podman system prune -a --volumes; }

# 更新软件
update() { sudo apt update; sudo apt full-upgrade -y; }

# 清理垃圾
clean() { sudo apt clean; sudo apt autoremove -y; pm_clean; }

# 双击 ESC 在命令前插入 sudo
sudo-command-line() {
    [[ -z $BUFFER ]] && zle up-history
    [[ $BUFFER != sudo\ * ]] && BUFFER="sudo $BUFFER"
    zle end-of-line                 #光标移动到行末
}
zle -N sudo-command-line
bindkey "\e\e" sudo-command-line
# }}}

### 终端代理 {{{
hostip="127.0.0.1"
# hostip=$(cat /etc/resolv.conf |grep -oP '(?<=nameserver\ ).*')
proxy_on() {
    proxy_status="on"
    export https_proxy="http://${hostip}:7890"
    export http_proxy="http://${hostip}:7890"
    export all_proxy="socks5://${hostip}:7890"
    echo -e "终端代理已开启。"
}

proxy_off(){
    unset http_proxy https_proxy all_proxy
    echo -e "终端代理已关闭。"
    proxy_status="off"
}
# }}}

### 历史纪录相关配置 {{{
# 历史文件路径
export HISTFILE="$HOME/.zsh/.zsh_history"
# 历史纪录条目数量
export HISTSIZE=200
# 注销后保存的历史纪录条目数量
export SAVEHIST=200
# 以附加的方式写入历史纪录
setopt INC_APPEND_HISTORY
# 如果连续输入的命令相同,历史纪录中只保留一个
setopt HIST_IGNORE_DUPS
# 为历史纪录中的命令添加时间戳
setopt EXTENDED_HISTORY
# 启用 cd 命令的历史纪录,cd -[TAB]进入历史路径
setopt AUTO_PUSHD
# 相同的历史路径只保留一个
setopt PUSHD_IGNORE_DUPS
#  转换时间戳并打印历史命令
hist() {
  # 获取参数:不传则显示全部,传数字则显示最近 N 条
  local lines="${1:-0}"

  awk -F': |:0;' '
    /^: [0-9]+:[0-9]*;/ {
      printf "%s | %s\n", strftime("%Y-%m-%d %H:%M:%S", $2), $3
    }
  ' $HISTFILE | if [ "$lines" -gt 0 ] 2>/dev/null; then
    tail -n "$lines"
  else
    cat
  fi
}
# }}}

### 杂项 {{{
# 编辑器
export EDITOR=vim
export VISUAL=vim
# 禁用 core dumps
limit coredumpsize 0
# 以下字符视为单词的一部分
WORDCHARS='*?_-[]~=&;!#$%^(){}<>'
# }}}

主题配置

p10k 在首次进入时需要进行配置,按照提示进行即可,配置之后,会在 zshrc 行首和行尾分别添加

if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
  source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi

以及

# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh

需要把上面三句代码移动到 4 个 source 的后面,否则每次启动终端都会报错

搞定收工