Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2009-03-22

GaucheでSLIME

| 22:43 | GaucheでSLIME - わだばLisperになる を含むブックマーク はてなブックマーク - GaucheでSLIME - わだばLisperになる

gaucheでも、SLIMEが使えたら、もっとGaucheのコード書くようになる気がするなあと常々思っていたのですが、ついに、swank-gaucheが登場しました!

まだ発展途上ということですが、今のところでもシンボルの補完と、マクロ展開ができるのでSLIMEに慣れた方なら便利に使えると思います!

自分的にはArglistが早く実装されてくれると物覚えの悪い自分には嬉しいので、期待して待ちたいです。…いや、自分でもできそうなら作ってみたいです(笑)

lequeさんのgauche-modeと合体するとかなり便利に使えるんじゃないかと想像しているのですが、とりあえず思い付いたユーティリティを書いてみました。

  1. Gaucheのリファレンスを引く
  2. マクロ展開をプリティプリント

の2点です。

プリティプリントには、ppが必要です。

基本的な設定(swank-gauche.scm参照)

;; Emacs Lisp
(pushnew "<path-to-slime-dir>/slime/contrib" load-path :test #'equal)
(require 'slime-scheme)
(setq slime-lisp-implementations
      '((gauche ("gosh") :init gauche-init)))

(defun gauche-init (file encoding)
  (format "%S\n\n"
          `(begin
             (add-load-path "<path-to-slime-dir>/slime/contrib") ;; add load path to swank-gauche.scm
             (require "swank-gauche")
             (import swank-gauche)
             (start-swank ,file))))

(defun gauche ()
  (interactive)
  (slime 'gauche))

(defun find-gauche-package ()
  (interactive)
  (let ((case-fold-search t)
        (regexp (concat "^(select-module\\>[ \t']*"
                        "\\([^)]+\\)[ \t]*)")))
    (save-excursion
     (when (or (re-search-backward regexp nil t)
               (re-search-forward regexp nil t))
       (match-string-no-properties 1)))))

(setq slime-find-buffer-package-function 'find-gauche-package)
(setq slime-complete-symbol-function 'slime-complete-symbol*)

Gaucheのリファレンスを引く(C-c C-d C-sh-h)

;; Emacs Lisp
(progn
  (defun gauche-ref-lookup ()
    (interactive)
    (browse-url
     (format "http://practical-scheme.net/gauche/man/?l=jp&p=%s" (thing-at-point 'symbol))))
  
  (define-key slime-mode-map [(control ?c) (control ?d) (shift ?h)] 'gauche-ref-lookup))

マクロ展開をプリティプリント

;; swank-gauche.scm
(use util.match)
(use pp)

(define (subst-by subst pred lst)
  (define self (cut subst-by subst pred <>))
  (match lst
    (() ())
    (((? pred head) . tail)
     (cons (subst head) (self tail)))
    (((? pair? head) . tail)
     (cons (self head) (self tail)))
    ((head . tail)
     (cons head (self tail)))))

(defslimefun swank-macroexpand-1 (string)
  (let ((sexp (read-from-string string)))
    (if (eof-object? sexp)
        ""
        (with-output-to-string 
          (lambda ()
            (pretty-print 
             (subst-by identifier->symbol identifier?
                       (macroexpand-1 sexp))))))))

(defslimefun swank-macroexpand-all (string)
  (let ((sexp (read-from-string string)))
    (if (eof-object? sexp)
        ""
        (with-output-to-string 
          (lambda ()
            (pretty-print 
             (subst-by identifier->symbol identifier?
                       (macroexpand-1 sexp))))))))
  • 動作具合(slime-macroexpand-1)
(match lst
    (() ())
    (((? pred head) . tail)
     (cons (subst head) (self tail)))
    (((? pair? head) . tail)
     (cons (self head) (self tail)))
    ((head . tail)
     (cons head (self tail))))

;==>
(if
 (null? lst)
 ((lambda () ()))
 (if
  (pair? lst)
  (if
   (pred (car lst))
   ((lambda (head tail) (cons (subst head) (self tail))) (car lst) (cdr lst))
   (if
    (pair? (car lst))
    ((lambda (head tail) (cons (self head) (self tail))) (car lst) (cdr lst))
    ((lambda (head tail) (cons head (self tail))) (car lst) (cdr lst))))
  (match:error lst)))