1 Star 0 Fork 3

rookieagle/Elisp

forked from advanceflow/Elisp 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
31-位置.org 34.00 KB
一键复制 编辑 原始数据 按行查看 历史
advanceflow 提交于 2022-05-28 10:12 . finish s2

31 位置

位置是缓冲区文本中字符的索引。 更准确地说,位置标识了两个字符之间的位置(或在第一个字符之前,或在最后一个字符之后),因此我们可以说在给定位置之前或之后的字符。 但是,我们经常说“在”一个位置的字符,意思是那个位置之后的字符。

位置通常表示为从 1 开始的整数,但也可以表示为标记 - 插入或删除文本时自动重新定位的特殊对象,以便它们与周围的字符保持一致。 期望参数是位置(整数)但接受标记作为替代的函数,通常忽略标记指向的缓冲区; 他们将标记转换为整数,并使用该整数,就像您将整数作为参数传递一样,即使标记指向错误的缓冲区。 无处指向的标记无法转换为整数; 使用它而不是整数会导致错误。 请参阅标记。

另请参阅字段功能(请参阅定义和使用字段),它提供了许多光标移动命令使用的功能。

31.1 点

点是许多编辑命令使用的特殊缓冲区位置,包括自插入键入的字符和文本插入功能。 其他命令在文本中移动点以允许在不同位置进行编辑和插入。

与其他位置一样,点表示两个字符之间的位置(或在第一个字符之前,或在最后一个字符之后),而不是特定字符。 通常终端将光标显示在紧跟在点后面的字符上; 点实际上在光标所在的字符之前。

point 的值是一个不小于 1 且不大于缓冲区大小加 1 的数字。如果变窄有效(请参阅 Narrowing),则点被限制在缓冲区的可访问部分内(可能在一端其中)。

每个缓冲区都有自己的点值,与其他缓冲区中的点值无关。 每个窗口也有一个point的值,它与同一缓冲区上其他窗口中的point值无关。 这就是为什么点在显示相同缓冲区的不同窗口中可以具有不同值的原因。 当一个缓冲区只出现在一个窗口中时,缓冲区的点和窗口的点通常具有相同的值,因此区别很少重要。 有关更多详细信息,请参阅 Windows 和 Point。

Function: point ¶

此函数以整数形式返回当前缓冲区中点的值。

  (point)
	   ⇒ 175
Function: point-min ¶

此函数返回当前缓冲区中点的最小可访问值。 这通常是 1,但如果收窄生效,它是您收窄到的区域的开始位置。 (见收窄。)

Function: point-max ¶

此函数返回当前缓冲区中点的最大可访问值。 这是 (1+ (buffer-size)),除非变窄生效,在这种情况下,它是您变窄到的区域末端的位置。 (见收窄。)

Function: buffer-end flag ¶

如果 flag 大于 0,此函数返回 (point-max),否则返回 (point-min)。 参数标志必须是一个数字。

Function: buffer-size &optional buffer ¶

此函数返回当前缓冲区中的字符总数。 在没有任何缩小的情况下(请参阅缩小),point-max 返回一个比这大一的值。

如果你指定一个缓冲区,buffer,那么这个值就是缓冲区的大小。

  (buffer-size)
	   ⇒ 35

  (point-max)
	   ⇒ 36

31.2 运动

运动功能改变点的值,或者相​​对于点的当前值,相对于缓冲区的开始或结束,或者相对于选定窗口的边缘。 见点。

31.2.1 角色动作

这些函数根据字符数移动点。 goto-char 是基本原语; 其他功能使用它。

Command: goto-char position ¶

此函数将当前缓冲区中的点设置为值位置。

如果窄化生效,位置仍然从缓冲区的开头开始计数,但点不能超出可访问部分。 如果位置超出范围,则 goto-char 将点移动到可访问部分的开头或结尾。

当以交互方式调用此函数时,位置是数字前缀参数(如果提供); 否则从 minibuffer 中读取。

