faceがnilのときだけsmartchr

ストリングのリストを引数にとって割り当てられたキーを連続して押すと順番に入力するコマンド関数を返す関数 - IMAKADO::BLOG
が便利そうだったので今日から導入してみました。
コメントとか、文字列の中では起動しないほうが自分は嬉しかったので、
faceがnilのときだけ起動するように、条件判定をかますようにしてみました。

;; http://d.hatena.ne.jp/IMAKADO/20080913/1221328814
;; 関数名だけsmartchrに変更させていただきました。
(eval-when-compile (require 'cl))
(defun smartchr (list-of-string)
  (lexical-let ((los list-of-string)
                (last-word "")
                (count 0))
    (lambda ()
      (interactive)
      (if (eq this-command real-last-command)
          (incf count)
        (setq count 0))
      (when (>= count (length los))
        (setq count 0))
      (let ((word (nth count los)))
        (when (eq this-command real-last-command)
          (delete-backward-char (length last-word)))
        (setq last-word word)
        (insert word)))))

(defun smartchr-if (list-of-string condition)
  (lexical-let ((f (smartchr list-of-string))
                (c condition))
    (lambda (arg)
      (interactive "p")
      (if (and (= arg 1) (funcall c))
          (funcall f)
        (self-insert-command arg)))))

(defmacro smartchr-if-face (list-of-string list-of-face)
  `(smartchr-if ,list-of-string
                (lambda ()
                  (memq (get-text-property (point) 'face)
                        ,list-of-face))))

(define-key php-mode-map (kbd "=") (smartchr-if-face '("=" " = "  " == " " === ") '(nil)))

追記 2009-05-29

  • C-u前置引数があればsmartchrは起動しないようにした。(無意識に結構使ってたみたいで不便だった)