『改訂版 やさしいEmacs-Lisp講座』

広瀬雄二・著 カットシステム 2011年7月10日初版第1刷

Emacs Lisp でも勉強しとこうと思って読んでいる。
以前読んだときは、Lispがどんなものかも知らずに読んでいたので、 なかなか難しかった。

今は、Lispも慣れたし、OCamlも勉強したので、だいぶわかるようになった。

この本には、ところどころ練習問題が載っているので、ぼくの考えた解答を 記録しておこうと思う。

今回のは、64ページにあるやつである。

問題

バッファ中に存在する「修正時刻: Thu Feb 10 22:29:42 2011」という 書式のタイムスタンプを検索し、ポイントを曜日位置に置く関数を作成せよ。 なお、日付は関数 current-time-string で得られる書式のものとする。

解答

;;; my-search-stamp.el
;;; タイムスタンプの曜日の文字列の先頭にポイントする
;;; 『改訂版 やさしいEmacs-Lisp講座』p64
;;;   広瀬雄二・著 カットシステム 2011.7.10 初版第1刷
;;; Copyright 2020 Seiichi Nukayama

(setq search-word "修正時刻")
(setq search-weekday "Sun\\|Mon\\|Tue\\|Wed\\|Thu\\|Fri\\|Sat")

;; 「修正時刻: Sun Feb 2020 ...」という言葉を探して、
;; 見つかったら、その曜日の先頭に移動する関数
;; 補助関数
;;   my-goto-top       -- バッファの先頭に移動
;;   my-search-word    -- 「修正時刻」を探す
;;   my-search-weekday -- 「Sun」などの曜日を探す
(defun my-search-stamp ()
  (interactive)
  (let ((p (my-goto-top)))
    (if (my-search-word)
        (progn
          (setq p (my-search-word))
          (if (my-search-weekday)
              t
            (message "曜日がないで")
            (goto-char p)
            nil))
      (progn
        (goto-char p)
        (message "ないで")
        nil))))

;; Sun...Sat を探す関数
;; もし見つけたら、そのワードの先頭のポイントに移動
(defun my-search-weekday ()
  (interactive)
  (if (re-search-forward search-weekday nil t)
      (goto-char (match-beginning 0))
    nil))

;; バッファの先頭に移動する関数
;; 移動する前のポイントを p に格納している
;; 移動のあとは、p の値を返す
(defun my-goto-top ()
  (interactive)
  (let (p)
    (setq p (point))
    (goto-char (point-min))
    p)
  )

;; 「修正時刻」というワードを探す関数
;; もし探したら、そのワードの先頭のポイントを返す
(defun my-search-word ()
  (interactive)
  (my-goto-top)
  (if (search-forward search-word nil t)
      (match-beginning 0)
    nil))
  

動かし方

何かテキストファイルを編集しているとする。
そのテキストファイルに、修正時刻を記述するようにしておく。

修正時刻: Sat Feb 8 09:13:20 2020

上記のスクリプト「my-search-stamp.el」をEmacsに読み込ませる。

M-x load-file <Enter>

とすると、現在のディレクトリが指定されるので、「my-search-stamp.el」を入力する。これで、このスクリプトが読み込まれ、実行可能となる。

M-x my-search-stamp <Enter>

とすると、「Sat」のところにポインタが移動する。

どのように使うか?

では、これをどのように使うかであるが、タイムスタンプを簡単に記述できるスクリプトを作っておく。

;;;====================================================
;;; タイムスタンプを挿入する
;;;
(defun my-insert-current-time ()
  (interactive)
  (insert (current-time-string)))

(define-key global-map "\C-cd" 'my-insert-current-time)

これを、「~/.emacs.d/init.el」に入れておくと、Ctrl-c d とすることで、タイムスタンプが自動的に挿入されるので、文書を作成したときは、先頭か末尾に必ず日付を入れておくようにすればよい。

あとは、今回のスクリプトを発展させて、タイムスタンプを更新するスクリプトをつくればよいだけである。

『改訂版・やさしいEmacs-Lisp講座』

広瀬雄二・著 カットシステム 2011年7月10日 初版第1刷