goto-char 返回位置。

Command: forward-char &optional count ¶

此函数将点计数字符向前移动,朝向缓冲区的末尾(或向后,朝向缓冲区的开头,如果 count 为负数)。 如果 count 为 nil,则默认为 1。

如果这试图越过缓冲区的开始或结束(或可访问部分的限制,当缩小生效时),它会用错误符号缓冲区开始或缓冲区结束发出错误信号。

在交互式调用中,count 是数字前缀参数。

Command: backward-char &optional count ¶

这就像 forward-char 一样,只是它朝相反的方向移动。

31.2.2 词动

下面描述的解析单词的函数使用语法表和 char-script-table 来确定给定字符是否是单词的一部分。 请参阅语法表和字符属性。

Command: forward-word &optional count ¶

此函数将点向前移动 count 个字(如果 count 为负数则向后移动)。 如果 count 被省略或为零,则默认为 1。在交互式调用中,count 由数字前缀参数指定。

“移动一个单词”是指移动直到点与一个单词组成字符交叉,该字符表示单词的开头,然后继续移动直到单词结束。 默认情况下,开始和结束单词的字符,称为单词边界,由当前缓冲区的语法表定义(参见语法类表),但模式可以通过设置合适的 find-word-boundary-function-table 来覆盖它, 如下面所描述的。 属于不同脚本的字符(由 char-script-table 定义)也定义了单词边界(请参阅字符属性)。 在任何情况下,此函数都不能将点移动到缓冲区可访问部分的边界之外,或者跨越字段边界(请参阅定义和使用字段)。 字段边界最常见的情况是小缓冲区中提示的结尾。

如果可以移动 count 个字,而不会被缓冲区边界或字段边界提前停止,则值为 t。 否则,返回值为 nil 并且点在缓冲区边界或字段边界处停止。

如果 inhibitor-field-text-motion 不为零,则此函数将忽略字段边界。

Command: backward-word &optional count ¶

这个函数就像 forward-word 一样,只是它向后移动直到遇到一个单词的前面,而不是向前。

User Option: words-include-escapes ¶

这个变量影响前向词和后向词的行为,以及所有使用它们的东西。 如果它不为 nil,则转义和字符引用语法类中的字符算作单词的一部分。 否则,他们不会。

Variable: inhibit-field-text-motion ¶

如果此变量非零,则某些运动函数(包括 forward-word、forward-sentence 和 forward-paragraph)会忽略字段边界。

Variable: find-word-boundary-function-table ¶

这个变量影响前向词和后向词的行为,以及所有使用它们的东西。 它的值是用于搜索单词边界的函数的字符表(请参阅字符表)。 如果一个字符在此表中有一个非零条目,那么当一个单词以该字符开头或结尾时,将使用 2 个参数调用相应的函数:pos 和 limit。 该函数应返回另一个单词边界的位置。 具体来说,如果 pos 小于 limit,则 pos 位于单词的开头,函数应该返回单词最后一个字符之后的位置; 否则, pos 位于单词的最后一个字符,并且该函数应返回该单词的第一个字符的位置。

Function: forward-word-strictly &optional count ¶

此功能类似于 forward-word,但不受 find-word-boundary-function-table 的影响。 当设置该表的模式(例如 subword-mode)修改单词移动时,不应改变行为的 Lisp 程序应该使用此函数而不是 forward-word。

Function: backward-word-strictly &optional count ¶

这个函数类似于backward-word,但不受find-word-boundary-function-table的影响。 与 forward-word-strictly 一样,当单词移动只考虑语法表时,使用此函数而不是 back-word。

31.2.3 移动到缓冲区末端

要将点移动到缓冲区的开头,请编写:

(goto-char (point-min))

同样,要移动到缓冲区的末尾,请使用:

(goto-char (point-max))

