【问题标题】:Elisp: is this an expected behavior of save-excursion?Elisp:这是保存游览的预期行为吗?
【发布时间】:2014-01-03 03:29:52
【问题描述】:

起始条件是*scratch*中的这段文字:

(
form
30
)

(
   baz
  41
)

空格是这里唯一重要的东西。 现在,在form 中的o 上,使用 M-:(eval-expression) 进行评估 这段代码:

(save-excursion
  (up-list)
  (backward-list)
  (indent-sexp))

给予

(
 form
 30
 )

点在or,m,0,a,z,1 上的点重复相同(预期的)行为。

但是对于f3b4 上的起点,结果点是前一个字符 预期的位置。

这是预期的行为还是错误? 如果符合预期,我想了解更多有关规则和极端情况的信息。

UPD:添加直观的保存游览变体

以防万一有人想要它, 这是对我来说更直观的行为(即在f3 等上保存点):

(defmacro save-excursion-ex (&rest body)
  "More intuitive (`save-excursion' BODY)."
  `(let ((ext (save-match-data
                (looking-back "^\\s-*")))
         (out (save-excursion
                ,@body)))
     (if ext
         (if (or (bolp)
                 (= (point)
                    (save-excursion
                      (back-to-indentation)
                      (point))))
             (back-to-indentation)
           (error "Unexpected")))
     out)) 

【问题讨论】:

  • 这是在emacs -Q 会话中吗?

标签: emacs elisp


【解决方案1】:

在 Emacs 中,该点被认为是“之前”(point)。 因此,当indent-sexp 插入空格时,它会在 点之后插入空格。 例如,当您说该点位于 f 上时,它实际上位于行首 f 之前,indent-sexpafterbefore 插入空格> f.

一般规则是,如果点在行首和行中第一个非空白字符之间,它将在行首结束,否则将保留其相对于周围文本的位置。

这样想:我们将代码缩进

  1. 删除所有前导空格
  2. 根据需要插入前导空格

所以,答案是:这是预期的行为。

对于您的问题的暗示要点,没有理由依赖缩进后点的特定位置如果该点与已标准化的空白相邻。 如果您需要让代码正常工作,请在缩进调用后添加(goto-char (line-beginning-position))(或等效项),然后跳到您要操作的位置。

【讨论】:

  • 我认为不变式是该点保留在它之前所在的字符上。这很直观。现在我看不到不变量。
  • @abo-abo:没有“关于角色”之类的东西。重点是个字符之间。
  • 很好,但请尝试在 baz 中使用 b。最初的点在 ` ` 和 b 之间。最后一点在^和``之间。
  • 空白已标准化。任何点位置在逻辑上都是有效的。
  • 抱歉,我没听懂。但是考虑一下:将初始点 o 更改为 r(即按 1)会导致最终点更改 1。与 r 相同,再次将 m 更改为 1。但将 o 更改为 f结果为 -2。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-09
相关资源
最近更新 更多