Skip to content

Latest commit

 

History

History
400 lines (294 loc) · 17.4 KB

res.org

File metadata and controls

400 lines (294 loc) · 17.4 KB

Emacs config

Emacs 29.x + Mac GUI。字体:Sarasa Term SC Nerd,主题:doom-one。

安装

基础环境

1、安装 emacs-plus

brew reinstall gcc libgccjit
brew tap d12frosted/emacs-plus
brew install emacs-plus@29 --with-cacodemon-icon
ln -s /usr/local/opt/emacs-plus@29/Emacs.app /Applications

卸载 brew uninstall emacs-plus@29

2、安装 Emacs package

git clone https://github.com/zhangjie2012/emacs.d.git ~/.emacs.d

打开 Emacs 时自动安装依赖包。我使用中科大的源(清华源更新经常出问题)。或者官方源 + 代理:

(setq package-archives
      '(("gnu" . "http://elpa.gnu.org/packages/")
        ("melpa" . "https://melpa.org/packages/")
        ("melpa-stable" . "https://stable.melpa.org/packages/")
        ("nongnu" . "https://elpa.nongnu.org/nongnu/")
        ))

(setq url-proxy-services
      '(("no_proxy" . "^\\(localhost\\|10.*\\)")
        ("http" . "127.0.0.1:1087")
        ("https" . "127.0.0.1:1087")))

或者 http_proxy=http://127.0.0.1:7890 emacs

如果遇到安装问题执行 M-x package-refresh-content 然后重启 Emacs。

3、安装依赖二进制

4、安装字体:brew install –cask font-sarasa-nerd[fn:6]

4、安装 nerd-icon:doom-mode-line 4.0.0 之后不再支持 all-the-icons 由 nerd-icons 代替:打开 nerdfont ,下载 Symbols Nerd Font 即可。

开发环境

基于 LSP,客户端使用 eglot

<2023-02-10 Fri> 从 lsp-mode 换到了 eglot。原因:

  • 从需求上:对我来说,必须的功能有 4 个,其他功能也基本没用过:
    1. 跳转到定义、反跳转 M-. M-,
    2. 查找所有引用
    3. 查找所有 interface 实现
  • 从复杂度上:eglot 配置简单(基本上没啥可配置的),lsp-mode 配置复杂(大项目会慢)
  • 从未来发展上:Emacs 29 之后,eglot 会作为内置组件

Go

按照 官方说明 安装 Go,LSP server 用的是 gopls

GO111MODULE=on go install golang.org/x/tools/gopls@latest

lint 工具:

curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.50.1

配置文件在:https://github.com/zhangjie2012/dotfiles/blob/master/_golangci.yaml

另外安装 gomodifytags

go install github.com/fatih/gomodifytags@latest

Python

lsp-server python3 -m pip install 'python-lsp-server[all]'

lint python3 -m pip install flake8 配置文件:https://github.com/zhangjie2012/dotfiles/blob/master/_flake8

format python3 -m pip install black

Web

适用于 React 开发。

使用安装 ESLint npm install -g eslint 。flycheck 配置 ESLint 经常出现各种奇奇怪怪的问题,从来没有一次性成功过,汇总的自查方法:

  1. 全局安装 ESLint,我不使用项目中单独的配置
  2. (setq flycheck-javascript-eslint-executable "eslint") 指定 eslint 路径
  3. flycheck-select-checker 指定 ESLint
  4. flycheck-verify-setup 查看二进制路径和配置文件是否生效
  5. 以上 Emacs 都没问题,但是检测不符合预期,要检查下用的是哪里的配置文件,以及配置文件是否有问题
    • eslint --print-config file.js 查看使用的配置文件是什么
    • eslint file.js 查看错误提示与 Emacs 是否相同
    • 看 eslint 报错,缺什么 全局 安装

核心思路是:先保证 eslint 本身运行没问题,再看 Emacs flycheck 配置是否正常。

目录结构

核心在 core 目录下:

  • init-base 基础设置
  • init-ui 主题、modeline、字体等
  • init-modern 更加现代化:项目管理、多光标操作等
  • init-enhance 对 Emacs 已经具备的能力进行增强
  • init-lang 编码相关
  • init-config yaml, protobuf, nginx, thrift 等轻量化语言配置
  • init-document 标记语言设置,markdown + orgmode
  • init-keymap 额外的快捷键绑定
  • init-feed rss 订阅管理

FAQ

doom-theme 配置备忘