以下是用户用来执行这些操作的两个命令。 此处记录它们是为了警告您不要在 Lisp 程序中使用它们,因为它们会在回显区域设置标记并显示消息。

Command: beginning-of-buffer &optional n ¶

此函数将点移动到缓冲区的开头(或可访问部分的限制,当窄化生效时),将标记设置在前一个位置(除了在瞬态标记模式下,如果标记已经激活,则不会设置标记。)

如果 n 不为零,则它将点放在距缓冲区可访问部分开头的十分之一处。 在交互式调用中,n 是数字前缀参数(如果提供); 否则 n 默认为 nil。

警告:不要在 Lisp 程序中使用这个函数!

Command: end-of-buffer &optional n ¶

此功能将点移动到缓冲区的末尾(或可访问部分的限制,当缩小生效时),将标记设置在前一个位置(除了在标记已经激活的瞬态标记模式下)。 如果 n 不为零,则它将点放在距缓冲区可访问部分末尾十分之一处。

在交互式调用中,n 是数字前缀参数(如果提供); 否则 n 默认为 nil。

警告:不要在 Lisp 程序中使用这个函数!

31.2.4 文本行的运动

文本行是由换行符分隔的缓冲区部分,被视为前一行的一部分。 第一个文本行从缓冲区的开头开始,最后一个文本行在缓冲区的末尾结束,无论最后一个字符是否为换行符。 将缓冲区划分为文本行不受窗口宽度、显示中的行连续性或制表符和控制字符的显示方式的影响。

Command: beginning-of-line &optional count ¶

此函数将点移动到当前行的开头。 如果参数 count 不是 nil 或 1,它会向前移动 count-1 行,然后到行首。

此函数不会将点移动到字段边界(请参阅定义和使用字段),除非这样做会越过那里移动到另一条线; 因此,如果 count 为 nil 或 1,并且 point 从场边界开始,则 point 不会移动。 要忽略字段边界,要么将禁止字段文本运动绑定到 t,要么使用前向线函数。 例如,(forward-line 0) 与 (beginning-of-line) 做同样的事情,只是它忽略了字段边界。

如果此函数到达缓冲区的末尾(或可访问部分的末尾,如果变窄有效),它将指向那里。 没有错误信号。

Function: line-beginning-position &optional count ¶

返回(行首计数)将移动到的位置。

Command: end-of-line &optional count ¶

此函数将点移动到当前行的末尾。 如果参数 count 不是 nil 或 1,它会向前移动 count-1 行,然后到行尾。

此函数不会将点移动到字段边界(请参阅定义和使用字段),除非这样做会越过那里移动到另一条线; 因此,如果 count 为 nil 或 1,并且 point 从场边界开始,则 point 不会移动。 要忽略字段边界,请将 inhibitor-field-text-motion 绑定到 t。

如果此函数到达缓冲区的末尾(或可访问部分的末尾,如果变窄有效),它将指向那里。 没有错误信号。

Function: line-end-position &optional count ¶

返回(行尾计数)将移动到的位置。

Command: forward-line &optional count ¶

此函数将点向前移动计数行,到其后行的开头。 如果 count 是负数,它会向后移动 point -count 行,到前一行的开头。 如果 count 为零,它将指向当前行的开头。 如果 count 为 nil,则表示 1。

如果 forward-line 在找到那么多行之前遇到缓冲区(或可访问部分)的开头或结尾,它将指向那里。 没有错误信号。

forward-line 返回计数与实际移动的行数之间的差值。 如果您尝试从只有三行的缓冲区的开头向下移动五行,则指向在最后一行的末尾停止,该值将为 2。作为一个明确的例外,如果最后一个可访问的行是非空,但没有换行符(例如,如果缓冲区结束时没有换行符),函数将指向该行的末尾,并且函数返回的值将该行计数为成功移动的一行。

在交互式调用中,count 是数字前缀参数。

Function: count-lines start end &optional ignore-invisible-lines ¶

