Hatena::ブログ(Diary)

ネットブックは開発マシンの夢を見るか

2011-04-08

xyzzy からDOS窓(cmd.exe)を開く

| 02:58

コレDOS窓版を作った。

  • カレントバッファがファイルのときは、そのファイルがあるフォルダで実行
  • そうじゃないときは、 xyzzy.exe があるフォルダで実行
  • M-x c で実行
(defun c ()
  (interactive)
  (let* ((fn (get-buffer-file-name))
         (ed::*launch-app-directory* (if fn (directory-namestring fn)
                                       (si:system-root))))
    (run-console)))

lisp/process.l の run-console (C-x c) を呼んでるだけ。

run-console と同じく、変数 *eshell* または *shell* を変更すれば cygwin とかにも対応できる。

cmd.exeオプションとか、start のオプションとかよくわからん。

参考URL:

xyzzy からエクスプローラを開く

| 02:14

ココを見つけた。

カレントバッファがファイルを持ってないときは xyzzy.exe があるフォルダを開くのはいいアイデアだと思った。

ちょっとだけ変更させてもらった。

(defun open-explorer (fn)
  (flet ((get-arg ()
           (if fn (concat "/e,/select," (map-slash-to-backslash fn))
             (concat "/e," (map-slash-to-backslash (si:system-root))))))
    (call-process
     (concat (get-windows-directory) "explorer " (get-arg)))))

(defun e ()
  (interactive)
  (let ((fn (get-buffer-file-name)))
    (cond ((null fn) (open-explorer nil))
          ((file-exist-p fn) (open-explorer fn))
          (t (message "not exist ~A" fn)))))

レキシカルスコープの使い方は間違ってないと思うけど、どうだろう。

参考URL:

ローカル関数 flet と labels

| 01:25

いわゆる、(defun ... の中だけで生きる関数なんだが、

flet と labels のどちらでも定義できる。が、微妙に振る舞いが違う。

fletlet みたいに並列に定義する
labelslet* みたいに直列に定義する

xyzzy で試してみた。

;; flet の場合
(defun test (a)
  (flet ((f1 (x) (+ x 1))         ; f1 と f2 は同時に定義されるので
         (f2 (y) (+ (f1 y) 10)))  ; f2 を定義する時点で f1 は未定義
    (f2 a)))

;; test
(test 5)
関数が定義されていません: f1    ; エラる



;; labels の場合
(defun test (a)
  (labels ((f1 (x) (+ x 1))        ; f1 --> f2 の順に定義されるので
           (f2 (y) (+ (f1 y) 10))) ; f2 を定義する時点では、すでに f1 が定義済み
    (f2 a)))

;; test
(test 5)
16                              ; 実行できる

じゃあ、なんで labels は flet* じゃないのか。他に違いがあるんだろうか。なぞだ。

参考URL:

http://d.hatena.ne.jp/Nobuhisa/20090123/1232720807

pme の 文字列中の改行文字をなんとかしてみる

| 21:35

pme はすごく便利だけど、少しだけ困ったことがある。

マクロ定義の中の文字列に改行が含まれていた場合は、そこで改行してしまって見づらくなることだ。

たとえば、以前書いたこのマクロは、

(pme (dbg-msgbox 'foo 'bar))
(msgbox (concat "~S
" "~S
")
         'foo 'bar)
nil

と展開されてしまって、ちょっと悲しい。

下のようにしてみた。

;; mod
(defun pprint-1 (s0)
  (pp-loop (substitute-string (format nil "~S" s0) "\n" "\\\\n"))
  (values))

ついでに、最後に nil って表示されてたのを消した。

結果、さっきの例だと↓こうなる。

(pme (dbg-msgbox 'foo 'bar))
(msgbox (concat "~S\n" "~S\n")
         'foo 'bar)

いい感じになった。

本当は、改行以外のコントロール文字(タブ文字とか)も考えたほうがいいけど、まあ今はこれでよしとする。