最近エロゲーばっかりなんだけど、ちょこちょことLispとか組んだりはしていたり。ただしちゃんとまとまってなくて、というかまともに動くのが少ないんだけど、とりあえず公開するだけはしておくか、とか
ちょっと前にC++でも触ってみようかな、と思って、Visual C++ Toolkit 2003をインストールしてみたんです。でもこれってIDEは付属してなくて、コンパイラとかヘッダファイルとか、ツールのみのパッケージなんですね。まぁそれはインストールする前から分かってたので、IDEは別に用意すればいいや、と思ってたんです
で、実際ほかの開発環境、Codeblocksなんかと一緒に使ってたんですけど、エディタ部分でどうも躓くんですよ。で、どうせならxyzzy上でコンパイルとかできるようにしてしまえ、ということで適当に作ったのがtoolkit-mode。まぁ、最初はc++-toolkit-mode、なんて名前だったんだけど
;;; -*- MODE: Lisp; PACKAGE: EDITOR; -*-
;;;
(provide "toolkit")
(export '(
*toolkit-base-path*
*toolkit-compile-path*
*toolkit-linker-path*
*toolkit-include-path*
*toolkit-library-path*
*toolkit-make-path*
*toolkit-debug-path*
*toolkit-toolkit-mode-prefix-key*
))
(defvar *toolkit-base-path* "J:/VCTOOLKIT")
(defvar *toolkit-compiler-path*
(merge-pathnames "bin/cl.exe"
(append-trail-slash *toolkit-base-path*)))
(defvar *toolkit-linker-path*
(merge-pathnames "bin/ln.exe"
(append-trail-slash *toolkit-base-path*)))
(defvar *toolkit-include-path*
(merge-pathnames "include"
(append-trail-slash *toolkit-base-path*)))
(defvar *toolkit-library-path*
(merge-pathnames "lib"
(append-trail-slash *toolkit-base-path*)))
(defvar *toolkit-make-path* "H:/programs/Microsoft Platform SDK/Bin/nmake.exe")
(defvar *toolkit-debugger-path* nil)
(defvar *toolkit-mode-prefix-key* '(#\C-c))
(defvar *toolkit-mode-map* nil)
(unless *toolkit-mode-map*
(setq *toolkit-mode-map* (make-sparse-keymap))
(define-key *toolkit-mode-map*
`(,@*toolkit-mode-prefix-key* #\C-c) 'compile-current-file)
(define-key *toolkit-mode-map*
`(,@*toolkit-mode-prefix-key* #\C-m) 'execute-make)
(define-key *toolkit-mode-map*
`(,@*toolkit-mode-prefix-key* #\C-e) ' toolkit-echo-path))
(defvar *toolkit-result-buffer* "*command output*")
(defvar-local *toolkit-mode* nil)
(defun toolkit-mode (&optional (arg nil sv))
"TOOLKIT"
(interactive "*p")
(ed::toggle-mode '*toolkit-mode* arg sv)
(if *toolkit-mode*
(progn
(set-minor-mode-map *toolkit-mode-map*)
)
(progn
(kill-all-local-variables)
(unset-minor-mode-map *toolkit-mode-map*)
))
(update-mode-line t))
(pushnew '(*toolkit-mode* . "TOOLKIT") *minor-mode-alist* :key #'car)
(defun compile-current-file ()
(interactive)
(let* ((buf (selected-buffer))
(cmd (format nil "\"~a\" ~a"
*toolkit-compiler-path* (get-buffer-file-name buf)))
(dir (default-directory (selected-buffer)))
(environ nil))
(setq environ (list
(cons "PATH" *toolkit-base-path*)
(cons "INCLUDE" *toolkit-include-path*)
(cons "LIB" *toolkit-library-path*)))
(execute-shell-command cmd nil *toolkit-result-buffer* environ dir)
(set-buffer *toolkit-result-buffer*)
(goto-char (point-max))
(if (= (point-min) (point-max))
(progn
(delete-window)
(switch-to-buffer buf))
(switch-to-buffer-other-window buf))))
(defun execute-make (&optional target)
(interactive)
(let* ((make-target (if *prefix-args* (read-string "Target: " :default "all")
"all"))
(buf (selected-buffer))
(cmd (format nil "\"~a\" ~a"
*toolkit-make-path* make-target))
(dir (default-directory (selected-buffer)))
(environ (list
(cons "PATH"
(format nil "~a;~a"
*toolkit-base-path*
(merge-pathnames
"bin"
(append-trail-slash
*toolkit-base-path*))))
(cons "INCLUDE" *toolkit-include-path*)
(cons "LIB" *toolkit-library-path*))))
(execute-shell-command cmd nil *toolkit-result-buffer* environ dir)
(set-buffer *toolkit-result-buffer*)
(goto-char (point-min))
(if (= (point-min) (point-max))
(progn
(delete-window)
(switch-to-buffer buf))
(switch-to-buffer-other-window buf))))
(defun toolkit-echo-path ()
(interactive)
(let* ((buf (selected-buffer))
(cmd (format nil "\"~a\" ~a"
*toolkit-compiler-path* (get-buffer-file-name buf)))
(dir (default-directory (selected-buffer)))
(environ nil))
(setq environ (list
(cons "PATH"
(format nil "~a;~a"
*toolkit-base-path*
(merge-pathnames
"bin"
(append-trail-slash
*toolkit-base-path*))))
(cons "INCLUDE" *toolkit-include-path*)
(cons "LIB" *toolkit-library-path*)))
(execute-shell-command "set" nil *toolkit-result-buffer* environ dir)
(set-buffer *toolkit-result-buffer*)
(goto-char (point-max))
(switch-to-buffer-other-window buf)))
defvarな変数は適宜読み替えで。とりあえずこれでコンパイルとかは可能になったはず。……あまり使い道がないけど<自分で言うな(^^;
しかもアレですよ、自分で作っておいてなんですが、このあとC++はころっと忘れ去ってしまったというダメっぷり(笑)。で、C++の代わりにC#なんぞに手を出す始末。……もうダメダメですな!
……で(まだ続くのか)、C#で遊ぶためにインストールしたVisual C# 2005 Express Edition Beta がまた重いんですな(^^;。これは我慢の限界だー、と思って↑のモードを流用できないかな、と思って作ったのが↓のtoolkit-setup.l。まぁ、コンパイラに渡す環境変数なんかを変えれば後は同じようなものなのかな、とか。細かいスイッチなんかはメイクファイルに書くってことで
;;; -*- MODE:Lisp; Package:EDITOR; -*-
;;;
;;;
(provide "toolkit-setup")
(defun toolkit-setup-csharp ()
(interactive)
(toolkit-setup-csharp-variables)
(toolkit-setup-csharp-commands)
(toolkit-mode))
(add-hook '*csharp-mode-hook* 'toolkit-setup-csharp)
(defun toolkit-setup-csharp-variables ()
(setq *toolkit-base-path* "C:/WINDOWS/Microsoft.NET/Framework/v2.0.40607")
(setq *toolkit-bin-path* *toolkit-base-path*)
(setq *toolkit-compiler-path*
(merge-pathnames "csc.exe /nologo" *toolkit-base-path*))
(setq *toolkit-unittest-path* "J:/NUnit 2.2/bin")
(setq *toolkit-unittest-program*
(merge-pathnames "nunit-console.exe" *toolkit-unittest-path*))
(setq *toolkit-linker-path* nil)
(setq *toolkit-include-path* *toolkit-base-path*)
(setq *toolkit-library-path* *toolkit-base-path*)
(setq *error-regexp-list*
(append *error-regexp-list*
(list (list (compile-regexp
"^\\([^\(]+\\)(\\([^,]+\\),[0-9]+): \\(.+\\)") 1 2))))
(setq *toolkit-unittest-result-regexp*
(compile-regexp "^\\(Tests.*seconds\\)"))
(setq *toolkit-delete-result-buffer-after-unittest* t))
(defun toolkit-unit-test ()
(interactive)
(let* ((buf (selected-buffer))
(file (read-string
"Test Unit: "
:default
(format nil "~a.dll"
(pathname-name
(get-buffer-file-name
(selected-buffer))))))
(cmd (format nil "\"~a\" ~a" *toolkit-unittest-program* file)))
(execute-shell-command cmd nil *toolkit-result-buffer* nil nil)
(set-buffer *toolkit-result-buffer*)
(goto-char (point-min))
(when (scan-buffer *toolkit-unittest-result-regexp* :regexp t)
(message (match-string 1)))
(if *toolkit-delete-result-buffer-after-unittest*
(delete-window)
(switch-to-buffer-other-window buf))))
(defun toolkit-setup-csharp-commands ()
(define-key *toolkit-mode-map*
`(,@*toolkit-mode-prefix-key* #\t) 'toolkit-unit-test))
(defun toolkit-setup-c++ ()
(interactive)
(toolkit-setup-c++-variables)
(toolkit-mode))
(defun toolkit-setup-c++-variables ()
(setq *toolkit-include-path*
(format nil "~a;~a"
*toolkit-include-path*
"H:/programs/Microsoft Platform SDK/include"))
(setq *toolkit-library-path*
(format nil "~a;~a"
*toolkit-library-path*
"H:/programs/Microsoft Platform SDK/lib")))
(add-hook 'ed::*c++-mode-hook* 'toolkit-setup-c++)
C++用の設定が残ってるのはもしかしたらまだ使うかも、とか思ってるから。あとNUnit用の設定もちょっと入れてみたり
(*1)。ちゃんとパッケージングすればいいんだろうけど、面倒だし(笑)。誰かxyzzyで動く、C#用のcode completion機能作ってくれよー、とか。ユーザーが定義したクラスなんかはちょっと厳しいかもしれないけど、.NET Frameworkのクラスライブラリあたりはリフレクション機能を使えば何とかならないかな、とか思ってるんだけど……ダメかな?
カレン「アレね」
LKPTeam「?」
カレン「『じゃ、言い出しっぺということで、よろしく』よね」
LKPTeam「うーあー、それはいやー(^^;」
カレン「なら高望みはしないの」
LKPTeam「あぅあぅあー」
あ、↑を使うときは(require ...)を~/.xyzzyとかにでも。私はtoolkit.lはsite-lispディレクトリ以下に、toolkit-setup.lは~/.toolkit-setup.lと名前と置き場所を変えて、
(require "toolkit")
(load-file "~/.toolkit-setup.l")
としてみたり。この辺はお好みで
話は変わって、Subversion1.2.0が出てたので、動作検証とか機能追加してsvn-modeもバージョンを一つあげようかな、とか思ったんだけど、以前のsvn:keywordsでUTF-8な文字列が変換されずにそのまま出力されてしまうせいで追随するのを諦めたり。この問題がなければ自分のPCで動かしてるSubversionもさっさと最新にするのになぁ
svnコマンドに環境変数としてLANGを一緒に渡すとLANGで設定した言語でメッセージが表示されるようになっていて、便利そうだったのにー
といったところが、最近の私のlisp事情でした(^^;