此函数返回当前缓冲区中位置 start 和 end 之间的行数。 如果 start 和 end 相等,则返回 0。否则它至少返回 1,即使 start 和 end 在同一行。 这是因为它们之间的文本,单独考虑,必须至少包含一行,除非它是空的。

如果可选的 ignore-invisible-lines 不为零,则不可见行将不包括在计数中。

Command: count-words start end ¶

此函数返回当前缓冲区中位置 start 和 end 之间的字数。

该函数也可以交互调用。 在这种情况下,它会打印一条消息,报告缓冲区中的行数、单词数和字符数,或者如果该区域处于活动状态,则该区域中的字符数。

Function: line-number-at-pos &optional pos absolute ¶

该函数返回当前缓冲区中与缓冲区位置 pos 对应的行号。 如果 pos 为 nil 或省略,则使用当前缓冲区位置。 如果 absolute 为 nil,则默认计数从 (point-min) 开始,因此该值指的是(可能缩小的)缓冲区的可访问部分的内容。 如果 absolute 不为零,则忽略任何缩小并返回绝对行号。

另请参阅检查文本近点中的函数 bolp 和 eolp。 这些函数不会移动点,而是测试它是否已经在一行的开头或结尾。

31.2.5 屏幕线运动

上一节中的行函数计算文本行数,仅由换行符分隔。 相比之下,这些函数计算屏幕行数,这是由文本在屏幕上出现的方式定义的。 如果文本行足够短以适合所选窗口的宽度,则它是单个屏幕行,否则它可能会占用多个屏幕行。

在某些情况下,屏幕上的文本行会被截断,而不是继续到其他屏幕行上。 在这些情况下,垂直运动的移动点很像向前线。 请参阅截断。

因为给定字符串的宽度取决于控制某些字符外观的标志,所以对于给定的文本,垂直运动的行为不同,取决于它所在的缓冲区,甚至取决于选定的窗口(因为宽度,截断标志和显示表可能因窗口而异)。 请参阅通常的显示约定。

这些函数扫描文本以确定屏幕线在哪里中断,因此所花费的时间与扫描的距离成正比。

Function: vertical-motion count &optional window cur-col ¶

此函数将点从包含点的屏幕行向下移动到屏幕行计数屏幕行的开头。 如果计数是负数,它会向上移动。

count 参数可以是一个 cons 单元格(cols .lines),而不是一个整数。 然后该函数逐行移动屏幕行,并从该屏幕行的视觉开始放置点 cols 列。 请注意,cols 是从行的视觉开始计算的; 如果窗口水平滚动(请参阅水平滚动),则该点将结束的列是文本滚动的列数之外的。

返回值是移动点的屏幕行数。 如果到达缓冲区的开头或结尾,则该值的绝对值可能小于 count。

窗口窗口用于获取宽度、水平滚动、显示表格等参数。 但是垂直运动总是在当前缓冲区上运行,即使窗口当前显示其他缓冲区。

可选参数 cur-col 指定调用函数时的当前列。 这是点的窗口相对水平坐标,以框架默认面的字体宽度为单位测量。 提供它可以加速函数,尤其是在很长的行中,因为函数不必返回缓冲区来确定当前列。 请注意,cur-col 也是从行的视觉开始计算的。

Function: count-screen-lines &optional beg end count-final-newline window ¶

此函数返回文本中从 beg 到 end 的屏幕行数。 由于行延续、显示表等原因,屏幕行数可能与实际行数不同。如果 beg 和 end 为 nil 或省略,则默认为缓冲区可访问部分的开头和结尾。

如果该区域以换行符结尾,则将被忽略,除非可选的第三个参数 count-final-newline 为非零。

可选的第四个参数window指定获取宽度、水平滚动等参数的窗口。 默认是使用选定窗口的参数。

与垂直运动一样,count-screen-lines 始终使用当前缓冲区,而不管窗口中显示的是哪个缓冲区。 这使得在任何缓冲区中使用 count-screen-lines 成为可能,无论它当前是否显示在某个窗口中。

