xyzzy

xyzzy

亀井氏による、emacs風エディタ。
説明はxyzzywikiに詳しい。

ちょっとした関数


xyzzy上でlispを書くのに便利な関数をいくつか載せておく。

(eval-when (:compile-toplevel :load-toplevel :execute)
  (in-package "lisp");●●lisp
  (export '(series group))
  ;macro-function
  (defun group (source n) ; cite `On Lisp' by Paul Graham
    (if (zerop n) (error "zero length"))
    (labels ((rec (source acc)
	(let ((rest (nthcdr n source)))
	  (if (consp rest)
	      (rec rest (cons (subseq source 0 n) acc))
	    (nreverse (cons source acc))))))
      (if source (rec source nil) nil)))
  ;macro
  (defmacro series (num func &rest args)
    (if (listp func)
 `(progn ,@(mapcar #'(lambda (x) `(,@func ,@x)) (group args num)))
      `(progn ,@(mapcar #'(lambda (x) `(,func ,@x)) (group args num)))))
  (in-package "user"));●●user

; (group (make-sequence 'list 10 :initial-element 0) 2)
; => ((0 0) (0 0) (0 0) (0 0) (0 0))
; (macroexpand-1 '(series 2 fn 1 2 3 4 5 6))
; => (progn (fn 1 2) (fn 3 4) (fn 5 6))


これは、リストの要素をグループにする関数と、それを用いたマクロである。
設定ファイルを書くのに便利なので、siteinit.lの始めの方に書いておくと良い。

(defun lisp-keyword () ; cite unknown
  (make-local-variable 'keyword-hash-table)
  (setf keyword-hash-table (load-keyword-file "lisp"))
  (make-local-variable 'regexp-keyword-list)
  (setf regexp-keyword-list
 (compile-regexp-keyword-list
  '(("(" t (:color 14))
    (")" t (:color 14))))))
(series
 2 add-hook
 '*post-startup-hook*
 #'(lambda ()
     (save-excursion
(set-buffer (find-buffer "*scratch*"))
(insert-file-contents "~/scratch" t)
(set-buffer-file-name "~/scratch" (find-buffer "*scratch*"))
(setq need-not-save nil)
(set-buffer-colors #(0 #xf2e2e2))))
 '*lisp-mode-hook* 'lisp-keyword
 '*lisp-interaction-mode-hook* 'lisp-keyword)

lisp-keywordは、lispのキーワードを色づけする関数である。
これは、lisp-modeとlisp-interaction-modeにフックしておく。
また、*scratch*はもともとファイルがないので、普通にファイルを開いた状態と同じにしておく。

(series 2 global-set-key
 #\M-F4 'kill-xyzzy
 #\F5 #'(lambda()
	  (interactive)
	  (insert (format-date-string "%Y-%m-%d %H:%M")))
 #\F1 #'(lambda () (interactive) (find-file (merge-pathnames ".xyzzy" (si:system-root))))
 #\C-Delete #'(lambda ()
		(interactive)
		(if (equalp "*scratch*" (buffer-name (selected-buffer)))
		    (message "*scratch* isn't deleted.")
		  (kill-selected-buffer))))

キー設定の例。一番上は、Alt+F4でxyzzyを終了させるためのもの。windows準拠。
F5はメモ帳みたいな、日付を入れる機能。F1は.xyzzyを開く。
C-Deleteでは、*scratch*を消さないようにしておく。

(defun strip-sexp ()
  (interactive "*")
  (let ((start (point))
 (to (and (forward-sexp) (point)))
 (from (and (backward-sexp) (point))))
    (if (eq start from)
 (if (scan-buffer "[`',@]" :regexp t :limit (1+ from))
     (delete-char 1)
   (if (scan-buffer "[ \t\n]+" :regexp t :tail t :limit to)
       (let (n)
	 (scan-buffer "(" :no-dup t :reverse t :limit (1+ from))
	 (delete-backward-char (setq n (- (point) start)))
	 (goto-char (- to n))
	 (delete-backward-char 1))
     (delete-char (- to start))))
      (delete-char (- start from)))
    (goto-char (min start from))))

(defun wear-paren ()
  (interactive "*")
  (forward-sexp)
  (backward-sexp)(insert "(")
  (forward-sexp)(insert ")")
  (backward-sexp)(forward-char))

;(list 1 2 3)
;^strip-sexp
;=> 1 2 3
;(list 1 2 3)
;^wear-paren
;=>((list 1 2 3))

この2つはマクロなどを編集するのに使うコマンド。上が括弧を一段階外すもので、下が一段階増やすもの。
whenやifなど、階層が深くなると対応をしたものを付けたり外したりするのが面倒なので。
下のは、S式でなくても括弧を付けられるので、他の場面でも使えたりする。
最終更新:2011年09月21日 18:05