上一节中的行相关函数统计的是 文本行(text line),仅由换行符分隔。与之相对,本节函数统计的是 屏幕行(screen line),由文本在屏幕上的实际显示方式定义。如果文本行长度足够短,能适配当前选中窗口的宽度,则一个文本行对应一个屏幕行;否则可能会占据多个屏幕行。
某些情况下,文本行在屏幕上会被截断而非延续为多个屏幕行。此时 vertical-motion 移动光标的行为与 forward-line 十分相似。See 截断显示。
由于给定字符串的显示宽度受控制特定字符外观的标志影响,vertical-motion 对同一段文本的行为会因所在缓冲区、甚至当前选中窗口而异(因为不同窗口的宽度、截断标志和显示表可能不同)。See 常规显示规则。
这些函数需要扫描文本以确定屏幕行的换行位置,因此耗时与扫描距离成正比。
该函数将光标移动到相对于当前所在屏幕行向下 count 个屏幕行的行首。如果 count 为负数,则向上移动。如果 count 为零,光标移至当前屏幕行的视觉起始位置。
参数 count 可以是整数,也可以是序对 (cols . lines)。在后一种情况下,函数按 lines 指定的屏幕行数移动(规则同上),并将光标置于该行视觉起始位置右侧 cols 列处。cols 可以是浮点数,单位为框架的标准字符宽度(see 框架字体);这使得在目标屏幕行使用可变宽度字体时,仍能精确定位光标水平位置。注意 cols 从行的**视觉**起始位置开始计算;如果窗口已水平滚动(see 水平滚动),光标最终所在列会额外加上文本滚动的列数;如果目标行是续行,则其最左侧列视为第 0 列(这与面向列的函数不同,see 列数统计)。
返回值为光标实际移动的屏幕行数。如果抵达缓冲区开头或末尾,返回值的绝对值可能小于 count。
参数 window 用于获取窗口宽度、水平滚动量、显示表等参数。但 vertical-motion 始终作用于当前缓冲区,即便 window 当前显示的是其他缓冲区。
可选参数 cur-col 用于指定调用函数时的当前列,即光标相对于窗口的水平坐标,单位为框架默认字体的字符宽度。提供该参数可加速函数执行,尤其在极长行中,因为函数无需回扫缓冲区以计算当前列。注意 cur-col 同样从行的视觉起始位置计算。
该函数返回从 beg 到 end 文本所占用的屏幕行数。由于行延续、显示表等原因,屏幕行数可能与实际文本行数不同。如果 beg 和 end 为 nil 或省略,则默认使用缓冲区可访问区域的开头和结尾。
如果区域以换行符结尾,该换行符会被忽略,除非可选的第三个参数 count-final-newline 为非 nil。
可选的第四个参数 window 指定用于获取宽度、水平滚动等参数的窗口,默认使用选中窗口的参数。
与 vertical-motion 一样,count-screen-lines 始终使用当前缓冲区,与 window 中显示的缓冲区无关。这使得该函数可在任意缓冲区中使用,无论其当前是否在某个窗口中显示。
该函数相对于选中窗口当前显示的文本移动光标。它将光标移至距离窗口顶部 count 个屏幕行的行首;0 表示窗口最顶行。如果 count 为负数,则指定距离窗口底部 −count 行的位置(若缓冲区在指定屏幕位置上方结束,则为缓冲区最后一行);因此 count 为 −1 时表示窗口最后一个完整可见的屏幕行。
如果 count 为 nil,光标移至窗口正中行的行首。如果 count 的绝对值大于窗口高度,光标会移至窗口足够高时本该出现在该行的位置,这通常会导致下一次重绘时滚动到该位置。
交互式调用时,count 为数字前缀参数。
返回值为光标移动到的、相对于窗口顶行的屏幕行号。
该函数与 move-to-window-line 类似,区别在于:当选中窗口属于某个窗口组时(see Window Group),move-to-window-group-line 会相对于整个窗口组定位,而非仅当前窗口。该生效条件为缓冲区局部变量 move-to-window-group-line-function 被设为某个函数。此时 move-to-window-group-line 会以 count 为参数调用该函数,并返回其结果。
该函数扫描当前缓冲区并计算屏幕位置。它从位置 from 开始向前扫描(假定该位置位于屏幕坐标 frompos),直到位置 to 或坐标 topos,以先到者为准,并返回扫描结束时的缓冲区位置与屏幕坐标。
坐标参数 frompos 和 topos 均为格式为 (hpos . vpos) 的序对。
参数 width 为可用于显示文本的列数,影响续行处理。nil 表示使用窗口实际可用文本列数,等价于 (window-width window) 的返回值。
参数 offsets 为 nil 或格式为 (hscroll . tab-offset) 的序对。其中 hscroll 为左侧未显示的列数,大多数调用者通过 window-hscroll 获取。tab-offset 为屏幕列号与缓冲区列号之间的偏移,仅当续行中前序屏幕行宽度之和不是 tab-width 的整数倍时非零,非续行中恒为零。
参数 window 仅用于指定使用的显示表。compute-motion 始终作用于当前缓冲区,与窗口显示内容无关。
返回值为包含五个元素的列表:
(pos hpos vpos prevhpos contin)
其中 pos 为扫描停止处的缓冲区位置,vpos 为垂直屏幕坐标,hpos 为水平屏幕坐标。
prevhpos 为 pos 前一个字符的水平位置。contin 为 t 表示最后一行在前一字符之后(或内部)发生续行。
例如,要查找某窗口第 line 个屏幕行、第 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))))
在迷你缓冲区中使用 compute-motion 时,需要用 minibuffer-prompt-width 获取首个屏幕行起始处的水平位置。See Minibuffer 内容。