Command: move-to-window-line count ¶

此函数相对于当前显示在选定窗口中的文本移动点。 它从窗口顶部移动点到屏幕行数屏幕行的开头; 零表示最上面的行。 如果 count 为负数,则指定位置 - 从底部开始计数行(或缓冲区的最后一行,如果缓冲区在指定屏幕位置上方结束); 因此,count of -1 指定窗口的最后一个完全可见的屏幕行。

如果 count 为 nil,则 point 移动到窗口中间的行首。 如果 count 的绝对值大于窗口的大小,那么如果窗口足够高,点就会移动到屏幕行上出现的位置。 这可能会导致下一次重新显示滚动以将该位置带到屏幕上。

在交互式调用中,count 是数字前缀参数。

返回的值是相对于窗口顶行的屏幕行号点已移动到的位置。

Function: move-to-window-group-line count ¶

此功能类似于 move-to-window-line,只是当所选窗口是一组窗口的一部分时(请参阅窗口组),move-to-window-group-line 将移动到相对于整个组,而不仅仅是单个窗口。 当缓冲区局部变量 move-to-window-group-line-function 设置为函数时,此条件成立。 在这种情况下,move-to-window-group-line 使用参数 count 调用函数,然后返回其结果。

Function: compute-motion from frompos to topos width offsets window ¶

此函数扫描当前缓冲区,计算屏幕位置。 它从位置 from 向前扫描缓冲区,假设在屏幕坐标 frompos 处,到 position to 或坐标 topos,以先到者为准。 它返回结束缓冲区位置和屏幕坐标。

来自pos 和 topos 的坐标参数是 (hpos . vpos) 形式的 cons 单元。

参数宽度是可用于显示文本的列数; 这会影响对续行的处理。 nil 表示窗口中实际可用的文本列数,相当于 (window-width window) 返回的值。

参数 offsets 是 nil 或形式为 (hscroll . tab-offset) 的 cons 单元格。 这里 hscroll 是不在左边距显示的列数; 大多数调用者通过调用 window-hscroll 来获得这个。 同时,tab-offset 是屏幕上的列号和缓冲区中的列号之间的偏移量。 当前面的屏幕行的宽度加起来不是制表符宽度的倍数时,这在续行中可以是非零的。 在非连续行中它始终为零。

窗口窗口仅用于指定要使用的显示表。 无论窗口中显示什么缓冲区,计算运动始终在当前缓冲区上运行。

返回值是五个元素的列表:

(pos hpos vpos prevhpos contin)

这里pos是扫描停止的缓冲位置,vpos是竖屏位置,hpos是横屏位置。

结果 prevhpos 是从 pos 向后一个字符的水平位置。 如果最后一行在前一个字符之后(或之内)继续,则结果 contin 为 t。

例如,要查找某个窗口的屏幕行行列col的缓冲位置,将窗口的显示起始位置作为from,窗口的左上角坐标作为frompos。 将缓冲区的 (point-max) 传递给 to,以将扫描限制在缓冲区可访问部分的末尾,并将 line 和 col 作为 topos 传递。 这是一个执行此操作的函数:

     (defun coordinates-of-position (col line)
	(car (compute-motion (window-start)
			     '(0 . 0)
			     (point-max)
			     (cons col line)
			     (window-width)
			     (cons (window-hscroll) 0)
			     (selected-window))))

当您对 minibuffer 使用 compute-motion 时,您需要使用 minibuffer-prompt-width 来获取屏幕第一行开头的水平位置。 请参阅 Minibuffer 内容。

31.2.6 移动平衡表达式

这里有几个与平衡括号表达式相关的函数(在 Emacs 中也称为与在它们之间移动相关的 sexps)。 语法表控制这些函数如何解释各种字符; 请参阅语法表。 有关用于扫描 sexps 或部分 sexps 的较低级别原语,请参阅解析表达式。 有关用户级命令,请参阅 The GNU Emacs Manual 中的带括号编辑命令。

