搭建 Emacs 的 Haskell/Idris 環境教程

原文發表在我的博客: 搭建 Emacs 的 Haskell/Idris 環境教程

最近看見 Haskell 群的萌新費盡心思也沒成功搭建環境,而且很多都是用瀏覽器編程,很不清真。為了拯救蒼生,順便為考 SAT 攢人品,我決定寫一篇搭建環境教程,來擴大 Emacs 勢力。

由於 Idris 用戶需要進行的操作基本上是 Haskell 用戶的超集,因此未說明的地方就是都要進行的,針對 Idris 用戶的額外步驟會說明。

編譯 Idris 是一種浪漫,我的筆記本 5 分鐘就編譯好了,湛忠勝說編譯了一下午。本文將講述編譯而不是下載二進位 Idris 的方法。

本文針對的操作系統是 Linux ,只要能用 apt 就可以了。

本文使用的工具及版本

  • Emacs 25
  • GHC 8.2.2
  • Cabal 1.24
  • Idris 1.1.1

本文使用的鏡像源

  • 清華大學 tuna 鏡像源

tuna 在本文發布的時候暫時掛掉了,因此在國慶期間搭建環境的同學們可以把下文中的 tuna 源智能替換為 ustc 源。 但是你就會遇到很多其它問題,所以我還是推薦等 tuna 活過來後用 tuna 。

  • ustc 源

apt 準備

先加源,然後安裝,下面的指令直接複製進終端執行:

$ sudo add-apt-repository ppa:hvr/ghcn$ sudo add-apt-repository ppa:ubuntu-elisp/ppan$ sudo apt-get updaten$ sudo apt-get install emacs25n$ sudo apt-get install ghc-8.2.2n$ sudo apt-get install cabal-install-1.24n

配置

打開你的 ~/.bashrc ,加入下面的配置:

alias ec="emacsclient25 -nw"nalias en="emacs25 -nw"nalias ecw="emacsclient25"nexport PATH=~/.cabal/bin:/opt/ghc/bin:/opt/cabal/bin:$PATH n

以上代碼節選自我的 bashrc 。

然後執行以下命令,以重新載入這些配置:

$ source ~/.bashrcn

配置 Cabal

根據上面給出的 tuna 源的指示進行操作。 這對於 Haskell 來說不是必須的,但卻是非常非常非常建議的。 Idris 用戶請確保完成這一步。

編譯 Idris

直接輸指令就行:

$ cabal-1.24 updaten$ cabal-1.24 install idrisn

搞懂啥是 emacsclient

其實是因為我使用了 linum-mode 這個插件,導致每次 Emacs 打開都特別慢 ,正好應了古人那句 EMACS == Emacs Makes A Computer Slower 。 因此我將會採用 Emacs Daemon 來加速 Emacs 啟動。 這個東西的原理就是先開個 Emacs 進程,在後台運行,把插件啥的都載入好,藍後每次使用 Emacs 的時候啟動一個客戶端,連上這個後台進程就是了。 於是就可以超級快了。

首先,在開始啟動第一個 Emacs 前,先啟動守護進程:

$ emacs25 --daemonn

藍後在命令行使用 Emacs 打開一個文件,請輸入

$ ec [你要打開的文件路徑]n

若要在 GUI 下使用 Emacs ,請使用

$ ecw [你要打開的文件路徑]n

推薦使用命令行。

這時如果你更新了你的配置,需要重啟 Emacs ,那麼你需要殺了 Emacs 並讓他復活:

$ pkill emacsn$ emacs25 --daemonn

這時候你的 Emacs 還是裸的,現在我們來配置它。

哦,差點忘了,為了防止一些悲劇發生,請在殺死 Emacs 前終止所有正在運行的 emacsclient 。

為了防止另一些悲劇的發生,請記下退出 Emacs 的快捷鍵: Ctrl+X Ctrl+C 。按法:按住 Ctrl 不放,然後分別按 X 和 C 。

你打開你的 Emacs 之後應該看到它是這樣的:

