Emacs

来自 Arch Linux 中文维基

本文内容或本节内容已经过期。

原因: 请提供模板的第一个位置参数以概括原因。 (在Talk:Emacs讨论)

这篇文章或章节的翻译不反映原文。

原因:Out of sync with the english pages since 2018(在 Talk:Emacs# 中讨论)

Emacs是一个可扩展、可定制、自文档化的实时显示编辑器。Emacs的核心构建在Emacs Lisp解释器之上,Emacs Lisp是大部分Emacs内建函数和拓展模块的实现语言。在图形界面系统下,Emacs使用GTK作为默认的X工具,在命令行界面下(CLI),Emacs也可以工作良好。在文本编辑能力上,Emacs常被拿来和vim比较。

安装[编辑 | 编辑源代码]

如果要安装稳定版本的 GNU Emacs,请安装 emacs 包,此外,还有以下发行版

  • emacs-gitAUR:GNU Emacs 的开发版本。自 2021 年 6 月起,它添加了对 feature/native-comp 的支持。
  • emacs-pgtk-native-comp-gitAUR 或者 emacs-native-comp-git-enhancedAUR:一个非官方的分支,结合了 GNU Emacs 的开发分支和新的渲染引擎PGTK((还有 feature/native-comp)。
  • emacs-nox:没有 GTK+ 支持的 GNU Emacs,没有声音或其它花哨的东西,在终端下使用。文字模式的Emacs有一些缺点:它支持的颜色和字体设置功能都要更少(实时改变字体大小,单文档多字体,等等)。而且 emacs-nox 存在一些高级功能上的缺陷,比如 Speedbar 和 GUD(调试环境),处理复杂的外观(face,文本在 Emacs 中呈现的样子)的时候速度也会变慢。

值得注意的是,archlinuxcn 源中也有一个名为 emacs-git 的包,它是 GNU Emacs 的开发版本,但是没有对 feature/native-comp 的支持。原版 emacsemacs-native-comp 的主要区别是后者的性能会更好一些。

运行Emacs[编辑 | 编辑源代码]

启动Emacs之前,你应该知道怎样关掉它(特别是你在终端里运行时):使用 Ctrl+xCtrl+c 按键顺序。

启动Emacs:

$ emacs

或者以文字模式启动:

$ emacs -nw

又或者,快速启动(不解析.emacs文件)并以文字模式启动:

$ emacs -Q -nw

如果你安装的是nox版本,'emacs' 和 'emacs -nw' 效果是一样的。

可以提供文件名直接打开文件:

$ emacs filename.txt

没有颜色[编辑 | 编辑源代码]

默认情况下,Emacs以颜色主题开始,显示超链接为深蓝色。

以文本模式,不使用任何颜色主题启动Emacs:

$ emacs -nw --color=no

这将导致所有的文本采用终端的字体颜色 –– 通常是黑色背景之上的白色文本,或白色背景上的黑色文本。

作为守护进程[编辑 | 编辑源代码]

如过不想让Emacs每次启动都读取配置文件的话,可以以守护进程运行Emacs:

$ emacs --daemon

连接到守护进程:

$ emacsclient -nc

这个命令会创建一个新的frame -c(如果你更喜欢文字模式,使用 -t )并且不会独占终端 -n--no-wait)。 有的程序,如Mutt和Git,(为了提交信息)会等待编辑器完成编辑,所以不能使用 -n 参数。 如果你的默认编辑器是默认使用-n,你需要为那些程序指定一个替代编辑器(比如 emacsclient -a "" -t)。

作为systemd单元[编辑 | 编辑源代码]

旧的systemd单元方法有一些需要注意的地方。 它给了一个限制shell调用的有限的shell环境,所以我们需要使用一个user单元,它往往比调用emacs --daemon好得多。 为Emacs创建一个systemd单元:

注意: 这样一个单元文件将会包含在Emacs 26.1中, 参见 emacs bug 16507.
~/.config/systemd/user/emacs.service
[Unit]
Description=Emacs: the extensible, self-documenting text editor

[Service]
Type=forking
ExecStart=/usr/bin/emacs --daemon
ExecStop=/usr/bin/emacsclient --eval "(kill-emacs)"
Restart=always

[Install]
WantedBy=default.target

需要启动并启用该单元,以便其在每次电脑启动时启动(请注意 - 请勿“以root运行” - 我们希望它以user,而不是根root user运行):

$ systemctl --user enable --now emacs

请注意,systemd user单元不会从登录shell(例如~/.bash_profile)继承环境变量,因此你可能需要在~/.pam_environment中设置变量。有关更多信息,请参见Systemd/User

如启动emacs作为守护程序,你可能会想把VISUALEDITOR环境变量设置为emacsclient,以便启动编辑器的程序使用emacsclient而不是一个完整的编辑器。使用外部编辑器的程序,包括电子邮件程序(用于编辑消息),Git(用于编辑提交消息)和less(用于编辑显示文件的v命令)。 不要对emacsclient使用-n--nowait)选项,因为程序通常要求在编辑器退出时编辑完成。