Command: forward-list &optional arg ¶

此函数在 arg(默认为 1)平衡的括号组中向前移动。 (其他句法实体,如单词或成对的字符串引号将被忽略。)

Command: backward-list &optional arg ¶

此函数在 arg(默认为 1)平衡的括号组中向后移动。 (其他句法实体,如单词或成对的字符串引号将被忽略。)

Command: up-list &optional arg escape-strings no-syntax-crossing ¶

此函数向前移出 arg(默认 1)级别的括号。 一个否定的论点意味着向后移动,但仍然到一个不那么深的地方。 如果 escape-strings 不是 nil (因为它是交互式的),也请移出封闭的字符串。 如果 no-syntax-crossing 是非 nil (因为它是交互式的),则宁愿跳出任何封闭的字符串,而不是移动到跨越多个字符串的列表的开头。 出错时,未指定点的位置。

Command: backward-up-list &optional arg escape-strings no-syntax-crossing ¶

这个函数就像 up-list 一样,但是有一个否定的参数。

Command: down-list &optional arg ¶

此函数向前移动到 arg(默认为 1)级别的括号。 否定论点意味着向后移动,但在括号中仍然更深(-arg 级别)。

Command: forward-sexp &optional arg ¶

此函数在 arg(默认为 1)平衡表达式中向前移动。 平衡表达式既包括由括号分隔的表达式,也包括其他类型的表达式,例如单词和字符串常量。 请参阅解析表达式。 例如,



  ---------- Buffer: foo ----------
  (concat∗ "foo " (car x) y z)
  ---------- Buffer: foo ----------


  (forward-sexp 3)
	   ⇒ nil

  ---------- Buffer: foo ----------
  (concat "foo " (car x) y∗ z)
  ---------- Buffer: foo ----------
Command: backward-sexp &optional arg ¶

此函数在 arg(默认为 1)平衡表达式中向后移动。

Command: beginning-of-defun &optional arg ¶

该函数返回到 defun 的 argth 开头。 如果 arg 是负数,这实际上向前移动,但它仍然移动到 defun 的开头,而不是结尾。 arg 默认为 1。

Command: end-of-defun &optional arg ¶

此函数向前移动到 defun 的第 argth 端。 如果 arg 是负数,这实际上是向后移动,但它仍然移动到 defun 的末尾,而不是一个的开头。 arg 默认为 1。

User Option: defun-prompt-regexp ¶

如果非零,则此缓冲区局部变量包含一个正则表达式,该表达式指定哪些文本可以出现在开始一个 defun 的左括号之前。 也就是说,defun 开始于以匹配此正则表达式的行开头,后跟具有开括号语法的字符。

User Option: open-paren-in-column-0-is-defun-start ¶

如果此变量的值非零,则第 0 列中的左括号被认为是 defun 的开始。 如果为 nil,则第 0 列中的左括号没有特殊含义。 默认值为 t。 如果字符串文字恰好在第 0 列中有括号,请使用反斜杠对其进行转义以避免误报。

Variable: beginning-of-defun-function ¶

如果非零,则此变量包含一个用于查找 defun 开头的函数。 函数开始的defun 调用这个函数而不是使用它的普通方法,传递它的可选参数。 如果参数不是 nil,则函数应该向后移动那么多函数,就像开始的 defun 一样。

Variable: end-of-defun-function ¶

如果非 nil,则此变量包含一个用于查找 defun 结尾的函数。 函数 end-of-defun 调用这个函数而不是使用它的正常方法。

31.2.7 跳过字符

以下两个函数将点移动到指定的字符集上。 例如,它们通常用于跳过空格。 有关相关功能,请参阅 Motion 和 Syntax。

如果缓冲区是多字节的,这些函数将设置的字符串转换为多字节,如果缓冲区是单字节的,它们会将其转换为单字节,就像搜索函数一样(请参阅搜索和匹配)。

