The Common Lisp Cookbook – Emacs を IDE として使う

Table of Contents

The Common Lisp Cookbook – Emacs を IDE として使う

📢 🎓 ⭐ Learn Common Lisp efficiently in videos, by the Cookbook's main contributor. Learn more.

🖊️ Discover a new Common Lisp and Coalton editor for beginners: mine and a new VSCode extension for Common Lisp: OLIVE.

このページでは、Emacs を Lisp IDE として使うための導入を説明します。

大まかに 3 つの節に分けています。Slime(または Sly)のインストール方法、使い方、そして Lisp コードを扱うための Emacs 組み込みコマンドに関する補足情報です。

Emacs の紹介画像

ところで、なぜ Emacs を使うのでしょうか。

SLIME: Superior Lisp Interaction Mode for Emacs

SLIME は CL プログラミングの定番のメジャーモードです。強力で統合された、非常に対話的な開発環境にするための機能を多数備えています。

SLY: Sylvester the Cat’s Common Lisp IDE

SLY は SLIME の fork で、次の変更と機能を含みます。

一方で、いくつか不足や違いも見つかりました。

Sly は Doom Emacs にデフォルトで同梱されています。

SLIME または SLY をインストールする

手動

Ubuntu では、SLIME は Emacs と SBCL と一緒に簡単にインストールできます。

sudo apt install emacs slime sbcl

それ以外では、次のコードを ~/.emacs.d/init.el ファイルに追加して SLIME をインストールします。