File Edit Options Buffers Tools HelpnWelcome to GNU Emacs, one component of the GNU/Linux operating system.nnGet help C-h (Hold down CTRL and press h)nEmacs manual C-h r Browse manuals C-h inEmacs tutorial C-h t Undo changes C-x unBuy manuals C-h RET Exit Emacs C-x C-cnActivate menubar M-`n(『C-』 means use the CTRL key. 『M-』 means use the Meta (or Alt) key.nIf you have no Meta key, you may instead type ESC followed by the character.)nUseful tasks:nVisit New File Open Home DirectorynCustomize Startup Open *scratch* buffernnGNU Emacs 25.3.50.2 (x86_64-pc-linux-gnu, GTK+ Version 3.18.9)n of 2017-09-16nCopyright (C) 2017 Free Software Foundation, Inc.nnGNU Emacs comes with ABSOLUTELY NO WARRANTY; type C-h C-w for full details.nEmacs is Free Software--Free as in Freedom--so you can redistribute copiesnof Emacs and modify it; type C-h C-c to see the conditions.nType C-h C-o for information on getting the latest version.n-UUU:%%--F1 *GNU Emacs* Top of 1.0k (1,0) (Fundamental) ---------------nFor information about GNU Emacs and the GNU system, type C-h C-a.n

配置 Emacs

把下面的東西原封不動地抄進 ~/.emacs 裡面。

(require package)n(setq package-archivesnttt(("gnu" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")ntttt("melpa" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")))nn(package-initialize)n(custom-set-variablesn ;; custom-set-variables was added by Custom.n ;; If you edit it by hand, you could mess it up, so be careful.n ;; Your init file should contain only one such instance.n ;; If there is more than one, they wont work right.n (ac-auto-show-menu 0.1)n (ac-modesnt (quotentt(emacs-lisp-mode lisp-mode lisp-interaction-mode slime-repl-mode nim-mode c-mode cc-mode c++-mode objc-moden swift-mode go-mode java-mode malabar-mode clojure-mode clojurescript-mode scala-moden scheme-mode ocaml-mode tuareg-mode coq-mode haskell-mode agda-mode agda2-mode perl-moden cperl-mode python-mode ruby-mode lua-mode tcl-mode ecmascript-mode javascript-moden js-mode js-jsx-mode js2-mode js2-jsx-mode coffee-mode php-mode css-mode scss-moden less-css-mode elixir-mode makefile-mode sh-mode fortran-mode f90-mode ada-mode xml-moden sgml-mode web-mode ts-mode sclang-mode verilog-mode qml-mode apples-moden haskell-mode fundamental-moden idris-mode ; 這一行僅 Idris 用戶添加n )))n (blink-cursor-mode t)n (column-number-mode t)n (custom-enabled-themes nil)n (flyspell-abbrev-p t)n (flyspell-after-incorrect-word-string nil)n (font-use-system-font t)n (global-auto-complete-mode t)n (global-linum-mode t)n (idris-interpreter-path "~/.cabal/bin/idris") ; 這一行僅 Idris 用戶添加n (show-paren-mode t)n (size-indication-mode t))n

上面的配置有兩行是只有 Idris 用戶需要添加的,請注意閱讀注釋。

配置節選自我的 .emacs ,原本還有一些其他內容,與 Haskell Idris 無關我就刪了。

這時候重啟 Emacs ,你會發現你的配置可能載入不起,因為你沒裝對應的插件。 我們首先在 Emacs 里按下 Alt+X ,然後這時你的游標出現在最下面。

輸入 package-list-package ,然後它應該是這樣的:

-UUU:%%--F1 *GNU Emacs* Top of 1.0k (1,0) (Fundamental) ---------------nM-x package-list-packagesn

等一會(這時開始下載 tuna 上的 elpa/gnu 源的內容),然後你會發現出現了插件列表。

大概是這樣的:

1 ace-window 0.9.0 available Quickly switch windows.n 2 ack 1.5 available interface to ack-like toolsn 3 ada-mode 5.3.1 available major-mode for editing Ada sou$n 4 ada-ref-man 2012.3 available Ada Reference Manual 2012n 5 adaptive-wrap 0.5.1 available Smart line-wrapping with wrap-$n 6 adjust-parens 3.0 available Indent and dedent Lisp code, a$n 7 aggressive-indent 1.8.3 available Minor mode to aggressively kee$n 8 ahungry-theme 1.5.0 available Ahungry color theme for Emacs.$n 9 all 1.0 available Edit all lines matching a give$n 10 ampc 0.2 available Asynchronous Music Player Cont$n 11 arbitools 0.71 available Package for chess tournaments $n 12 ascii-art-to-un... 1.11 available a small artist adjunctn 13 async 1.9.2 available Asynchronous processing in Ema$n 14 auctex 11.91.0 available Integrated environment for *Te$n 15 aumix-mode 7 available run the aumix program in a buf$n 16 auto-correct 1.1 available Remembers and automatically fi$n 17 auto-overlays 0.10.9 available Automatic regexp-delimited ove$n 18 beacon 1.3.2 available Highlight the cursor whenever $n 19 bug-hunter 1.3.1 available Hunt down errors by bisecting $n 20 caps-lock 1.0 available Caps-lock as a minor moden-UUU:%%--F1 *Packages* Top of 25k (1,0) (Package Menu) --------------n

使用快捷鍵 Ctrl+S 進入搜索,這時你的游標在最下面。 輸入 auto-complete ,找到叫這個名字的插件。搜索結果之間用 Ctrl+S 切換。

藍後對它按下回車,看到半個屏幕變成了它的安裝說明。

我的是安裝好了的,看起來和你們的會不大一樣,不過基本上是這樣的:

-UUU:%%--F1 *Packages* 65% of 25k (199,9) (Package Menu) --------------n 1auto-complete is a dependency package.n 2n 3 Status: Installed in 『auto-complete-20170124.1845/』 (unsigned).n 4 Version: 20170124.1845n 5 Summary: Auto Completion for GNU Emacsn 6 Requires: popup-0.5.0, cl-lib-0.5n 7Required by: ac-c-headers-20151021.134n 8n 9This extension provides a way to complete with popup menu like:n10n-UU-:%%--F1 *Help* Top of 618 (1,0) (Help) ----------------------nType C-x 1 to delete the help window, C-M-v to scroll help.n

用 Ctrl+X O 切到這半個屏幕,然後把游標移動到 [Install] 上(上面就沒有,因為我已經裝好了),回車安裝。

按理說安裝是很快的,然後用 Ctrl+0 關掉這半個窗口。 你會發現原本的插件列表界面變成了一些編譯信息。用 Ctrl+X K (輸完這快捷鍵它會讓你確認一下,這時回車就好)關掉它,回到原本的插件列表。

按照同樣的步驟搜索並安裝 haskell-mode 。 Idris 用戶請安裝 idris-mode 。

然後就什麼都沒有了!再用 Emacs 打開一個 .hs 結尾的文件,就可以看到漂亮的高亮了!

快樂生活每一天

你可以使用 Tab 鍵來調整縮進(而不是輸入 Tab), Haskell 插件會自動告訴你可以用哪些縮進,不會讓你吃縮進的虧。

這個插件很牛逼。比如,你會發現,只有開啟了 TypeFamilies 插件後,

type family Xxx n

才會高亮出來。

對於 Idris

一樣的,只是可以用 Ctrl+C Ctrl+L 自動進行 type check ,而且報錯時還會把報錯那一行高亮出來。

填 hole 請用 Ctrl+C Ctrl+A 。

健康生活一輩子

建議開啟一個終端里兩個 Tab ,一個開 Emacs ,一個開 ghci 。 Idris 同理。

推薦閱讀:

Haskell 的 Typeclass 怎麼理解?
為什麼haskell里需要monoid?
為什麼 Haskell 始終沒法流行呢?
Robert Harper 不支持Haskell 的理由是?

TAG:Emacs | Haskell | 编程 |