有想重写 emacs
配置的想法很久了,一直因为各种原因而没实施,今天终于开始重写了。
上一份 emacs
的配置是参考 prelude 写的,新版本依然会按照其架构( core
, modules
, personal
)配置。
但具体的配置模块会根据自我需求一一重写,同时会记录下配置过程。
作为代码编辑器最重要的是编辑功能和代码补全功能,重写的重点也是在这两方面,详细如下:
aspell-en
拼写检查
mlocate
counsel-locate
使用silversearcher-ag
counsel-ag
和helm-ag
使用git
magit
使用golang
go
代码支持,需要执行bash ./misc/golang_install_binaries.sh
安装依赖的命令c/c++
使用
ccls
提供代码补全功能,配置方法见 ccls 配置使用global
默认使用
gtags
进行代码阅读libtool-bin
vterm
依赖texlab
LaTex
代码补全,从 https://github.com/latex-lsp/texlab/releases 下载,目前会偶现cpu 100%
的问题,也可换用digestif
。使用
lsp-latex
时可通过lsp-latex-build
编译tex=文件,但需要设定 =~/.latexmkrc
文件,可从./templates/
中复制,默认用的是lualatex
。luarocks, digestif
sudo apt install luarocks liblua5.3-0 liblua5.3-dev
,sudo luarocks --server http://luarocks.org/dev install digestif
。用digestif
作为默认的lsp-tex-server
,可通过wen-tex-server
修改。pip install pygments
LaTex
代码高亮graphviz
dot/plantuml
画图default-jdk
plantuml
画图trans
immersive-translate backend,
wget git.io/trans
git clone https://github.com/jouyouyun/emacs.d-reborn ~/.emacs.d
把 loaded-modules-simple.el
复制到 personal/
下,并重命名为 loaded-modules.el
。
ln -svf ~/.emacs.d/pyim ~/.local/share/
wen-frontend
默认使用
ivy
,如需使用helm
,请添加以下内容:(setq wen-frontend "helm")
wen-terminal
默认使用
ansi-term
,如需使用vterm
,请添加以下内容:(setq wen-frontend "vterm")
Directory Tracking
功能需要SHELL
配合,zsh
需要添加的配置如下:ansi-term
if [ -n "$INSIDE_EMACS" ]; then chpwd() { print -P "\033AnSiTc %d" } print -P "\033AnSiTu %n" print -P "\033AnSiTc %d" fi
vterm
# https://github.com/akermu/emacs-libvterm vterm_printf(){ if [ -n "$TMUX" ]; then # Tell tmux to pass the escape sequences through # (Source: http://permalink.gmane.org/gmane.comp.terminal-emulators.tmux.user/1324) printf "\ePtmux;\e\e]%s\007\e\\" "$1" elif [ "${TERM%%-*}" = "screen" ]; then # GNU screen (screen, screen-256color, screen-256color-bce) printf "\eP\e]%s\007\e\\" "$1" else printf "\e]%s\e\\" "$1" fi } vterm_prompt_end() { vterm_printf "51;A$(whoami)@$(hostname):$(pwd)"; } setopt PROMPT_SUBST PROMPT=$PROMPT'%{$(vterm_prompt_end)%}'
init.el
文件是 emacs
启动后入口,故在这个文件中实现配置文件的模块化加载, 模块目录的说明如下:
core
: 存放核心模块,必须加载modules
: 存放可选模块,根据配置文件loaded-modules.el
的设置加载personal
: 存放私有模块,自动扫描加载
init.el
配置的关键代码:
(defvar config-dir (file-name-directory load-file-name)
"Emacs configuration root dir.")
(defvar config-core-dir (expand-file-name "core" config-dir)
"Emacs core modules dir.")
(defvar config-modules-dir (expand-file-name "modules" config-dir)
"Emacs optional modules dir.")
(defvar config-personal-dir (expand-file-name "personal" config-dir)
"Emacs personal modules dir.")
(defvar config-modules-file (expand-file-name "loaded-modules.el" config-personal-dir)
"This file contains a list of optional modules will be loaded.")
core
中的模块需要全部加载,但模块之间有顺序要求,所以需要在一一按顺序 require
(require 'core-packages)
(require 'core-custom)
(require 'core-ui)
(require 'core-buffer)
(require 'core-window)
(require 'core-editor)
(require 'core-projects)
(require 'core-search)
(require 'core-env-path)
(require 'core-terminal)
**注意:** core-custom.el
定义了一些配置项,若在 personal
中改了默认值,需要紧随其后加载。
modules
中的模块通过 personal/loaded-modules.el
指明需要加载的模块,故直接加载这个文件
(if (file-exists-p config-modules-file)
(progn
(load config-modules-file))
(message "Missing optional modules file %s" config-modules-file)
(message "You can get started by copying the example file from sample/loaded-modules/el"))
personal
目录下的所有模块都会被加载,模块之间不应有顺序要求,加载时要过滤掉 loaded-modules.el
文件
(when (file-exists-p config-personal-dir)
(message "Loading personal modules in %s..." config-personal-dir)
(mapc 'load (delete
config-modules-file
(directory-files config-personal-dir 't "^[^#\.].*\\.el$"))))
package
模块中设置了仓库,提供了 packages
更新的接口并包装了安装函数。
关键代码如下:
;; repository help: https://mirror.tuna.tsinghua.edu.cn/help/elpa/
(setq package-archives '(
("gnu" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
("melpa" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")
("org" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/org/")))
(defun wen-require-package (package)
"Install PACKAGE unless already installed."
(unless (memq package preloaded-packages)
(add-to-list 'preloaded-packages package))
(unless (package-installed-p package)
(package-install package)))
(defun wen-require-packages (packages)
"Ensure PACKAGES are installed."
(mapc #'wen-require-package packages))
(defun wen-update ()
"Update Wen to its latest version."
(interactive)
(when (y-or-n-p "Do you want to update Wen? ")
(message "Updating installed packages...")
(epl-upgrade)
(message "Updating Wen...")
(cd config-dir)
(shell-command "git pull")
(wen-recompile-init)
(message "Update finished. Restart Emacs to complete the process.")))
(defun wen-update-packages ()
"Update Wen's packages."
(interactive "P")
(when (y-or-n-p "Do you want to update packages? ")
(if arg
(epl-upgrade)
(epl-upgrade (cl-remove-if-not (lambda (p) (memq (epl-package-name p) preloaded-packages))
(epl-installed-packages))))
(message "Update finished. Restart Emacs to complete the process.")))
主题根据 wen-theme
变量指定,默认是 zenburn
。
字体这块目前只提供了字体放大和缩小的功能,字体的配置跟随系统。
常用快捷键如下:
C-+ # 调大字体
C-- # 调小字体
使用 seethru
实现透明度的更改。
常用快捷键如下:
C-c 8 # 调大透明度
C-c 9 # 调小透明度
C-c 0 # 重置透明度
Buffer
的管理与使用的 frontend
密切相关,支持 ivy
和 helm
,默认使用 ivy
.
常用快捷键如下:
C-c C-r # 恢复上一次的补全
F6 # 恢复上一次的补全
C-s # 使用 swiper 搜索
M-x # 使用 counsel 补全
C-x C-f # 访问文件
F1 f # 显示函数描述
F1 v # 显示变量描述
F1 l # 显示 library 描述
F2 i # 查找 symbol
F2 u # 插入 unicode char
C-c g # 在当前 git 项目中查找文件
C-c j # 在当前 git 项目中搜索
C-c k # 使用 ag 搜索当前目录
C-x l # 调用 locate 命令
C-c s # tramp for ssh, docker
C-c p # 项目管理
M-t # gtags 查找定义
M-r # gtags 查找引用
M-s # gtags 查找符号
M-, # gtags 回到上一次的 stack
常用快捷键如下:
S-? # 使用 ag 搜索
C-c h # helm 快捷键帮助
C-c p h # 打开项目导航
使用 ace-window
来进行窗口切换。
常用快捷键如下:
C-x o # 窗口调整
使用 projectile
管理项目, frontend
也提供了对应的集成插件,故具体的配置在 core-ivy
或 core-helm
中。
快捷键前缀是 C-c p
editorconfig
自动根据项目中的
.editorconfig
来配置编辑器avy
快速跳转到指定的字符,单词和行,常用快捷键如下:
M-g c # 跳转到字符 M-g w # 跳转到单词 M-g f # 跳转到行
anzu
高亮匹配的内容,替代了
query-replace
和query-replace-regexp
,快捷键如下:M-% # 查找并替换 C-M-% # 正则查找并替换
multi-cursor
多光标模式,可快速更改多个相同的匹配项。常用快捷键如下:
C-S-c C-S-c # 编辑选中区域中的每一行 C-> # 标记下一个匹配项 C-< # 标记上一个匹配项 C-c C-< # 标记所有的匹配项 C-c C-s # 跳到下一个匹配项
popup-kill-ring
显示
kill-ring
历史,常用快捷键如下:M-y # 显示历史列表
whole-line-or-region
复制整行或选中的区域,快捷键如下:
M-w # 复制
- 注释
注释整行或选中区域,快捷键如下:
M-; # 注释
flyspell
拼写检查,依赖
aspell
需要安装aspell-en
tab
使用
space
替换tab
作为缩进,width
为4
另外不同的语言需要单独设置
expand-region
快捷选中表达式,快捷键是:
C-=
smartreq/operate-on-number
数值计算操作,以
C-c .
引导- 其他
- 括号高亮
使用
highlight-parentheses
实现高亮,会高亮选中行 - 自动匹配括号
使用
smartparens
实现,不全局启动,只打开指定语言 - 自动加载文件当文件发生改变
- 保存访问历史
- 括号高亮
使用 eshell
和 multi-term(zsh)
,配置如下:
C-x m # 启动或切换到激活的 eshell
C-x M # 开启一个新的 eshell
C-x M-m # 开启一个普通的 shell
C-c M-t # 打开 shell,默认是 zsh
C-c C-c # 终止
C-c M-e # 发送 ESC 键
C-c M-[ # 切换到前一个 shell
C-c M-] # 切换到后一个 shell
C-c C-j # term line 模式
C-c C-k # term char 模式,可编辑
C-p # 上一行
C-n # 下一行
C-r # 搜索历史
C-y # 粘贴
M-f # 跳到前一个单词
M-b # 调到后一个单词
M-DEL # 删除前一个单词
M-d # 删除当前单词
每次启动后随机提示一个快捷键的功能
目前只实现了基本框架,但 =tips= 内容没有填充完毕,后续继续添加
模块中主要设置各种语言,如 tab
设置、补全设置等。其中重要的是 company
和 lsp
的配置,语言的自动补全默认使用 lsp
来实现,所以有些语言需要安装 language server
才能使用,这点需要注意。