(use-package doom-themes
  :ensure t
  :init
  (defun toggle-theme ()
    (interactive)
    (cond ((eq (car custom-enabled-themes) 'doom-one)
           (mapc #'disable-theme custom-enabled-themes)
           (load-theme 'doom-snazzy t))
          ((eq (car custom-enabled-themes) 'doom-snazzy)
           (mapc #'disable-theme custom-enabled-themes)
           (load-theme 'doom-one t))))
  ;; day/night use diff theme: via https://github.com/jakebox/jake-emacs
  (let ((hour (string-to-number (substring (current-time-string) 11 13))))
    (if (or (> hour 17) (< hour 7))
        (load-theme 'doom-one t)
      (load-theme 'doom-snazzy t)))
  :config
  (setq doom-themes-enable-bold t
        doom-themes-enable-italic nil)
  (doom-themes-visual-bell-config)
  (doom-themes-org-config)
  (global-set-key (kbd "<f5>") 'toggle-theme))

cape + corfu 配置备忘

(use-package cape
  :ensure t
  :init
  (add-to-list 'completion-at-point-functions #'cape-dabbrev)
  (add-to-list 'completion-at-point-functions #'cape-file)
  (add-to-list 'completion-at-point-functions #'cape-keyword)
  (add-to-list 'completion-at-point-functions #'cape-history))

(use-package corfu
  :ensure t
  :hook (prog-mode . corfu-mode)
  :bind (:map corfu-map
              ("C-n" . corfu-next)
              ("C-p" . corfu-previous))
  :config
  (setq corfu-auto t
        corfu-auto-prefix 1
        corfu-auto-delay 0.1
        corfu-quit-no-match t
        corfu-quit-at-boundary t)
  (add-hook 'multiple-cursors-mode-enabled-hook (lambda () (corfu-mode -1)))
  (add-hook 'multiple-cursors-mode-disabled-hook (lambda () (corfu-mode 1))))

projectile 配置备忘

<2023-05-13 Sat> 从 projectile 切换到了 project.el 留一份老的配置备忘:

(use-package projectile
  :ensure t
  :bind (:map projectile-mode-map
              ("<f8>" . projectile-command-map)
              ("C-c p" . projectile-command-map)
              :map projectile-command-map
              ("F" . projectile-find-file-other-window)
              ("w" . projectile-find-file-in-known-projects)
              ("D" . projectile-dired-other-window)
              ("k" . projectile-kill-buffers)
              ("v" . projectile-vc)
              ("b" . projectile-switch-to-buffer))
  :config
  ;; 打开项目缓存, 否则大的项目每次构建会比较慢
  ;; 你可以通过下面两个名称来清除缓存
  ;; - projectile-purge-file-from-cache
  ;; - projectile-purge-dir-from-cache
  (setq projectile-enable-caching t)
  ;; projectile 有三种构建索引的方式: native, hybird, alien
  ;;   native 使用 Emacs lisp 实现, hybird/alien 使用外部命令类似 find, git 来实现
  ;;   alien 优化了 hybird 的性能: 它不会对外部命令返回的结果做任何处理和排序, 以获得最好的性能
  ;;   使用外部命令的话, 类似 .gitignore 会自动生效
  ;; 注意: alien 会忽略 .projectile 文件
  (setq projectile-indexing-method 'alien)
  ;; 在每个目录下都可用(即使没有项目文件)
  (setq projectile-require-project-root 'prompt)
  ;; 对结果进行排序(active buffer + recently opened)
  (setq projectile-sort-order 'recentf-active)

  ;; fix windows system "projectile-find-file" throw
  ;; 'tr' is not recognized as an internal or external command ...
  ;; via: https://github.com/bbatsov/projectile/issues/1302
  (setq projectile-git-submodule-command nil)
  (defun project-find-go-module (dir)
    (when-let ((root (locate-dominating-file dir "go.mod")))
      (cons 'go-module root)))

  (cl-defmethod project-root ((project (head go-module)))
    (cdr project))

  :init
  (projectile-mode +1))

Emacs 启动速度太慢怎么办?

M-x emacs-init-time 可以查看 Emacs 启动耗费时间。

多一个插件都会增加启动成本,不信你 emacs -Q 试试,所以要尽可能的减少插件。你可以使用 keyfreq 来查看你常用的快捷键有哪些。 筛选出不常用的插件给干掉,这是解决启动速度慢的根本办法。

如何定位插件耗时?

定位之后如何优化?

elisp 比较熟的有自己的办法优化,当然我不熟。我的解决办法是:

使用 use-package ,use-package 并不是包管理工具,只是一个宏,用来配置和加载包。你可以通过配置(合理的使用 init、config、hook、 bind 等)实现延迟加载,提高打开的速度。

Org _ ^ 不被转义成下标和上标?

可以在 +OPTIONS 中设置 ^:nil 来禁掉它。

Org 9.2 后继续使用 <s [Tab] 快捷插入?

orgmode 9.2 之后不再直接支持 <s [Tab] 的快捷方式插入代码块,而提供了统一的 org-insert-structure-template 函数, 快捷键为 C-c C-, 。如果想要提供以前的简洁方式,需要引入 org-tempo ,比如 (require 'org-tempo) 我使用的是 (use-package org-tempo) 。具体见:

Org TODO 如何区分优先级?

  1. 任务可以分优先级 [#A], [#B], [#C] 三种。使用 <shift> + <up/down> 进行切换
  2. org-sort-entris 对任务进行排序(很有用),选择按照权重 [p]riority 排序

Org 控制标题展开?

打开文件后,控制几级标题展示 #STARTUP 选项:

#+STARTUP: overview
#+STARTUP: content
#+STARTUP: showall
#+STARTUP: show2levels
#+STARTUP: show3levels
#+STARTUP: show4levels
#+STARTUP: show5levels
#+STARTUP: showeverything

全局在 org 配置中打开 org-startup-fold [fn:1]。

Org 文档如何展示目录?

  1. 新建 Table Of Content 以及标题,后面加上 :TOC: 注解,保存自动生成
  2. 控制显示多级标题 TOC_n ,默认为 TOC_2 ,即显示到两级标题

tab 和空格转换?[fn:2]

  • tabify 空格转 tab
  • untabify tab 转空格

为什么选择 LSP?

语言的开发环境配置一直很费时间,我记得以前刚配置 C/C++ 的开发环境时,折腾了一个月左右时间才找到一个相对比较 满意的开发环境(折腾完之后使用起来可真爽啊): xcscope + etags + c++-mode

写 Python 的时候也折腾了长时间的缩进问题。 Go 就更不用说了···,Go 工具链很完整,但由于 Go 的版本升级很快,工具链根本跟不上, gocode 已经迁移了三次地址了。

后来看到了 LSP(Language Server Protocol) 项目,感觉这个项目才是终极解法:插件化,C/S 模式。 目前已经默认支持 Python 和 Go 了,虽然还是有许许多多的 Bug,但比起 2018 年我试的时候已经成熟太多了。有社区的驱动,发展很快。

  1. lsp-workspace-folders-remove 可以移出之前添加的 workspace,但是如果遇到大的目录变更,一个一个的移出很慢。 目前似乎没有提供一次性 remove all 的方法。一个解决办法是删除 lsp 的存储文件(lsp 提供了 lsp-session-file 变量来定义文件路径, 默认在 .emacs.d/.lsp-session-* 路径下,如果没找到也可以在 lsp 源代码中搜索 lsp-session-file)。
  2. 当前 LSP 还不太稳定 ,遇到各种问题就可以重启是最有效的办法: lsp-workspace-restart

lsp-mode 的功能比较多,官方提供了 开启/关闭 lsp-mode 特性介绍,否则真的抓瞎。

<2023-02-10 Fri> 由 lsp-mode 换到了 eglot。

项目管理?

使用 projectile 管理项目,非常方便。svn/git 项目会认为是一个 projectile,而且 ignore 的文件和目录也会自动过滤。 你也可以手动添加 .projectile 标识。

已经切换到内置的 project.el

写 Go 代码时如何禁用注释中自动补全?

company 只是个补全框架,实现依赖于底层语言的补全工具(lsp)。

之前给 lsp-mode 提过 issue:emacs-lsp/lsp-mode#2215 ,后来也没有提供直接的解决方案。

事实上,lsp-go 中有控制,但没有暴露出去。我简单粗暴的把 lsp-go.el 中的 completion-in-comments 设置为了 nil , 然后删掉 lsp-go.elc 文件。

英文 Ubuntu 下输入法无法切换中文?

核心解决思路是加上(据说是 fctix 的 bug) env LC_CTYPE=zh_CN.UTF-8 环境变量。解决办法:

  1. GUI 修改 /usr/share/application/emacs.desktop 中的启动命令 Exec=env LC_CTYPE=zh_CN.UTF-8 /usr/bin/emacs %F
  2. TUI 就简单了,直接在 .bashrc 加个 alias

具体可以见这个帖子:https://emacs-china.org/t/topic/974/20 ,正如 scutdk 所说,修改系统全局的 locale 可能带来其他问题。

其他资料

有点乱,参差不齐:

Footnotes

[fn:6] https://github.com/laishulu/Sarasa-Term-SC-Nerd

[fn:5] https://emacs-china.org/t/homebrew-emacs-plus-28/19106

[fn:4] https://github.com/joaotavora/eglot#emacscore

[fn:3] https://github.com/jwiegley/use-package

[fn:2] https://www.masteringemacs.org/article/converting-tabs-whitespace

[fn:1] https://stackoverflow.com/questions/52722096/build-emacs-and-gnutls-not-found