Ink

Contents related to tech, hobby, etc

elispのpointは自動的に調整されている?

|
(version)
GNU Emacs 29.4 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.42, cairo version 1.18.0)

手元で色々試していた所、pointが行の終点(eolp)に到達した際、そのプロ グラムが走り終わるとその手前に移動されるらしい?です。

有識者の方、何かご存知であればtwittergithub issuecjbcsd@misskey.resonite.lovecj-bc-sd.bsky.social等で教えていただけ ると嬉しいです。emacs-jp(@Cj.bcsd)とvim-jp(@Cj.BCSD)にもいます。

ひとまずの検証

簡単な検 証の経緯をメモしておきます。

発端: evil-up-parenの定義より疑問を持つ

evil-up-paren の定義を読んでいた時、以下の挙動が目につきました。

(cond
 ((> dir 0)
  (while (progn
           (up-list dir t)
           (/= (char-before) close))))
 (t
  (while (progn
           (up-list dir t)
           (/= (char-after) open)))))

このうち、1つ目のwhileループについて疑問を感じました。 (up-list &optional ARG ESCAPE-STRINGS NO-SYNTAX-CROSSING) は、手元で試した所括 弧を1段階登り閉じ括弧の後に point を置きます。しかし、閉じ括弧の後ろ に文字がない場合は閉じ括弧の手前に置くようでした。

(foo ba!r baz)

pointが ! のある場所にある時、 (up-list) すると以下まで移動します。

(foo bar baz!)

ここでの (char-before)z です。何度やっても同じです。

そのため、whileループの条件となる (/= (char-before) close) は永遠に t を返してしまい終了しないのではないか?と思い以下のようにして試し てみると、 nil を返しました。

(progn
  (up-list 1 t)
  (/= (char-before) ?\)))

これはどうしてなのでしょうか?

(progn (up-list) (point))と (up-list) (point) で動作が異なる?

条件を取り出して捏ねていた所、どうやら (char-before) する前の point の値が異なっているということが分かりました。そこで、 up-list の実行周りを調べてみます。

current-buffer は以下の内容とします。( with-temp-buffer を使ってし まうと再現しないので eval-expression で実行しています。)

(foo bar baz) 

以下を順番に実行した所、 13 を返しました。

(goto-char 8)
(up-list)
(point)
;; => 13

それに対し、以下は 14 を返しました。

(progn
  (goto-char 8)
  (up-list)
  (point))
;; => 14

そして、以下は 13 を返します。

(progn
  (goto-char 8)
  (up-list))
(point)
;; => 14

3つ目の挙動(progn の外側の point は同様に13になっている)があること から、 「 (up-list) ではいつも14まで移動しているが、 progn が終了 した後に何らかの処理が行なわれているのではないか」という推測をしました。

そこで、より一般化してみます。

sexp評価後にpointが調整される?

(up-list) 固有ではなさそうであったことから、最もプリミティブなpoint 操作として (goto-char) を用いて検証をします。

先程と同じBufferのまま進めます。

(goto-char 14) ;; = (point-max)
(point)

これは13になります。

(progn
  (goto-char 14) ;; = (point-max)
  (point))

これは14になります。

(progn
  (progn
    (goto-char 2))
  (point))

追加で、これも14になります。

このことから、 progn 固有の何かではなく式が全て評価された後にpointが 調整されているのではないかなと考えます。