
#| habuki-mode for xyzzy-0.2.2.235 or over version

 Copyright (C) 2007-2008 Kneneglect Refe
 All rights reserved.
 <kneneglect_std@yahoo.co.jp>

漢直「小ノ目（はぶき）」をマイナーモードで使う。
トレーナー、配列一覧機能付き。

以下の２つのファイルに分けられている。
habuki.l:　　　 本体。
habuki-board.l: 配置一覧表を作成。

説明

準備
habuki.lをsite-lisp下に置き、バイトコンパイルする。
例えば、.xyzzyに以下を追加する。
(require "habuki")
(global-set-key #\C-2 'habuki-mode)
(setq *habuki-normal-rule* '("~/habuki.rl" "~/habuki-kanji.rl")
      *habuki-abbrev-rule* "~/habuki-abbrev.rule")
付属のhabuki.rl habuki-kanji.rl をxyzzy.exeと同じディレクトリに置く。

使い方

使いたいバッファでhabuki-modeを起動する。
qwerty配列に対して、左人差し指をG、右人差し指をKの位置に乗せる。
適当にキーを叩くと文字が出る。
Q →ヘルプが出る。 ~ →機能一覧みたいの。

配列の詳細は後日、別ファイルにて説明する……かも。

履歴
lapse001 2007-02-26 10:25 とりあえず完成。
lapse002 2007-03-28 02:41 ひととおり調整。
lapse003 2008-02-26 22:05 小ノ目に名称変更。辞書と番号を分ける。
lapse004 2008-02-28 23:34 ハッシュを無駄に使うのを止めた。
lapse005 2008-03-03 23:00 overwrite-modeの使い道が分かった。
lapse006 2008-03-05 18:08 abbrev機能と盤面出力機能（別ファイル）を付けた。
lapse007 2008-03-08 20:35 登録語とメモの表示機能を付けた。
lapse008 2008-03-10 00:27 ギリシャ字の大文字小文字変換。

権利・責任関係
日本国の著作権法が適用される範囲でkneneglectが著作権を持つ。
細かく見ると、どこにも主張するべき点がなさそうだけれども。
ライセンスは以下の通り。MIT Licenseと同等であると考えて良い。

配布、改造、編纂等の再利用を許可する。二次創作物の権利は一切主張しない（し得ない）。
ただし、ファイルのバージョンや作成・配布元が区別できるように名前や表示を考慮すること。
後に情報元がたどれるように、著作権表示を付けること。
何人も、このプログラムによって生じた損益について責任を持たない。
このプログラムを使用する者は、同時にこのライセンスを許諾しているものとみなす。


 漢直「小ノ目」コード

次の３つのファイルに分けられている。
habuki.rl:　　　 英字や数字など。
habuki-kanji.rl: 日本語。
habuki-back.rl:　日本語の追加コード。

日本語の配置については、作者個人の頻度表を用いて作成したので、
分野がまるきり異なる人には合わない。
自分の頻度表を作り、後日公開する（かも知れない）規則作成キットを用いて、
自分用の規則を作ることが望ましい。あくまで参考用の配列である。

英字に関しては、dvorakのサイトで公開されている頻度表を参考に、作者が
吟味して作成したものなので、そのまま用いて問題ないと思う。
数字・記号は適当に配置したので、気に入らないなら入れ替えると良い。
その場合は、*habuki-memo* および *habuki-num-convert* を合わせて変更する
と、配列通りのコマンドが使える。

 履歴
lapse003 2008-02-26 22:05 一新。3503字くらい登録してある。
lapse004 2008-02-28 23:31 かたまりで使う字はつなげた。3471項目ほど。
lapse005 2008-03-09 0:06 頻度表を一新。キーごとの負荷率を改善。
lapse006 2008-03-10 0:53 ギリシャ語他、デモ用のおまけを追加。

えんいー |#

(provide "habuki")

(defpackage "habuki" (:use "lisp"))
(use-package "habuki")
(in-package "habuki")

(eval-when (:compile-toplevel :load-toplevel :execute)
  (require "habuki")
  (use-package "editor"))

(export
 '(*habuki-mode*
   *habuki-mode-hook*
   *habuki-input*
   *habuki-num-convert*
   *habuki-rule-table*
   *habuki-anti-rule-table*
   *habuki-help-table*
   *habuki-convert-table*
   *habuki-abbrev-rule-list*
   *habuki-normal-rule*
   *habuki-abbrev-rule*
   *habuki-cur-root-name*
   *habuki-help-on*
   *habuki-help-word*
   *habuki-help-after-num*
   *habuki-help-before-num*
   *habuki-help-keyboard-on*
   *habuki-habuki-output-method*
   habuki-mode
   habuki-help-on
   habuki-help-off
   habuki-set-normal-rule
   habuki-set-habuki-rule
   habuki-save-rule
   habuki-set-help-after-num
   habuki-set-help-before-num
   habuki-help-keyboard-toggle
   habuki-help-toggle
   habuki-convert
   habuki-set-help-after-num
   habuki-set-help-before-num
   habuki-input-abbrev
   habuki-set-abbrev-rule
   habuki-help-set-default
   habuki-forward-char
   habuki-next-virtual-line
   habuki-previous-virtual-line
   habuki-backward-char
   habuki-newline
   habuki-delete-backward-char-or-selection
   habuki-delete-char
   habuki-undo
   habuki-redo
   habuki-write-fullsize-space
   habuki-show-memo
   habuki-show-abbrev))

