SLIME 使用手冊(帝歸翻譯)

1、簡介

Slime 的意思是「Emacs 下優秀的 Lisp 交互式開發模式」。 linux

經過支持 Common Lisp 的交互式編程,Slime 擴展了 Emacs。因此的特性都基於 slime-mode,一個 Emacs 的 minor-mode,它爲標準的 lisp-mode 提供補充。lisp-mode 爲編輯 Lisp 源文件提供支持,而 slime-mode 則提供了與一個 Lisp 進程進行交互的功能,包括編譯、調試、文檔查找等等。 git

slime-mode 開發環境效仿 Emacs 原生的 Emacs Lisp 環境。咱們也從某些相似的系統(例如 ILISP)那裏借鑑了一些,固然也包括咱們本身的想法。 github

Slime 由兩部分組成:用 Emacs Lisp 寫的用戶界面,和用 Common Lisp 寫的服務器端。這兩部分經過套接字鏈接在一塊兒,而且使用一個相似於 RPC 的協議通訊。 正則表達式

服務器端的 Lisp 主要是可移植的 Commom Lisp。所須要的跟特定 Lisp 實現相關的特性都由一個接口定義好,而後由不一樣的 Lisp 實現提供。這使得 Slime 很是容易移植。 算法

2、開始

本章告訴你如何配置和啓動 Slime。 shell

2.1 支持平臺

Slime 普遍地支持多種操做系統和 Lisp 實現。Slime 能夠在類 Unix 系統、Mac OSX 和 Microsoft Windows 上運行。GNU Emacs 2一、22 和 23 以及 XEmacs 21 均可以運行 Slime。 express

粗略地根據支持的良好程度來排序的話,全部支持的 Lisp 實現爲: 編程

  • CMU Common Lisp(CMUCL),19d 版或更新
  • Steel Bank Common Lisp(SBCL),1.0 版或更新
  • Clozure Common Lisp(CCL),1.3 版或更新
  • LipsWorks,4.3 版或更新
  • Allegro Common Lisp(ACL),6 版或更新
  • CLISP,2.35 版或更新
  • Armed Bear Common Lisp(ABCL)
  • Corman Common Lisp,2.51 版或更新,須要 http://www.grumblesmurf.org/lisp/corman-patches 的補丁
  • Scieneer Common Lisp(SCL),1.2.7 版或更新
  • Embedded Common Lisp(ECL)

絕大部分特性在不一樣實現上的表現都是一致的,可是有些可能會有所不一樣。這些包括放置編譯信息的註釋的精度、XREF 支持以及調試器命令(例如「重啓緩衝區」)。 瀏覽器

2.2 下載 Slime

你能夠選擇使用發行版本的 Slime 或者直接經過 CVS 倉庫使用 Slime。你能夠從咱們的網站下載最新發布版本: http://www.common-lisp.net/project/slime/ 。 緩存

咱們建議加入了 slime-dev 郵件列表的用戶使用 CVS 版本的代碼。

2.2.1 從 CVS 下載

能夠從 common-lisp.net 的 CVS 倉庫取得 Slime。你能夠選擇使用最新版本的代碼或者是帶有 FAIRLY-STABLE 標籤的快照版本。

跟 FAIRLY-STABLE 版本的代碼相比,最新版本的代碼可能有更多的特性和更少的 BUG,但也有可能由於較大的改動而不穩定。根據經驗法則,咱們建議若是你加入了 slime-dev 郵件列表,你最好使用最新版本(當進行主要的變更時,咱們會發出通告)。若是你沒有加入郵件列表,你就沒法得知最新版本代碼的狀況,因此使用 FAIRLY-STABLE 或者發佈版本是一個安全的選擇。

若是你從 CVS 遷出代碼,記得常常更新。常常會有小的改進提交上去,而 FAIRLY-STABLE 標籤也會隨時推動。

2.2.2 使用 CVS

要下載 Slime 你要先配置你的 CVSROOT 而且登陸到倉庫。

export CVSROOT=:pserver:anonymous@common-lisp.net:/project/slime/cvsroot
cvs login

最新版的代碼能夠經過如下方式遷出:

cvs checkout slime

或者能夠經過如下方式遷出 FAIRLY-STABLE 版本:

cvs checkout -rFAIRLY-STABLE slime

若是你想知道最新版本的代碼跟你運行的版本有什麼新的東西,你能夠將本地的 ChangeLog 和版本倉庫的進行對比:

cvs diff -rHEAD ChangeLog # or: -rFAIRLY-STABLE

2.3 安裝

若是你已經有了一個能夠從命令行啓動的 Lisp 實現,那麼僅需在 .emacs 文件中添加幾行便可安裝成功:

(setq inferior-lisp-program "/opt/sbcl/bin/sbcl") ; your Lisp system
(add-to-list 'load-path "~/hacking/lisp/slime/")  ; your SLIME directory
(require 'slime)
(slime-setup)

在 README 文件裏也能夠見到上面這些代碼。你能夠從那裏複製粘貼,但要記得替換正確的路徑。

這是沒有其它雜項的最小化配置。若是基本配置能夠工做,那麼你能夠試附加模塊。(8.1 加載擴展包)

咱們建議若是你要使用 Slime 就不要在 Emacs 里加載 ILISP 包。若是你這麼作了,那麼在編輯 Lisp 源文件時就會加入許多鍵綁定,並且這些鍵綁定可能會跟 Slime 啓動的 Lisp 進程發生衝突而沒法正常工做。

2.4 啓動 Slime

Emacs 命令 M-x slime 能夠啓動 Slime。它使用 inferior-lisp 包來啓動一個 Lisp 進程,加載並啓動 Lisp 端服務器(叫作「Swank」),而後在 Emacs 和 Lisp 之間創建一個 socket 鏈接。最後會生成一個 REPL 緩衝區,你能夠在這裏輸入 Lisp 表達式並求值。

因而如今 Slime 啓動完成,你能夠開始使用了。

2.5 調整設置

這一部分說明了如何減小 Slime 的啓動時間和如何爲多 Lisp 系統配置 Slime。

在進行本部分以前請確認你的基本配置已經能夠工做。若是你對基本配置感到滿意,那麼請跳過這部分。

關於附加模塊請看「8.1 加載擴展包」。

2.5.1 自動加載

基本設置始終會加載 Slime,即便你不使用它。若是你只在須要的時候才加載 Slime,那麼 Emacs 會啓動的快一點。要這樣,你須要稍微更改你的 .emacs 文件:

(setq inferior-lisp-program "the path to your Lisp system")
(add-to-list 'load-path "the path of your slime directory")
(require 'slime-autoloads)
(slime-setup)

跟基本配置相比,差異只在這一行 (require 'slime-autoloads)。它告訴 Emacs 當 M-x slime 或者 M-x slime-connect 命令第一次執行以後 Slime 的其它部分會被自動加載。

2.5.2 多種 Lisp

默認狀況下,M-x slime 命令啓動的程序是由 inferior-lisp-program 指定的。若是你在執行 M-x slime 命令時添加了一個前綴參數,Emacs 會啓動參數中指定的程序。若是你須要常用它或者命令的名稱太長,那麼在 .emacs 文件裏設置 slime-lisp-implementations 變量則較爲方便。例如,在這裏咱們定義了兩個程序:

(setq slime-lisp-implementations
      '((cmucl ("cmucl" "-quiet"))
  (sbcl ("/opt/sbcl/bin/sbcl") :coding-system utf-8-unix)))

這個變量包含了一個 Lisp 程序的列表,若是你經過一個減號前綴參數啓動 Slime,M-- M-x slime,你能夠從這個列表裏選擇一個程序。當不加前綴地啓動該命令,slime-default-lisp 變量裏指定的程序或者是列表中的第一項會被使用。列表的元素應該像這樣:

(NAME (PROGRAM PROGRAM-ARGS...) &key CODING-SYSTEM INIT INIT-FUNCTION ENV)
  • NAME 是一個符號,用來指定 Lisp 程序
  • PROGRAM 是程序的文件名。注意文件名能夠包含空格。
  • PROGRAM-ARGS 是一個命令行參數的列表。
  • CODING-SYSTEM 指定了鏈接的編碼系統(見 6.1 Emacs 端 slime-net-coding-system)。
  • INIT 應該是一個接受兩個參數的函數:一個文件名和一個字符編碼。這個函數應該返回一個字符串格式的 Lisp 表達式,來指導 Lisp 啓動 Swank 服務器而且將端口號寫入文件。啓動時,Slime 啓動一個 Lisp 進程並將此函數的結果發送給 Lisp 的標準輸入。默認狀況下,slime-init-command 會被使用。「2.5.3 更快地加載 Swank」裏有一個例子。
  • INIT-FUNCTION 應該是一個不接受參數的函數。鏈接創建以後它會被調用。(見 6.1.1 鉤子 slime-connected-hook)
  • ENV 一個爲子進程指定環境變量的列表。例如:
(sbcl-cvs ("/home/me/sbcl-cvs/src/runtime/sbcl"
     "--core" "/home/me/sbcl-cvs/output/sbcl.core") :env ("SBCL_HOME=/home/me/sbcl-cvs/contrib/"))

在子進程中初始化 SBCL_HOME。

2.5.3 更快地加載 Swank

對於 SBCL,咱們建議你新建一個有 socket 支持和 POSIX 綁定的核心配置文件,由於這些模塊加載起來很耗時。爲了新建一個這樣的核心,執行如下的命令:

shell$ sbcl (mapc 'require '(sb-bsd-sockets sb-posix sb-introspect sb-cltl2 asdf)) (save-lisp-and-die "sbcl.core-for-slime")

而後,在你的 .emacs 文件里加入以下代碼:

(setq slime-lisp-implementations
      '((sbcl ("sbcl" "--core" "sbcl.core-for-slime"))))

爲了最大化啓動速度,你能夠在覈心文件裏直接包含 Swank 服務器。這樣作的缺點是設置的時候比較麻煩,而且當你想升級你的 Slime 或者 SBCL 的時候你要新建一個核心文件。這樣作的步驟是:

shell$ sbcl (load ".../slime/swank-loader.lisp") (swank-loader:dump-image "sbcl.core-with-swank")

而後在 .emacs 里加入以下代碼:

(setq slime-lisp-implementations
      '((sbcl ("sbcl" "--core" "sbcl.core-with-swank") :init (lambda (port-file _)
        (format "(swank:start-server %S)\n" port-file)))))

相似的配置對其它 Lisp 實現也適用。

3、使用 Slime 模式

Slime 的全部命令都經過 slime-mode 提供。它是一個與 Emacs 的 lisp-mode 配合使用的 minor-mode。本章描述 slime-mode 及其相關事項。

3.1 用戶介面須知

要方便地使用 Slime,瞭解一些「全局的」用戶界面特性是十分重要的。這一部分描述了最爲重要的原則。

3.1.1 臨時緩衝區

某些 Slime 命令會建立臨時緩衝區來顯示結果。雖然這些緩衝區有它們本身的爲了特定目的而使用的 major-mode,但某些特定的約定是通用的。

能夠經過按 q 鍵來關閉臨時緩衝區。此操做會關閉緩衝區而且回覆緩衝區顯示以前的窗口配置。臨時緩衝區也能夠經過通常的命令例如 kill-buffer 來關閉,這樣的話以前的窗口配置就不會被恢復。

按 RET 鍵被認爲是「作最明顯的有用的事情」。例如,在 apropos 緩衝區此操做會打印出當前光標處的符號的詳細描述,而在 XREF 緩衝區此操做會顯示當前光標處的索引的源代碼。這樣的行爲是效仿 Emacs 的顯示相關內容、補全結果等的緩衝區。

含有 Lisp 符號的臨時緩衝區會使用 slime-mode 來補充它本身的特定的模式。這樣就可使用通常的 Slime 命令,例如描述符號、查找函數定義等等。

對這些「描述性的」緩衝區的初始聚焦由變量 slime-description-autofocus 肯定。若是它是 nil(默認的),這些描述性緩衝區不會自動聚焦,反之則會。

3.1.2 *inferior-lisp*緩衝區

Slime 在內部使用 comint 包來啓動 Lisp 進程。這會產生一些用戶可見的結果,有些是好的,另外一些則不是。爲了不產生疑惑,理解其交互特性是頗有用的。

inferior-lisp 緩衝區包含有 Lisp 進程本身的 top-level。這個與 Lisp 的直接鏈接對錯誤排查頗有用,而且使用 inferior-slime-mode 能夠達到某種程度上的 Slime 集成。許多人選擇加載更好的集成模塊 SLIME REPL 包(見 8.2 REPL)而無視 inferior-lisp 緩衝區。(見 8.1 加載擴展包 得到更多關於啓動 REPL 的信息。)

3.1.3 多線程

若是 Lisp 支持多線程,對於每一個請求 Slime 會生成一個新的線程,例如,C-x C-e 會建立一個新線程來對錶達式求值。可是對於從 REPL 來的請求則是一個例外:全部在 REPL 緩衝區裏輸入的命令都會在一個專用的 REPL 線程裏求值。

多線程和特殊變量會致使一些複雜性。非全局的特殊綁定是在本地線程裏的,也就是說,在一個線程裏改變一個由 let 綁定的特殊變量的值不會影響到其它線程裏相同名字的變量的值。這增長了改變新線程的打印和讀取行爲的困難程度。變量 swank:default-worker-thread-bindings 就是爲了應付這種狀況的:不須要改變一個變量的全局的值,而是增長 swank:default-worker-thread-bindings 的綁定,例如,使用下面的代碼,新的線程會默認將浮點值讀取爲 double。

(push '(*read-default-float-format# . double-float)
      swank:*default-worker-thread-bindings*)

3.1.4 鍵綁定

整體上咱們會讓咱們的鍵綁定跟 Emacs 的鍵綁定配合良好。咱們也使用了咱們本身的某種不太尋常的約定:當鍵入一個三次按鍵的命令時,最後一次按鍵能夠按 Control 也能夠不按。例如,slime-describe-symbol 命令的鍵綁定是 C-c C-d d,可是按 C-c C-d C-d 也是一樣的。咱們將兩種方式都綁定了,由於有些人喜歡三次按鍵都按着 Control 鍵,而有些人則不是。而且有兩次按鍵做爲前綴,咱們不怕鍵不夠用。

這條規則只有一個例外,但願不要讓你中招。咱們歷來不在任何命令裏綁定 C-h 鍵,因此 C-c C-d C-h 跟 C-c C-d h 作的事情是不同的。這是由於 Emacs 內建的默認狀況是,輸入一個前綴,而後按 C-h,會顯示處全部以該前綴開始的鍵綁定。因此 C-c C-d C-h 命令實際上會顯示出全部的文檔命令。這個特性太有用了因此咱們不會替換它!

「你是故意破壞 Emacs 超級牛逼的在線幫助機制嗎?上帝都會震怒的!」

此建議十分有用。Emacs 的在線幫助機制是你最快捷、最完整和最新的關於鍵綁定的信息來源。它們是你的朋友:

  • C-h k 或者 M-x describe-key

    描述當前緩衝區的綁定到的函數。

  • C-h b 或 describe-bindings

    列出當前緩衝區的全部鍵綁定。

  • C-h m 或 describe-mode

    顯示全部當前緩衝區可用的 major-mode 的命令,而後是全部的 minor-mode 的命令。

  • C-h l 或 view-lossage

    按順序顯示出你剛剛按了的全部按鍵的序列。

注意:在本文檔裏 C-h 指定的意思是一個「典型鍵綁定」(canonical key),它多是 Ctrl-h 或者是 F1。或者是普通狀況下你的.emacs 文件裏配置的 help-command 函數的綁定。下面是一種情形:

(global-set-key [f1]   'help-command)
(global-set-key "\C-h" 'delete-backward-char)

在這種狀況下,在本文檔中任何地方你看到的 C-h 你均可以用 F1 來代替。

你能夠像這樣用 global-set-key 函數在你的~/.emacs 文件裏全局地更改默認的鍵綁定:

(global-set-key "\C-c s" 'slime-selector)

這會綁定 slime-select 函數到 C-c s。

或者,若是你只是想在特定的 slime 模式下新建或改變鍵綁定,你能夠像這樣在你的~/.emacs 文件裏使用 define-key 函數:

(define-key slime-repl-mode-map (kbd "C-c ;") 'slime-insert-balanced-comments)

這會在 REPL 緩衝區裏綁定 slime-insert-balanced-comments 函數到 C-c ; 鍵綁定。

3.2 求值命令

這些命令每個都以不一樣的方式來對一個 Common Lisp 表達式求值。通常來講它們模仿 Emacs Lisp 的求值命令。默認狀況下它們會在顯示區顯示出結果,可是一個前綴參數會讓結果插入到當前緩衝區中。

  • C-x C-e 或 M-x M-x slime-eval-last-expression

    對光標前的表達式求值而且將結果顯示到顯示區

  • C-M-x 或 M-x slime-eval-defun

    對當前 toplevel 的形式進行求值並將結果打印到顯示區。「C-M-x」會特別對待「defvar」。正常來說,若是定義的變量已經有一個值了,「defvar」表達式不會作任何事情。可是「C-M-x」命令無條件的將「defvar」表達式裏定義的值初始化並賦予指定的值。這個特性十分便於調試 Lisp 程序。

若是帶數字參數地執行 C-M-x 或者 C-x C-e,它會將結果插入到當前緩衝區,而不是將其打印到顯示區。

  • C-c : 或 M-x slime-interactive-eval

    從迷你緩衝區讀取一個表達式並求值

  • C-c C-r 或 M-x slime-eval-region

    對區域進行求值

  • C-c C-p 或 M-x slime-pprint-eval-last-expression

    對光標前的表達式進行求值並將結果漂亮地打印在一個新的緩衝區裏

  • C-c E 或 M-x slime-edit-value

    在一個叫作「Edit

    」的新緩衝區裏編輯一個能夠 setf 的形式的值。這個值會被插入一個臨時緩衝區以便編輯,而後用 C-c C-c 命令來提交設置於 Lisp 中。
  • C-x M-e 或 M-x slime-eval-last-expression-display-output

    對光標前的表達式求值並將結果打印在顯示緩衝區裏。若是表達式會寫一些內容到輸出流的話這會頗有用。

  • C-c C-u 或 M-x slime-undefine-function

    用 fmakunbound 來取消當前光標處函數的定義。

3.3 編譯命令

Slime 有許多很好的命令來編譯函數、文件和包。好的地方在於,不少 Lisp 編譯器生成的提示和警告會被攔截,而後直接註釋給 Lisp 源文件緩衝區裏相應的表達式。(試一試看會發生什麼。)

  • C-c C-c 或 M-x slime-compile-defun

    編譯光標處的 top-level 形式。被選擇的區域會閃一下以給出迴應,代表是哪一部分被選擇了。若給了一個(正的)前綴參數的時候,形式會以最小調試設置來編譯。如果一個負的前綴參數,編譯速度會被優化。區域裏的代碼在編譯以後將要被執行,總的來講,此命令將該區域寫入一個文件,編譯該文件,而後加載結果代碼。

  • C-c C-k 或 M-x slime-compile-and-load-file

    編譯和加載當前緩衝區的源文件。若是編譯步驟失敗了,那麼文件不會被加載。編譯是否失敗並不老是那麼容易判斷的:某些狀況下你可能會在加載階段進入調試器。

  • C-c M-k 或 M-x slime-compile-file

    編譯(但不加載)當前緩衝區的源文件。

  • C-c C-l 或 M-x slime-load-file

    加載 Lisp 文件。此命令用到了 Common Lisp 的 LOAD 函數。

  • M-x slime-compile-region

    編譯選中的區域。

Slime 經過在源代碼的形式下加下劃線來表示有提示信息。能夠經過將鼠標置於文本處或者下面這些選擇命令來閱讀帶有提示信息的編譯器消息。

  • M-n 或 M-x slime-next-note

    將光標移到下一個編譯器消息處並顯示消息。

  • M-p 或 M-x slime-previous-note

    將光標移到上一個編譯器消息處並顯示消息。

  • C-c M-c 或 M-x slime-remove-notes

    刪除緩衝區裏的全部提示信息。

  • C-x ‘ 或 M-x next-error

    訪問下一個錯誤消息。實際上這不是一個 Slime 命令,Slime 會建立一個隱藏的緩衝區,而後大部分的編譯模式的命令(見 info 「emacs」文件的「Compilation Mode」節點)都會相似批處理編譯器同樣地編譯 Lisp。

3.4 補全命令

補全命令的做用是根據光標處已有的東西來補全一個符號或者形式。典型的補全假設一個肯定的前綴,給出的選擇也只是可能發生的分支。模糊補全會作更多的嘗試。

  • M-TAB 或 M-x slime-complete-symbol

    補全光標處的符號。注意,Slime 裏有三種模式的補全;默認的模式跟正常的 Emacs 補全相似(見 6.1 slime-complete-symbol-function)

3.5 查找定義(「Meta-Point」命令)

Slime 提供了熟悉的 M-. 命令。對於普遍函數來說此命令會找出全部的方法,而在某些系統上它會作一切其它事情(例如根據 DEFSTRUCT 定義來追蹤結構訪問器)。

  • M-. 或 M-x slime-edit-definition

    跳至光標處符號的定義處

  • M-, 或 M-# 或 M-x slime-pop-find-definition-stack

    回到 M-. 命令執行的光標處。若是 M-. 被執行了屢次,那麼此命令會多重地回溯。

  • C-x 4 . 或 M-x slime-edit-definition-other-window

    相似 slime-edit-definition,可是會跳到另外一個窗口來編輯其定義。

  • C-x 5 . 或 M-x slime-edit-definition-other-frame

    相似 slime-edit-definition,可是會跳到另外一個框架來編輯其定義。

  • M-x slime-edit-definition-with-etags

    使用 ETAGES 的表來尋找當前光標處的定義。

3.6 文檔命令

Slime 的在線文檔命令效仿了 Emacs 的例子。這些命令都以 C-c C-d 爲前綴,而且容許更改其鍵綁定或者取消更改(見 3.1.4 鍵綁定)

  • SPC 或 M-x slime-space

    Space 鍵插入一個空格鍵,而且也查找並顯示出當前光標處函數的參數列表,若是有的話。

  • C-c C-d d 或 M-x slime-describe-symbol

    描述當前光標處的符號。

  • C-c C-d f 或 M-x slime-describe-function

    描述當前光標處的函數。

  • C-c C-d a 或 M-x slime-apropos

    對於一個正則表達式執行一個合適的搜索,來搜索全部的 Lisp 符號名稱,而且顯示出相應的文檔字符串。默認狀況下全部包的外部變量都會被搜索,你能夠用一個前綴參數來指定特定的包或者是否包含未導出的符號。

  • C-c C-d z 或 M-x slime-apropos-all

    相似 slime-apropos 可是默認包含全部內部符號。

  • C-c C-d p 或 M-x slime-apropos-package

    顯示包內全部符號的合適的結果。這個命令是用來在一個較高層次瀏覽包的。加上包名補全,它能夠差很少被看成是一個 Smalltalk 相似的圖像瀏覽器。

  • C-c C-d h 或 M-x slime-hyperspec-lookup

    在《Common Lisp Hyperspec》裏查找當前光標處的符號。它使用經常使用的 hyperspec.el 來在瀏覽器裏顯示相應的部分。Hyperspec 能夠在網絡上或者在 common-lisp-hyperspec-root 處,默認打開的瀏覽器經過 browse-url-browser-function 指定。

    注意:這裏就是一個 C-c C-d h 跟 C-c C-d C-h 不一樣的例子

  • C-c C-d ~ 或 M-x hyperspec-lookup-format

    在《Common Lisp Hyperspec》裏查找一個 foramt 格式控制符。

  • C-c C-d # 或 M-x hyperspec-lookup-reader-macro

    在《Common Lisp Hyperspec》裏查找一個讀取宏。

3.7 交叉引用命令

Slime 的交叉引用命令是基於 Lisp 系統的支持的,而此特性在不一樣 Lisp 實現上差別頗大。對於那些沒有內置 XREF 支持的 Lisp 系統,Slime 須要一個可移植的 XREF 包,這個包是從 CMU AI Repository 得到而且與 Slime 綁定在一塊兒的。

因此這些命令的操做對象都是當前光標處的符號,若是沒有,則會要求用戶輸入。若是有前綴參數,則總會要求用戶輸入符號。你能夠輸入如下所示的鍵綁定,或者將最後一個鍵加上 control。見 3.1.4 鍵綁定。

  • C-c C-w c 或 M-x slime-who-calls

    顯示該函數的調用者。

  • C-c C-w c 或 M-x slime-who-calls

    顯示該函數調用了的函數。

  • C-c C-w r 或 M-x slime-who-references

    顯示對全局變量的引用。

  • C-c C-w b 或 M-x slime-who-binds

    顯示對全局標量的綁定。

  • C-c C-w s 或 M-x slime-who-sets

    顯示對全局標量的賦值。

  • C-c C-w m 或 M-x slime-who-macroexpands

    顯示某個宏擴展以後的結果。

  • M-x slime-who-specializes

    顯示一個類全部已知的方法。

固然也有所謂的「列出調用者 / 被調用者」命令。這些操做會在一個很底層的層次上搜尋堆上的函數對象,來肯定全部調用的狀況。只有某些 Lisp 系統有此功能,而且在沒法得到精確的 XREF 信息時,這些功能能夠做爲備用。

  • C-c < 或 M-x slime-list-callers

    列出一個函數的全部調用者。

  • C-c > 或 M-x slime-list-callees

    列出一個函數全部調用的函數。

3.7.1 XREF 緩衝區命令

XREF 緩衝區可用的命令。

  • RET 或 M-x slime-show-xref

    在另外一個窗口裏顯示當前光標處的符號的定義。不離開 XREF 緩衝區。

  • Space 或 M-x slime-goto-xref

    在另外一個窗口裏顯示當前光標處的符號的定義而且關閉 XREF 緩衝區。

  • C-c C-c 或 M-x slime-recompile-xref

    從新編譯當前光標處的定義。

  • C-c C-c 或 M-x slime-recompile-all-xrefs

    從新編譯全部定義。

3.8 宏擴展命令

  • C-c C-m 或 M-x slime-macroexpand-1

    將光標處的表達式宏展開一次。若是帶有一個前綴參數,則使用 macroexpand 代替 macroexpand-1。

  • C-c M-m 或 M-x slime-macroexpand-all

    將光標處的表達式徹底宏展開。

  • M-x slime-compiler-macroexpand-1

    顯示光標處的編譯宏展開的 sexp。

  • M-x slime-compiler-macroexpand

    反覆展開光標處的編譯宏的 sexp。

更多的 minor-mode 命令及相關討論見 5.2 slime-macroexpansion-minor-mode。

3.9 分解命令

  • C-c M-d 或 M-x slime-disassemble-symbol

    分解光標處的函數定義。

  • C-c C-t 或 M-x slime-toggle-trace-fdefinition

    觸發對光標處函數的跟蹤。如有前綴參數,則讀取附加信息,例如跟蹤某個指定的方法。

  • M-x slime-untrace-all

    中止跟蹤全部函數。

3.10 停止 / 恢復命令

  • C-c C-b 或 M-x slime-interrupt

    中斷 Lisp 進程(發送 SIGINT)。

  • M-x slime-restart-inferior-lisp

    重啓 inferior-lisp 進程。

  • C-c ~ 或 M-x slime-sync-package-and-default-directory

    從 Emacs 到 Lisp 同步當前包到工做目錄。

  • C-c M-p 或 M-x slime-repl-set-package

    設置 REPL 的包。

  • M-x slime-cd

    設置 Lisp 進程所在的當前目錄。這也改變了 REPL 的當前目錄。

  • M-x slime-pwd

    打印出 Lisp 進程的當前目錄。

3.11 檢查命令

Slime 查看器是一個基於 Emacs 的對普通 INSPECT 函數的替代選擇。Slime 查看器會在一個 Emacs 緩衝區中結合使用文本和對其它對象的超連接來展現一個對象。

Slime 查看器能夠輕易地爲你的程序裏的對象作定製化。詳細用法見 swank-backend.lisp 裏的 inspect-for-emacs 普遍函數。

  • C-c I 或 M-x slime-inspect

    查看輸入在一個迷你緩衝區裏的表達式的值。

在查看器裏可使用的標準命令有:

  • RET 或 M-x slime-inspector-operate-on-point

    若是光標處是一個值,那麼對這個值遞歸地調用查看器查看它。若是光標處是一個命令,則調用它。

  • d 或 M-x slime-inspector-describe

    描述光標處的槽。

  • v 或 M-x slime-inspector-toggle-verbose

    在冗餘模式和簡潔模式之間切換。默認值由 swank:inspector-verbose 指定。

  • l 或 M-x slime-inspector-pop

    回到前一個對象(從 RET 返回)。

  • n 或 M-x slime-inspector-next

    l 的逆操做。也綁定到了空格鍵。

  • g 或 M-x slime-inspector-reinspect

    再次查看。

  • q 或 M-x slime-inspector-quit

    關閉查看緩衝區。

  • p 或 M-x slime-inspector-pprint

    在另外一個緩衝區裏打印出光標處的對象。

  • . 或 M-x slime-inspector-show-source

    查看光標處的對象的源碼。

  • 或 M-x slime-inspector-fetch-all

    取得全部查看器的內容而且移到其最後。

  • M-RET 或 M-x slime-inspector-copy-down

    將光標以後全部在「*」變量裏的值存儲起來。這些對象能夠以後在 REPL 中訪問。

  • TAB, M-x slime-inspector-next-inspectable-object 或 S-TAB, M-x slime-inspector-previous-inspectable-object

    分別是跳至下一個或者前一個可查看對象。

3.12 分析命令

全部的分析命令都是給予 CMUCL 的分析器。它們都是對函數的簡單包裝,而後打印一些信息到輸出緩衝區。

  • M-x slime-toggle-profile-fdefinition

    觸發對一個函數的分析。

  • M-x slime-profile-package

    分析一個包裏的函數。

  • M-x slime-profile-by-substring

    分析全部名字含有某個子串的函數。

  • M-x slime-unprofile-all

    中止全部分析。

  • M-x slime-profile-report

    報告分析數據。

  • M-x slime-profile-reset

    重置分析數據。

  • M-x slime-profiled-functions

    顯示當前全部正在分析的函數。

3.13 遮蓋命令

  • C-c C-a, M-x slime-nop 和 C-c C-v, M-x slime-nop

    此鍵綁定由 inf-lisp 遮蓋。

3.14 語義縮進

Slime 會自動地決定如何縮進你的 Lisp 程序裏的宏。爲了達到這個目的,Lisp 端會查看系統內全部的宏而且將有 &body 參數的宏報告給 Emacs。而後 Emacs 會對這些宏的縮進特殊處理,一般狀況是,將其第一個參數縮進四個空格,而 body 參數縮進兩個空格。

這僅僅「夠用」。若是你是那種很幸運的人,那麼你要閱讀本節剩下的內容。

爲了簡化實現,Slime 並不區分宏和其餘簡單的符號名,除了不一樣的包名。這使得 Slime 和 Emacs 本身的縮進方式兼容得很好。可是,若是你有些宏和某些簡單符號有相同的名字,那麼它們的縮進會相同,使用它們的參數列表裏任一縮進方式。你能夠找出有哪些符號有縮進衝突:

(swank:print-indentation-lossage)

若是有衝突讓你很惱火,不要崩潰,只要用你喜歡的縮進方式覆蓋 elisp 符號的 common-lisp-indent-function 屬性就能夠了。Slime 不會覆蓋你的定製變量,它只是嘗試給你最好的默認設置。

更加巧妙的是,有個不那麼完美的緩存機制來保證良好的性能。

理想狀況下,在每次 Emacs 操做以後,Lisp 會自動查看全部符號的縮進的改變狀況。可是若要每次都執行,那麼效率就過低了。因此,Lisp 一般只會查看那些 Emacs 使用到的屬於本地包的符號,而全部的請求都是從它們那裏來的。這使得取得在交互環境下定義的宏的縮進變得十分高效。爲了查看剩下的那些,當有新的 Lisp 包被建立的時候——例如新系統被加載,全部的符號都會被查看。

你可使用 M-x slime-update-indentation 來強制要求全部符號的縮進信息都被查看。

3.15 根據讀取器的結果字符化

Slime 會自動對讀取器條件判斷表達式進行求值,例如#+linux,在源代碼緩衝區裏,全部會被當前 Lisp 鏈接所忽略掉的代碼都會呈現爲灰色以示不被讀取。

4、SLDB:Slime 調試器

Slime 有一個本身的基於 Emacs 的調試器,SLDB。Lisp 系統裏的情況(Condition)發出的信號會在 Emacs 裏經過 Lisp 符號*DEBUGGER-HOOK*觸發 SLDB。

當有情況發出信號時,SLDB 會生成一個新的緩衝區。這個緩衝區會顯示對情況的描述、一系列重啓選項和調用棧。能夠經過提供的命令來出發重啓、檢查調用棧和在堆棧調用窗口裏移動。

4.1 檢查窗口

用來查看光標處的堆棧調用窗口的命令。

  • t 或 M-x sldb-toggle-details

    出發顯示本地變量和 CATCH 標籤

  • v 或 M-x sldb-show-source

    查看窗口處的當前代碼表達式。此表達式會被展示在 Lisp 源代碼的緩衝區裏。

  • e 或 M-x sldb-eval-in-frame

    對窗口裏的表達式求值。表達式能夠引用窗口裏可用的局部變量。

  • d 或 M-x sldb-pprint-eval-in-frame

    對窗口裏的表達式求值,而且在一個臨時緩衝區裏打印出來。

  • D 或 M-x sldb-disassemble

    拆解窗口處的函數。包括例如窗口對指令指針等信息。

  • i 或 M-x sldb-inspect-in-frame

    查看對窗口裏一個函數求值後的結果。

  • C-c C-c 或 M-x sldb-recompile-frame-source

    從新編譯窗口。C-u C-c C-c 是以最大調試模式從新編譯。

4.2 重啓

  • a 或 M-x sldb-abort

    觸發 ABORT 重啓。

  • q 或 M-x sldb-quit

    「QUIT」——THROW 一個 top-level 的 Slime 請求循環能夠捕獲的標籤。

  • c 或 M-x sldb-continue

    觸發 CONTINUE 重啓。

  • 0 ... 9

    經過數字觸發重啓。

重啓也能夠經過在緩衝區裏按 RET 或者 Mouse-2 來觸發。

4.3 在不一樣的窗口間操做

  • n 或 M-x sldb-down, p 或 M-x sldb-up

    在不一樣窗口間移動。

  • M-n 或 M-x sldb-details-down, M-p 或 M-x sldb-details-up

    有技巧地在不一樣窗口間移動:隱藏以前窗口的詳細信息,顯示下一個窗口的詳細信息和源代碼。這些小技巧讓你只看到當前窗口的詳細信息和源代碼。

  • 或 M-x sldb-end-of-backtrace

    獲取全部的堆棧調用而且到最後一個窗口。

  • < 或 M-x sldb-beginning-of-backtrace

    到第一個窗口。

4.4 單步調試

單步調試並不是在全部的 Lisp 實現裏都是可用的,在那些可用的 Lisp 實現中,它的表現也很不一樣。

  • s 或 M-x sldb-step

    單步運行窗口中的下一個表達式。對 CMUCL 來講,即時在從當前位置可到達的全部代碼的位置上設置斷點。

  • x 或 M-x sldb-next

    單步運行函數裏的下一個形式。

  • o 或 M-x sldb-out

    暫時中止單步調試,當前函數一返回則恢復單步調試。

4.5 其它命令

  • r 或 M-x sldb-restart-frame

    以當前窗口最早運行時的參數爲參數重啓。(此命令並不是在全部 Lisp 實現裏均可用)

  • R 或 M-x sldb-return-from-frame

    在 minibuffer 裏輸入一個值,並以這個值爲返回值回到窗口。(此命令並不是在全部 Lisp 實現裏均可用)

  • B 或 M-x sldb-break-with-default-debugger

    退出 SLDB 而且以 Lisp 默認的調試器調試情況。

  • C 或 M-x sldb-inspect-condition

    查看當前正在調試的情況。

  • : 或 M-x slime-interactive-eval

    在 minibuffer 裏輸入一個表達式並求值。

5、雜項

5.1 slime-selector

slime-selector 用來快速切換到重要的緩衝區:REPL、SLDB、你正在 hack 的 Lisp 源代碼等等。一旦觸發 slime-selector,該命令會要求你輸入一個字母來指定顯示哪個緩衝區。這裏是一些選項。

  • ?

    一個幫助緩衝區,它會列出全部 slime-selector 能夠顯示的緩衝區。

  • r

    當前 Slime 鏈接的 REPL 緩衝區。

  • d

    當前鏈接最近使用的 SLDB 緩衝區。

  • l

    最近訪問的 Lisp 源代碼緩衝區。

  • s

    slime-scratch 緩衝區。

  • c

    Slime 鏈接緩衝區。

  • t

    Slime 線程緩衝區。

slime-selector 沒有一個默認的鍵綁定,可是咱們建議你給它設置一個全局的鍵綁定。你能夠像這樣將它設置爲 C-c s:

(global-set-key "\C-c s" 'slime-selector)

而後你就能夠經過 C-c s r 從任何地方切換到 REPL。

宏 def-slime-selector-method 能夠用來定義 slime-selector 可識別的新緩衝區。

5.2 slime-macroexpansion-minor-mode

一個 Slime 宏擴展緩衝區提供了一些其它命令(這些命令一直是可用的,只是只有在宏擴展緩衝區裏才綁定到了特定的鍵上)

  • C-c C-m 或 M-x slime-macroexpand-1-inplace

    像 slime-macroexpand-1 同樣不過原來的形式被展開後的形式替代了。

  • g 或 M-x slime-macroexpand-1-inplace

    最後的宏展開再次被執行,當前宏展開緩衝區的內容被新展開的內容替換掉了。

  • q 或 M-x slime-temp-buffer-quit

    關閉展開緩衝區。

  • C-_ 或 M-x slime-macroexpand-undo

    取消最後一次宏展開操做。

5.3 多重鏈接

Slime 能夠同時鏈接到多個 Lisp 進程。當帶有前綴參數地調用 M-x slime 命令時,若是已經有一個 Lisp 進程了,它會建立一個新的 Lisp 鏈接。這很方便,可是這須要一些技巧來確保你的 Slime 命令是在你指望的 Lisp 進程裏執行的。

有些緩衝區是鏈接到特定的 Lisp 進程的。每一個 Lisp 進程都有本身的 REPL 緩衝區,在相應緩衝區裏輸入的全部表達式和全部命令都會被髮送到相應的鏈接。其它 Slime 建立的進程也相似地跟它們最開始的進程綁定在一塊兒,包括 SLDB 緩衝區、搜索結果等等。這些緩衝區是跟 Lisp 進程交互的結果,因此在這些緩衝區裏執行的命令也發送到相應的進程。

在其它地方執行的命令,例如 slime-mode 源代碼緩衝區,老是使用「默認的「連接。一般來說是最近創建的鏈接,可是這能夠經過「鏈接列表「緩衝區從新指定。

  • C-c C-x c 或 M-x slime-list-connections

    生成一個緩衝區並列出全部已創建的鏈接。

  • C-c C-x t 或 M-x slime-list-threads

    生成一個緩衝區並顯示當前線程。

slime-list-connections 生成的緩衝區顯示對每一個鏈接有個一行的簡介。簡介顯示了鏈接的序列號、Lisp 實現的名字以及其它的 Lisp 進程信息。當前的「默認」鏈接經過一個星號來指示。

connection-list 緩衝區裏可用的命令有:

  • RET 或 M-x slime-goto-connection

    顯示光標處鏈接的 REPL 緩衝區。

  • d 或 M-x slime-connection-list-make-default

    讓光標處的鏈接成爲「默認「鏈接。它會被 slime-mode 源代碼緩衝區的命令使用。

  • g 或 M-x slime-update-connection-list

    更新緩衝區裏的鏈接列表。

  • q 或 M-x slime-temp-buffer-quit

    退出鏈接列表緩衝區(殺掉緩衝區,回到以前的窗口設置)

  • R 或 M-x slime-restart-connection-at-point

    重啓光標處的進程的鏈接。

  • M-x slime-connect

    鏈接到一個運行中的 Swank 服務器。

  • M-x slime-disconnect

    退出全部鏈接。

  • M-x slime-abort-connection

    取消當前的鏈接嘗試。

6、定製

6.1 Emacs 端定製

Slime 的 Emacs 部分能夠經過 Emacs 的定製系統來進行配置,經過 M-x customize-group slime RET。因爲此定製系統是自描述的,所以在本文檔裏咱們只會包含某些重要的或者可能有歧義的選項。

  • slime-truncate-lines

    在 Slime 生成的 line-by-line 摘要緩衝區裏使用 truncate-lines 的值。這是默認的,來保證行不會被以某種回溯的列表來摺疊。它可能會形成某些信息超出屏幕。

  • slime-complete-symbol-function

    用來補全 Lisp 符號的函數。有三種補全方式:slime-simple-complete-symbol,slime-complete-symbol*(見 8.5 混合補全),和 slime-fuzzy-complete-symbol(見 8.6 模糊補全)。

    默認的是 slime-simple-complete-symbol,相似於 Emacs 的補全方式。

  • slime-filename-translations

    這個變量控制 Emacs 和 Lisp 之間文件名的轉換。當你在不一樣的機器上運行 Emacs 和 Lisp,而它們的文件系統並不相同,或者它們有相同的文件系統可是佈局不一樣,例如使用了 SMB 的文件共享的時候,這個變量就有用了。

  • slime-net-coding-system

    若是你想在 Emacs 和 Lisp 之間傳送 Unicode 字符,你應該設置此變量。例如你使用 SBCL,你應該這樣設置:

    (setq slime-net-coding-system 'utf-8-unix)

    要顯示 Unicode 字符你還須要適當的字體,不然這些字符會被渲染成空心方塊。若是你使用的是 Allegro CL 和 GNU Emacs,你也可使用 emacs-mule-unix 做爲編碼系統。GNU Emacs 給較新的編碼提供了很不錯的字體。(不一樣的 Lisp 系統可使用不一樣的編碼,見 2.5.2 多種 Lisp。)

6.1.1 鉤子

  • slime-mode-hook

    每次有一個緩衝區進入 slime-mode,這個鉤子就會啓動。它最有用的是在你的 Lisp 源代碼緩衝區裏設置當前緩衝區的配置。有個例子是用它來啓動 slime-autodoc-mode(見 8.7 slime-autodoc-mode)。

  • slime-connected-hook

    這個鉤子在每次鏈接到 Lisp 服務器的時候創建。有個例子是用它來生成一個打印窗口(見 8.13 打印窗口)。

  • sldb-hook

    這個鉤子在 SLDB 啓動時建立。這個鉤子的函數是從 SLDB 緩衝區創建後調用的。有個例子是添加 add sldb-print-condition 函數到這個鉤子,這會讓全部 SLDB 調試的情況被 REPL 緩衝區記錄到。

6.2 Lisp 端(Swank)

Slime 的 Lisp 服務器端(也叫作「Swank」),提供幾個變量可供設置。初始化文件~/.swank.lisp 在啓動時會被自動求值,能夠用來設置這些變量。

6.2.1 通訊模式

最重要的能夠配置的變量是 SWANK:COMMUNICATION-STYLE,它指定了 Lisp 端接收和讀取 Emacs 發出的信息的協議。通訊方式的選擇會在全局影響 Slime 的行爲。

可選的通訊方式有:

  • NIL

    這種方式只是簡單地循環地讀取通訊套接字裏的輸入和當 Slime 協議事件發生是提供服務。這種簡單意味着當處於 Slime 的控制的時候 Lisp 不能作其它的處理。

  • :FD-HANDLER

    這種方式使用經典的 Unix 的「select-loop()」。Swank 經過一個事件分發框架(例如 CMUCL 和 SBCL 裏的 SERVE-EVENT)來註冊一個通訊套接字,當數據到達時接收一個回調。在這種方式下,從 Emacs 而來的請求只在 Lisp 進入了事件循環時纔會被檢測到並處理。這種方式簡單而且可預測。

  • :SIGIO

    這種方式使用帶有 SIGIO 信號處理函數的信號驅動 I/O。Lisp 接收來自 Emacs 的請求,附帶一個信號,使 Lisp 中斷任何正在作的事來處理請求。這種方式的好處是迴應即時,由於 Emacs 可使 Lisp 執行某些操做,即便 Lisp 正在忙於某些事情。它也容許 Emacs 併發地發起請求,例如發起一個長期的請求(例如編譯)而後在它完成前發起幾個短時間的請求。它的缺點是它可能其它用戶的 Lisp 代碼的 SIGIO 信號衝突,並且在某些特殊的時刻中斷 Lisp 進程的話則可能產生很嚴重的後果。

  • :SPAWN

    這種方式經過 Lisp 裏的多線程支持來在每一個線程裏執行一個請求。這種方式跟:SIGIO 有某些相似的特性,但它不使用信號,而且全部來自 Emacs 的請求均可以並行處理。

默認的請求處理方式是根據你的 Lisp 系統的能力來選擇的。一般的選擇順序是::SPAWN,而後是:SIGIO,而後:FD-HANDLER,最後是 NIL。你能夠經過調用 SWANK-BACKEND::PREFERRED-COMMUNICATION-STYLE 來查看默認的方式。你也能夠經過在你的 Swank 初始化文件裏設置 SWANK:COMMUNICATION-STYLE 變量來覆蓋默認設置。

6.2.2 其它配置

這些 Lisp 變量能夠經過你的~/.swank.lisp 文件設置:

  • SWANK:CONFIGURE-EMACS-INDENTATION

    這個變量控制宏裏 &body 參數的縮進方式是否會被探測到併發送給 Emacs。它默認開啓。

  • SWANK:GLOBALLY-REDIRECT-IO

    當它爲真,標準輸出流(例如 standard-output)會被全局重定向到 Emacs 裏的 REPL。當它爲假(默認狀況),這些流只是在處理請求時經過動態綁定臨時重定向到 Emacs。主意 standard-input 如今不會被全局重定向到 Emacs,由於當它嘗試從 Emacs 裏讀取信息時,它跟 Lisp 原生的 REPL 交互得不好。

  • SWANK:GLOBAL-DEBUGGER

    當它爲真(默認狀況),它讓 DEBUGGER-HOOK 全局設置爲 SWANK:SWANK-DEBUGGER-HOOK,當後讓 Slime 處理 Lisp 進程裏的全部調試工做。這是用來調試多線程或回調驅動的應用的。

  • SWANK:SLDB-PRINTER-BINDINGS 和 SWANK:MACROEXPAND-PRINTER-BINDINGS 和 SWANK:SWANK-PPRINT-BINDINGS

    這些變量能夠在不一樣的狀況下設置打印器。這些變量的值是打印器變量名和對應的值組成的聯合列表。例如,在 SLDB 中開啓 pretty 打印器來處理調用棧,你能夠這樣:

    (push '(*print-pretty* . t) swank:*sldb-printer-bindings*)
  • SWANK:USE-DEDICATED-OUTPUT-STREAM

    這個變量控制了是否用一個不安全但頗有效的 hack 來從 Lisp 打印輸出到 Emacs。默認是 nil,而且強烈建議不要使用它。

    當它爲 t 時,會創建一個單獨的套接字來把 Lisp 的輸出打印到 Emacs,這比使用協議發送信息來將輸出發送到 Emacs 快。可是,因爲不能保證一個專用的輸出流和一個給予協議消息的流之間的時間,Lisp 命令的輸出到達的時間可能在 REPL 相應時間以前或以後。輸出結果和 REPL 的顯示結果可能以錯誤的順序呈現,甚至在 REPL 裏交叉出現。使用一個專用的輸出流也會讓用 SSH 跟一個在遠程服務器上的 Lisp 程序通訊變得困難。(見 7.1 鏈接到遠程 Lisp)

  • SWANK:DEDICATED-OUTPUT-STREAM-PORT

    當 USE-DEDICATED-OUTPUT-STREAM 是 t,流會在此端口開啓。默認值是 0,表示流會在某個隨機端口開啓。

  • SWANK:LOG-EVENTS

    將這個變量設置爲 t 會讓全部與 Emacs 交換的協議信息都打印到 TERMINAL-IO。這在底層調試和觀察 Slime 底層如何運行是頗有用。TERMINAL-IO 的輸出能夠在 Lisp 系統本身的監視器裏看到,一般是inferior-lisp 緩衝區。

7、小技巧

7.1 鏈接到遠程 Lisp

7.1.1 設置 Lisp 鏡像

若是你不想經過通常的基於 Emacs 的方式加載 swank,只須要加載 swank-load.lisp 文件就能夠了。只須要在一個運行中的 Lisp 鏡像 [1] 裏執行如下代碼:

(load "/path/to/swank-loader.lisp")

如今,咱們須要作的就是啓動 swank 服務器。在第一個例子裏,咱們假設使用默認配置。

(swank:create-server)

因爲咱們將要使用 ssh[2] 來創建連接而且只打開了一個端口,咱們不但願 swank 使用另外一個端口做爲輸出(目前這在 swank 裏是默認的):

(setf swank:*use-dedicated-output-stream* nil)

若是你有其它特別的需求(例如在結束後從新鏈接到 swank),請查看 swank:create-server 的其它參數。其中的一些參數以下:

  • :PORT

    指定服務器所監聽的端口號(默認端口:4005)

  • :STYLE

    見 6.2.1 通訊模式

  • :DONE-CLOSE

    布爾值,指明瞭在服務器在接受了第一個鏈接後是否還會接收其它鏈接(默認值:nil)。對於你但願能夠隨時鏈接的長期運行的 Lisp 進程,指定:done-close t

  • :CODING-SYSTEM

    字符串,指明瞭 Emacs 和 Lisp 之間進行通信的編碼

更加完整的實例以下:

(swank:create-server :port 4005  :dont-close t :coding-system "utf-8-unix")

在 Emacs 端,你會進行相似以下的設置來鏈接到同一臺機器上的 Lisp 鏡像:

(setq slime-net-coding-system 'utf-8-unix)
  (slime-connect "127.0.0.1" 4005)

7.1.2 設置 Emacs

如今咱們須要在本地機器和遠程機器之間創建鏈接。

ssh -L4005:127.0.0.1:4005 username@remote.example.com

這裏調用的 ssh 在本地機器的 4005 端口和遠程機器的 4005 端口上創建了一個 ssh 鏈接 [3]

最後,咱們啓動 Slime:

M-x slime-connect RET RET

RET RET 按鍵表示咱們要使用默認主機(127.0.0.1)和默認端口(4005)。雖然咱們是鏈接到遠程機器上的,ssh 鏈接讓 Emacs 覺得咱們是在本地操做。

7.1.3 設置路徑名翻譯

遠程運行 swank 的一個主要問題就是,Emacs 覺得能夠經過普通的文件名找到文件。若是咱們但願例如 slime-compile-and-load-file (C-c C-k)或者 slime-edit-definition (M-.)這樣的函數正常工做,咱們須要找到一種方法讓本地的 Emacs 正確地找到遠程文件。

要作到這一點主要有兩種方式。第一種是掛載,使用 NFS 或者相似的東西。將遠程機器的硬盤掛載到本地機器的文件系統上,這樣的話例如 /opt/project/source.lisp 的文件名就能夠在兩臺機器上都指向同一個文件。不幸的是,NFS 很慢,並且容易出錯,而且不老是可行的。幸運的是咱們有 ssh 鏈接以及 Emacs 的 tramp-mode 來完成這項工做。

咱們須要作的事情是讓 Emacs 接收一個遠程機器上的文件名,而後將其翻譯爲某種 tramp 能夠理解和使用的格式,反之亦然。假設遠程機器的主機名叫作 remote.example.com,cl:machine-instance 返回「remote」,咱們以「user」用戶登錄,咱們使用 slime-tramp 擴展包來設置適當的翻譯方式,以下:

(push (slime-create-filename-translator :machine-instance "remote.example.com"
                                          :remote-host "remote"
                                          :username "user")
        slime-filename-translations)

7.2 重定向全局 IO 到 REPL

默認狀況下 Slime 並不會改變 standard-output 和 REPL 之外的其它事物。若是你有一些其它的線程,例如 format,write-string 等等,相應的輸出僅僅能在 inferior-lisp 緩衝區或者是終端下看到,一般來講這很不方便。因此若是你有這樣的代碼:

(run-in-new-thread
   (lambda ()
     (write-line "In some random thread.~%" *standard-output*)))

而且想讓它輸出到 Slime 的 REPL 緩衝區而不是 inferior-lisp 緩衝區,只須要將 swank:globally-redirect-io 設置爲 T。

注意,這個變量的值只會在 swank 接收鏈接的時候被檢查,因此你須要把它寫在~/.swank.lisp 文件裏。不然你要本身調用 swank::globally-redirect-io-to-connection 命令,可是你不該該這樣作除非你知道緣由。

7.3 自動鏈接到 Slime

若是想要在打開一個 Lisp 文件的時候自動啓動 Slime,將如下設置加入~/.emacs 文件裏:

(add-hook 'slime-mode-hook
            (lambda ()
              (unless (slime-connected-p)
                (save-excursion (slime)))))

7. 腳註

[1]

Slime 也提供了一個功能相同的 ASDF 系統定義

[2]

有一種不使用 ssh 來鏈接的方法,可是其反作用是將容許全部東西鏈接到你的 Lisp 鏡像,因此咱們不討論這種方式

[3]

默認狀況下 swank 監聽來自 4005 端口的鏈接,若是咱們調用 swank:create-server 函數時指定:port 參數,咱們就可使用其它端口了。

8、擴展包

在 3.0 版中,咱們將一些功能移到了單獨的包裏。本章講述如何加載擴展包的模塊,而且描述了這些包的功能。

8.1 加載擴展包

默認狀況下擴展包並無被加載。你必須稍微設置一下,這樣 Emacs 就能夠知道在哪裏找到這些擴展包、加載哪些擴展包。總的來講,你應該調用 slime-setup 函數,並將須要用的包的名字做爲一個列表傳給它。例如,加載 slime-scratch 和 slime-editing-commands 包的設置以下:

(setq inferior-lisp-program "/opt/sbcl/bin/sbcl") ; your Lisp system
  (add-to-list 'load-path "~/hacking/lisp/slime/")  ; your SLIME directory
  (require 'slime-autoloads)
  (slime-setup '(slime-scratch slime-editing-commands))

啓動 Slime 後,這些擴展包的命令應該均可用了。

這裏要特別提到 REPL 和 slime-fancy 擴展包。許多用戶認爲 REPL(見 8.2 REPL)很必要,而 slime-fancy(見 8.20 slime-fancy)加載了 REPL 包和其它幾乎全部經常使用的包。因此,若是你不知道怎樣啓動,試試:

(slime-setup '(slime-repl)) ; repl only

若是你喜歡你見到的,試試:

(slime-setup '(slime-fancy)) ; almost everything

8.2 REPL:「頂層環境」

Slime 使用定製的讀 - 寫 - 打印循環(REPL,也被稱做「頂層環境」,或者是監聽者)。REPL 界面使用 Emacs Lisp 寫成,所以與傳統的基於 comint 的 Lisp 交互相比,它與 Emacs 更加契合:

  • 能夠經過 SLDB 調試 REPL 裏表達式的情況信號

  • 打印出的不一樣的返回值能夠經過不一樣的 Emacs faces(顏色)加以區分

  • Emacs 經過不一樣的符號管理 REPL 提示符。這確保了 Lisp 的輸出被插入到正確的位置,而且不會和其它的用戶輸入搞混。

加載 REPL 須要在你的.emacs 文件裏調用 (slime-setup '(slime-repl))。

  • C-c C-z 或 M-x slime-switch-to-output-buffer

    選擇輸出緩衝區,通常是在另外一個窗口裏

  • C-c C-y 或 M-x slime-call-defun

    在 REPL 裏調用在當前光標處定義的函數

8.2.1 REPL 命令

  • RET 或 M-x slime-repl-return

    若是輸入完成,則在 Lisp 裏對當前輸入求值。若是沒有,則開啓一個新行並縮進。若是給出了前綴參數,則不檢查輸入完整性而直接求值。

  • C-RET 或 M-x slime-repl-closing-return

    關閉全部未匹配的括號並對當前輸入求值。也綁定到了 M-RET。

  • TAB 或 M-x slime-indent-and-complete-symbol

    縮進當前行並進行符號補全。

  • C-j 或 M-x slime-repl-newline-and-indent

    新開一行並縮進。

  • C-a 或 M-x slime-repl-bol

    到行首,可是在 REPL 提示符以後。

  • C-c C-c 或 M-x slime-interrupt

    以 SIGINT 中斷 Lisp 進程。

  • C-c M-o 或 M-x slime-repl-clear-buffer

    清空當前緩衝區,只留一個提示符。

  • C-c C-o 或 M-x slime-repl-clear-output

    從緩衝區裏清空以前表達式的輸出和結果

8.2.2 輸入引導

輸入導航(歷史)命令是模仿 coming-mode 的。若是你習慣了相似 Bash 的鍵綁定,那麼要注意了: M-p 和 M-n 使用當前的輸入做爲搜索樣本,而且相似 Bash 同樣只有在當前行是空的狀況下才工做。C-和 C-像 Bash 裏的 up 和 down 鍵效果同樣。

  • C- 或 M-x slime-repl-forward-input 和 C- 和 M-x slime-repl-backward-input

    去到前一個 / 後一個歷史輸入

  • M-n 或 M-x slime-repl-next-input 和 M-p 或 M-x slime-repl-previous-input

    使用當前的輸入做爲搜索樣本,在輸入歷史裏向前 / 向後搜索相關輸入。若是 M-n/M-n 被連續按兩次,第二次調用會使用相同的搜索樣本(即便當前輸入已經改變)。

  • M-s 或 M-x slime-repl-next-matching-input 和 M-r 或 M-x slime-repl-previous-matching-input

    使用正則表達式在輸入歷史裏向前 / 向後搜索

  • C-c C-n 或 M-x slime-repl-next-prompt 和 C-c C-p 或 M-x slime-repl-previous-prompt

    在 REPL 緩衝區的當前和前一個提示符之間移動。在有以前輸入的一行裏按 RET 會把那一行復制到最新的提示符處。

slime-repl-wrap-history 變量控控制了環繞行爲,便是若是到了末尾那麼是否應該從新跳轉到歷史的最開頭。

8.2.3 快捷命令

「快捷命令」是一組經過名稱調用的 REPL 命令。要調用一個快捷命令,你須要先在 REPL 提示符後輸入一個逗號,而後再輸入命令的名稱來執行。

快捷命令處理一些相似於切換目錄和加載編譯 Lisp 系統的事務。快捷命令在下面列出,或者你能夠經過 help 快捷命令來交互式地列出來。

  • change-directory (aka !d, cd)

    改變當前目錄

  • change-package (aka !p, in, in-package)

    改變當前包

  • compile-and-load (aka cl)

    編譯(若是)並加載一個 Lisp 文件

  • defparameter (aka !)

    定義一個新的全局的特殊的變量

  • disconnect

    關閉全部鏈接

  • help (aka ?)

    顯示幫助

  • pop-directory (aka -d)

    彈出當前目錄

  • pop-package (aka -p)

    彈出包棧的頂端元素

  • push-directory (aka +d, pushd)

    將一個新的目錄推到目錄棧裏

  • push-package (aka +p)

    將一個包推到包棧裏

  • pwd

    顯示當前目錄

  • quit

    退出 Lisp

  • resend-form

    再次發送最後的形式

  • restart-inferior-lisp

    重啓 inferior-lisp 並從新鏈接 Slime

  • sayoonara

    退出全部 Lisp 並關閉全部 Slime 緩衝區

8.3 多 REPL

slime-mrepl 擴展包爲多監聽者緩衝區提供了支持。M-x slime-open-listener 命令建立一個新的緩衝區。在多線程 Lisp 裏,每個監聽者都與一個單獨的線程相連。在單線程 Lisp 裏,建立多監聽者緩衝區也是能夠的,可是其命令都是在同一個進程裏順序執行的。

8.4 inferior-slime-mode

inferior-slime-mode 是一個用來與 inferior-lisp 緩衝區一塊兒使用的次模式。它提供了一些 Slime 命令,例如符號補全和文檔查詢。它也跟蹤 Lisp 進程的當前目錄。將如下代碼加入.emacs 配置來使用它:

(slime-setup '(inferior-slime-mode))
  • M-x inferior-slime-mode

    打開或關閉 inferior-slime-mode

inferior-slime-mode-map 變量包含了額外的鍵綁定

8.5 混合補全

slime-c-p-c 擴展包提供了不一樣的符號補全算法,它經過中劃線分割的符號名 [1] 的單詞子串來進行「並行」的補全。形式上來說,「a-b-c」能夠補全任何匹配「^a.-b.-c.*」正則表達式的符號(「圓點」匹配任何除了中劃線以外的東西)。下面的例子會給你更直觀的感受:

  • m-v-b 補全爲 multiple-value-bind。

  • w-open 稍有歧義:它能夠補全 with-open-file 或 with-open-stream。它會擴展到最長的相同匹配(with-open-)而後光標會停留在有歧義的第一個字符處,在這裏就是最後一個單詞處。

  • w--stream 擴展爲 with-open-stream

slime-c-p-c-unambiguous-prefix-p 變量定義了在補全符號後光標應該置於何處。例如 f-o 可能的補全是 finish-output 和 force-output,默認狀況下光標會移動到 f 後面,由於這裏是明確的前綴。若是 f-o are finish-output and force-output 是 nil,光標會到插入的文本的最後,在這裏就是在 o 以後。

除此以外,slime-c-p-c 也爲字符名提供補全(對不少能夠識別 Unicode 的 Lisp 實現來說一般頗有用):

CL-USER> #\Sp<TAB>

在這裏 Slime 會將其補全爲#\Space,但在一個能夠識別 Unicode 的實現裏,就可能會有如下的補全:

Space                              Space
  Sparkle                            Spherical_Angle
  Spherical_Angle_Opening_Left       Spherical_Angle_Opening_Up

slime-c-p-c 擴展包也提供了對關鍵字的大小寫敏感的補全。例如:

CL-USER> (find 1 '(1 2 3) :s<TAB>

在這裏 Slime 會補全爲:start,而不是將全部以:s 開頭的關鍵字列出來。

  • C-c C-s 或 M-x slime-complete-form

若是有的話,將當前光標處的函數的參數列表列出來並插入緩衝區。更加通常地,此命令給不徹底的形式的缺失參數提供了一個模板。對於發現泛函數的額外參數,處理 make-instance、defmethod 和其它不少函數來講有特殊的代碼,例如:

(subseq "abc" <C-c C-s>
           --inserts--> start [end])
  (find 17 <C-c C-s>
           --inserts--> sequence :from-end from-end :test test
           :test-not test-not :start start :end end
           :key key)
   (find 17 '(17 18 19) :test #'= <C-c C-s>
            --inserts--> :from-end from-end
            :test-not test-not :start start :end end
            :key key)
   (defclass foo () ((bar :initarg :bar)))
   (defmethod print-object <C-c C-s>
              --inserts-->   (object stream)
              body...)
   (defmethod initialize-instance :after ((object foo) &key blub))
   (make-instance 'foo <C-c C-s>
                   --inserts--> :bar bar :blub blub initargs...)

8.6 模糊補全

slime-fuzzy 擴展包提供了另外一種符號補全方式。

[最好有人描述一下這種算法究竟是作什麼的]

它嘗試一次性補全整個符號,而不是隻補全一部分。例如,「mvb」會補全爲「multiple-value-bind」,「norm-df」會補全爲「least-positive-normalized-double-float」。

這種算法嘗試以不一樣的方式擴展每個字符,而後如下列的方式將全部可能的補全排序列出。

根據在字符串裏的位置,字母會被賦予一個權值。字符串最開頭,或者是前綴字母以後的字母的權值是最高的。分隔符以後的字符,例如#-,權值是次高的。字符串最後或者是後綴字母以前的字母有中等權值,其它地方的字母的權值最低。

若是一個字母在另外一個匹配字母以後,它在此處的可能性就比以前字母的可能性低,因此就會使用以前的可能性。

最後,一個偏好因子會做用於一些經常使用的較短的匹配,其它的東西都是同樣的。

  • C-c M-i 或 M-x slime-fuzzy-complete-symbol

    根據當前光標處的縮寫列出全部可能的補全。若是你將變量 slime-complete-symbol-function 的值設爲這個命令,則能夠經過 M-TAB 使用模糊補全。

8.7 slime-autodoc-mode

Autodoc 模式是一個用來自動顯示光標附近符號的相關信息的 minor-mode。對於函數名,參數列表會被顯示,對於全局變量,則顯示它的值。Autodoc 是經過 Emacs 的 eldoc-mode 來實現的。

該模式能夠經過你~/.emacs 文件裏的 slime-setup 調用來默認開啓:

(slime-setup '(slime-autodoc))
  • M-x slime-arglist NAME

    顯示函數 NAME 的參數列表

  • M-x slime-autodoc-mode

    根據參數的值開啓或關閉 autodoc-mode。當沒有參數時,觸發該模式。

若是變量 slime-use-autodoc-mode 被設置(默認狀況),Emacs 會啓動一個計時器,不然信息只會在按 SPC 以後顯示。

8.8 ASDF

ASDF 是一個流行的「系統構建工具」。slime-asdf 擴展包提供了一些命令來從 Emacs 里加載和編譯這些系統。ASDF 自己沒有被包含在 Slime 裏,你必須本身把它加載到 Lisp 裏。還有,你必須在鏈接以前加載 ASDF,不然你會收到關於符號缺失的錯誤。

  • M-x slime-load-system NAME

    編譯並加載 ASDF 系統。默認的系統名字是從當前目錄下第一個符合 *.asd 的文件裏得到的。

  • M-x slime-open-system NAME &optional LOAD

    打開系統裏的全部文件,若是 LOAD 不是 nil 的話則加載進來。

  • M-x slime-browse-system NAME

    使用 Dired 瀏覽系統裏的全部文件。

該擴展包也加載了一些新的 REPL 快捷命令(見 8.2.3 快捷命令);

  • load-system

    編譯(根據須要)並加載一個 ASDF 系統

  • compile-system

    編譯(但不加載)一個 ASDF 系統

  • force-compile-system

    從新編譯(但不加載)一個 ASDF 系統

  • force-load-system

    從新編譯並加載一個 ASDF 系統

  • open-system

    打開系統裏的全部文件

  • browse-system

    使用 Dired 打開系統裏的全部文件

8.9 導航條

slime-banner 擴展包在當前 REPL 緩衝區安裝一個位於窗口頂端的橫條。開始的時候還會播放一段動畫。

經過將 slime-startup-animation 設置爲 nil,你能夠關閉動畫,而 slime-header-line-p 能夠設置橫條。

8.10 編輯命令

slime-editing-commands 擴展包提供了一些命令來編輯 Lisp 表達式。

  • C-c M-q 或 M-x slime-reindent-defun

    從新縮進當前的 defun,或者重排當前段落。若是光標在一段註釋裏,那麼光標附近的文本會被當作一個段落,而後用 fill-paragraph 重排。不然,它會被當作 Lisp 代碼,當前 defun 會被從新縮進。若是當前 defun 有沒匹配的括號,在從新縮進前會嘗試修復。

  • C-c C-] 或 M-x slime-close-all-parens-in-sexp

    補全當前光標處未閉合的 S 表達式的括號。插入足夠多的右括號,使得跟它的左括號數量匹配。刪除多餘的左括號,將結尾處的括號格式化爲 Lisp 形式。

    若是 REGION 是 true,對該區域操做。不然對頂層環境光標前的表達式操做。

  • M-x slime-insert-balanced-comments

    在包含光標的表達式裏插入對稱的註釋。若是該命令被重複調用(屢次調用之間沒有其它命令了),註釋逐漸從裏面的表達式向外擴展。若是調用的時候有前綴參數,S 表達式的參數列表會有一個對稱的註釋。

  • M-C-a 或 M-x slime-beginning-of-defun

  • M-C-e 或 M-x slime-end-of-defun

8.11 更好的檢查器

有一個默認檢查器的替代物,由 slime-fancy-inspector 擴展包提供。該檢查器更加了解 CLOS 對象和方法。它提供不少用來使 Lisp 代碼檢查對象的行爲。例如,爲了展現一個泛函數,檢查器會以純文本的形式顯示其文檔,而對於每一個方法則會列出它的超連接和一個你能夠調用的「除去該方法」行爲。它的鍵綁定跟默認檢查器是同樣的。

8.12 對象描述

在 Slime 裏,一個「對象描述」 [2] 指的是跟一個 Lisp 對象有關的一塊文本。右鍵點擊文本會彈出操做該對象的一個菜單。有些操做,例如查看,對全部對象都適用,但對象也能夠有本身特有的操做。例如,路徑對象有 Dired 相關的操做。

更加劇要的是,可使用全部標準的 Emacs 命令來剪切和粘貼這些描述(也就是 Lisp 對象,而不只僅是打印出來的樣子)。經過這種方式,能夠剪切和粘貼 REPL 裏以前計算出來的結果。這對不可讀對象來講十分重要。

slime-presentations 擴展包在 REPL 裏安裝這種對象描述,也就是求值命令的結果會被顯示出來。使用這種方法,相關描述會生成標準 Common Lisp REPL 歷史變量 *,**,*** 的用法。例如:

CL-USER> (find-class 'standard-class) #<STANDARD-CLASS STANDARD-CLASS> CL-USER>

在緩衝區裏描述會以紅色顯示。使用標準的 Emacs 命令,描述能夠被複制進 REPL 內的一個新的輸入裏:

CL-USER> (eql '#<STANDARD-CLASS STANDARD-CLASS> '#<STANDARD-CLASS STANDARD-CLASS>) T

當你複製了一個不完整的描述,或者編輯描述裏的文本,該描述會變爲純文本,丟失與 Lisp 對象之間的關聯。在緩衝區裏,這會經過其顏色從紅色變回黑色來表示,並且不能撤銷。

對象描述也能夠在查看器(全部能夠查看的部分都是對象描述)和調試器(全部的本地變量都是對象描述)裏使用。這樣就可使用出如今調試窗口裏的對象來在 REPL 裏求值。這比使用 M-x sldb-eval-in-frame 更加方便。警告:從查看器和調試器而來的對象只在相關窗口打開的時候纔是可用的。不然的話會引發錯誤或者混淆。

對於某些 Lisp 實現,你還能夠安裝 slime-presentation-streams 包,它讓對象描述適用於 standard-output 流和其它流。這意味着不僅是計算的結果,而是某些對象均可以經過與對象描述相關聯來打印到標準輸出(做爲計算的反作用)。目前全部的不可讀對象和路徑都被做爲對象描述打印出來。

CL-USER> (describe (find-class 'standard-object)) #<STANDARD-CLASS STANDARD-OBJECT> is an instance of #<STANDARD-CLASS STANDARD-CLASS>: The following slots have :INSTANCE allocation:
      PLIST                   NIL
      FLAGS                   1
      DIRECT-METHODS ((#<STANDARD-METHOD SWANK::ALL-SLOTS-FOR-INSPECTOR (STANDARD-OBJECT T)>

這也使得能夠複製粘貼、查看這些對象。

除了標準 Emacs 命令,還有一些鍵盤命令,一個 menu-bar 菜單,一個上下文菜單來操做對象描述。咱們在下面解釋了這些鍵盤命令,它們也能夠經過 menu-bar 訪問。

  • C-c C-v SPC 或 M-x slime-mark-presentation

    若是光標在描述內,將其移到描述的最前並標記其末尾。這樣就能夠複製該描述。

  • C-c C-v w 或 M-x slime-copy-presentation-at-point-to-kill-ring

    若是光標在描述內,將該描述複製到 kill ring 裏。

  • C-c C-v r 或 M-x slime-copy-presentation-at-point-to-repl

    若是光標在描述內,將該描述複製到 REPL 裏。

  • C-c C-v d 或 M-x slime-describe-presentation-at-point

    若是光標在描述內,顯示相關對象的註釋。

  • C-c C-v i 或 M-x slime-inspect-presentation-at-point

    若是光標在描述內,在 Slime 查看器裏查看該對象。

  • C-c C-v n 或 M-x slime-next-presentation

    將光標移到緩衝區裏的下一個描述處。

  • C-c C-v p 或 M-x slime-previous-presentation

    將光標移到緩衝區裏的上一個描述處。

相關的操做也能夠在每個描述的上下文菜單裏找到。在一個描述處單擊 mouse-3 打開上下文菜單會,會顯示可用的命令。對於某些對象,某些特別的命令也是可用的。用戶能夠經過給 swank::menu-choices-for-presentation 定義方法來定義特殊的命令。

警告:對於沒有弱哈希表的 Lisp 實現,全部跟對象描述相關聯的對象都被垃圾回收保護起來。若是你的 Lisp 進程所以變得太大,使用 C-c C-v M-o(slime-clear-presentations)斷開這些關聯,這會清空 REPL 緩衝區,而且斷開全部對象描述的關聯。

警告:對象描述可能讓新用戶迷惑。

CL-USER> (cons 1 2) (1 . 2) CL-USER> (eq '(1 . 2) '(1 . 2)) T

可能有人會指望結果是 nil,由於這看起來像是兩個新建立的 cons 在相互比較,而忽視了它們的對象身份。可是在上例中,對象描述 (1 . 2) 是被兩次複製到 REPL 裏的,因此 eq 確實是做用在相同的對象上的,也就是以前輸入到 REPL 裏的 cons 對象。

8.13 打印窗口

打印窗口是一個特殊的 Emacs 窗口,用來代替顯示區域(mini 緩衝區)來顯示 Slime 命令的信息。這是一個可選的特性。跟顯示區域相比,打印窗口的優點是能夠顯示更多的文本,能夠被滾動,並且當你按鍵時內容不會消失。全部可能的較長的信息都會被髮送到打印窗口,例如參數列表、宏展開等等。

  • M-x slime-ensure-typeout-frame

    保證打印窗口存在,若是須要就新建一個。

若是打印窗口關閉那麼會從新使用顯示區域。

若是要在啓動時自動建立一個打印窗口,須要加載 slime-typeout-frame 擴展包。(見 8.1 加載擴展包)

slime-typeout-frame-properties 變量指定了打印窗口的長度和其它可能的特性。它的值會傳給 make-frame。

8.14 TRAMP

slime-tramp 擴展包提供了一些爲 TRAMP 進行文件名轉換的函數。(見 7.1.3 設置路徑名翻譯)

8.15 文檔連接

對於某些錯誤信息,SBCL 包含了 ANSI 標準或者 SBCL 用戶手冊相關的參考。slime-references 擴展包將這些參考變爲能夠點擊的連接。這使得在 HyperSpec 裏找到這些參考相關的章節更加容易。

8.16 交叉引用和類查看器

slime-xref-browser 擴展包提供了一個基礎的類查看器。

  • M-x slime-browse-classes

    該命令須要一個類的名字,它會顯示出類的全部繼承關係。

  • M-x slime-browse-xrefs

    該命令顯示一個符號及其交叉引用,即它的調用者。以該符號爲根的引用樹會在以後顯示出來。

8.17 高亮編輯

slime-highlight-edits 是一個用來高亮顯示 Lisp 源代碼裏被修改了的部分的 minor 模式。這對於快速找到那些須要從新編譯(用 C-c C-c)的函數十分有用。

  • M-x slime-highlight-edits-mode

    打開或關閉 slime-highlight-edits-mode

8.18 空白緩衝區

由 slime-scratch 擴展包提供的 Slime 的空白緩衝區,模仿 Emacs 的 scratch 緩衝區。若是 slime-scratch-file 被設置,它被用來備份空白緩衝區,使其變得可持久。它跟其它的 Lisp 緩衝區是同樣的,除了綁定到 C-j 的命令。

  • C-j 或 M-x slime-eval-print-last-expression

    對光標前的表達式求值,並將結果插入到當前緩衝區裏。

  • M-x slime-scratch

    建立一個 slime-scratch 緩衝區。在此緩衝區裏你能夠輸入 Lisp 表達式並用 C-j 來求值,相似於 Emacs 的scratch 緩衝區。

8.19 slime-sprof

slime-sprof 擴展包用來集成 SBCL 的靜態分析器,sb-sprof。

slime-sprof-exclude-swank 變量控制是否顯示 swank 函數,默認值是 nil。

  • M-x slime-sprof-start

    開始分析。

  • M-x slime-sprof-stop

    中止分析。

  • M-x slime-sprof-browser

    報告分析結果

下面的命令在 slime-sprof-browser 模式裏定義:

  • RET 或 M-x slime-sprof-browser-toggle

    打開或摺疊函數的詳細信息(調用者、調用)

  • v 或 M-x slime-sprof-browser-view-source

    查看函數源碼

  • d 或 M-x slime-sprof-browser-disassemble-function

    拆開該函數

  • s 或 M-x slime-sprof-toggle-swank-exclusion

    標記 swank 函數使其不在報告裏

8.20 元包 slime-fancy

slime-fancy 包是一個用來加載那些最受歡迎的包的元包。

腳註

[1]

這種類型的補全由 Chris McConnell 在 completer.el 裏被構建。該包跟 ILISP 綁定在一塊兒。

[2]

對象描述是來自於 Lisp 機的特性。能夠經過定義 present 方法來適用於不一樣的設備,例如將對象繪到位圖顯示屏或者將文本寫到字符流。

9、致謝

黑客們

Slime 是由 Eric Marsden 寫的 Slim 的擴展版。在撰寫的時候,Slime 的做者和核心貢獻者是:

Helmut Eller Tobias C. Rittweiler Luke Gorrie 
Matthias Koeppe Marco Baringer Alan Ruttenberg 
Stas Boukarev Nikodemus Siivola Edi Weitz 
Juho Snellman Peter Seibel Martin Simmons 
Geo Carncross Christophe Rhodes Attila Lendvai 
Douglas Crosher Mark Evenson Daniel Barlow 
Wolfgang Jenkner Michael Weber Lawrence Mitchell 
Gábor Melis Luís Oliveira Brian Downing 
Bill Clementson Andras Simon Zach Beane 
Espen Wiborg Antonio Menezes Leitao Utz-Uwe Haus 
Thomas Schilling Thomas F. Burdick Takehiko Abe 
Richard M Kreuter Matthew Danish James Bielman 
Harald Hanche-Olsen Andreas Fuchs Willem Broekema 
Terje Norderhaug Taylor R. Campbell Stelian Ionescu 
Raymond Toy Lars Magne Ingebrigtsen John Paul Wallington 
Joerg Hoehle Bryan O'Connor Alan Shutko 
Travis Cross Tobias Rittweiler Tiago Maduro-Dias 
Stefan Kamphausen Sean O'Rourke Robert Lehr 
Robert E. Brown Nathan Bird Mark Harig 
Jouni K Seppanen Ivan Toshkov Ian Eslick 
Gary King Eric Blood Eduardo Muñoz 
David Reitter Christian Lynbech Chris Capel 
Bjørn Nordbø Ariel Badichi Anton Vodonosov 
Alexey Dejneka Alan Caulkins Yaroslav Kavenchuk 
Wolfgang Mederle Wojciech Kaczmarek William Bland 
Tom Pierce Tim Daly Jr. Sven Van Caekenberghe 
Svein Ove Aas Steve Smith StanisBaw Halik 
Russell McManus Rui Patrocínio Robert Macomber 
R. Matthew Emerson Reini Urban Pawel Ostrowski 
Paul Collins NIIMI Satoshi Neil Van Dyke 
Mikel Bancroft Matt Pillsbury Matthew D. Swank 
Mészáros Levente Masayuki Onjo Mark Wooding 
Marco Monteiro Lynn Quam Levente Mészáros 
Lasse Rasinen Knut Olav Bøhmer Kai Kaminski 
Julian Stecklina Juergen Gmeiner Jon Allen Boone 
Johan BockgÃ¥rd Jan Rychter James McIlree 
Ivan Shvedunov Ivan Boldyrev Ignas Mikalajunas 
Hannu Koivisto Gerd Flaig Gail Zacharias 
Frederic Brunel Dustin Long Didier Verna 
Dan Weinreb Dan Pierson Daniel Koning 
B.Scott Michel Brian Mastenbrook Brandon Bergren 
Bob Halley Barry Fishman Aleksandar Bakic 
Alain Picard 

更不要說 hyperspec.el、CLOCC 和 CMU AI Repository 附帶而來的代碼。

許多在 slime-devel 郵件列表裏的人雖然沒有寫代碼但都爲 Slime 作出了貢獻。可是生活是殘酷的:你必須提交代碼才能將名字列在這裏。:)

多謝

咱們十分感謝 common-lisp.net 的人幫咱們提供空間以及其它幫助,以及從「Sourceforge 地獄」裏拯救咱們。

咱們支持的 Lisp 實現者都頗有幫助。咱們要感謝 CMUCL 維護者的頗有幫助的回答,Franz 的 Craig Norvell 和 Kevin Layer 爲 Slime 的開發提供了 Allegro CL 協議,Peter Graves 使 Slime 能跑在 ABCL 上。

對於加入到 Slime 開發裏的 Lisp 實現者們,咱們表示很高興跟他們一塊兒工做:Dan Barlow and Christophe Rhodes of SBCL, Gary Byers of OpenMCL, and Martin Simmons of LispWorks. 同時感謝 Alain Picard 以及 Memetrics 贊助 Martin LispWorks 後臺的初期工做!

相關文章
相關標籤/搜索