Emacs的小技巧,注释,tab,undo和lsp补全

Clloz · · 4,558次浏览 ·

前言

在使用 emacstabundoredo 的时候,emacs 的反应和我们平常使用的一些编辑器或者 IDE 很不一样,有时候按 tab 缩进是 4 格,有时候缩进是 2 格,有时候不管怎么按都没反应。undo 一般大家都知道,一般有几个快捷键可用:C-_C-x uC-/,但是 redo 的操作新手可能不太了解。最后还有注释和 lsp 补全的使用,以及在命令行中用 emacs 的一些注意点。

本文的内容是在 spacemacs 的基础上的一些配置,可能有些内容需要单独在进行一些配置。

alt 问题

mac 的终端上会出现 alt 无法使用的情况,因为 macoption 默认是用来输入特殊符号的,所以我们要禁用掉特殊符号这个功能,在 iTerm2 里面直接在 Profiles 里面的 keys 选项卡中的 left option 选择为 +ESC 即可。如果是 terminal 则直接在 preferences->Profiles->keyboard 的最下面勾选上 用 option 键作为 meta 键。如果是在 windows 中一般不会在终端使用 emacs,如果是通过 ssh 链接服务器,那么也可以在 xshell 中设置 将左alt键用作meta键。其实 emacs 中的 M-x 中的 M 就是 meta 键的意思,它在不同的系统代表不同的键,emacs 中的文档也说了 M-x, it means "press Alt/Esc/Option/Edit key and x together",所以在 linux 中其实用 esc 也可以代替 meta 但是比较麻烦,所以我们还是对终端进行配置,一般是将 alt 或者 alt 设置为 meta

tab 的使用

上面说到 emacs 中的 tab 并不像大家平时用的 IDE 或者编辑器的表现,刚开始很不习惯。其实你可以把 emacs 中的 tab 理解为格式化代码,对选中区域或光标所在行进行代码的格式化,类似在 vscode 中的快捷键 Shift + Alt + f 的作用,在有些插件里面,补全也会用到 tab 键。那么如果我们需要输入正常的 tab 要怎么做呢,emacs 默认提供了一个 quoted insert 方法来让你输入一些特殊的键或者字符的八进制编码,比如 <del> 或者 <tab> 等,所以要输入 tab 就用快捷键 C+q tab 就可以了,如果你觉得这很麻烦,也可以自己绑定快捷键。emacs 提供的一个方法 tab-to-tab-stop 来输入 tab,快捷键是 M + i

关于 quoted insert 的内容可以查看官方文档 Insert Text,或者用 C-h k 来查看快捷键对应的用法。

另外关于 tab 的缩进 indent,不同的语言可以设置不同的缩进,如果你使用的是别人的配置那么可能你需要改多个地方的配置,可以用 M-x customize-variable 来查看 indent 相关的配置,比如 jsindent 设置在 js-indent-level 这个变量里面,而 html 的设置在 web-mode-code-indent-offset 这个变量里面,具体要更改哪个,要看你的语言对应的模式然后查找对应的变量。

最后再提一点就是 backtab 就是我们在其他编辑器常用的 Shift + tab,这个我是使用的一个自定义函数来实现的:

(defun un-indent-by-removing-4-spaces ()
    "remove 4 spaces from beginning of of line"
    (interactive)
    (save-excursion
      (save-match-data
        (beginning-of-line)
        ;; get rid of tabs at beginning of line
        (when (looking-at "^\\s-+")
          (untabify (match-beginning 0) (match-end 0)))
        (when (looking-at (concat "^" (make-string tab-width ?\ )))
          (replace-match "")))))

(global-set-key (kbd "<backtab>") 'un-indent-by-removing-4-spaces)

undo 和 redo

emacs 中提供了好几种 undo 的快捷键 C-_C-x uC-/,其中在命令行中 C-x u 可能无效,我一般是使用 C-_redo 操作一般我们在其他编辑器中用 Ctrl + Shift + z 来操作,在 emacs 上显然不可以这样。其实在 emacs 中,每个缓冲区都有一个 undo 记录,每次更改缓冲区都会放入这个 undo 记录中,我们可以通过连续的 c-_ 进行 undo,如果在连续的 undo 命令序列中插入其他命令比如文档中提到的 C-f 或者是 C-g,那么前面的连续的 undo 操作都会被作为单独的修改集合放入 undo 记录中,从而可以重新应用刚才被 undo 的操作。

也就是说,比如你进行了 操作1 操作2 操作3,此时你是用 undo 回到了 操作2 执行后的状态,这时候你想要 redo 回到操作3 执行后的状态,就先输入一个非 undo 命令,比如 C-g,然后在输入 undo 就编程 redo 操作了,具体的说明请看官方文档:Undoing Changes

当然更好的做法是使用 undo tree 这个插件,安装好插件后 C-x u 就称为打开undo-tree-visualizer-mode 这个 buffer 的快捷键,打开后我们能在一个新的 buffer 里面看到我们所有的历史操作,并且细分出了各个分支。undo tree 的操作方式有如下几种,p,n 在节点上上下移动,b,f 来选择分支(选中的分支会显示黑色),t 显示时间戳,q 退出。undo tree 同时提供了一个 undo tree redo 的方法,我们可以直接进行 redo 不在需要那么复杂的逻辑,比价符合我们正常的思维。

注释 comment`

emacs 提供的注释默认快捷键是 C-;,但是在命令行里面几乎所有和标点符号有关的快捷键都不能生效,这种情况下我们可以给 comment-line 这个函数定义两组快捷键,这样我们可以在命令行和 GUI 都能够使用注释的功能。

(global-set-key (kbd "C-c C-k") 'comment-line)
(global-set-key (kbd "C-;") 'comment-line)

lsp 自动补全

LSP (Language Server Protocol) 是微软领导开发的编程语言语法补全和代码分析框架,Emacslsp-modeLSP 协议在 Emacs 的客户端实现. lsp-mode 现在能够很好的支持 C++, Python, Ruby, Golang, Haskell, OCamel, Rust, PHP 等语言. 当然也包括 JavaScript

spacemacs 已经默认集成了 lsp,不过想要实现补全还需要安装对应语言的对应服务,比如补全 js 需要安装 typescript-language-server;,其他语言参考lsp-supported-languages。在 spacemacs 中要给对应的 mode 开启 lsp,加入如下内容

(use-package lsp-mode
  :hook (XXX-mode . lsp)
  :commands lsp)

也可以在 dotspacemacs-configuration-layers 对应的模块中直接设置,比如 (javascript :variables javascript-backend 'lsp)。需要注意的是,如果是手动启用,不是启动 lsp-mode,而是启动 lsp,如果出现 spacemacs-jump-handlers-xxx-mode 报错的话,在 user-config 里面加上 (defvar spacemacs-jump-handlers-xxx-mode nil)

如果不小心将文件加入到 lspblacklist 中,可以用 lsp-workspace-blacklist-remove 方法来移除。

参考文章

  1. Emacs的Tab键

Clloz

人生をやり直す

发表评论

电子邮件地址不会被公开。 必填项已用*标注

我不是机器人*

 

00:00/00:00