建议将Emacs的任何GUI开始菜单条目(或等效条目)更改为指向emacsclient而不是emacs,以便使用emacs守护程序而不是启动新的emacs进程。

获得帮助[编辑 | 编辑源代码]

尽管Emacs很复杂,但了解定制和可扩展性带来的好处并不需要很长时间。此外,已有的各种扩展允许将其转变为针对几乎任何形式的强大文本编辑环境。

Emacs有一个很好的内置教程,可以通过点击启动画面上的第一个链接进行访问; 通过从菜单中选择帮助-> Emacs 教程或按F1 + t,亦或者按 C-h t (C 默认是 Ctrl 键, - 符号代表同时按下,也就是说你需要按 Ctrl 键的同时按 h 键,然后放开再按 t 键)

Emacs设计为良好的自文档化。 因此,你很容易知道一些特定命令和快捷键是什么意思,比如命令 find-file ,而它的默认快捷键是 C-x C-f, f 键可联想为file。Emacs 提供大量文档给使用者,建议频繁使用C-h C-h查看所有命令,快捷键和方法。

Emacs还包含一组参考卡,对初学者和专家都很有用,请参阅/usr/share/emacs/<version>/etc/refcards/(用您的emacs版本替换<version>)。

手册[编辑 | 编辑源代码]

如果你真的想要掌握Emacs,最推荐的文档来源仍然是官方手册:

  • Emacs:完整的Emacs用户手册。
  • Emacs 常见问题。
  • Emacs Lisp简介:如果你以前从未使用任何编程语言。
  • Elisp:如果你已经熟悉一门编程语言。

通过内置'info'阅读器,你可以从官网的 PDF 文档GNU.org 或直接从 Emacs 本身访问:C-h i。 可以按 m 键快速选择特定章节。

有些用户更喜欢使用'info'阅读器来阅读文本,因为它有很方便的默认快捷键来帮使用者浏览整本书。另外其段落会适应窗口宽度,字体会适应当前屏幕分辨率。有些人觉得这样不那么刺激眼睛。最后,你可以轻松地将章节中的内容复制到任何Emacs缓冲区,甚至可以直接从文本的示例中执行Lisp代码片段。

尝试用 C-h i m info <RET> 快捷键获取更多 info reader 的信息。 在info模式下按 ? 可以快速查看快捷键列表。

定制化[编辑 | 编辑源代码]

Emacs 其中一个主要的特点就是拥有极高自由度的扩展性,而且配置起来很容易。Emacs 内置自定义页面,你可以通过M-x customize快捷键查看自定义选项列表,亦或者用M-x customize-group查询特定插件的自定义列表。更多详细请查询 Emacs manual C-h r 里的 Easy Customization

配置文件[编辑 | 编辑源代码]

当Emacs启动时,通常会自动加载初始化配置文件。这些配置文件由 lisp 语言编写(准确地来说是Emacs lisp),配置文件默认是在~/.emacs.el或者~/.emacs。你也可以把配置文件放在目录里方便管理,默认下是在~/.emacs/init.el。更多详细请看 Emacs manual 里的 Init File 章节。

