自分用のEmacs Lispを書く

なんだか無性に、Emacs Lispを書きたくなったのでネタを探して書いてみた。

練習

まずは練習。
指定した正規表現にマッチする後が、現在開いているバッファにいくつあるか数え上げる。

  • re-search-forwardの使い方を学んだ
  • mapではなく mapcarなのね
  • 手続きを渡す場合は function を使う。

などなど。

(defun hige-count-reg(reg)
  (defun count-reg()
    (save-excursion
      (progn
        (goto-char (point-min))
        (let ((count 0))
          (while (re-search-forward reg nil t)
            (setq count (+ count 1)))
          count))))
  (interactive)
  (let ((count 0) (buffers (buffer-list)))
    (save-current-buffer
      (apply (function +)
             (mapcar (lambda (b)
                       (set-buffer b)
                       (count-reg)) buffers)))))

すべてのバッファから任意の文字列を消したい

たまに printf-debugをするのですが、以下のように簡単に printf を挿入できるようしてあります。

(defun my-insert-printf-debug ()
  (interactive)
  (insert-string "printf(\"%s %s:%d\\n\", __func__, __FILE__, __LINE__);fflush(stdout);// debug")
  (indent-according-to-mode)
)

(add-hook 'c++-mode-hook
  (function (lambda ()
              (define-key c++-mode-map (kbd "C-c d") 'my-insert-printf-debug)
)))


これはとても便利で使いまくりなのですが、デバッグが終わってから消すのが面倒です。
なのでこいつらをまとめて消してくれるLisp を書いてみるテスト。

(defun hige-delete-reg-buffers(reg)
  (defun delete-reg()
    (save-excursion
      (progn
        (goto-char (point-min))
        (while (re-search-forward reg nil t)
            (delete-region (match-beginning 0) (match-end 0))))))
  (interactive)
  (let ((target-buffers (buffer-list)))
    (save-current-buffer
      (mapcar (lambda (b)
                (set-buffer b)
                (delete-reg)) target-buffers))))

(defun hige-delete-debug-printf()
  (interactive)
  (hige-delete-reg-buffers "printf(\"%s %s:%d.*\\\\n\", __func__, __FILE__, __LINE__[^)]*);fflush(stdout);// debug")
  (indent-according-to-mode)
)


ここで使うべきは、mapcarじゃなくて while のような気がするけどどうだろうか。
突っ込み募集。


SICPSchemeを書いているせいか、Emacs Lispが全然苦痛じゃない。
むしろ楽しい。Perlより(ry