Function: skip-chars-forward character-set &optional limit ¶

此函数向前移动当前缓冲区中的点,跳过给定的字符集。 它检查点后面的字符,如果字符匹配字符集,则前进点。 这一直持续到它到达一个不匹配的字符。 该函数返回移动的字符数。

参数字符集是一个字符串,就像正则表达式中的 ‘[…]’ 的内部,除了 ‘]’ 不会终止它,并且 ‘' 引用 ‘^’、’-’ 或 ‘'。 因此,“a-zA-Z”跳过所有字母,在第一个非字母之前停止,而“^a-zA-Z”跳过在第一个字母之前停止的非字母(参见正则表达式)。 也可以使用字符类,例如“[:alnum:]”(参见字符类)。

如果提供了限制(它必须是数字或标记),则它指定缓冲区中可以跳过该点的最大位置。 点将在限制处或之前停止。

在以下示例中,点最初直接位于“T”之前。 评估表单后,point 位于该行的末尾(在 ‘hat’ 的 ‘t’ 和换行符之间)。 该函数跳过所有字母和空格,但不跳过换行符。



  ---------- Buffer: foo ----------
  I read "∗The cat in the hat
  comes back" twice.
  ---------- Buffer: foo ----------


  (skip-chars-forward "a-zA-Z ")
	   ⇒ 18

  ---------- Buffer: foo ----------
  I read "The cat in the hat∗
  comes back" twice.
  ---------- Buffer: foo ----------
Function: skip-chars-backward character-set &optional limit ¶

此函数向后移动点,跳过匹配字符集的字符,直到限制。 除了运动方向之外,它就像向前跳过字符。

返回值表示行进的距离。 它是一个小于或等于 0 的整数。

31.3 远足

在程序的局部区域内临时移动点通常很有用。 这称为游览,它是通过保存游览特殊形式完成的。 此构造记住当前缓冲区的初始标识及其点值,并在偏移完成后恢复它们。 这是在程序的一部分内移动点并避免影响程序其余部分的标准方法,并且在 Emacs 的 Lisp 源代码中使用了数千次。

如果您只需要保存和恢复当前缓冲区的标识,请改用 save-current-buffer 或 with-current-buffer(请参阅当前缓冲区)。 如果您需要保存或恢复窗口配置,请参阅窗口配置和框架配置中描述的表格。

Special Form: save-excursion body… ¶

这种特殊的形式保存了当前缓冲区的标识和其中的点值,评估主体,最后恢复缓冲区及其保存的点值。 即使通过 throw 或 error 异常退出,两个保存的值也会恢复(请参阅非本地退出)。

save-excursion 返回的值是 body 中最后一个形式的结果,如果没有给出 body 形式,则返回 nil。

因为 save-excursion 仅保存在偏移开始时当前的缓冲区的点,所以在偏移期间对指向其他缓冲区所做的任何更改都将在之后保持有效。 这经常会导致意想不到的后果,因此如果您在偏移期间调用 set-buffer,字节编译器会发出警告:

Warning: Use ‘with-current-buffer’ rather than
	   save-excursion+set-buffer

为避免此类问题,您应仅在设置所需的当前缓冲区后调用 save-excursion,如下例所示:

 (defun append-string-to-buffer (string buffer)
   "Append STRING to the end of BUFFER."
   (with-current-buffer buffer
     (save-excursion
	(goto-char (point-max))
	(insert string))))

同样,save-excursion 不会恢复由 switch-to-buffer 等函数更改的窗口缓冲区对应关系。

警告:与保存的点值相邻的普通文本插入会重新定位保存的值,就​​像它重新定位所有标记一样。 更准确地说,保存的值是插入类型为 nil 的标记。 请参阅标记插入类型。 因此,当保存的点值恢复时,它通常在插入的文本之前。

Macro: save-mark-and-excursion body… ¶

