如何让Emacs和Scheme一起愉快玩耍

众所周知,Emacs是一款功能强大的操作系统,有些人也错误地将其作为文本编辑器使用。本文要介绍的是如何将Emacs调教成一个功能弱小的Scheme IDE,并且帮你越过一些作者踩过的坑。

配置MELPA源

本文的许多插件要用到MELPA源,如果你的Emacs版本 < 24,最好先更新你的Emacs。如果 > 24,且没有配置过MELPA源,请在你的init.el或.emacs.el中添加如下代码:

1
2
3
4
5
6
7
8
9
10
11
(require 'package)

(let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
(not (gnutls-available-p))))
(url (concat (if no-ssl "http" "https") "://melpa.org/packages/")))
(add-to-list 'package-archives (cons "melpa" url) t))
(when (< emacs-major-version 24)
;; For important compatibility libraries like cl-lib
(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))

(package-initialize)

安装Geiser,company-mode, paredit

Geiser类似于Common Lisp的SLIME插件,包含了一系列minor和major mode来帮助你更好地编辑Scheme代码,更重要的是,Geiser可以和一个Scheme后端进行通讯,从而实现REPL、eval-buffer、即时的宏展开等功能。想要安装Geiser,在你的Emacs中输入:M-x package-install RET geiser RET。点击这里查看geiser的详细使用文档。

Company-mode 是一个知名的代码补全前端,相信很多读者已经安装过这个插件,如果没有的话请输入M-x package-install RET company RET安装。如果你使用的是auto-complete,则安装ac-geiser替代。

Scheme作为本体是括号的语言,一个编辑括号的插件必不可少。paredit是一个结构化编辑括号的插件,可以帮助你在括号之间玩出花来。输入M-x package-install RET paredit RET安装这个插件,点击这里可以在注释中找到使用方式。
选择一个后端

Scheme作为一个十分简洁的语言,有大约114514种不同实现,因此可以用于代码补全等功能的后端选择也十分多样。本文选择的后端是较为常见的Chez Scheme。最简单的安装方式是使用你的系统包管理器,如:

1
brew install chezscheme

如果你的系统包管理器没有Chez,或你在使用windows等非Unix-like系统,那么你可以选择手动安装。请参考Chez Scheme的官方文档了解如何从源码编译Chez。

Geiser支持六种Scheme后端,分别是Guile,Chicken,GNU/MIT,Chez,Chibi和Racket。其中Chicken和Racket也是比较常见的后端,Chicken同时还支持flycheck-mode,可以动态标记语法错误的位置。

踩坑是Emacs的一环,不爽不要玩。 —— 圣Ignucius,Emacs教会的先知

环境变量

Emacs并不会从你的shell中自动读取$PATH变量,因此你需要手动将你的Chez或其他Scheme实现的$PATH变量加入到Emacs中,如:

1
(add-to-list 'exec-path "/usr/local/bin")

executable的名字

Geiser默认的Chez executable名称为scheme,而从homebrew安装的chez executable名称为chez,因此我们需要调整默认executable的名称(同时也调整一下默认的scheme-mode):

1
2
(setq scheme-program-name "chez")
(setq geiser-chez-binary "chez")

Geiser的默认Scheme实现

Geiser会从你打开的代码中猜你使用的scheme实现,然而大部分情况下都猜不对,因此我们需要手动减少geiser的竞猜列表:

1
(setq geiser-active-implementations '(chez))

如果你使用的是其他实现,就把列表中的chez改为chicken,guile,racket等。如果你懒得设置这一条,也可以每次使用M-x geiser-use-scheme来手动修改。


你看到尾巴了