29.20 Позиции начала и конца окна

Каждое окно поддерживает маркер, используемый для отслеживания позиции в буфере, с которой должно начинаться отображение. Эта позиция называется позицией начала отображения окна (или просто началом). Символ после этой позиции — это тот, который появляется в верхнем левом углу окна. Обычно, но не обязательно, он находится в начале текстовой строки.

После переключения окон или буферов, а также в некоторых других случаях, если начало окна оказывается в середине строки, Emacs корректирует начало окна до начала строки. Это предотвращает ситуации, когда некоторые операции оставляют начало окна в бессмысленной точке внутри строки. Эта возможность может мешать тестированию некоторого кода Lisp путём его выполнения с помощью команд режима Lisp, поскольку они запускают эту перекорректировку. Для тестирования такого кода поместите его в команду и привяжите команду к клавише.

Функция: window-start &optional window

Эта функция возвращает позицию начала отображения для окна window. Если window равен nil, используется выбранное окно.

Когда вы создаёте окно или отображаете в нём другой буфер, позиция начала отображения устанавливается в позицию начала отображения, недавно использовавшуюся для того же буфера, или в point-min, если у буфера её нет.

Перерисовка обновляет позицию начала окна (если вы не задали её явно после предыдущей перерисовки), чтобы гарантировать, что точка отображается на экране. Ничто, кроме перерисовки, автоматически не изменяет позицию начала окна; если вы перемещаете точку, не ожидайте, что позиция начала окна изменится в ответ до следующей перерисовки.

Функция: window-group-start &optional window

Эта функция аналогична window-start, за исключением того, что когда window является частью группы окон (см. Группа окон), window-group-start возвращает начальную позицию всей группы. Это условие выполняется, когда буферно-локальная переменная window-group-start-function установлена в функцию. В этом случае window-group-start вызывает эту функцию с единственным аргументом window и возвращает её результат.

Функция: window-end &optional window update

Эта функция возвращает позицию, где заканчивается отображение буфера в окне window. По умолчанию для window используется выбранное окно.

Простое изменение текста буфера или перемещение точки не обновляет значение, возвращаемое window-end. Значение обновляется только тогда, когда Emacs выполняет перерисовку и перерисовка завершается без прерывания.

Если последняя перерисовка window была прервана и не завершилась, Emacs не знает позицию конца отображения в этом окне. В этом случае функция возвращает nil.

Если update не равен nil, window-end всегда возвращает актуальное значение позиции конца отображения, основанное на текущем значении window-start. Если ранее сохранённое значение этой позиции всё ещё действительно, window-end возвращает это значение; в противном случае оно вычисляет правильное значение путём сканирования текста буфера.

Даже если update не равен nil, window-end не пытается прокручивать отображение, если точка вышла за пределы экрана, как это делает настоящая перерисовка. Он не изменяет значение window-start. По сути, он сообщает, где закончится отображаемый текст, если прокрутка не требуется. Обратите внимание, что возвращаемая позиция может быть видна только частично.

Функция: window-group-end &optional window update

Эта функция аналогична window-end, за исключением того, что когда window является частью группы окон (см. Группа окон), window-group-end возвращает конечную позицию всей группы. Это условие выполняется, когда буферно-локальная переменная window-group-end-function установлена в функцию. В этом случае window-group-end вызывает эту функцию с двумя аргументами window и update и возвращает её результат. Аргумент update имеет то же значение, что и в window-end.

Функция: set-window-start window position &optional noforce

Эта функция устанавливает позицию начала отображения для window в position в буфере этого окна. Она возвращает position.

Отображающие подсистемы требуют, чтобы позиция точки была видима при отображении буфера. Обычно они выбирают позицию начала отображения в соответствии со своей внутренней логикой (и прокручивают окно при необходимости), чтобы сделать точку видимой. Однако если вы задаёте начальную позицию с помощью этой функции с nil в качестве noforce, это означает, что вы хотите, чтобы отображение начиналось с position, даже если это приведёт к тому, что точка окажется за пределами экрана. Если это действительно помещает точку за пределы экрана, то подсистемы отображения пытаются переместить точку на левое поле средней строки в окне.

Например, если точка равна 1, а вы устанавливаете начало окна в 37 (начало следующей строки), точка окажется выше верхней части окна. Подсистемы отображения автоматически перемещают точку, если она всё ещё равна 1, когда происходит перерисовка. Вот пример:

;; Вот как выглядит ‘foo’ перед выполнением
;;   выражения set-window-start.

