EmacsでLispを覚える

Emacsを覚えると悟りが開けるんじゃないかと思っている一番の理由が、EmacsにLispが組み込まれているという点です。私はLispを知らないわけではないのですが、自由にプログラミングできるかと言えば、まったくできない、と言ってもいいレベルです。
英語が話せるようになりたいけど、英語の勉強をしない人の理屈と同じで、Lispで自由にプログラミングしたいけど、Lispでプログラミングする必要性を感じない、ってのがLispをものにできない原因だと思います。
Lispが使えない自分を克服するため、Emacsを普段使いのテキストエディタにしてしまい、無理やりLispと触れ合う環境を作っていこうと思います。今日からLispは友達です。

では、テキスト整形するコマンドを探します。テキストを反転する(tac)のようなコマンドがあると思いますので、当てずっぽうですが、reverseで検索しましょう。C-a reverse(Ctrl + a、reverse入力してEnter)。

reverseでいろいろ見つかりました。reverseそのものはありませんでしたが、reverse-regionってのがありますね。説明を読むと、まさに探していたtacみたいなもののようです。

reverse-regionをマウスでクリック。sort.elというファイルにあるようです。

まずは使ってみましょう。適当に1~6を並べました。

適当に複数行を選択して、M-x reverse-region (Alt + x、reverse-regionでEnter)

選択部分が上限反転されました。しかも、別ウィンドウに出力されるでもなく、選択部分がフィルタリングされた形です。これです。求めていたものです。

さきほどsort.elにあることは分かりましたので、ソースを見てみます。sort.elにあるreverse-regionでgrepします。

takk@deb9:~/tmp$ zcat /usr/share/emacs/24.5/lisp/sort.el.gz | grep reverse-region -A30
(defun reverse-region (beg end)
  "Reverse the order of lines in a region.
From a program takes two point or marker arguments, BEG and END."
  (interactive "r")
  (if (> beg end)
      (let (mid) (setq mid end end beg beg mid)))
  (save-excursion
    ;; put beg at the start of a line and end and the end of one --
    ;; the largest possible region which fits this criteria
    (goto-char beg)
    (or (bolp) (forward-line 1))
    (setq beg (point))
    (goto-char end)
    ;; the test for bolp is for those times when end is on an empty line;
    ;; it is probably not the case that the line should be included in the
    ;; reversal; it isn't difficult to add it afterward.
    (or (and (eolp) (not (bolp))) (progn (forward-line -1) (end-of-line)))
    (setq end (point-marker))
    ;; the real work.  this thing cranks through memory on large regions.
    (let (ll (do t))
      (while do
	(goto-char beg)
	(setq ll (cons (buffer-substring (point) (progn (end-of-line) (point)))
		       ll))
	(setq do (/= (point) end))
	(delete-region beg (if do (1+ (point)) (point))))
      (while (cdr ll)
	(insert (car ll) "\n")
	(setq ll (cdr ll)))
      (insert (car ll)))))

takk@deb9:~/tmp$ 

とりあえず、このソースについて理解していこうと思います。

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA