はじめに
2015 年は SICP を読んでいく予定です.
というわけで, Scheme の開発環境を Emacs で構築しました.
Scheme の処理系 Gauche
まずは, Scheme 処理系をインストール.(ゴーシュ)
gosh -V
scheme-mode
Default で Emacs にはいっている. 以下の設定を参考にした.
;; UTF-8 に統一
(setq process-coding-system-alist
(cons '("gosh" utf-8 . utf-8) process-coding-system-alist))
(setq scheme-program-name "gosh -i")
(autoload 'scheme-mode "cmuscheme" "Major mode for Scheme." t)
(autoload 'run-scheme "cmuscheme" "Run an inferior Scheme process." t)
;; 別のウィンドウに gosh を動作させる
(defun scheme-other-window ()
"Run Gauche on other window"
(interactive)
(split-window-horizontally (/ (frame-width) 2))
(let ((buf-name (buffer-name (current-buffer))))
(scheme-mode)
(switch-to-buffer-other-window
(get-buffer-create "*scheme*"))
(run-scheme scheme-program-name)
(switch-to-buffer-other-window
(get-buffer-create buf-name))))
(define-key global-map "\C-cS" 'scheme-other-window)
smartparens
カッコをあつかうための多機能な移動・編集ツール.
- https://github.com/Fuco1/smartparens
- https://github.com/Fuco1/smartparens/wiki
- smartparens.el での括弧処理 - 理系学生日記
(require 'smartparens-config)
(smartparens-global-mode t)
default
smartparens-config では以下が設定される.
example
設定例.
あまりに多機能すぎて使いこなす自信がないな..
覚えておきたいのは,
- かっこで囲む xx sp-pair M-(
- かっこを外す sp-unwrap C-M-s
(define-key sp-keymap (kbd "C-M-f") 'sp-forward-sexp)
(define-key sp-keymap (kbd "C-M-b") 'sp-backward-sexp)
(define-key sp-keymap (kbd "C-M-d") 'sp-down-sexp)
(define-key sp-keymap (kbd "C-M-a") 'sp-backward-down-sexp)
(define-key sp-keymap (kbd "C-S-a") 'sp-beginning-of-sexp)
(define-key sp-keymap (kbd "C-S-d") 'sp-end-of-sexp)
(define-key sp-keymap (kbd "C-M-e") 'sp-up-sexp)
(define-key emacs-lisp-mode-map (kbd ")") 'sp-up-sexp)
(define-key sp-keymap (kbd "C-M-u") 'sp-backward-up-sexp)
(define-key sp-keymap (kbd "C-M-t") 'sp-transpose-sexp)
(define-key sp-keymap (kbd "C-M-n") 'sp-next-sexp)
(define-key sp-keymap (kbd "C-M-p") 'sp-previous-sexp)
(define-key sp-keymap (kbd "C-M-k") 'sp-kill-sexp)
(define-key sp-keymap (kbd "C-M-w") 'sp-copy-sexp)
(define-key sp-keymap (kbd "C-M-s") 'sp-unwrap-sexp)
(define-key sp-keymap (kbd "M-<backspace>") 'sp-backward-unwrap-sexp)
(define-key sp-keymap (kbd "C-<right>") 'sp-forward-slurp-sexp)
(define-key sp-keymap (kbd "C-<left>") 'sp-forward-barf-sexp)
(define-key sp-keymap (kbd "C-M-<left>") 'sp-backward-slurp-sexp)
(define-key sp-keymap (kbd "C-M-<right>") 'sp-backward-barf-sexp)
(define-key sp-keymap (kbd "M-D") 'sp-splice-sexp)
(define-key sp-keymap (kbd "C-M-<delete>") 'sp-splice-sexp-killing-forward)
(define-key sp-keymap (kbd "C-M-<backspace>") 'sp-splice-sexp-killing-backward)
(define-key sp-keymap (kbd "C-S-<backspace>") 'sp-splice-sexp-killing-around)
(define-key sp-keymap (kbd "C-]") 'sp-select-next-thing-exchange)
(define-key sp-keymap (kbd "C-<left_bracket>") 'sp-select-previous-thing)
(define-key sp-keymap (kbd "C-M-]") 'sp-select-next-thing)
(define-key sp-keymap (kbd "M-F") 'sp-forward-symbol)
(define-key sp-keymap (kbd "M-B") 'sp-backward-symbol)
(define-key sp-keymap (kbd "H-t") 'sp-prefix-tag-object)
(define-key sp-keymap (kbd "H-p") 'sp-prefix-pair-object)
(define-key sp-keymap (kbd "H-s c") 'sp-convolute-sexp)
(define-key sp-keymap (kbd "H-s a") 'sp-absorb-sexp)
(define-key sp-keymap (kbd "H-s e") 'sp-emit-sexp)
(define-key sp-keymap (kbd "H-s p") 'sp-add-to-previous-sexp)
(define-key sp-keymap (kbd "H-s n") 'sp-add-to-next-sexp)
(define-key sp-keymap (kbd "H-s j") 'sp-join-sexp)
(define-key sp-keymap (kbd "H-s s") 'sp-split-sexp)
;;;;;;;;;;;;;;;;;;
;; pair management
(sp-local-pair 'minibuffer-inactive-mode "'" nil :actions nil)
;;; lisp modes
(sp-with-modes sp--lisp-modes
(sp-local-pair "(" nil :bind "C-("))
(sp-pair "(" ")" :wrap "M-(")
rainbow-delimiters
かっこの深さに応じて色付けしてくれる.
かっこの強調をどきつくする. これはいいなぁ.
注意 テーマ読み込みのあとに配置すること.
(require 'rainbow-delimiters)
(add-hook 'emacs-lisp-mode-hook 'rainbow-delimiters-mode)
(add-hook 'scheme-mode-hook 'rainbow-delimiters-mode)
(add-hook 'lisp-mode-hook 'rainbow-delimiters-mode)
;; these setting should be placed after load-theme
;; using stronger colors
(require 'cl-lib)
(require 'color)
;; 関数にしないとうまくいかない...手動で有効に
(defun rainbow-delimiters-using-stronger-colors ()
(interactive)
(cl-loop
for index from 1 to rainbow-delimiters-max-face-count
do
(let ((face (intern (format "rainbow-delimiters-depth-%d-face" index))))
(cl-callf color-saturate-name (face-foreground face) 100))))
;; making unmatched parens stand out more
(set-face-attribute 'rainbow-delimiters-unmatched-face nil
:foreground 'unspecified
:inherit 'error
:strike-through t)
SICP を info で読む
以下の設定で Emacs の info で SICP が読める (English)
- Emacs の info として SICP を読む - 大切なものは目に見えない - mahata の日記 (はてなブランチ)
- SICP 読むための設定とか - Clipboard
- 計算機プログラムの構造と解 - とりあえず暇だったし何となく始めたブログ
この方法のよいところは, テキストの文章をそのまま C-x C-e で評価して実 行できるところ.
# sicp.info 取得
wget https://www.neilvandyke.org/sicp-texi/sicp.info.gz
gunzip sicp.info.gz
# /usr/local/info に sicp.info をコピー.
$ sudo mkdir -p /usr/local/info
$ sudo cp sicp.info /usr/local/info
# dir ファイルを編集.
$ sudo emacs /usr/local/share/info/dir
# 次の二行を追記.
The Algorithmic Language Scheme
* SICP : (sicp.info). Structure and Interpretation of Computer Programs.
調べたけど利用しないもの
せっかく調べたけど, 設定を有効にしない (できない) ものも列挙.
paredit
Lisp コードで頻出する括弧類のバランスを維持することを目的としたもの.
smartparens に人気をとられてしまったかわいそうな子.
gosh-mode
scheme-mode の拡張.
scheme-mode を継承しているので, 基本的な操作は変わらないそうだ.
el-get で取得. リボジトリから取得後に make && make install
(require 'gosh-config)
M-x gosh-run で gosh が起動すれば OK.
scheme-mode に比べて情報がすくないのと, すごさがわからないので, ひとまずは scheme-mode を利用することにした.
なれてきたらそのうちもう一度挑戦する.
scheme-complete
auto-complete で補完をすることができる. デフォルト設定で, そこそこの補完候補が出る.
scheme-complete というものもあるそうなので,気休め程度に導入.
本家のサーバ落ちた?? github の mirror より取得.
以下を参考にして, auto-complete の source に scheme-complete の情報源を加える.
メンテされていないのと, auto-complete で何とかなるので削除.
(autoload 'scheme-smart-complete "scheme-complete" nil t)
(autoload 'scheme-get-current-symbol-info "scheme-complete" nil t)
(eval-after-load 'scheme
'(define-key scheme-mode-map "\e\t" 'scheme-smart-complete))
;; scheme-mode-hook
(defvar ac-source-scheme
'((candidates
. (lambda ()
(require 'scheme-complete)
(all-completions ac-target (car (scheme-current-env))))))
"Source for scheme keywords.")
(add-hook 'scheme-mode-hook
'(lambda ()
(make-local-variable 'ac-sources)
(setq ac-sources (append ac-sources '(ac-source-scheme)))))
eldoc
- Emacs Lisp モードを便利にする機能 3 選 (auto-complete, eldoc, rainbow-delimiters) | プログラマーズ雑記帳
- sicpstudygroup @ ウィキ - 環境設定例集
scheme の eldoc は scheme-complete と合わせて利用するらしいが, eldoc error void-function eldoc-current-symbol とでてエラーする.
(require 'eldoc-extension)
(add-hook 'scheme-mode-hook
(lambda ()
;; Gauche の場合, 次の 2 個の変数を設定しておいたほうがよいのかも.
(setq default-scheme-implementation 'gauche)
(setq *current-scheme-implementation* 'gauche)
;; eldoc-mode
(set (make-local-variable 'eldoc-documentation-function)
'scheme-get-current-symbol-info)
(eldoc-mode t)
)
)
(setq lisp-indent-function 'scheme-smart-indent-function)
flymake 設定
glint というものがあるらしい. gauche 0.8.13 でしか動作しないようなので試していない.