テキストブラウザ#1
2007/08/11
よく考えたら*1、clispにべったりになってしまうのか。作り方にもよると思いますが、あまり考えずに飽きるまで進めようと思います。
hjkl によるカーソル移動まで実装してみました。
(use-package :screen) (use-package :ext) (defun print-center (win row str) (multiple-value-bind (height width) (window-size win) (set-window-cursor-position win row (- (floor width 2) (floor (length str)))) (delete-window-line win) (princ str))) (defun print-intro (win) (multiple-value-bind (height width) (window-size win) (let ((row (floor height 3)) (col (floor width 2))) (print-center win (incf row) "------------") (print-center win (incf row) "| hello! |") (print-center win (incf row) "------------")))) (defun normal-proc (win char) (multiple-value-bind (height width) (window-cursor-position win) (case (or (ext:char-key char) (character char)) ((#\q #\Q) (error 'quit-condition)) (#\j (set-window-cursor-position win (1+ height) width)) (#\k (set-window-cursor-position win (1- height) width)) (#\h (set-window-cursor-position win height (1- width))) (#\l (set-window-cursor-position win height (1+ width))) (t )))) (defun search-proc (win char) (princ key)) (let ((mode :normal) (mode-plist (list :normal #'normal-proc :search #'search-proc))) (defun current-mode-proc () (getf mode-plist mode)) (defun normal-mode () (setf mode :normal)) (defun search-mode () (setf mode :search))) (define-condition quit-condition (simple-condition) () (:documentation "終了")) (defun main () (handler-case (with-window (print-intro *window*) (sleep 1) (clear-window *window*) (with-keyboard (loop for char = (read-char ext:*keyboard-input*) do (funcall (current-mode-proc) *window* char)))) (quit-condition () (princ "bye!")) (error (c) (format t "~a" c)))) (main)
20070812 ちょっとリファクタリングしました。
キーボード入力を監視しつつ、入力によってカーソル位置を設定しているだけです。文字を表示するのは、文字を表示したい位置にカーソルを移動し、標準出力に出力しているだけです。screenパッケージどころかNcursesも良く知っていないので、正しいのかどうなのかわかりません。とりあえず、カーソル移動はできるのですが、画面の端までたどりつく前に止まってしまいます。
screenパッケージの14個のプリミティブな関数だけだと、それぞれを使うのには楽なんですが、何かと面倒です。Ncursesだと、指定した矩形を指定して再描画とか、仮想画面(20070826:パッドのことでした。http://www.fireproject.jp/feature/c-language/curses/pad.html)とかあった気がするのですが、その辺全部自分で面倒見ないとなのだろうか。デバッグも標準出力に出力してしまうと、カーソル位置変わっちゃうし、どうしようかな。
*1:clispのscreenパッケージを使うということは