(defvar-local *habuki-mode* nil)
(defvar *habuki-mode-hook* nil)
(defvar *habuki-memo*
  '("|ｘｍｈｂ（‖）ｆｃｌ；| |  1-7:省出力／表示    0:省表示のリセット    9:省表示一覧"
    "ｙ５１２ｄ？−ｗ４７８△||  ?:省表示  q:省出力  =:省登録  ,:アンドゥ  .:リドゥ m:改行"
    "┃ｊ，．０６９３／＾＝┃?|  PNBF:上下左右  J:全角スペース  ;:このメモを表示"
    " ━━━ｚｋ¬ｐ□━━━　|  C-2:終了   x:盤面表示切り替え   h:ヘルプ表示切り替え"))

(defvar *habuki-rule-table* nil)
(defvar *habuki-anti-rule-table* nil)
(defvar *habuki-abbrev-rule-list* nil)

(defvar *habuki-normal-rule* nil)
(defvar *habuki-abbrev-rule* nil)

(defvar *habuki-help-on* nil)
(defvar *habuki-help-table* nil)
(defvar *habuki-help-after-num* 2)
(defvar *habuki-help-before-num* 1)
(defvar *habuki-help-keyboard-on* t)
(defvar *habuki-help-word* "")
(defvar *habuki-abbrev-output-method* nil)

(defvar *habuki-cur-root-name* "")
(defvar *habuki-input* nil)
(defvar *habuki-num-convert* nil)
(unless *habuki-num-convert*
  (setq *habuki-num-convert* "GERKOWHP`J"))