这个宏类似于save-excursion,但也可以保存和恢复mark location和mark-active。 这个宏的作用与 Emacs 25.1 之前的 save-excursion 相同。

31.4 收窄

缩小意味着将 Emacs 编辑命令可寻址的文本限制在缓冲区中有限的字符范围内。 保持可寻址的文本称为缓冲区的可访问部分。

缩小是用两个缓冲区位置指定的,它们成为可访问部分的开始和结束。 对于大多数编辑命令和原语,这些位置替换缓冲区的开头和结尾的值。 当缩小生效时,可访问部分之外的文本不会显示,并且点不能移动到可访问部分之外。 请注意,收窄不会改变实际的缓冲区位置(见点); 它只确定哪些位置被认为是缓冲区的可访问部分。 大多数函数拒绝对可访问部分之外的文本进行操作。

保存缓冲区的命令不受变窄的影响; 他们保存整个缓冲区,而不管任何缩小。

如果您需要在单个缓冲区中显示几种不同类型的文本,请考虑使用在两个缓冲区之间交换文本中描述的替代工具。

Command: narrow-to-region start end ¶

此函数将当前缓冲区的可访问部分设置为从 start 开始并在 end 结束。 两个参数都应该是字符位置。

在交互式调用中,开始和结束设置为当前区域的边界(点和标记,最小的在前)。

Command: narrow-to-page &optional move-count ¶

此函数将当前缓冲区的可访问部分设置为仅包含当前页面。 可选的第一个参数 move-count non-nil 表示向前或向后移动移动计数页,然后缩小到一页。 变量 page-delimiter 指定页面的开始和结束位置(请参阅编辑中使用的标准正则表达式)。

在交互式调用中,move-count 设置为数字前缀参数。

Command: widen ¶

此函数取消当前缓冲区中的任何缩小,以便可以访问整个内容。 这称为加宽。 它等价于以下表达式:

(narrow-to-region 1 (1+ (buffer-size)))
Function: buffer-narrowed-p ¶

如果缓冲区变窄,此函数返回非 nil,否则返回 nil。

Special Form: save-restriction body… ¶

这种特殊形式保存了可访问部分的当前边界,评估了主体形式,最后恢复了保存的边界,从而恢复了以前有效的缩小(或不存在)的相同状态。 即使在通过 throw 或 error 异常退出的情况下也会恢复收缩状态(请参阅非本地退出)。 因此,此构造是一种临时缩小缓冲区的干净方法。

save-restriction 返回的值是 body 中最后一个表单返回的值,如果没有给出 body 表单,则返回 nil。

注意:使用 save-restriction 结构时很容易出错。 在您尝试之前,请阅读此处的完整说明。

如果 body 改变了当前缓冲区,save-restriction 仍然会恢复对原始缓冲区(保存限制的缓冲区)的限制,但不会恢复当前缓冲区的标识。

保存限制不恢复点; 为此使用保存游览。 如果同时使用 save-restriction 和 save-excursion,那么 save-excursion 应该放在第一位(在外面)。 否则,将恢复旧的点值,但暂时变窄仍然有效。 如果旧点值超出临时收窄的范围,则无法准确恢复。

这是正确使用保存限制的简单示例:



     ---------- Buffer: foo ----------
     This is the contents of foo
     This is the contents of foo
     This is the contents of foo∗
     ---------- Buffer: foo ----------


     (save-excursion
	(save-restriction
	  (goto-char 1)
	  (forward-line 2)
	  (narrow-to-region 1 (point))
	  (goto-char (point-min))
	  (replace-string "foo" "bar")))

     ---------- Buffer: foo ----------
     This is the contents of bar
     This is the contents of bar
     This is the contents of foo∗
     ---------- Buffer: foo ----------
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/rookieagle/elisp.git
git@gitee.com:rookieagle/elisp.git
rookieagle
elisp
Elisp
main

搜索帮助