提示和技巧[编辑 | 编辑源代码]

TRAMP[编辑 | 编辑源代码]

TRAMP (Transparent Remote Access, Multiple Protocols) ,顾名思义,是一个可以通过很多协议透明访问远程文件的一个扩展。当提示输入文件名时,输入特定的格式就可以使用TRAMPP。比如:

在打开/etc/hosts文件之前提示输入root的密码以获取root权限:

C-x C-f /su::/etc/hosts

要通过SSH使用'you'用户名登录'remotehost'主机打开文件~/example.txt

C-x C-f /ssh:you@remotehost:~/example.txt

TRAMP的路径一般是这种格式'/[protocol]:[[user@]host]:<file>'。

作为用户'you'连接至'myhost'并以sudo编辑/etc/hosts

/ssh:you@remotehost|sudo:remotehost:/etc/hosts

TRAMP支持的不只上面的两个简单例子。请查看Emacs里面的TRAMPP info手册了解更多的信息。

使用Emacs作为git mergetool[编辑 | 编辑源代码]

默认情况下,Git支持使用Emacs的Emerge模式作为合并工具。但是你可能更喜欢Ediff模式。不幸的是,由于技术原因,这种模式不被git支持。通过在emacs调用时对一些elisp代码赋值,仍然有一种方法可以使用Ediff。

.gitconfig
[mergetool.ediff]
    cmd = emacs --eval \" (progn (defun ediff-write-merge-buffer () (let ((file ediff-merge-store-file)) (set-buffer ediff-buffer-C) (write-region (point-min) (point-max) file) (message \\\"Merge buffer saved in: %s\\\" file) (set-buffer-modified-p nil) (sit-for 1))) (setq ediff-quit-hook 'kill-emacs ediff-quit-merge-hook 'ediff-write-merge-buffer) (ediff-merge-files-with-ancestor \\\"$LOCAL\\\" \\\"$REMOTE\\\" \\\"$BASE\\\" nil \\\"$MERGED\\\"))\" 

[merge]
	tool = ediff

请注意,该命令必须在同一行上。在上面的例子中,我们启动了一个Emacs的新实例。你可能想要使用emacsclient更快地启动; 不建议这样做,因为Ediff调用不是很干净:它可能会打断当前的Emacs会话。

如果你想要一个即时启动,可以使用-q参数。如果想在保留至少一部分配置的情况下快速启动Emacs,则可以这样使用Emacs:

emacs -q -l ~/.emacs-light

light配置文件仅加载Ediff所需的内容。

关于这个技巧的细节和Ediff问题,参见kerneltrap.orgstackoverflow

使用大写锁定作为控制键[编辑 | 编辑源代码]

一些用户喜欢这种个修改,以避免所谓的'emacs pinky'。如果你想在 X Keyboard 上试用它,运行

$ setxkbmap -option 'ctrl:nocaps'

或者,交换键值,运行

$ setxkbmap -option 'ctrl:swapcaps'

要永久更改它,请考虑将其添加到.xinitrc文件中。

如果要将一个区域变为大写,只需使用默认的C-x C-u键绑定,调用upcase-region函数。

参见[1]了解另一种方法。

如果缺少Caps Lock功能,请同时将其映射为“Shift”。

$ setxkbmap -option "shift:both_capslock"

某些桌面环境包含图形工具以简化键盘重新映射。 例如,在Plasma 5中打开系统设置并点击输入设备。选择键盘,然后在高级选项卡中会看到Caps Lock设置,可以在其中选择Caps Lock也是一个Ctrl。

复用 emacs and emacsclient[编辑 | 编辑源代码]

emacs-session以同样的方式打开一个新文件需要使用emacsclient. 如果会话emacs存在,命令可以自己包装以执行更智能的行为来打开文件。 要开始会话您需要start-server. 这将会在emacs的第一个会话中创建服务器.将此添加到您的emacs 配置文件中.

