在使用 macOS 作为主力机十多年后,最近想尝试一下 Linux,看一看 2026 年的 Linux 桌面环境是否可以提供媲美 macOS 的开发体验。
macOS 的特点就是流畅,字体渲染细腻,不折腾,作为开发环境很省心,而且对于 Emacs 党来说,macOS 还有一点优势,其在系统层面内置了一套 Emacs 风格的光标移动快捷键,在所有原生文本输入框里都能用,不需要任何额外配置,比如:
| 快捷键 | 功能 |
Ctrl+a | 行首 |
Ctrl+e | 行尾 |
Ctrl+f | 前移一字符 |
Ctrl+b | 后移一字符 |
Ctrl+p | 上移一行 |
Ctrl+n | 下移一行 |
Ctrl+d | 删除光标后一字符 |
Ctrl+h | 删除光标前一字符(同 Backspace) |
Ctrl+k | 删除到行尾 |
Ctrl+t | 交换光标前两个字符 |
Ctrl+o | 在光标处插入换行 |
Option+f | 前移一个词 |
Option+b | 后移一个词 |
Option+d | 删除后一个词 |
这套快捷键是 macOS 在 AppKit/Cocoa 层实现的,覆盖 Safari、Chrome、Terminal、所有原生 App 的输入框。因此,在尝试 Linux 的过程中,快捷键对标 macOS 是我很重要的一个指标。
有一点需要说明的是,日常开发使用的软件主要是 Emacs、Brave、Zed、Ghostty,这四个软件天然就是跨平台的,所以在 Linux 上也能使用。因此本文主要记录从 macOS 迁移到 Linux 的过程,系统层面的配置和优化。下图是迁移前后的对比:
发行版选择
选择 Linux 的第一件事情就是确定发行版。不同人有不同的选择,由于公司开发时使用 Ubuntu 环境,因此我更偏向 Ubuntu 这一派系。
一开始尝试的是 Ubuntu 26.04,刚装机不久,在使用时就能感到莫名卡顿, ps 一看,无用的服务一大堆,与其尝试定制这个逐渐商业化的系统, 不如直接转向更轻量、更稳重的 Debian。截止到写文章时,已使用 Debian 13(trixie)一周左右(这篇文章就是在 Debian 上完成 😎),即使装了些后台服务,也丝毫没觉得卡顿。
安装踩坑:离线镜像也会联网
Debian 提供几种 ISO,选之前先搞清楚两个维度:
- netinst(网络安装)— ISO 很小(~400MB),安装过程中从网络拉包。需要全程联网,但装出来的系统最干净,只装你选的东西
- DVD/BD(离线完整镜像)— 包含大量预编译包(3.5G),安装时理论上不需要联网。之所以说是理论上,是因为安装过程中仍然会尝试联网去拉软件包更新,如果不联网就跳过,装完系统后再配置网络和镜像源。
虽然安装时可以选择国内镜像源,但在安装过程中仍然会尝试联网去拉软件包更新,根据安装时已选择国内镜像源,为何还走国外服务器这个帖子的讨论,有些与安全相关的包依然会去国外源拉取,导致安装速度慢,甚至失败。解决方法很简单——在提示联网时直接选择跳过,装完系统再配置网络和镜像源。
固件支持
早期 Debian 官方 ISO — 不含非自由固件(non-free firmware),如果你的网卡、显卡需要私有驱动,装完可能没网、没图形加速。 Debian 12 (bookworm)开始官方把 non-free firmware 合并进了正式 ISO,所以直接下载最新的就可以了。
基础环境
sudo 权限
Debian 默认安装不把普通用户加进 sudoers,需要手动:
1su root
2chmod +w /etc/sudoers
3# 添加一行:your-username ALL=(ALL:ALL) ALL
4chmod -w /etc/sudoers常用工具
1#!/usr/bin/env bash
2function command_exists() {
3 command -v "$1" &> /dev/null
4}
5
6# https://github.com/sharkdp/fd
7# https://github.com/burntsushi/ripgrep
8command_exists fdfind || (sudo apt install -y fd-find && sudo ln -s "$(which fdfind)" /usr/local/bin/fd)
9command_exists rg || sudo apt install -y ripgrep
10
11command_exists vim || sudo apt install -y vim
12command_exists git || sudo apt install -y git
13command_exists make || sudo apt install -y make
14command_exists sshd || sudo apt install -y openssh-server
15command_exists pinentry || sudo apt install -y pinentry-tty
16command_exists g++ || sudo apt install -y build-essential python3-dev
17command_exists pkg-config || sudo apt install -y pkg-config
18command_exists hunspell || sudo apt install -y hunspell hunspell-en-gb hunspell-en-us
19
20[ -d /usr/include/rime ] || sudo apt install -y librime-dev
21
22export UV_NO_MODIFY_PATH=1
23command_exists uv || (curl -LsSf https://astral.sh/uv/install.sh | sh -s -- --no-modify-path)
24command_exists zfetch || (curl -fsSL https://zigcli.liujiacai.net/install.sh | sh -s -- --china)
25command_exists flauth-cli || (curl -fsSL https://jiacai2050.github.io/flauth/install.sh | sh -s -- --china)
26command_exists zed || (curl -f https://zed.dev/install.sh | sh)很惊喜的是,Debian 的官方源里已经有了 fd 和 ripgrep 这两个现代化的命令行工具,Emacs 也是 30 版本,直接 apt 安装就好,不需要自己编译了。
核心挑战:键盘习惯
这是整个迁移里最花精力的部分。在 macOS 上, Cmd+C/V/Z 这套肌肉记忆已经刻进手指了,切到 Linux 之后如果什么都不做,每次复制粘贴都要重新思考用哪个键,极其割裂。
经过一番折腾,最终选择了 xremap,一个支持 Wayland 的键盘重映射工具。
配置思路
分两层:
modmap 层 —— 硬件键位交换:
1modmap: 2- name: Global 3 remap: 4 # Swap Ctrl and CapsLock 5 CapsLock: Ctrl_L 6 Ctrl_L: CapsLock 7 # Swap Alt and Super(模拟 Mac 的 Cmd/Option 位置) 8 KEY_LEFTALT: KEY_LEFTMETA 9 KEY_LEFTMETA: KEY_LEFTALT把 CapsLock 换成 Ctrl(Emacs 必备),同时把 Alt 和 Super 对调,让左手大拇指旁边的键变成
Super(对应 Mac 的Cmd)。keymap 层 ——组合键语义映射:
1keymap: 2- name: Super shortcuts (global except Emacs/Ghostty/Zed) 3 application: 4 not: [Emacs, com.mitchellh.ghostty, dev.zed.Zed] 5 remap: 6 Win-c: C-c # 复制 7 Win-v: C-v # 粘贴 8 Win-x: C-x # 剪切 9 Win-z: C-z # 撤销 10 Win-a: C-a # 全选 11 Win-s: C-s # 保存 12 Win-w: C-w # 关闭标签页 13 Win-t: C-t # 新建标签页 14 Win-n: C-n # 新建窗口 15 Win-f: C-f # 查找关键细节是
application.not列表——Emacs、Ghostty、Zed 这些工具有自己的键位体系,需要排除在外,让它们接收原始键值。 这里附上 Ghostty 的相关配置,供大家参考:theme = light:Primary, dark:Nordfox gtk-titlebar = false keybind = super+alt+arrow_right=next_tab keybind = super+alt+arrow_left=previous_tab keybind = super+t=new_tab keybind = super+w=close_tab keybind = super+1=goto_tab:1 keybind = super+2=goto_tab:2 keybind = super+3=goto_tab:3 keybind = super+4=goto_tab:4 keybind = super+5=goto_tab:5 keybind = super+c=copy_to_clipboard keybind = super+v=paste_from_clipboard
按词移动
macOS 上是 Option+左右箭头 按词移动,Linux 对应的标准是 Ctrl+左右箭头 。在 xremap 里把这个映射进来,在 Brave 等浏览器的输入框里也能用 Emacs 风格的 Meta+b/f 和 Ctrl+a/e :
1 Ctrl-n: down
2 Ctrl-p: up
3 Ctrl-b: left
4 Ctrl-f: right
5 Ctrl-a: home
6 Ctrl-e: end
7 Alt-f: ctrl-right # 向前一个词
8 Alt-b: ctrl-left # 向后一个词
9 Alt-backspace: ctrl-backspace # 删除前一个词
10 Alt-d: ctrl-delete # 删除后一个词服务管理
xremap 以 systemd user service 运行,常用命令:
1systemctl --user enable --now xremap
2systemctl --user status xremap
3journalctl --user -u xremap -fsystemd 的用户服务做得非常好,开机自启、状态管理、日志查看都很方便。相比 macOS 的 launchctl,Linux 的 systemd user service 更加成熟和易用。
GNOME 快捷键清理
GNOME 默认占用了大量 Super 组合键,和 xremap 的映射会打架,需要系统性地清理。
Activities 触发方式
macOS 上用 Raycast( Cmd+Space ),迁移过来自然想用 Super+Space 对应:
1# 禁用单按 Super 触发 Activities(避免误触)
2gsettings set org.gnome.mutter overlay-key ''
3# 改用 Super+Space
4gsettings set org.gnome.shell.keybindings toggle-overview "['<Super>space']"
5# 清掉输入法切换的默认绑定(Super+Space 默认是切换 input source)
6gsettings set org.gnome.desktop.wm.keybindings switch-input-source "[]"
7gsettings set org.gnome.desktop.wm.keybindings switch-input-source-backward "[]"其他冲突键位
1# 工作区切换(会和 Brave 标签切换冲突)
2gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-left "[]"
3gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-right "[]"
4
5# 锁屏
6gsettings set org.gnome.settings-daemon.plugins.media-keys screensaver "[]"
7
8# Dash-to-Dock 的 Super+数字(会抢占 Emacs 的 Meta+数字)
9gsettings set org.gnome.shell.extensions.dash-to-dock hot-keys false
10for i in $(seq 1 9); do
11 gsettings set org.gnome.shell.keybindings switch-to-application-$i "[]"
12done
13
14# 杂项
15gsettings set org.gnome.shell.keybindings toggle-message-tray "[]"
16gsettings set org.gnome.desktop.wm.keybindings show-desktop "['']"
17gsettings set org.gnome.shell.keybindings toggle-quick-settings "['']"
18gsettings set org.gnome.mutter.keybindings switch-monitor []如果你不确定是哪个特定的配置项吞掉了快捷键,可以直接在终端用以下命令全局过滤当前系统中所有绑定了 <Super>n 或 <Alt>n 的 GNOME 设置项:
1gsettings list-recursively | grep -E "(<Super>|<Alt>)[nN]"剪贴板管理
之前在 macOS 中使用的时 Raycast 自带的剪贴板历史功能,很是方便,支持搜索、图片,在 Debian 上尝试了 copyq、gpaste 后,效果很不是很满意, 体验远不如 raycast。目前使用的时 fcitx5 自带的剪贴板历史功能,虽然功能简单,不支持搜索、图片,但胜在稳定、快捷键响应迅速,满足日常使用需求。
对于剪贴板搜索,社区已有 PR:clipboard: allow searching the clipboard history by pslldq · Pull Request #1504 · fcitx/fcitx5,希望未来能原生支持。
输入法:fcitx5 + Rime
ibus 在 Wayland 下体验不理想,直接换 fcitx5:
1sudo apt purge fcitx* ibus*
2sudo apt install --install-recommends fcitx5 fcitx5-rime fcitx5-config-qt
3
4# 设置默认输入法框架
5im-config -n fcitx5之后配置环境变量,让 Qt/GTK 应用都走 fcitx5:
1sudo tee -a /etc/environment << 'EOF'
2XMODIFIERS=@im=fcitx
3QT_IM_MODULE=fcitx
4GTK_IM_MODULE=fcitx
5SDL_IM_MODULE=fcitx
6EOF重新登录后生效,再通过 systemd user service 设置开机自启。参考:Setup Fcitx 5
Rime 的词库和配置沿用之前的,迁移成本很低。唯一的坑是 fcitx5 在 Wayland 下启动有竞态问题,有时莫名其妙的输入法就消失了。临时的解决方式是在 systemd service 里加 ExecStartPre 做 socket 轮询,等 Wayland compositor 就绪后再启动。
1[Unit]
2Description=Fcitx5 Input Method Engine
3After=graphical-session.target
4
5[Service]
6ExecStartPre=/bin/bash -c 'until [ -S $XDG_RUNTIME_DIR/wayland-0 ]; do sleep 0.2; done'
7Type=exec
8ExecStart=/usr/bin/fcitx5
9Restart=on-failure
10
11[Install]
12WantedBy=graphical-session.target另一点问题比较大的是目前 Gnome 桌面不支持 app_options 方式设置输入法状态,导致在特定程序里无法使用英文模式。社区已经有人提了 issue,期待官方修复。
字体渲染
macOS 的字体渲染是出了名的好看,Linux 上要接近这个效果需要仔细调 fontconfig。
安装字体
1sudo apt install fonts-noto-cjk fonts-noto-cjk-extra \
2 fonts-jetbrains-mono fonts-interfontconfig 配置
配置文件路径: ~/.config/fontconfig/fonts.conf
1<fontconfig>
2 <!-- 抗锯齿 -->
3 <match target="font">
4 <edit name="antialias" mode="assign"><bool>true</bool></edit>
5 </match>
6
7 <!-- 次像素渲染:横向排列屏幕用 rgb -->
8 <match target="font">
9 <edit name="rgba" mode="assign"><const>rgb</const></edit>
10 </match>
11
12 <!-- LCD filter:lcddefault 最接近 macOS -->
13 <match target="font">
14 <edit name="lcdfilter" mode="assign"><const>lcddefault</const></edit>
15 </match>
16
17 <!-- Hinting:hintslight 避免字形变形,最接近 macOS 风格 -->
18 <match target="font">
19 <edit name="hinting" mode="assign"><bool>true</bool></edit>
20 <edit name="hintstyle" mode="assign"><const>hintslight</const></edit>
21 </match>
22
23 <!-- 字体映射 -->
24 <alias>
25 <family>sans-serif</family>
26 <prefer>
27 <family>Inter</family>
28 <family>Noto Sans CJK SC</family>
29 </prefer>
30 </alias>
31
32 <alias>
33 <family>monospace</family>
34 <prefer><family>JetBrains Mono</family></prefer>
35 </alias>
36
37 <alias>
38 <family>serif</family>
39 <prefer><family>Noto Serif CJK SC</family></prefer>
40 </alias>
41</fontconfig>几个关键选择:
Inter作为无衬线字体:比 Ubuntu/Noto Sans 更接近 macOS 的 SF Pro 风格hintslight:比 hintfull 保留更多字形细节,不会像素化lcddefault:在主流屏幕上彩色边缘控制最好- 中文 fallback 到 Noto Sans/Serif CJK SC,避免落到质量参差不齐的系统字体
一些常用命令:
1# 配置改了不生效时,手动刷新缓存:
2fc-cache -fv
3# 查看某个字体族实际解析结果
4fc-match sans-serif # 返回 Inter-Regular.otf: "Inter" "Regular"
5fc-match monospace # 返回 JetBrainsMono-Regular.ttf: "JetBrains Mono" "Regular"
6fc-match serif # 返回 NotoSerifCJK-Regular.ttc: "Noto Serif CJK SC" "Regular"
7
8# 查看完整匹配链(包含所有属性)
9fc-match -v sans-serif | grep -E "family|file|hintstyle|lcdfilter|rgba|antialias"
10# 返回
11# family: "Inter"(w)
12# familylang: "en"(s)
13# antialias: True(w)
14# hintstyle: 1(i)(w)
15# file: "/usr/share/fonts/opentype/inter/Inter-Regular.otf"(s)
16# rgba: 1(i)(w)
17# lcdfilter: 1(i)(w)性能调优
禁用 tracker-miner
tracker-miner-fs-3 文件索引服务对我来说没用,直接关掉:
1sudo systemctl --global mask tracker-xdg-portal-3.service
2sudo systemctl --global mask tracker-miner-fs-3.service
3killall tracker-miner-fs-3休眠策略
笔记本作为开发机,不希望跑着任务突然睡过去:
1# 关掉插电时的自动挂起
2gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type 'nothing'总结
整体跑下来,日常使用体验已经很平滑了。 Cmd+C/V 、 Cmd+Tab 、光标移动这些高频操作的肌肉记忆基本没有断裂感。Emacs 目前在 XWayland 下运行,计划后续迁移到 emacs-pgtk 以获得原生 Wayland 支持。
字体渲染在 4K 屏幕上达到了满意的效果,Inter + JetBrains Mono 的组合比默认配置好看很多。
最大的收获是对整个系统的掌控感——知道每个配置项在哪、为什么这么设置,这是 macOS 上做不到的。也许,这就是开源的魅力吧!