(setq habuki-num (map 'list 'cons *habuki-num-convert* '(0 1 2 3 4 5 6 7 8 9)))

(setq habuki-all-char (coerce "1234567890-^\\qwertyuiop@[asdfghjkl;:]zxcvbnm,./" 'list))
(defvar *habuki-lone-char* (coerce "17\\a]ncxz./" 'list))
(setq habuki-char (set-difference habuki-all-char *habuki-lone-char*))
(setq habuki-read-root-name "")
(setq habuki-help-buff-name "*小ノ目ヘルプ*")

(defvar *habuki-mode-map* nil)
(unless *habuki-mode-map*
  (setq *habuki-mode-map* (make-keymap))
  (dolist (c habuki-all-char)
    (define-key *habuki-mode-map* c 'habuki-input))
  (dolist (c (coerce (substring *habuki-num-convert* 1 8) 'list))
    (define-key *habuki-mode-map* c 'habuki-input-abbrev))
  (define-key *habuki-mode-map* #\Q 'habuki-help-toggle)
  (define-key *habuki-mode-map* #\" 'habuki-help-keyboard-toggle)
  (define-key *habuki-mode-map* #\V 'habuki-set-help-before-num)
  (define-key *habuki-mode-map* #\< 'habuki-set-help-after-num)
  (define-key *habuki-mode-map* #\) 'habuki-forward-char)
  (define-key *habuki-mode-map* #\% 'habuki-backward-char)
  (define-key *habuki-mode-map* #\` 'habuki-next-virtual-line)
  (define-key *habuki-mode-map* #\M 'habuki-previous-virtual-line)
  (define-key *habuki-mode-map* #\# 'habuki-newline)
  (define-key *habuki-mode-map* #\$ 'habuki-delete-backward-char-or-selection)
  (define-key *habuki-mode-map* #\T 'habuki-delete-char)
  (define-key *habuki-mode-map* #\D 'habuki-undo)
  (define-key *habuki-mode-map* #\F 'habuki-redo)
  (define-key *habuki-mode-map* #\S 'habuki-write-fullsize-space)
  (define-key *habuki-mode-map* #\G 'habuki-help-set-default)
  (define-key *habuki-mode-map* #\+ 'habuki-coerce-output)
  (define-key *habuki-mode-map* #\Y 'habuki-coerce-show)
  (define-key *habuki-mode-map* #\* 'habuki-set-abbrev-rule)
  (define-key *habuki-mode-map* #\~ 'habuki-show-memo)
  (define-key *habuki-mode-map* #\J 'habuki-show-abbrev))
(pushnew '(*habuki-mode* . "省") *minor-mode-alist* :key #'car)

(defun habuki-version ()
  (interactive)
  (and (interactive-p)
       (message "小ノ目 lapse ~A in 2008-03-10" (habuki-version)))
  "008")

(defun habuki-mode (&optional (arg nil sv))
  (interactive "p")
  (ed::toggle-mode '*habuki-mode* arg sv)
  (update-mode-line t)
  (if *habuki-mode*
      (progn
	(or *habuki-rule-table*
	    (habuki-set-rule))
	(or *habuki-abbrev-rule-list*
	    (habuki-read-abbrev-rule-file *habuki-abbrev-rule*))
	(setq *habuki-cur-root-name* "" *habuki-input* "")
	(set-minor-mode-map *habuki-mode-map*)
	(and *habuki-help-on*
	     (habuki-help-activate)
	     (habuki-help))
	(run-hooks '*habuki-mode-hook*))
    (progn
      (unset-minor-mode-map *habuki-mode-map*)
      (habuki-help-kill)))
    t)

(defvar *habuki-convert-table* nil)
(unless *habuki-convert-table*
  (setq *habuki-convert-table* (make-hash-table :size 499 :test 'equal))
  (map nil #'(lambda (x y)
	       (setf (gethash x *habuki-convert-table*) y)
	       (setf (gethash y *habuki-convert-table*) x))
       (concat "ABCDEFGHIJKLMNOPQRSTUVWXYZ.,-!':ＡＢＣＤＥＦＧＨＩＪＫＬＭＮＯＰＱＲＳＴＵＶＷＸＹＺ．，−！’："
	       "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΠΡΣΥΦΧΨΩ")
       (concat "abcdefghijklmnopqrstuvwxyz*=+?`;ａｂｃｄｅｆｇｈｉｊｋｌｍｎｏｐｑｒｓｔｕｖｗｘｙｚ＊＝＋？‘；"
	       "αβγδεζηθικλμνξοπρστυφχψω")))

(defun habuki-set-rule ()
  (long-operation
    (setq *habuki-rule-table* (make-hash-table :size 4999 :test 'equal)
	  *habuki-anti-rule-table* (make-hash-table :size 4999 :test 'equal))
    (mapc #'habuki-read-rule-file *habuki-normal-rule*)
    (message "規則を読み込んだ。")))

(defun habuki-read-rule-file (file)
  (when (and file
	     (file-exist-p file))
    (with-open-file (in file :direction :input)
      (message "~A を読み込んでるところ。" file)
      (let (buff from to)
	(while (setq buff (read-line in nil))
	  (setq buff (string-trim " \t" buff))
	  (or (string-match "^%" buff)
	      (and (string-match "^#s" buff)
		   (setq from (1+ (string-match "\"" buff)))
		   (setq to (string-match "\"" buff from))
		   (setq habuki-read-root-name (substring buff from to)))
	      (and (setq to (string-match ">" buff))
		   (habuki-push-word (substring buff 0 to) (substring buff (1+ to)) habuki-read-root-name))
	      ))))))

(defun habuki-read-abbrev-rule-file (file)
  (when (and file
	     (file-exist-p file))
    (with-open-file (in file :direction :input)
      (message "~A を読み込んでるところ。" file)
      (let (buff)
	(while (setq buff (read-line in nil))
	  (push (cons (char-into-num (elt buff 0)) (substring buff 1)) *habuki-abbrev-rule-list*))))
    (message "規則を読み込んだ。")))

(setq char-into-num (map 'list 'cons "0123456789" '(0 1 2 3 4 5 6 7 8 9)))
(defun char-into-num (c)
  (cdr (assoc c char-into-num)))

(defun habuki-push-word (key word root-name)
  (and (> (length key) 0)
       (> (length word) 0)
       (setf (gethash (list root-name key) *habuki-rule-table*) word)
       (setf (gethash (char word 0) *habuki-anti-rule-table*) (list root-name key))
       ))

(defun habuki-input ()
  (interactive "*")
  (let ((s (habuki-input-sub *last-command-char*)))
    (when (stringp s)
      (habuki-output s))
    (habuki-help)))

(defun habuki-output (s)
  (if overwrite-mode
      (mapcar #'overwrite-char (coerce s 'list))
    (insert s))
  (when (not (equal *habuki-help-word* ""))
    (setq *habuki-help-word*
	  (if (< (length s) (length *habuki-help-word*))
	      (substring *habuki-help-word* (length s))
	  ""))))

;#p:prefix #s "":switch to "" ##:insert # #c convert
(defun habuki-input-sub (c)
  (or (and (find c *habuki-lone-char*)
	   (setq c (string c)))
      (setq c (concat *habuki-input* (string c))))
  (setq *habuki-input* "")
  (let ((word (gethash (list *habuki-cur-root-name* c) *habuki-rule-table*)))
    (or (null word)
	(when (string-match "^#p" word) (setq *habuki-input* c) t)
	(when (string-match "^#c" word) (habuki-convert) t)
	(when (string-match "^##" word) "#")
	(when (string-match "^#s" word)
	     (let* ((from (1+ (string-match "\"" word)))
		    (to (string-match "\"" word from)))
	       (setq *habuki-cur-root-name* (substring word from to))
	       t))
	word)))

(defun habuki-help ()
  (if (not (equal *habuki-help-word* ""))
      (save-excursion
	(erase-buffer (switch-to-buffer habuki-help-buff-name))
	(insert "\n\n\n")
	(when *habuki-help-keyboard-on*
	  (habuki-help-push (habuki-help-keyboard *habuki-input*)))
	(dolist (c (coerce *habuki-help-word* 'list))
	  (habuki-help-push (habuki-help-char c))))
    (when *habuki-help-on*
      (let ((s (buffer-substring (- (point) *habuki-help-before-num*)
				 (+ (point) *habuki-help-after-num*))))
	(save-excursion
	  (erase-buffer (switch-to-buffer habuki-help-buff-name))
	  (insert "\n\n\n")
	  (when *habuki-help-keyboard-on*
	    (habuki-help-push (habuki-help-keyboard *habuki-input*)))
	  (dolist (c (coerce s 'list))
	    (habuki-help-push (habuki-help-char c)))))))
  (when (and (not *habuki-help-on*)
	     (equal *habuki-help-word* ""))
    (habuki-help-kill))
  (message *habuki-input*))

(defun habuki-help-on ()
  (setq *habuki-help-on* t)
  (habuki-help-activate)
  (habuki-help))

(defun habuki-help-off ()
  (setq *habuki-help-on* nil)
  (habuki-help-kill))

(defun habuki-help-kill ()
  (let ((buff (find-buffer habuki-help-buff-name)))
    (when buff
      (and (get-buffer-window buff)
	   (delete-window))
      (kill-buffer buff))))

(defun habuki-help-activate ()
  (with-selected-window
    (pop-to-buffer (get-buffer-create habuki-help-buff-name) -4)
    (set-buffer-fold-width nil)
    (set-local-window-flags (selected-buffer) *window-flag-half-width-space* nil)
    (set-local-window-flags (selected-buffer) *window-flag-eof* nil)
    (set-local-window-flags (selected-buffer) *window-flag-fold-mark* nil)
    (set-local-window-flags (selected-buffer) *window-flag-eof* nil)
    (set-local-window-flags (selected-buffer) *window-flag-hscroll-bar* nil)
    (set-local-window-flags (selected-buffer) *window-flag-mode-line* nil)
    (set-local-window-flags (selected-buffer) *window-flag-vscroll-bar* nil)
    (set-local-window-flags (selected-buffer) *window-flag-newline* nil)
    (make-local-variable 'need-not-save)
    (setq need-not-save t)))

(defun habuki-help-toggle ()
  (interactive)
  (if *habuki-help-on*
      (habuki-help-off)
    (habuki-help-on)))

(defun habuki-help-keyboard-toggle ()
  (interactive)
  (setq *habuki-help-keyboard-on* (not *habuki-help-keyboard-on*))
  (habuki-help))

(defun habuki-help-fundamental ()
  (setq habuki-help-figure
	(list (copy-string "|　　　‐　‖　‐　　　| |")
	      (copy-string "　‐¨¨　　　　¨¨‐　||")
	      (copy-string "┃　　　ー　　ー　　　┃ |")
	      (copy-string " ━━━　　¬　　━━━　|"))))

(setq help-appearance
      (map 'list
	   #'cons
	   (concat "abcdefghijklmnopqrstuvwxyz"
		   "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		   "1234567890 !\"#$%&'()=~|`{+"
		   "\n*}<>?_-^\\@[;:],./")
	   (concat "ａｂｃｄｅｆｇｈｉｊｋｌｍｎｏｐｑｒｓｔｕｖｗｘｙｚ"
		   "ＡＢＣＤＥＦＧＨＩＪＫＬＭＮＯＰＱＲＳＴＵＶＷＸＹＺ"
		   "１２３４５６７８９０□！”★＄％＆’（）＝〜｜‘｛＋"
		   "　＊｝＜＞？＿−＾＼＠［；：］，．／")))

(setq help-position
      (map 'list
	   #'cons
	   "23456890-^qwertyuiop@[sdfghjkl;:vbm,"
	   '((1 0) (2 0) (3 0) (4 0) (5 0)        (7 0) (8 0) (9 0) (10 0) (11 0)
	     (0 1) (1 1) (2 1) (3 1) (4 1) (5 1)  (6 1) (7 1) (8 1) (9 1) (10 1) (11 1)
	     (1 2) (2 2) (3 2) (4 2) (5 2)        (6 2) (7 2) (8 2) (9 2) (10 2)
	     (4 3) (5 3)  (7 3) (8 3))))

(defun habuki-help-replace (p c)
  (and p c
       (setf (elt (elt habuki-help-figure (second p)) (first p)) c)))

(defun habuki-help-push (str)
  (goto-char 0)
  (end-of-line)
  (dolist (s str)
    (insert s)
    (next-line)))

(defun habuki-help-char (c)
  (habuki-help-fundamental)
  (let* ((arg (gethash c *habuki-anti-rule-table*))
	 (root-name (first arg))
	 (key (second arg)))
    (habuki-help-replace '(6 0) (or (cdr (assoc c help-appearance)) c))
    (and (> (length root-name) 0)
	 (habuki-help-replace '(12 2) (elt root-name 0)))
    (or (not key)
	(when (= (length key) 1)
	  (habuki-help-replace (cdr (assoc (char key 0) help-position)) #\●))
	(when (= (length key) 2)
	  (or (when (equal (elt key 0) (elt key 1))
		(habuki-help-replace (cdr (assoc (char key 0) help-position)) #\◆))
	      (and (habuki-help-replace (cdr (assoc (char key 0) help-position)) #\●)
		   (habuki-help-replace (cdr (assoc (char key 1) help-position)) #\○))))
	(when (= (length key) 3)
	  (or (when (equal (elt key 0) (elt key 1))
		(or (and (equal (elt key 0) (elt key 2))
			 (habuki-help-replace (cdr (assoc (char key 0) help-position)) #\★))
		    (and (habuki-help-replace (cdr (assoc (char key 0) help-position)) #\◆)
			 (habuki-help-replace (cdr (assoc (char key 2) help-position)) #\△))))
	      (when (equal (elt key 0) (elt key 2))
		(habuki-help-replace (cdr (assoc (char key 0) help-position)) #\▼)
		(habuki-help-replace (cdr (assoc (char key 1) help-position)) #\○))
	      (when (equal (elt key 1) (elt key 2))
		(habuki-help-replace (cdr (assoc (char key 0) help-position)) #\●)
		(habuki-help-replace (cdr (assoc (char key 1) help-position)) #\◇))
	      (when (habuki-help-replace (cdr (assoc (char key 0) help-position)) #\●)
		(habuki-help-replace (cdr (assoc (char key 1) help-position)) #\○)
		(habuki-help-replace (cdr (assoc (char key 2) help-position)) #\△)))))
    habuki-help-figure))

(defun habuki-help-keyboard (input)
  (habuki-help-fundamental)
  (and (> (length *habuki-cur-root-name*) 0)
       (habuki-help-replace '(12 2) (elt *habuki-cur-root-name* 0)))
  (dolist (pos habuki-char)
    (let* ((word (gethash (list *habuki-cur-root-name* (concat input (string pos))) *habuki-rule-table*))
	   (c (elt word 0))
	   (display-char (or (and (null word) #\　)
			     (and (string-match "^#p" word) #\□)
			     (and (string-match "^#c" word) #\△)
			     (and (string-match "^##" word) #\＃)
			     (and (string-match "^#s" word) #\☆)
			     (cdr (assoc c help-appearance))
			     c)))
    (habuki-help-replace (cdr (assoc pos help-position)) display-char)))
  habuki-help-figure)

(defun habuki-convert ()
  (let ((s (gethash (char (buffer-substring (1- (point)) (point)) 0) *habuki-convert-table*)))
    (and s
	 (backward-char)
	 (overwrite-char s))))

(defun habuki-coerce-show ()
  (interactive)
  (setq *habuki-abbrev-output-method* #\?)
  (message "表示する"))

(defun habuki-coerce-output ()
  (interactive)
  (setq *habuki-abbrev-output-method* #\^)
  (message "出力する"))

(defun habuki-safe-input-num (&optional (start 0) (end 10))
  (let (x)
  (while (and (not (eq (peek-char *standard-input* ed:*keyboard*) #\C-g))
	      (not (and (setq x (cdr (assoc (read-char ed:*keyboard*) habuki-num)))
			(>= x start)
			(< x end)))))
    x))

(defun habuki-set-help-after-num ()
  (interactive)
  (when *habuki-help-on* (message "後の文字数？"))
  (let ((n (habuki-safe-input-num)))
    (and n
	 (setq *habuki-help-after-num* n)))
  (habuki-help))

(defun habuki-set-help-before-num ()
  (interactive)
  (when *habuki-help-on* (message "前の文字数？"))
  (let ((n (habuki-safe-input-num)))
    (and n
	 (setq *habuki-help-before-num* n)))
  (habuki-help))

(defun habuki-input-abbrev ()
  (interactive "*")
  (let ((s (cdr (assoc (cdr (assoc *last-command-char* habuki-num)) *habuki-abbrev-rule-list*))))
    (if (stringp s)
	(if (or (eq *habuki-abbrev-output-method* #\?)
		(and (eq *habuki-abbrev-output-method* nil)
		     (eq (char s 0) #\?)))
	    (habuki-show-help-word (substring s 1))
	  (habuki-output (substring s 1)))
      (message "ないよ"))
  (setq *habuki-input* "")
    (habuki-help)))

(defun habuki-show-help-word (s)
  (setq *habuki-help-word* s)
  (unless *habuki-help-on*
    (habuki-help-activate)))

(defun habuki-set-abbrev-rule ()
  (interactive)
  (let* ((n (progn (message "何文字？") (habuki-safe-input-num)))
	 (sw (let ()
	       (message "~A -> S-^:出力する S-?:表示する" n)
	       (while (and (not (eq (peek-char *standard-input* ed:*keyboard*) #\C-g))
			   (not (or (eq (peek-char *standard-input* ed:*keyboard*) #\+)
				    (eq (peek-char *standard-input* ed:*keyboard*) #\Y))))
		 (read-char ed:*keyboard*))
	       (or (and (eq (peek-char *standard-input* ed:*keyboard*) #\+) #\^)
		   (and (eq (peek-char *standard-input* ed:*keyboard*) #\Y) #\?)
		   " ")))
	 (num (progn (message "~A -> どのキー？" sw) (habuki-safe-input-num 1 8)))
	 (s (when n (concat (string sw) (buffer-substring (- (point) n) (point))))))
    (when (and n sw num)
      (push (cons num s) *habuki-abbrev-rule-list*)
      (when *habuki-abbrev-rule*
	(with-open-file (to *habuki-abbrev-rule* :direction :output
			    :if-exists :append :if-does-not-exist :create)
	  (format to "~D~A~%" num s)))
      (message "\"~A\"を~A番に登録した。" s num))))

(defun habuki-help-set-default ()
  (interactive)
  (setq *habuki-abbrev-output-method* nil)
  (setq *habuki-help-word* "")
  (setq *habuki-input* "")
  (habuki-help)
  (message "デフォルト"))

(defun habuki-forward-char ()
  (interactive)
  (forward-char)
  (setq *habuki-input* "")
  (habuki-help))

(defun habuki-next-virtual-line ()
  (interactive)
  (next-virtual-line)
  (setq *habuki-input* "")
  (habuki-help))

(defun habuki-previous-virtual-line ()
  (interactive)
  (previous-virtual-line)
  (setq *habuki-input* "")
  (habuki-help))

(defun habuki-backward-char ()
  (interactive)
  (backward-char)
  (setq *habuki-input* "")
  (habuki-help))

(defun habuki-newline ()
  (interactive)
  (newline)
  (setq *habuki-input* "")
  (habuki-help))

(defun habuki-delete-backward-char-or-selection ()
  (interactive)
  (delete-backward-char-or-selection)
  (setq *habuki-input* "")
  (habuki-help))

(defun habuki-delete-char ()
  (interactive)
  (delete-char)
  (setq *habuki-input* "")
  (habuki-help))

(defun habuki-undo ()
  (interactive)
  (undo)
  (setq *habuki-input* "")
  (habuki-help))

(defun habuki-redo ()
  (interactive)
  (redo)
  (setq *habuki-input* "")
  (habuki-help))

(defun habuki-write-fullsize-space ()
  (interactive)
  (if overwrite-mode
      (overwrite-char #\　)
    (insert "　"))
  (setq *habuki-input* "")
  (habuki-help))

(defun habuki-show-memo ()
  (interactive)
  (unless *habuki-help-on*
    (habuki-help-on))
  (save-excursion
    (erase-buffer (switch-to-buffer habuki-help-buff-name))
    (insert "\n\n\n")
    (habuki-help-push *habuki-memo*)))

(defun habuki-show-abbrev ()
  (interactive)
  (unless *habuki-help-on*
    (habuki-help-activate))
  (save-excursion
    (erase-buffer (switch-to-buffer habuki-help-buff-name))
    (insert "\n\n\n")
    (habuki-help-push (list (concat "1 " (cdr (assoc 1 *habuki-abbrev-rule-list*))
				    "  2 " (cdr (assoc 2 *habuki-abbrev-rule-list*)))
			    (concat "3 " (cdr (assoc 3 *habuki-abbrev-rule-list*))
				    "  4 " (cdr (assoc 4 *habuki-abbrev-rule-list*)))
			    (concat "5 " (cdr (assoc 5 *habuki-abbrev-rule-list*))
				    "  6 " (cdr (assoc 6 *habuki-abbrev-rule-list*)))
			    (concat "7 " (cdr (assoc 7 *habuki-abbrev-rule-list*))
				    "  ^:出力  ?:表示")))))
			    

