カーソル位置から行末までの数字を全て加算してその結果を返すelisp

Dec 21, 2008   #Emacs  #Lisp  :

やさしいEmacs‐Lisp講座』での勉強がてら作ってみました。編集系コマンドを駆使すると、できました。要は、

100 200 300 400

という行があったときに、100の「1」の部分にカーソルを合わせてこの関数を実行すると、

1000

としてくれます。

対象とする人

とりあえず簡単なLispはわかるーという人。letとかの説明はされなくても大丈夫な人。

できたコード

(defun my-calc-sum ()
(interactive)
;; tmp_point: カーソル行末のポイント
;; sum: 計算結果を格納するための変数
(let ((tmp_point (progn
(save-excursion ;; 現在のカーソル位置を記憶
(end-of-line) ;; 行末に移動
(point))))    ;; 現在のポイント位置を取得し、tmp_pointに代入
(sum ))                     ;; sumに0を代入
(save-excursion ;; 現在のカーソル位置を記憶
;; 数字がカーソル行に存在する間は以下の処理を実施
(while (re-search-forward "[0-9]+" tmp_point t)
;; 検索結果を数字として認識し、sumに加算
(setq sum (+ sum (string-to-number (buffer-substring (match-beginning ) (match-end )))))))
(kill-line)                       ;; カーソル位置から行末までを消去
(insert (number-to-string sum)))) ;;計算結果を挿入

考えたこと

  1. とりあえず正規表現を使って、数字を抜き出そう
  2. 正規表現を使った検索コマンドは範囲指定ができるから、行末のポイント位置が知りたい(→prognが必要となる理由が理解できた!)
  3. whileを使うなら、検索コマンドは見つからなかったときにnilを返してほしいな
  4. 検索結果を抜き出すイディオムがあるんだー

用いた関数

re-search-forward

re(gular)-search-forwardという意味です。そのままずばりで、「正規表現を用いた前方検索」というやつです。使い方は、

(re-search-forward "正規表現" 検索する範囲 エラー回避 回数)

となります。

  • 正規表現: 自分で勉強してください
  • 検索する範囲: Emacsでいうところのポイントで指定します。ここで指定された部分まで検索します。
  • エラー回避: 正規表現で指定したものが見つからないと、この関数はエラーを返します。それが嫌なときはここに「t」を指定します。
save-excursion

現在位置のポイントを記憶し、以降に記述する処理を実行します。save-excursionのブロックを抜けると、記憶したポイント位置に戻ります。

kill-line

カーソル位置から行末までを消去します。これは知っている人も多い?Ctrl-kにデフォルトでは割り当てられています。

やさしいEmacs‐Lisp講座

やさしいEmacs‐Lisp講座