我的极简 emacs 配置

刚毕业的时跟着第一任 leader 学了 Emacs,一直用到现在。也许 Vi/Vim 可能是更实用一些(服务器上随处可见,同事们也大多用它),但我的肌肉记忆已经长在 Emacs 键位上,我尝试熟悉 Vim 这些快捷键, 但是实在无法适应。平时主要还是使用 CLion(我买过最贵的软件, 同时也是最值得),但是远程开发或者简单修改测试, 还是切换成 Emacs, CLion 的 remote 体验非常差。CLion 有默认的 Emacs keymap,可以无缝随意切换。

这份配置奉行”够用就好”:启动快、界面干净、键位比默认的更顺手。尽量使用内置功能解, 只使用了两个插件——neotree 做文件树,undo-tree 支持撤销重做。Spacemacs 这种巨大的配置项目,但对我来说太重了;我更喜欢使用自己能完全看懂的东西。

source: https://github.com/duanfuxiang0/emacs

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Emacs 配置文件 - fuxiang
;; 最后更新: 2022
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 界面外观配置
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; 主题设置 - 使用内置的深色主题护眼
(load-theme 'wombat t)

;; 隐藏滚动条
(when (fboundp 'scroll-bar-mode)
  (scroll-bar-mode -1))

;; 隐藏菜单栏
(when (fboundp 'menu-bar-mode)
  (menu-bar-mode -1))

;; 隐藏工具栏
(when (fboundp 'tool-bar-mode)
  (tool-bar-mode -1))

;; 显示行号
(global-display-line-numbers-mode t)

;; 隐藏欢迎界面
(setq inhibit-splash-screen t)

;; 禁用系统蜂鸣声,改用视觉提示
(setq visible-bell t)

;; 设置字体和大小
(set-frame-font "Monaco 20" nil t)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 编辑器行为配置
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; 默认使用 ido mode
(ido-mode 1)
;; 让 Ido 接管所有地方
(ido-everywhere 1)

;; 使用 y/n 替代 yes/no
(defalias 'yes-or-no-p 'y-or-n-p)

;; 与系统剪贴板集成 (macOS)
(setq select-enable-clipboard t)
(setq select-enable-primary t)
(setq save-interprogram-paste-before-kill t)

;; macOS 强制使用 pbcopy/pbpaste
(defun copy-to-osx-clipboard (text &optional push)
  "Copy TEXT to macOS clipboard using pbcopy."
  (let ((process-connection-type nil))
    (let ((proc (start-process "pbcopy" "*Messages*" "pbcopy")))
      (process-send-string proc text)
      (process-send-eof proc))))

(defun paste-from-osx-clipboard ()
  "Paste from macOS clipboard using pbpaste."
  (shell-command-to-string "pbpaste"))

(setq interprogram-cut-function 'copy-to-osx-clipboard)
(setq interprogram-paste-function 'paste-from-osx-clipboard)

;; 使用空格替代制表符
(setq-default indent-tabs-mode nil)

;; 设置制表符宽度为 2 个空格
(setq tab-width 2)

;; 退出 Emacs 时不需要确认
(setq confirm-kill-emacs nil)

;; 关闭包含进程的 buffer 时不需要确认
(setq kill-buffer-query-functions
  (remq 'process-kill-buffer-query-function
        kill-buffer-query-functions))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 自动保存和备份配置
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; 启用自动保存功能(类似 VSCode 行为)
(setq auto-save-default t)
(setq auto-save-interval 100)   ;; 每 100 次按键后自动保存
(setq auto-save-timeout 10)     ;; 闲置 10 秒后自动保存
(setq auto-save-file-name-transforms
      `((".*" "~/.emacs.d/auto-save-list/" t)))

;; 备份文件配置 - 保存到专用目录
(setq make-backup-files t)
(setq backup-directory-alist '((".*" . "~/.emacs.d/backups/")))
(setq version-control t)        ;; 使用版本号管理备份
(setq kept-new-versions 10)     ;; 保留最新的 10 个版本
(setq kept-old-versions 0)      ;; 不保留旧版本
(setq delete-old-versions t)    ;; 自动删除多余的备份

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 鼠标支持配置
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; GUI 模式下的鼠标滚轮支持
(when (fboundp 'mouse-wheel-mode)
  (mouse-wheel-mode t))
(setq mouse-wheel-scroll-amount '(1 ((shift) . 1)))
(setq mouse-wheel-progressive-speed nil)
(setq mouse-wheel-follow-mouse t)

;; 终端模式下的鼠标支持
(unless window-system
  (require 'mouse)
  (xterm-mouse-mode t)
  (global-set-key [mouse-4] (lambda ()
                              (interactive)
                              (scroll-down 1)))
  (global-set-key [mouse-5] (lambda ()
                              (interactive)
                              (scroll-up 1)))
  (defun track-mouse (e))
  (setq mouse-sel-mode t))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 快捷键配置
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; 跳转到指定行: Ctrl+c Ctrl+g
(define-key global-map "\C-c\C-g" 'goto-line)

;; Undo/Redo 快捷键
(global-set-key (kbd "C-/") 'undo-tree-undo)     ;; Ctrl+/ 撤销
(global-set-key (kbd "C-_") 'undo-tree-undo)     ;; Ctrl+Shift+- 撤销(备用)
(global-set-key (kbd "C-?") 'undo-tree-redo)     ;; Ctrl+Shift+/ 重做
(global-set-key (kbd "M-z") 'undo-tree-redo)     ;; Alt+z 重做(更方便)

;; 上下移动当前行: Meta+上/下方向键
(global-set-key (kbd "M-<up>") 'move-line-up)
(global-set-key (kbd "M-<down>") 'move-line-down)

;; NeoTree 文件树: F8 键切换显示
(global-set-key [f8] 'neotree-toggle)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 自定义功能函数
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; 上下移动行的功能实现(支持单行和多行)
;; 参考 move-text.el 实现

(defun move-text-region (start end n)
  "向上或向下移动选中区域 N 行."
  (let ((line-text (delete-and-extract-region start end)))
    (forward-line n)
    (let ((start-pos (point)))
      (insert line-text)
      (setq deactivate-mark nil)
      (set-mark start-pos))))

(defun move-text-line-up ()
  "向上移动当前行."
  (let ((col (current-column)))
    (transpose-lines 1)
    (forward-line -2)
    (move-to-column col)))

(defun move-text-line-down ()
  "向下移动当前行."
  (let ((col (current-column)))
    (forward-line 1)
    (transpose-lines 1)
    (forward-line -1)
    (move-to-column col)))

(defun move-line-up ()
  "向上移动当前行或选中的多行."
  (interactive)
  (if (region-active-p)
      (move-text-region (region-beginning) (region-end) -1)
    (move-text-line-up)))

(defun move-line-down ()
  "向下移动当前行或选中的多行."
  (interactive)
  (if (region-active-p)
      (move-text-region (region-beginning) (region-end) 1)
    (move-text-line-down)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 外部插件和模式配置
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Org Mode 配置
(setq org-startup-indented t)

;; NeoTree 文件树插件
(add-to-list 'load-path "~/.emacs.d/neotree")
(require 'neotree)
(setq neo-theme (if (display-graphic-p) 'icons 'arrow))

;; Rust 语言
(add-to-list 'load-path "~/.emacs.d/rust-mode")
(autoload 'rust-mode "rust-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode))

;; undo-tree - 提供类似 VSCode 的 undo/redo 功能
(add-to-list 'load-path "~/.emacs.d/undo-tree")
(require 'undo-tree)
(global-undo-tree-mode)

;; undo-tree 配置
(setq undo-tree-auto-save-history t)  ;; 自动保存 undo 历史
(setq undo-tree-history-directory-alist '((".*" . "~/.emacs.d/undo-tree-history/")))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Custom 自动生成配置(请勿手动编辑)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(word-wrap nil))

(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )
Hello World
Codis vs redis 集群