.emacs or .emacs.d/init.el
(require 'server)
(unless (server-running-p)
  (server-start))

Shell 别名方法不适用于此,因为您还需要传递变量或启动您自己的独立会话. 将此添加到.bashrc或其它的shell rc文件中. 如果$ emacs传递了参数,这将使您的命令表现得像emacsclient.

function emacs {
    if [[ $# -eq 0 ]]; then
        /usr/bin/emacs # "emacs" is function, will cause recursion
        return
    fi
    args=($*)
    for ((i=0; i <= ${#args}; i++)); do
        local a=${args[i]}
        # NOTE: -c for creating new frame
        if [[ ${a:0:1} == '-' && ${a} != '-c' && ${a} != '--' ]]; then
            /usr/bin/emacs ${args[*]}
            return
        fi
    done
    setsid emacsclient -n -a /usr/bin/emacs ${args[*]}
} 

如果您想在新会话中运行它,只需执行emacs <file> -.

多种配置[编辑 | 编辑源代码]

你可以使用少量配置然后告诉Emacs来加载其他配置。

例如,我们来定义两个配置文件。

.emacs
(load "~/.emacs.d/main" nil t)
(load "~/.emacs.d/functions" nil t)
(load "~/.emacs.d/modes" nil t)
(load "~/.emacs.d/plugins" nil t)
(load "~/.emacs.d/theme" nil t)

这是我们在后台载入的完整配置。但是plugins文件太大导致载入太慢,如果我们要打开一个新的Emacs窗口,可能就不会使用plugins配置,每次加载它实在是太笨重了。

.emacs-light
(load "~/.emacs.d/main" nil t)
(load "~/.emacs.d/functions" nil t)
(load "~/.emacs.d/modes" nil t)
(load "~/.emacs.d/theme" nil t)

现在我们这样来加载Emacs:

emacs -q -l ~/.emacs-light

你可以为这个命令创建一个别名。

本地化和自定义变量[编辑 | 编辑源代码]

您可以在配置文件中定义变量,稍后可以在本地为文件修改这些变量.

(defcustom my-compiler "gcc" "Some documentation")

现在在任何文件中,您都可以通过两种方式定义局部变量:

  • 使用M-x add-file-local-variable-prop-line,它在开头添加了一个类似于以下内容的注释行:
// -*- my-compiler:g++; mode:c++ -*-
  • 或者您可以使用M-x add-file-local-variable在文件末尾附近添加行:
// Local Variables:
// my-compiler: g++
// mode: c++
// End:

请注意,要使这些值生效,您需要调用M-x revert-buffer.

默认情况下,自定义变量被认为是不安全的。如果您试图打开一个包含重新定义自定义变量的局部变量的文件,Emacs将要求您确认.

您可以将变量声明为安全的,从而删除Emacs确认提示。您需要指定任何新值都必须验证的谓词,以便将其视为安全的.

(defcustom my-compiler "gcc" "Some documentation" :safe 'stringp)

在前一个示例中,如果试图设置字符串以外的任何东西,Emacs会认为它不安全.

定制颜色和主题[编辑 | 编辑源代码]

使用face功能可以轻松定制颜色.

(set-face-background  'region                 "color-17")
(set-face-foreground  'region                 "white")
(set-face-bold-p      'font-lock-builtin-face t ) 

您可以让Emacs告诉您点所在的面的名称。为此,请使用customize-face功能。该设施将向您展示如何设置颜色、粗体、下划线等.

控制台中的Emacs可以处理256色,但您必须为此使用适当的terminal。例如,URxvt支持256色。您可以使用list-colors-display查看受支持颜色的综合列表。这是高度依赖terminal的.

SyncTeX支持[编辑 | 编辑源代码]

Emacs是一个功能强大的LaTeX编辑器。这主要是因为您可以调整或创建一个LaTeX模式以最适合您的需要.

尽管如此,还是有一些挑战,比如SyncTeX支持。首先,您需要确保您的TeX发行版拥有它。如果手动安装TeX Live,则可能需要安装synctex软件包.

# umask 022 && tlmgr install synctex

SyncTeX支持依赖于查看器。这里我们将以Zathura为例,因此如果您想使用另一个PDF查看器,则需要修改代码.

(defcustom tex-my-viewer "zathura --fork -s -x \"emacsclient --eval '(progn (switch-to-buffer  (file-name-nondirectory \"'\"'\"%{input}\"'\"'\")) (goto-line %{line}))'\"" 
  "PDF Viewer for TeX documents. You may want to fork the viewer
so that it detects when the same document is launched twice, and
persists when Emacs gets closed.

Simple command:

  zathura --fork

We can use

  emacsclient --eval '(progn (switch-to-buffer  (file-name-nondirectory \"%{input}\")) (goto-line %{line}))'

to reverse-search a pdf using SyncTeX. Note that the quotes and double-quotes matter and must be escaped appropriately."
:safe 'stringp)

这里我们定义了自定义变量。如果您使用的是AucTeX或Emacs默认LaTeX模式,则必须相应地设置查看器.

现在用Emacs打开一个LaTeX源文件,编译文档,并启动查看器。Zathura会触发的。如果按{ic | Ctrl+左键单击}},则Emacs应将点放置在相应位置.

systemd文件的语法高亮[编辑 | 编辑源代码]

您可以用systemd-mode.

或者,您可以简单地告诉emacs为systemd文件(服务、计时器等)高亮,方法是将其添加到init文件中:

 (add-to-list 'auto-mode-alist '("\\.service\\'" . conf-unix-mode))
 (add-to-list 'auto-mode-alist '("\\.timer\\'" . conf-unix-mode))
 (add-to-list 'auto-mode-alist '("\\.target\\'" . conf-unix-mode))
 (add-to-list 'auto-mode-alist '("\\.mount\\'" . conf-unix-mode))
 (add-to-list 'auto-mode-alist '("\\.automount\\'" . conf-unix-mode))
 (add-to-list 'auto-mode-alist '("\\.slice\\'" . conf-unix-mode))
 (add-to-list 'auto-mode-alist '("\\.socket\\'" . conf-unix-mode))
 (add-to-list 'auto-mode-alist '("\\.path\\'" . conf-unix-mode))
 (add-to-list 'auto-mode-alist '("\\.netdev\\'" . conf-unix-mode))
 (add-to-list 'auto-mode-alist '("\\.network\\'" . conf-unix-mode))
 (add-to-list 'auto-mode-alist '("\\.link\\'" . conf-unix-mode))

emacs-nox的剪贴板支持[编辑 | 编辑源代码]

要在emacs-nox中使用Xorg的剪贴板, 安装 xclip并将以下函数添加到~/.emacs [2]

;; use xclip to copy/paste in emacs-nox
(unless window-system
  (when (getenv "DISPLAY")
    (defun xclip-cut-function (text &optional push)
      (with-temp-buffer
	(insert text)
	(call-process-region (point-min) (point-max) "xclip" nil 0 nil "-i" "-selection" "clipboard")))
    (defun xclip-paste-function()
      (let ((xclip-output (shell-command-to-string "xclip -o -selection clipboard")))
	(unless (string= (car kill-ring) xclip-output)
	  xclip-output )))
    (setq interprogram-cut-function 'xclip-cut-function)
    (setq interprogram-paste-function 'xclip-paste-function)
    ))
提示:您还可以通过添加:
;; xterm mouse support
(require 'mouse)
(xterm-mouse-mode t)
参考mwheel.el.

[编辑 | 编辑源代码]

Emacs的功能可以通过第三方软件包进行扩展。内置的包管理器package.el是被官方支持的方式, 尽管还有其他几个包管理器是由Emacs社区的成员编写的. package.el依赖于变量package-archives寻找包. 默认它包含Emacs Lisp Package Archive (ELPA). M-x list-packages将创建一个缓冲区,列出Emacs知道的所有包。手册((info "(emacs) Packages"))包含更多信息.

可以添加第三方包存档。其中应用最广泛的是MELPA.

许多流行的扩展程序包在[community] repository, and more still, via the AUR. 这些包的名称通常有一个'emacs-'前缀(例如, emacs-lua-mode), 虽然不总是这样 (例如, auctexAUR).

提示:ArchLinuxWiki贡献者可能对Emacs Mediawiki感兴趣.

某些软件包可能需要您对配置文件进行更改,以便激活它们,从而使其功能在Emacs会话期间可用。例如,如果您安装auctexAUR,您将需要添加

(load "auctex.el" nil t t)
(load "preview-latex.el" nil t t)

到您的配置文件. 其他软件包应该让您知道如何在源代码的注释部分或README中激活它们.

疑难杂症[编辑 | 编辑源代码]

彩色输出的问题[编辑 | 编辑源代码]

Emacs默认使用原生的转义串来输出颜色。也就是说,它会在要显示颜色的地方显示奇怪的字符。

~/.emacs中加入下面的代码解决这个问题:

(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)

菜单显示为空[编辑 | 编辑源代码]

一些菜单显示为空,这是GNU Emacs 23.1的一个bug(使用GTK toolkit的时候)。好像在Emacs的CVS trunk中已经修复了。对应的Debian bug report 有一个应对措施。

X 窗口下的字符显示问题[编辑 | 编辑源代码]

当你使用X窗口启动emacs时,如果发现主窗口中的所有字符都是黑框白块(就像你没有安装正确的字体看到的字符一样),那么你需要安装 xorg-fonts-75dpi 或者 xorg-fonts-100dpi 并且重启X窗口。

启动速度慢[编辑 | 编辑源代码]

启动速度慢经常是由下面两种情况引起的。

要确定是哪种情况,这样打开Emacs:

$ emacs -q

如果Emacs还是启动很慢,则是#错误的网络配置。如果不是,则可以确定是.emacs的问题

错误的网络配置[编辑 | 编辑源代码]

当启动Emacs的时候,一些错误,特别是在/etc/hosts中的,经常会导致5秒以上的延迟。在网络配置指南中查看'set the hostname' 了解更多内容。

初始化文件加载慢[编辑 | 编辑源代码]

一个很简单的方法查找原因是注释掉(比如在行开头使用';')你的~/.emacs(或者~/.emacs.d/init.el)里面可疑的地方,然后再启动Emacs,看速度是否有改善。记住,使用"require"和"load"会减慢启动速度,特别是用在很大的插件上。一般来说,他们应该用在当目标是Emacs启动的时候就需要或者提供仅仅是一个扩展的"autoloads"。否则,直接使用'autoload'函数。比如,不是这样:

(require 'anything)

你应该这样:

(autoload 'anything "anything" "Select anything" t)

不能打开配置文件: ...[编辑 | 编辑源代码]

这个错误最常见的原因是'load-path'变量没有包含某些插件的目录。要解决这个问题,在加载插件前,把需要加载的插件目录加入到要搜索的list中:

 (add-to-list 'load-path "/path/to/directory/")

当尝试使用一个插件的包,而这个包又被Emacs加上了非'/usr'的前缀时,load-path需要更新。把下面的代码放到使用这个插件的包的代码的前面:

 (add-to-list 'load-path "/usr/share/emacs/site-lisp")

如果手动编译Emacs,记住默认的前缀是'/usr/local'。

Dead-accent keys problem: '<dead-acute> is undefined'[编辑 | 编辑源代码]

Searching about this bug on Google, we find this link: https://lists.gnu.org/archive/html/help-gnu-emacs/2009-05/msg00167.html

Explaining the problem: in recent versions of b72

Emacs, the normal way to use accent keys does not work as expected. Trying to accent a word like 'fiancé' will produce the message above.

A way to solve it is just put the line above on your startup file, ~/.emacs:

  (require 'iso-transl)

And no, it is not a bug, but a feature of new Emacs versions. Reading the subsequent messages about it on the mail list, we found it (https://lists.gnu.org/archive/html/help-gnu-emacs/2009-05/msg00179.html):

It seems that nothing is loaded automatically because there is a choice betwee iso-transl and iso-acc. Both seem to provide an input method with C-x 8 or Alt-<accent> prefix, but what you and I are doing is just pressing a dead key (^, ´, `, ~, ¨) for the accent and then another key to "compose" the accented character. And there is no Alt key used in this! And according to documentation it seems be appropriate for 8-bit encodings, so it should be pretty useless in UTF-8. I reported this bug when it was introduced, but the bug seems to be

a3b

classified as a feature ... Maybe it's just because the file is auto-loaded though pretty useless. 

C-M-% and some other bindings do not work in emacs nox[编辑 | 编辑源代码]

This is because terminals are more limited than Xorg. Some terminals may handle more bindings than other, though. Two solutions:

  • either use the graphical version,
  • or change the binding to a supported one.

Example:

.emacs
(global-set-key (kbd "C-M-y") 'query-replace-regexp)

Emacs client gets stuck when switching back to it[编辑 | 编辑源代码]

If you are using Emacs daemon, then you should know that input is blocking. If one Emacs instance is in the minibuffer (after an M-x for instance), then all other instance will wait for it to finish. Press C-g to cancel any input to make sure this Emacs session is not blocking.

Emacs-nox output gets messy[编辑 | 编辑源代码]

When working in a terminal, the color, indentation, or anything related to the output might become crazy. This is (probably?) because Emacs was sent a special character at some point which may conflict with the current terminal. There is not much to be done but restarting emacs. If someone has a workaround or a more detailed explanation on the issue, feel free to contribute.

Graphical Emacs does not suffer from this issue.

Shift + 方向键在tmux中使用Emacs时不工作[编辑 | 编辑源代码]

首先,你需要在tmux配置中启用xterm-keys。

.tmux.conf
setw -g xterm-keys on

但这样的话,会破坏其他的组合键。在Emacs配置中写入以下内容来修复这个问题。

.emacs
;; handle tmux's xterm-keys
;; put the following line in your ~/.tmux.conf:
;;   setw -g xterm-keys on
(if (getenv "TMUX")
    (progn
      (let ((x 2) (tkey ""))
	(while (<= x 8)
	  ;; shift
	  (if (= x 2)
	      (setq tkey "S-"))
	  ;; alt
	  (if (= x 3)
	      (setq tkey "M-"))
	  ;; alt + shift
	  (if (= x 4)
	      (setq tkey "M-S-"))
	  ;; ctrl
	  (if (= x 5)
	      (setq tkey "C-"))
	  ;; ctrl + shift
	  (if (= x 6)
	      (setq tkey "C-S-"))
	  ;; ctrl + alt
	  (if (= x 7)
	      (setq tkey "C-M-"))
	  ;; ctrl + alt + shift
	  (if (= x 8)
	      (setq tkey "C-M-S-"))

	  ;; arrows
	  (define-key key-translation-map (kbd (format "M-[ 1 ; %d A" x)) (kbd (format "%s<up>" tkey)))
	  (define-key key-translation-map (kbd (format "M-[ 1 ; %d B" x)) (kbd (format "%s<down>" tkey)))
	  (define-key key-translation-map (kbd (format "M-[ 1 ; %d C" x)) (kbd (format "%s<right>" tkey)))
	  (define-key key-translation-map (kbd (format "M-[ 1 ; %d D" x)) (kbd (format "%s<left>" tkey)))
	  ;; home
	  (define-key key-translation-map (kbd (format "M-[ 1 ; %d H" x)) (kbd (format "%s<home>" tkey)))
	  ;; end
	  (define-key key-translation-map (kbd (format "M-[ 1 ; %d F" x)) (kbd (format "%s<end>" tkey)))
	  ;; page up
	  (define-key key-translation-map (kbd (format "M-[ 5 ; %d ~" x)) (kbd (format "%s<prior>" tkey)))
	  ;; page down
	  (define-key key-translation-map (kbd (format "M-[ 6 ; %d ~" x)) (kbd (format "%s<next>" tkey)))
	  ;; insert
	  (define-key key-translation-map (kbd (format "M-[ 2 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))
	  ;; delete
	  (define-key key-translation-map (kbd (format "M-[ 3 ; %d ~" x)) (kbd (format "%s<delete>" tkey)))
	  ;; f1
	  (define-key key-translation-map (kbd (format "M-[ 1 ; %d P" x)) (kbd (format "%s<f1>" tkey)))
	  ;; f2
	  (define-key key-translation-map (kbd (format "M-[ 1 ; %d Q" x)) (kbd (format "%s<f2>" tkey)))
	  ;; f3
	  (define-key key-translation-map (kbd (format "M-[ 1 ; %d R" x)) (kbd (format "%s<f3>" tkey)))
	  ;; f4
	  (define-key key-translation-map (kbd (format "M-[ 1 ; %d S" x)) (kbd (format "%s<f4>" tkey)))
	  ;; f5
	  (define-key key-translation-map (kbd (format "M-[ 15 ; %d ~" x)) (kbd (format "%s<f5>" tkey)))
	  ;; f6
	  (define-key key-translation-map (kbd (format "M-[ 17 ; %d ~" x)) (kbd (format "%s<f6>" tkey)))
	  ;; f7
	  (define-key key-translation-map (kbd (format "M-[ 18 ; %d ~" x)) (kbd (format "%s<f7>" tkey)))
	  ;; f8
	  (define-key key-translation-map (kbd (format "M-[ 19 ; %d ~" x)) (kbd (format "%s<f8>" tkey)))
	  ;; f9
	  (define-key key-translation-map (kbd (format "M-[ 20 ; %d ~" x)) (kbd (format "%s<f9>" tkey)))
	  ;; f10
	  (define-key key-translation-map (kbd (format "M-[ 21 ; %d ~" x)) (kbd (format "%s<f10>" tkey)))
	  ;; f11
	  (define-key key-translation-map (kbd (format "M-[ 23 ; %d ~" x)) (kbd (format "%s<f11>" tkey)))
	  ;; f12
	  (define-key key-translation-map (kbd (format "M-[ 24 ; %d ~" x)) (kbd (format "%s<f12>" tkey)))
	  ;; f13
	  (define-key key-translation-map (kbd (format "M-[ 25 ; %d ~" x)) (kbd (format "%s<f13>" tkey)))
	  ;; f14
	  (define-key key-translation-map (kbd (format "M-[ 26 ; %d ~" x)) (kbd (format "%s<f14>" tkey)))
	  ;; f15
	  (define-key key-translation-map (kbd (format "M-[ 28 ; %d ~" x)) (kbd (format "%s<f15>" tkey)))
	  ;; f16
	  (define-key key-translation-map (kbd (format "M-[ 29 ; %d ~" x)) (kbd (format "%s<f16>" tkey)))
	  ;; f17
	  (define-key key-translation-map (kbd (format "M-[ 31 ; %d ~" x)) (kbd (format "%s<f17>" tkey)))
	  ;; f18
	  (define-key key-translation-map (kbd (format "M-[ 32 ; %d ~" x)) (kbd (format "%s<f18>" tkey)))
	  ;; f19
	  (define-key key-translation-map (kbd (format "M-[ 33 ; %d ~" x)) (kbd (format "%s<f19>" tkey)))
	  ;; f20
	  (define-key key-translation-map (kbd (format "M-[ 34 ; %d ~" x)) (kbd (format "%s<f20>" tkey)))

	  (setq x (+ x 1))
	  ))
      )
  )

替代方案[编辑 | 编辑源代码]

这里有几个类似 Emacs的工具。 你也可以尝试在在Arch仓库或在AUR中找相似 Emacs 的工具。

  • mg — C 语言编写实现轻量级 emacs。注意这软件不支持 UTF-8。
https://homepage.boetes.org/software/mg/ || mg
  • Zile — "Zile Is Lossy Emacs", 一个轻量级的克隆版本,编写得尽可能类似 Emacs 。
https://www.gnu.org/software/zile/ || zile
  • uemacs — 由 Linus Torvalds定制的“ Micro-emacs”版本。
https://git.kernel.org/pub/scm/editors/uemacs/uemacs.git || uemacs-gitAUR
  • remacs — Rust 主打的 emacs。
https://github.com/remacs/remacs || remacsAUR[损坏的链接:package not found]

资源[编辑 | 编辑源代码]