(require 'package)

(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)

(defvar my-packages '(slime))

(dolist (package my-packages)
  (unless (package-installed-p package)
    (package-install package)))

(require 'slime)

Emacs と SBCL もインストール済みだと仮定します。

SLIME はかなりモジュール化されており、デフォルトでは最低限(SLIME REPL すら含まない)しか有効にならないため、次のようにより多くの機能を有効にしたくなるかもしれません。

(require 'slime)
(slime-setup '(slime-fancy slime-quicklisp slime-asdf slime-mrepl))

最後に、Slime に SBCL を使うよう伝えます。

(setq inferior-lisp-program "sbcl")

これでキーボードの Alt-X を押して slime と入力し、Common Lisp を試せます。

(Alt-X は Emacs の世界ではよく M-x と書かれます。)

詳しくはドキュメントを参照してください(Info ページとしても利用できます)。

これで、前述のとおり M-x slimeM-x slime-connect で SLIME を実行できます。

関連項目:

Doom Emacs

Doom Emacs は人気の Emacs 設定です。Sly の統合を簡単に有効にできます。

SLIME fancy と contrib パッケージ

SLIME の機能はパッケージといわゆる contrib モジュール に分かれており、追加機能を使うにはロードする必要があります。前述の slime-fancy には次が含まれます。

SLIME には Helm-SLIME のような便利な拡張機能もあります。主な機能は次のとおりです。

SLIME(または SLY)で作業する

最初にやりたくなることの一つは、Lisp コードをコンパイルしてロードすることです。関数上で C-c C-c、またはファイル全体をコンパイルするには C-c C-k を使います。しかしそれだけではありません。続きを読んでください。

ここでは SLIME の関数名を示します。多くの場合 SLY でも似ています。

ちょっとしたコツ: Emacs のメニューを使う

このページの情報は多くて圧倒されるかもしれませんが、ここで扱うコマンドやキーバインドは Emacs の Slime メニューの下で簡単に見つけられます。そのためメニューは無効にしないことを勧めます。とても便利です。

見えない場合は M-x menu-bar-mode RET を呼び出します。

ターミナル版 Emacs(emacs -nw)では、M-x menu-bar-open でメニューを開けます。これはデフォルトで f10 に割り当てられています。また、マウスが有効ならマウスも使えます(M-: または *scratch* バッファで (xterm-mouse-mode +1) を評価します)。

コード補完

SLIME でシンボルを補完するには、組み込みの C-c TAB を使います。company-mode を使うとツールチップも得られます。

REPL では単に TAB です。

ほかの開いているバッファにある任意の文字列を補完するには、M-/ に割り当てられた Emacs の hippie-expand を使います。

SLIME で Lisp を評価・コンパイルする

バッファ全体をコンパイルするには C-c C-kslime-compile-and-load-file)を押します。

リージョンM-x slime-compile-region でコンパイルします。

defun はカーソルをその中に置き、C-c C-cslime-compile-defun)を押してコンパイルします。

コードをコンパイルしたら、たとえば REPL で試せます。

コンパイルではなく評価するには:

メニューにある他のコマンドも参照してください。

では、コードを評価することとコンパイルすることにはどんな違いがあるのでしょうか。

評価とコンパイルの違い

コンパイルと評価のどちらを選ぶかには、いくつか実用上の違いがあります。

ただし SBCL のような処理系では、REPL にコードを書く場合や評価用ショートカットを使う場合でも、明示的に別指定しない限り 式は常にコンパイルされます。

そうは言っても一般には、トップレベルのフォームはコンパイルする方がよいです。理由は 2 つあります。

eval は、トップレベルではない個々のフォームの結果を観察するのに今でも便利です。たとえば次の関数があるとします。

(defun foo ()
  (let ((f (open "/home/mariano/test.lisp")))
    ...))

OPEN 式の末尾へ移動して評価(C-x C-e)し、結果を観察します。

=> #<SB-SYS:FD-STREAM for "file /mnt/e6b00b8f-9dad-4bf4-bd40-34b1e6d31f0a/home/marian/test.lisp" {1003AAAB53}>

また次の例では、カーソルを最後の括弧に置いて C-x C-e を押すと let を評価できます。

(let ((n 20))
  (loop for i from 0 below n
     do (print i)))

REPL に数値が出力されるはずです。

下の「REPL にコードを送る」と C-c C-j のショートカットも参照してください。

デバッグ

デバッグ用のコマンドは独立した デバッグ の章で扱います。

定義へ移動する

任意のシンボルにカーソルを置き、M-.slime-edit-definition)を押すとその定義へ移動します。戻るには M-, を押します。

任意のシンボルへ移動し、現在のソース内のシンボルを一覧する

C-u M-.(前置引数付きの slime-edit-definitionM-- M-. としても利用可能)を使うと、シンボルを自動補完してそこへ移動できます。

このコマンドはカーソルがシンボル上にあっても常にシンボルを尋ねます。ロード済みの任意の定義で動作します。短いデモ動画があります。

これは、任意の Lisp シンボルに対して常に動く imenu の補完のようなものだと考えられます。最大の威力を得るには Slime のあいまい補完 も追加してください。

引数リスト

関数上にカーソルを置くと、SLIME はそのシグネチャをミニバッファに表示します。

よりよく見たい場合は、関数名の後で C-c C-s を試してください。

たとえば、with-open-file の使い方を忘れたとします。これを書きます。

(with-open-file

ここで C-c C-sslime-complete-form)を押すと、次が得られます。

(with-open-file (stream filespec :direction direction
                                 :element-type element-type
                                 :if-exists if-exists
                                 :if-does-not-exist if-does-not-exist
                                 :external-format external-format
                                 :class class
                         )
           body...)

これはソースファイル(または REPL)に書き込まれます。

ミニバッファには引数のデフォルト値が表示されます。

ドキュメントの参照

知っておくべき主なショートカットは次です。

役立つかもしれないその他の割り当て:

ヘルプバッファは Slime の拡張 slime-doc-contribs で強化できます。見やすいバッファにより多くの情報を表示し、ドキュメント表示コマンドに選択肢を追加します。

インスペクタ

REPL から (inspect 'symbol) を呼ぶか、ソースファイルから C-c I で呼び出せます。

ドキュメント で使い方を確認してください。たとえば、l で前のオブジェクトに戻り、* でポイント位置のオブジェクトをコピーできます。

マクロ展開

マクロの呼び出しを展開するには C-c M-m を使います。

警告の間を移動する

C-c C-k でファイルをコンパイルしてロードする場合(または C-c C-c で単一関数をコンパイルする場合)、コンパイル時の警告があっても対話デバッガは出ません。ソースファイルの横に開く専用の “*slime-compilation*” Emacs バッファ内に警告の一覧が表示されます。

警告の影響を受けたソースの各行は赤で下線が引かれます。

slime-compilation バッファの各警告はクリックでき、キーバインド M-nM-pslime-[next, previous]-note)により次または前の警告(”notes” または “annotations” と呼ばれます)へ素早く移動できます。

通常の Emacs のショートカットである compilation-mode の C-x `(Control-x とバッククォート)も使えます。

ソースの赤い注釈を見たくない場合は、C-c M-cslime-remove-notes を使います。ただし自動で修正されるわけではありません。

コードにスタイル警告しかない場合、それらは slime-compilation バッファに捕捉されますが、バッファは自動ではポップアップしません。

これらのキーバインドはいつもどおり Emacs の Slime メニューから見つけられます。

参考: https://slime.common-lisp.dev/doc/html/Compilation.html#Compilation

相互参照: 誰が呼び出し、参照し、シンボルを設定しているかを調べる

Slime には便利な相互参照機能があります。たとえば、誰が関数を呼ぶか、誰がマクロを展開するか、グローバル変数がどこで使われているかを尋ねられます。

結果は新しいバッファに表示され、特定の対象を参照する場所が一覧されます。そこから Enter を押すと対応するソース行へ移動できます。さらに興味深いことに、その行で C-c C-c を押すとポイントの場所を再コンパイルできます。同様に C-c C-k はすべての参照を再コンパイルします。これはマクロ、インライン関数、定数を変更するときに便利です。

割り当ては次のとおりです(Slime のメニューにも表示されます)。

slime-asdf contrib が有効な場合、C-c C-w dslime-who-depends-on)は依存する ASDF システムを一覧します。

一般的なキーバインドである M-? または M-_slime-edit-uses)は上記すべてを組み合わせ、あらゆる種類の参照を一覧表示します。

システムとの対話

Slime では、.asd ファイル内で通常の C-c C-k を使ってコンパイルしてロードし、その後 ql:quickload(または asdf:load-system)で実際にシステムをロードできます。SLIME は Lisp のシステムと対話するための、より対話的なコマンドを提供します。

Sly のユーザーにはより多機能な sly-load-system コマンドがあり、現在のディレクトリと親ディレクトリで .asd ファイルを検索します。

REPL との対話

SLIME REPL では、, を押すとコマンドのプロンプトが出ます。利用可能なシステムとパッケージに対して補完があります。例:

ほかにも多数あります。通常、前節で示した対話的なコマンドには REPL のショートカットがあります。

slime-quicklisp contrib を使うと、,ql でインストール可能な全システムからシステムを自動補完してインストールできます。

さらに Quicklisp-systems という Slime の拡張を使うと、Emacs から Quicklisp のシステムを検索、閲覧、ロードできます。

REPL にコードを送る

REPL にコードを書けますが、ソースファイルからコードと直接やり取りすることもできます。

C-c C-j は見ました。ポイントの式を REPL に送り、評価します。

C-c C-yslime-call-defun): コードを REPL に送ります(Sly にはありません)。

ポイントが defun 内にあり、C-c C-y が押された場合(下では [] をカーソル位置の目印として使います)

(defun foo ()
 nil[])

すると (foo []) が REPL に挿入され、追加引数を書いて実行できます。

foo が REPL のパッケージとは異なるパッケージにあった場合、(package:foo ) または (package::foo ) が挿入されます。

この機能は、書いたばかりの関数をテストするのにとても便利です。

これは defun だけでなく、defgenericdefmethoddefmacrodefine-compiler-macro に対しても defun と同じように動作します。

defvardefparameterdefconstant の場合は [] *foo* が挿入されます(シンボルの前にカーソルが置かれるため、簡単に関数呼び出しで包めます)。

defclass の場合: (make-instance ‘class-name )

デバッガ内のフレームへの呼び出しを挿入する

SLDB のフレーム上で C-y を押すと、そのフレームへの呼び出しが REPL に挿入されます。例:

(/ 0) =>
…
1: (CCL::INTEGER-/-INTEGER 1 0)
…

C-y(CCL::INTEGER-/-INTEGER 1 0) を挿入します。

Slime tips に感謝)

パッケージを同期する

C-c ~slime-sync-package-and-default-directory): lisp ファイルのバッファで実行すると、REPL の現在のパッケージをそのファイルのパッケージに変更し、REPL の現在のディレクトリもファイルの親ディレクトリに設定します。

シンボルを export する

Slime はパッケージに export 宣言を追加するショートカットを提供します。実質的に一つまたは複数のシンボルを export したり、逆に un-export したりできます。

slime-package-fu contrib の C-c xslime-export-symbol-at-point): ポイントのシンボルを取り、対応する defpackage フォームの :export 節を変更します。またシンボルも export します。負の引数(C-u C-c x)付きで呼ぶと、シンボルを :export から削除し unexport します。

M-x slime-export-class も同じことをしますが、アクセサ、コンストラクタなど、構造体またはクラスによって定義されるシンボルが対象です。今のところ構造体では SBCL と Clozure CL でのみ動作します。クラスは MOP によりどこでも動くはずです。

カスタマイズ

defpackage でシンボルを表示するスタイルにはいくつかあり、デフォルトは uninterned シンボル(#:foo)を使います。これは変更できます。

キーワードを使うには、Emacs の init ファイルに次を追加します。

(setq slime-export-symbol-representation-function
      (lambda (n) (format ":%s" n)))

または文字列:

(setq slime-export-symbol-representation-function
 (lambda (n) (format "\"%s\"" (upcase n))))

(任意)Hyper Spec(CLHS)を offline で参照する

Common Lisp Hyper Spec は ANSI Common Lisp 標準の公式オンライン版です。starting points から閲覧を始められます。短縮された table of contents of highlightsシンボル索引、用語集、総合索引があります。

2023 年 1 月以降、Common Lisp Community Spec があります: https://cl-community-spec.github.io/pages/index.html。これは仕様書の新しい Web 表示です。より現代的な見た目です。

公式の Web サイトには検索バーがないため、CLHS 上のシンボルを他のツールですばやく参照したい場合は、次を使えます。

MacOS では Dash、GNU/Linux では Zeal、Windows では Velocity を使って CLHS をオフラインで閲覧できます。

しかし Emacs からもオフラインで閲覧できます。CL パッケージをインストールし、Emacs 側を一つのコマンドで設定します。

(ql:quickload "clhs")
(clhs:install-clhs-use-local)

次を Emacs configuration に追加します。

(load "~/quicklisp/clhs-use-local.el" 'noerror)

これで C-c C-d h を使って、ポイントのシンボルを HyperSpec で参照できます。ブラウザが開きますが、URL が “file://home/” で始まることを見てください。ローカルファイルを開いています。

他のコマンドも利用できます。

Emacs で作業する

この節では、Lisp コード一般を扱うため、またよくある操作を行うために最も役立つ Emacs のコマンドを学びます。

まず Emacs の組み込みドキュメントで道を見つける方法から始めます。学ぶべき技能が一つあるとすれば、これです。

Emacs の GUI とターミナルのインターフェイスの両方にメニューがあることを忘れないでください。利用可能なコマンドを発見する助けになります。見えない場合は、emacs の設定が隠していないことを確認してください。M-x menu-bar-mode でメニューを表示できます。

組み込みのドキュメント

Emacs には組み込みチュートリアルとドキュメントが付属します。さらに、自己ドキュメント化と自己発見性を備えたエディタであり、introspection によって現在のキーバインド、関数のドキュメント、利用可能な変数、ソースコード、チュートリアルなどを知ることができます。「x をするためのショートカットは何があるか」や「このキーバインドは実際に何をするのか」といった疑問を持ったとき、答えはほぼ確実に Emacs の中でキー操作一つ先にあります。Emacs で Emacs を滞りなく発見できるよう、いくつかのキーバインドを覚えるべきです。

この話題のヘルプはここにあります。

ヘルプのキーバインドは C-h または F1 で始まります。重要なものは次です。

Emacs パッケージの中には、さらに多くのヘルプを提供するものもあります。

さらにヘルプと発見性を高めるパッケージ

キーの並びを入力し始めたものの、完全には思い出せないことがあります。また、関連する他のキーバインドが気になることもあります。そこで which-key-mode です。このパッケージは、入力したキーで始まる可能なキーバインドをすべて表示します。

たとえば、C-x の下に便利なキーバインドがあることは知っているけれど、どれかを覚えていないとします。C-x と入力し、半秒待つだけで、which-key が利用可能なものをすべて表示します。

C-h でも試してみてください。

組み込みの Emacs ヘルプの代替で、より多くの文脈情報を提供する Helpful も参照してください。

The Emacs helpful package shows detailed information about a symbol.

組み込みのチュートリアル

Emacs には独自のチュートリアルが付属しています。重要なキーバインドと概念を学ぶために一度見ておくとよいでしょう。

M-x help-with-tutorial(ここで M-xalt-x)で呼び出します。

括弧を編集する

Emacs にはもちろん、S 式を扱う組み込みコマンドがあります。

S 式による前後・上下の移動と選択

C-M-fC-M-bforward-sexpbackward-sexp)を使うと、ポイントの S 式の終端(始端)や、同じ階層の次の式へ移動できます。C-M-nC-M-p(next、previous)も似ています。

C-M-ubackward-up-list)と C-M-ddown-list)で S 式の木構造を上下に移動します。

C-M-a(lisp-mode では beginning-of-defun または slime-beginning-of-defun)と C-M-eend-of-defun または slime-end-of-defun)でトップレベルの S 式の始端(または終端)へ移動します。たとえば現在の関数定義の先頭へ移動します。

S 式全体をハイライトするには C-M-@ または C-M-space(どちらも mark-sexp)を使います。その後 C-M-u で選択範囲を「上方向」に広げ、C-M-d で括弧の一段下へ進めます。mark-sexp を繰り返し押すこともできます。

M-)move-past-close-and-reindent)を使うと、現在のレキシカルブロックの終端へ移動し、新しい行を作ってインデントします。

C-M-ttranspose-sexps)を使うと、ポイントの S 式を前の S 式の前へ移動できます。

例:

;; C-M-t を押し、異なる additions がどう動くかを観察します。

(defun c ()
  "another function"
  (let ((x 42))
    (+ x
       (+ 2 2)
     [](+ 3 3)  ; <-- cursor
       (+ 4 4))))

;; C-M-t =>

(defun c ()
  "another function"
  (let ((x 42))
    (+ x
       (+ 3 3)
       (+ 2 2)[]  ; <-- cursor moved too (now right before (+ 4 4)
       (+ 4 4))))

行またはリージョンをコメントにする

M-; でコメントを挿入するかリージョンをコメントにし、M-q でテキストを整えます。

括弧と S 式を削除する

ポイントの前方にある括弧の対を削除するには M-x delete-pair を使います。実際には対になる任意の記号(ダブルクォート、角括弧…)で動作します。

例:

[](1 2 3)
;; M-x delete-pair =>
1 2 3

C-M-kkill-sexp)と C-M-backspacebackward-kill-sexp)を使います(ただし注意: このキーバインドは GNU/Linux でシステムを再起動することがあります)。

たとえばポイントが (progn の前にある場合([] をカーソルの位置として使います):

(defun d ()
  (if t
      (+ 3 3)
     [](progn
        (+ 1 1)
        (if t
            (+ 2 2)
            (+ 3 3)))
      (+ 4 4)))

C-M-k を押すと、次になります。

(defun d ()
  (if t
      (+ 3 3)
      []
      (+ 4 4)))

raise: S 式を上へ移動する

現在の式を “raise” するには M-x raise-sexp(デフォルトでは未割り当て)を使います。これは一段上へ移動し、以前の式を消します。たとえばポイントが下の位置にある場合:

(defun d ()
  (when t
    [](+ 3 3)

raise-sexp を呼ぶと、次になります。

(defun d ()
  [](+ 3 3))

グローバルキーに割り当てられます。

(keymap-global-set "M-+" #'raise-sexp) ;; M-+ originally unbound

S 式をインデントする

Lisp フォームのインデントは自動です。

TAB を押すと、誤ってインデントされたコードをインデントします。たとえば (+ 3 3) フォームの先頭にポイントを置いて TAB を押します。

(progn
(+ 3 3))

正しく次のようになります。

(progn
  (+ 3 3))

ポイントのフォームを再インデントするには C-M-qindent-sexp)を使います。

;; cursor を "(defun ..." の open parens に置き、
;; "C-M-q" を押して code を indent します:
[] (defun e ()
   "A badly indented function."
 (let ((x 20))
 (print x)))

次のようになります。

(defun e ()
  "A correctly indented function."
  (let ((x 20))
    (print x)))

現在の関数定義をインデントするには C-c M-qslime-reindent-defun)を使います。

;; cursor を function 内のどこかに置き、
;; "C-M-q" を押して code を indent します:
(defun e ()
"A badly indented function."
(let ((x 20))
(loop for i from 0 to x
do (loop for j from 0 below 10
do (print j))
(if (< i 10)
(let ((z nil) )
(setq z (format t "x=~d" i))
(print z))))))

;; This is the result:

(defun e ()
  "A badly indented function (now correctly indented)."
  (let ((x 20))
    (loop for i from 0 to x
       do (loop for j from 0 below 10
             do (print j))
         (if (< i 10)
             (let ((z nil) )
               (setq z (format t "x=~d" i))
               (print z))))))

リージョンを選択して M-x indent-region を呼ぶこともできます。

括弧を開閉する

Lisp の括弧を管理するのに、多くのキーバインドは(あるいはまったく)必要ないかもしれません。M-x show-paren-mode だけでも非常に便利です(下記参照)。とはいえ、役立つキーバインドもあります。

Slime REPL では、C-return または M-returnslime-repl-closing-return)で残りの括弧を閉じて入力文字列を評価できることを知っていましたか。

ソースファイルでは、必要な数の閉じ括弧を挿入するために C-c C-]slime-close-all-parens-in-sexp)を使えます。

例:

(defun example ()
  (when t
    (when (+ 1 2)
      nil[]  ;; <--- point

;; C-c C-]
;; =>

(defun example ()
  (when t
    (when (+ 1 2)
      nil)))
         ^^^ 3 closing ) were inserted.

ファイルでは、M-( で括弧の対(())を挿入できます。同じキーバインドに前置引数 C-u M-( を付けると、カーソルの前の式を括弧の対で囲みます。

たとえば最初の括弧の前にカーソルがある状態から始めます。

[](- 2 2)

C-u M-( を押して parens で囲みます。

([](- 2 2))
;; now write anything.
(zerop (- 2 2))

数値の前置引数(C-u 2 M-()を使うと、その数の S 式を囲みます。

さらに、不正な形の S 式を見つけるには M-x check-parens を使います。

括弧の利用を簡単にする追加パッケージもあります。

(任意)構造化編集のパッケージ

組み込みの Emacs コマンドとモード(show-paren-mode は必須です。上記参照)に加えて、括弧やインデントのバランスを保つ助けになるパッケージがさらにあります。下の一覧は、history of Lisp editing による拡張の年代順にある程度並べています。

個人的には、まず組み込み関数をよく知り、その後有名な Paredit や evil ユーザー向けの Lispy から着想を得ることを勧めます。さらに詳しくは Wikemacs を参照してください。

コードを隠す/表示する

C-x n n(narrow-to-region)と C-x n w を使って元に戻します。

外部パッケージによる code folding も参照してください。

検索と置換

前方/後方のインクリメンタル検索、正規表現検索、検索・置換

C-s は前方へのインクリメンタル検索を行います。たとえば検索文字列の各キーを入力するたびにソースファイルが最初の一致に向けて検索されます。一意になる文字だけを入力すればよいため、特定のテキストをかなり素早く見つけられます。同じ検索文字を使った繰り返し検索は、C-s を繰り返し押すことで行えます。

C-r は後方へのインクリメンタル検索を行います。

C-s RETC-r RET はどちらも通常の文字列検索を行います(それぞれ前方と後方)。

C-M-sC-M-r はどちらも正規表現検索を行います(それぞれ前方と後方)。

M-% は検索・置換を行い、C-M-% は正規表現の検索・置換を行います。

出現箇所を探す(occur、grep)

M-x greprgrepoccur などを使います。

対話的な版として helm-swoop、helm-occur、ag.el も参照してください。

質問と回答

Emacs Lisp vs Common Lisp

Common Lisp 用に Emacs を Slime または Sly と一緒に使うために、Emacs Lisp を書く必要はありません。

ただし Emacs Lisp を学ぶことは役に立ちますし、CL と似ています(しかし異なります)。

Emacs Lisp 学習に役立つ資料:

LSP(Language Server Protocol)はどうか?

Common Lisp 向けの LSP サーバーとクライアントの移植版は存在しますが、高品質な IDE 連携を得るためにそれらが必要なわけではありません。実際、Slime/Swank は LSP のようなクライアント/サーバー型のアーキテクチャに従っていますが、Slime は LSP より何十年も前からあり、今でも LSP より lisper 向けにずっと多くの機能を提供しています。

utf-8 エンコーディング

init file に次を設定したくなるかもしれません。

(set-language-environment "UTF-8")
(setenv "LC_CTYPE" "en_US.UTF-8")

Sly では次のようにします。

(setf sly-lisp-implementations
      '((sbcl ("/usr/local/bin/sbcl") :coding-system utf-8-unix)
        ))

これにより、SLIME で評価するファイルに非 ASCII 文字があるときの ascii stream decoding error を避けられます。

デフォルトの切り取り・コピー・貼り付け用キーバインド

私はテキストのコピーと貼り付けに C-c、C-v などを使うことに慣れすぎていて、Emacs のデフォルトショートカットがまったくしっくりきません。

幸い、解決策があります。cua-mode をインストールすれば、これらのショートカットを使い続けられます。

;; C-z=Undo, C-c=Copy, C-x=Cut, C-v=Paste (needs cua.el)
(require 'cua) (CUA-mode t)

付録

Slime REPL のショートカットすべて

REPL で動作するすべての Slime のショートカットのリファレンスです。

見るには REPL に移動し、C-h m と入力して Slime REPL map の節へ進みます。

REPL mode defined in ‘slime-repl.el’:
Major mode for interacting with a superior Lisp.
key             binding
---             -------

C-c             Prefix Command
C-j             slime-repl-newline-and-indent
RET             slime-repl-return
C-x             Prefix Command
ESC             Prefix Command
SPC             slime-space
  (that binding is currently shadowed by another mode)
,               slime-handle-repl-shortcut
DEL             backward-delete-char-untabify
<C-return>      slime-repl-closing-return
<C-down>        slime-repl-forward-input
<C-up>          slime-repl-backward-input
<return>        slime-repl-return

C-x C-e         slime-eval-last-expression

C-c C-c         slime-interrupt
C-c C-n         slime-repl-next-prompt
C-c C-o         slime-repl-clear-output
C-c C-p         slime-repl-previous-prompt
C-c C-s         slime-complete-form
C-c C-u         slime-repl-kill-input
C-c ESC         Prefix Command
C-c I           slime-repl-inspect

M-RET           slime-repl-closing-return
M-n             slime-repl-next-input
M-p             slime-repl-previous-input
M-r             slime-repl-previous-matching-input
M-s             slime-repl-next-matching-input

C-c C-z         run-lisp
  (that binding is currently shadowed by another mode)

C-M-x           lisp-eval-defun

C-M-q           indent-sexp

C-c M-e         macrostep-expand
C-c M-i         slime-fuzzy-complete-symbol
C-c M-o         slime-repl-clear-buffer

その他すべての Slime のショートカット

ここで示した以上のものがあります。Slime には、ポイントのシンボルの関数定義を逆アセンブルしたり、インスペクタの操作方法を学んだり、関数のプロファイリングを切り替えたり、インデントや補完の方法を学んだり、複数の Lisp 接続を使ったり、presentations を操作したりするショートカットがあります。

Slime モードによって定義されるデフォルトのキーバインドは次のとおりです。

見るには .lisp ファイルに移動し、C-h m と入力して Slime の節へ進みます。

Commands to compile the current buffer’s source file and visually
highlight any resulting compiler notes and warnings:
C-c C-k	- Compile and load the current buffer’s file.
C-c M-k	- Compile (but not load) the current buffer’s file.
C-c C-c	- Compile the top-level form at point.

Commands for visiting compiler notes:
M-n	- Goto the next form with a compiler note.
M-p	- Goto the previous form with a compiler note.
C-c M-c	- Remove compiler-note annotations in buffer.

Finding definitions:
M-.
- Edit the definition of the function called at point.
M-,
- Pop the definition stack to go back from a definition.

Documentation commands:
C-c C-d C-d	- Describe symbol.
C-c C-d C-a	- Apropos search.
C-c M-d	- Disassemble a function.

Evaluation commands:
C-M-x	- Evaluate top-level from containing point.
C-x C-e	- Evaluate sexp before point.
C-c C-p	- Evaluate sexp before point, pretty-print result.

Full set of commands:
key             binding
---             -------

C-c             Prefix Command
C-x             Prefix Command
ESC             Prefix Command
SPC             slime-space

C-c C-c         slime-compile-defun
C-c C-j         slime-eval-last-expression-in-repl
C-c C-k         slime-compile-and-load-file
C-c C-s         slime-complete-form
C-c C-y         slime-call-defun
C-c ESC         Prefix Command
C-c C-]         slime-close-all-parens-in-sexp
C-c x           slime-export-symbol-at-point
C-c ~           slime-sync-package-and-default-directory

C-M-a           slime-beginning-of-defun
C-M-e           slime-end-of-defun
M-n             slime-next-note
M-p             slime-previous-note

C-M-,           slime-previous-location
C-M-.           slime-next-location

C-c TAB         completion-at-point
C-c RET         slime-expand-1
C-c C-p         slime-pprint-eval-last-expression
C-c C-u         slime-undefine-function
C-c ESC         Prefix Command

C-c C-b         slime-interrupt
C-c C-d         slime-doc-map
C-c C-e         slime-interactive-eval
C-c C-l         slime-load-file
C-c C-r         slime-eval-region
C-c C-t         slime-toggle-fancy-trace
C-c C-v         Prefix Command
C-c C-w         slime-who-map
C-c C-x         Prefix Command
C-c C-z         slime-switch-to-output-buffer
C-c ESC         Prefix Command
C-c :           slime-interactive-eval
C-c <           slime-list-callers
C-c >           slime-list-callees
C-c E           slime-edit-value
C-c I           slime-inspect

C-x C-e         slime-eval-last-expression
C-x 4           Prefix Command
C-x 5           Prefix Command

C-M-x           slime-eval-defun
M-,             slime-pop-find-definition-stack
M-.             slime-edit-definition
M-?             slime-edit-uses
M-_             slime-edit-uses

C-c M-c         slime-remove-notes
C-c M-e         macrostep-expand
C-c M-i         slime-fuzzy-complete-symbol
C-c M-k         slime-compile-file
C-c M-q         slime-reindent-defun

C-c M-m         slime-macroexpand-all

C-c C-v C-d     slime-describe-presentation-at-point
C-c C-v TAB     slime-inspect-presentation-at-point
C-c C-v C-n     slime-next-presentation
C-c C-v C-p     slime-previous-presentation
C-c C-v C-r     slime-copy-presentation-at-point-to-repl
C-c C-v C-w     slime-copy-presentation-at-point-to-kill-ring
C-c C-v ESC     Prefix Command
C-c C-v SPC     slime-mark-presentation
C-c C-v d       slime-describe-presentation-at-point
C-c C-v i       slime-inspect-presentation-at-point
C-c C-v n       slime-next-presentation
C-c C-v p       slime-previous-presentation
C-c C-v r       slime-copy-presentation-at-point-to-repl
C-c C-v w       slime-copy-presentation-at-point-to-kill-ring
C-c C-v C-SPC   slime-mark-presentation

C-c C-w C-a     slime-who-specializes
C-c C-w C-b     slime-who-binds
C-c C-w C-c     slime-who-calls
C-c C-w RET     slime-who-macroexpands
C-c C-w C-r     slime-who-references
C-c C-w C-s     slime-who-sets
C-c C-w C-w     slime-calls-who
C-c C-w a       slime-who-specializes
C-c C-w b       slime-who-binds
C-c C-w c       slime-who-calls
C-c C-w d       slime-who-depends-on
C-c C-w m       slime-who-macroexpands
C-c C-w r       slime-who-references
C-c C-w s       slime-who-sets
C-c C-w w       slime-calls-who

C-c C-d C-a     slime-apropos
C-c C-d C-d     slime-describe-symbol
C-c C-d C-f     slime-describe-function
C-c C-d C-g     common-lisp-hyperspec-glossary-term
C-c C-d C-p     slime-apropos-package
C-c C-d C-z     slime-apropos-all
C-c C-d #       common-lisp-hyperspec-lookup-reader-macro
C-c C-d a       slime-apropos
C-c C-d d       slime-describe-symbol
C-c C-d f       slime-describe-function
C-c C-d g       common-lisp-hyperspec-glossary-term
C-c C-d h       slime-documentation-lookup
C-c C-d p       slime-apropos-package
C-c C-d z       slime-apropos-all
C-c C-d ~       common-lisp-hyperspec-format
C-c C-d C-#     common-lisp-hyperspec-lookup-reader-macro
C-c C-d C-~     common-lisp-hyperspec-format

C-c C-x c       slime-list-connections
C-c C-x n       slime-next-connection
C-c C-x p       slime-prev-connection
C-c C-x t       slime-list-threads

C-c M-d         slime-disassemble-symbol
C-c M-p         slime-repl-set-package

C-x 5 .         slime-edit-definition-other-frame

C-x 4 .         slime-edit-definition-other-window

C-c C-v M-o     slime-clear-presentations

関連項目

Page source: ja/emacs-ide.md

T
O
C