---------- Буфер: foo ----------
∗Это содержимое буфера foo.
2
3
4
5
6
---------- Буфер: foo ----------

(set-window-start
 (selected-window)
 (save-excursion
   (goto-char 1)
   (forward-line 1)
   (point)))
⇒ 37

;; Вот как выглядит ‘foo’ после выполнения
;;   выражения set-window-start.
---------- Буфер: foo ----------
2
3
∗4
5
6
---------- Буфер: foo ----------

Если попытка сделать точку видимой (т.е. на полностью видимой строке экрана) не удаётся, подсистемы отображения всё равно проигнорируют запрошенную позицию начала окна и вычислят новую. Таким образом, для получения надёжных результатов программы на Lisp, вызывающие эту функцию, должны всегда перемещать точку внутрь окна, отображение которого начинается с position.

Если noforce не равен nil и position при следующей перерисовке поместит точку за пределами экрана, то перерисовка вычисляет новую позицию начала окна, которая хорошо работает с точкой, и, следовательно, position не используется.

Функция: set-window-group-start window position &optional noforce

Эта функция аналогична set-window-start, за исключением того, что когда window является частью группы окон (см. Группа окон), set-window-group-start устанавливает начальную позицию всей группы. Это условие выполняется, когда буферно-локальная переменная set-window-group-start-function установлена в функцию. В этом случае set-window-group-start вызывает эту функцию с тремя аргументами window, position и noforce и возвращает её результат. Аргументы position и noforce в этой функции имеют те же значения, что и в set-window-start.

Функция: pos-visible-in-window-p &optional position window partially

Эта функция возвращает не nil, если position находится в диапазоне текста, видимого в данный момент на экране в окне window. Она возвращает nil, если position прокручена по вертикали за пределы видимости. Позиции, которые частично скрыты, не считаются видимыми, если только partially не равен nil. Аргумент position по умолчанию равен текущей позиции точки в window; window по умолчанию равен выбранному окну. Если position равен t, это означает проверку либо первой видимой позиции последней строки экрана в window, либо позиции конца буфера — в зависимости от того, что наступит раньше.

Эта функция учитывает только вертикальную прокрутку. Если position не видна только из-за того, что window была прокручена по горизонтали, pos-visible-in-window-p всё равно возвращает не nil. См. Горизонтальная прокрутка.

Если position видима, pos-visible-in-window-p возвращает t, если partially равен nil; если partially не равен nil, и символ, следующий за position, полностью видим, возвращается список вида (x y), где x и y — это пиксельные координаты относительно верхнего левого угла окна; в противном случае возвращается расширенный список вида (x y rtop rbot rowh vpos), где rtop и rbot задают количество пикселей за пределами окна сверху и снизу строки в позиции position, rowh задаёт видимую высоту этой строки, а vpos задаёт вертикальную позицию (номер строки, начиная с нуля) этой строки.

Вот пример:

;; Если точка сейчас за пределами экрана, отцентрируйте её.
(or (pos-visible-in-window-p
     (point) (selected-window))
    (recenter 0))
Функция: pos-visible-in-window-group-p &optional position window partially

Эта функция аналогична pos-visible-in-window-p, за исключением того, что когда window является частью группы окон (см. Группа окон), pos-visible-in-window-group-p проверяет видимость pos во всей группе, а не только в одном окне window. Это условие выполняется, когда буферно-локальная переменная pos-visible-in-window-group-p-function установлена в функцию. В этом случае pos-visible-in-window-group-p вызывает эту функцию с тремя аргументами position, window и partially и возвращает её результат. Аргументы position и partially имеют те же значения, что и в pos-visible-in-window-p.

Функция: window-line-height &optional line window

Эта функция возвращает высоту текстовой строки line в окне window. Если line равно header-line или mode-line, window-line-height возвращает информацию о соответствующей строке окна. В противном случае line — это номер текстовой строки, начиная с 0. Отрицательное число отсчитывается от конца окна. По умолчанию для line используется текущая строка в window; по умолчанию для window используется выбранное окно.

Если отображение неактуально, window-line-height возвращает nil. В этом случае для получения связанной информации можно использовать pos-visible-in-window-p.

Если нет строки, соответствующей указанной line, window-line-height возвращает nil. В противном случае он возвращает список (height vpos ypos offbot), где height — это высота в пикселях видимой части строки, vpos и ypos — это вертикальная позиция в строках и пикселях строки относительно верха первой текстовой строки, а offbot — это количество пикселей за пределами окна в нижней части текстовой строки. Если есть пиксели за пределами окна в верхней части (первой) текстовой строки, ypos отрицателен.