EmacsでのCommon Lisp開発
Posted on August 10, 2020
by nobiruwa
tl;dr
$ sudo apt-get -y install git build-essential automake libcurl4-openssl-dev
$ git clone -b release https://github.com/roswell/roswell.git $HOME/repo/roswell.git
$ cd $HOME/repo/roswell.git
$ sh bootstrap
$ ./configure --prefix=$HOME/opt/roswell
$ make
$ make install
// $HOME/opt/roswell/binをPATHに通した後:
$ ros setup
動機
QuickLispを使っていたのですが、cronで動作するスクリプトを作成するためにQuickLispのディレクトリをスクリプト内に埋め込んだり、イマイチ使いこなせている気がしなかったので、環境を管理するユーティリティがないかを探してRoswellに辿り着きました。
RoswellはCommon Lispの実装のインストーラー兼マネージャー兼ランチャー兼etc.です。
丁寧なWikiがあり、使い方を学ぶことができます。
インストール
Wikiで十分に説明されています。が、私はユーザーディレクトリのopt
ディレクトリにインストールしてPATHを通すスタイルが好きなので、実行するコマンドを少し変更しました。ソースコードリポジトリのローカルディレクトリ名も<プロジェクト名>.<コマンド名>
(ex: roswell.git
、rxvt-unicode.svn
など)と独特の管理をしています。
$ sudo apt-get -y install git build-essential automake libcurl4-openssl-dev
$ git clone -b release https://github.com/roswell/roswell.git $HOME/repo/roswell.git
$ cd $HOME/repo/roswell.git
$ sh bootstrap
$ ./configure --prefix=$HOME/opt/roswell
$ make
$ make install
// $HOME/opt/roswell/binをPATHに通した後:
$ ros setup
Emacsのセットアップ
Wikiのfor Emacsの通りです。
$ ros install slime
私はddskkを使って日本語入力をしており、SKKの変換ができるようキーバインドを変更しています。
let ((slime-helper (expand-file-name "~/.roswell/helper.el")))
(when (file-exists-p slime-helper)
(load slime-helper)
(
;; SLIMEとSKKとの衝突を回避する設定
;; 特定の場面で、SLIMEとSKKとの間でスペースキーのキーバインドが競合して、SKKでの変換ができなくなります。
;; https://lisphub.jp/common-lisp/cookbook/index.cgi?SLIME#H-33uy3rfpe0845
defun my-slime-space (n)
("p")
(interactive if (and (boundp 'skk-henkan-mode) skk-henkan-mode)
(
(skk-insert n)
(slime-autodoc-space n)))" " 'my-slime-space)
(define-key slime-autodoc-mode-map setq inferior-lisp-program "ros -Q run"))) (
サンプルスクリプト
WikiのScripting with Roswellの通りです。
$ cd $HOME
$ ln -s .roswell/local-projects lispprojects
$ cd lispprojects
$ mkdir scripting-with-roswell
$ cd scripting-with-roswell
$ ros init fact
// fact.rosが生成されるので、次のように編集する:
$ cat fact.ros
#!/bin/sh
#|-*- mode:lisp -*-|#
#|
exec ros -Q -- $0 "$@"
|#
(defun fact (n)
(if (zerop n)
1
(* n (fact (1- n)))))
(defun main (n &rest argv)
(declare (ignore argv))
(format t "~&Factorial ~D = ~D~%" n (fact (parse-integer n))))
$ ./fact.ros 10
Factorial 10 = 3628800