Функция действия — это функция, которую display-buffer вызывает для выбора окна для отображения буфера. Функции действий принимают два аргумента: buffer — отображаемый буфер и alist — список действий (см. Списки действий для отображения буферов). Предполагается, что они возвращают окно, отображающее buffer, в случае успеха, и nil — в случае неудачи.
В Emacs определены следующие базовые функции действий.
Эта функция пытается отобразить buffer в выбранном окне. Она завершается ошибкой, если выбранное окно является окном минибуфера или выделено другому буферу (см. Выделенные окна). Она также завершается ошибкой, если alist содержит ненулевой элемент inhibit-same-window.
Эта функция пытается отобразить buffer, найдя окно, которое уже его отображает. Окна на выбранном фрейме имеют приоритет над окнами на других фреймах.
Если alist содержит ненулевой элемент inhibit-same-window, выбранное окно не подлежит повторному использованию. Набор фреймов для поиска окна, уже отображающего buffer, можно задать с помощью элемента списка действий reusable-frames. Если alist не содержит элемента reusable-frames, эта функция ищет только на выбранном фрейме.
Если эта функция выбирает окно на другом фрейме, она делает этот фрейм видимым и, если alist не содержит элемента inhibit-switch-frame, при необходимости поднимает этот фрейм.
Эта функция пытается отобразить buffer, найдя окно, которое отображает буфер в заданном режиме.
Если alist содержит элемент mode, его значение задает основной режим (символ) или список основных режимов. Если alist не содержит элемента mode, вместо него используется текущий основной режим buffer. Окно является кандидатом, если оно отображает буфер, режим которого является производным от одного из указанных таким образом режимов.
Поведение также контролируется элементами alist для inhibit-same-window, reusable-frames и inhibit-switch-frame, как и в display-buffer-reuse-window.
Эта функция пытается отобразить buffer, разделив самое большое или наименее недавно использовавшееся окно (обычно расположенное на выбранном фрейме). Фактически разделение выполняется путем вызова функции, заданной параметром split-window-preferred-function (см. Дополнительные параметры для отображения буферов).
Размер нового окна можно настроить, указав элементы window-height и window-width в alist. Если alist содержит элемент preserve-size, Emacs также попытается сохранить размер нового окна при будущих операциях изменения размера (см. Сохранение размеров окон).
Эта функция завершается ошибкой, если ни одно окно не может быть разделено. Чаще всего это происходит потому, что ни одно окно не является достаточно большим для разделения. Установка split-height-threshold или split-width-threshold на меньшие значения может помочь в этом отношении. Разделение также завершается ошибкой, если выбранный фрейм имеет параметр фрейма unsplittable; см. Параметры буфера.
Эта функция пытается отобразить buffer в окне, в котором он отображался ранее.
Если alist содержит ненулевой элемент inhibit-same-window, выбранное окно не подходит для использования. Выделенное окно можно использовать, только если оно уже показывает buffer. Если alist содержит элемент previous-window, окно, указанное этим элементом, можно использовать, даже если оно никогда раньше не показывало buffer.
Если alist содержит элемент reusable-frames (см. Списки действий для отображения буферов), его значение определяет, на каких фреймах искать подходящее окно. Если alist не содержит элемента reusable-frames, эта функция ищет только на выбранном фрейме, если и display-buffer-reuse-frames, и pop-up-frames равны nil; она ищет на всех фреймах текущего терминала, если любая из этих переменных не равна nil.
Если более одного окна соответствуют этим правилам, эта функция делает выбор в следующем порядке предпочтения:
previous-window, при условии, что оно не является выбранным окном.
previous-window, либо раньше показывало buffer.
Эта функция пытается отобразить buffer, выбрав существующее окно и отобразив буфер в этом окне. Сначала она пытается найти окно, которое не использовалось недавно (см. Циклический порядок окон) на любом фрейме, указанном элементом alist lru-frames, возвращаясь к выбранному фрейму, если такого элемента нет. Она также предпочитает окна, удовлетворяющие ограничениям, заданным элементами alist window-min-width и window-min-height; предпочитая окна полной ширины, если элемент window-min-width не найден. Наконец, она не вернет окно, время использования которого превышает значение, указанное любым элементом lru-time, предоставленным alist.
Если окно, использовавшееся менее недавно, не найдено, эта функция попытается использовать другое окно, предпочтительно большое окно на каком-либо видимом фрейме. Она может завершиться ошибкой, если все окна выделены другим буферам (см. Выделенные окна).
Вышеописанное описывает поведение, когда элемент alist some-window равен lru или nil, что является значением по умолчанию. Другое возможное значение — mru. Если, например, display-buffer-base-action настроен на (nil . ((some-window . mru))), то эта функция будет предпочитать наиболее недавно использовавшееся окно. Это позволит отображать несколько буферов из последовательных вызовов display-buffer в одном окне. Рассмотрим конфигурацию из трех или более окон, в которой пользователь хочет просматривать в невыбранном окне один за другим результаты запроса, распределенные по нескольким буферам. При стратегии lru Emacs может постоянно выбирать другое окно, потому что наименее недавно использовавшееся окно меняется при каждом вызове display-buffer-use-some-window. При стратегии mru выбранное окно всегда будет оставаться одним и тем же, что обеспечит предсказуемый пользовательский опыт.
Эта функция похожа на display-buffer-use-some-window, но прилагает больше усилий, чтобы не использовать недавно использовавшееся окно. В частности, она не использует выбранное окно. Кроме того, она сначала попытается повторно использовать окно, которое уже показывает buffer, основывать решение о том, следует ли использовать окно, показывающее другой буфер, исключительно на времени использования этого окна и создать новое окно, если подходящее окно не найдено.
Наконец, эта функция увеличит время использования (см. Выбор окон) любого возвращаемого окна, чтобы избежать использования этого окна для отображения другого буфера при последующих вызовах. Приложение, которое хочет отобразить несколько буферов подряд, может помочь этой функции, предоставив элемент alist lru-time, который изначально установлен в значение времени использования выбранного окна. Каждый вызов этой функции будет увеличивать время использования возвращенного окна до значения выше этого, и последующий вызов запретит этой функции использовать окно, которое она вернула ранее.
Эта функция пытается отобразить buffer в месте, указанном alist. Для этой цели alist должен содержать элемент direction, значение которого является одним из left (слева), above (выше) (или up (вверх)), right (справа) и below (ниже) (или down (вниз)). Другие значения обычно интерпретируются как below.
Если alist также содержит элемент window, его значение задает эталонное окно. Это значение может быть специальным символом, таким как main (главное), которое обозначает главное окно выбранного фрейма (см. Параметры и функции боковых окон) или root (корневое), обозначающее корневое окно выбранного фрейма (см. Окна и фреймы). Оно также может задавать произвольное допустимое окно. Любое другое значение (или пропуск элемента window полностью) означает использование выбранного окна в качестве эталонного.
Эта функция сначала пытается повторно использовать окно в указанном направлении, которое уже показывает buffer. Если такого окна нет, она пытается разделить эталонное окно, чтобы создать новое окно в указанном направлении. Если это также не удается, она попытается отобразить buffer в существующем окне в указанном направлении. В любом случае выбранное окно появится на стороне эталонного окна, указанной элементом direction, разделяя с эталонным окном по крайней мере одну границу.
Если эталонное окно является живым, граница, которую будет разделять выбранное окно с ним, всегда противоположна той, которая указана элементом direction. Например, если значение элемента direction равно left, координата правой границы выбранного окна (см. Координаты и окна) будет равна координате левой границы эталонного окна.
Если эталонное окно является внутренним, повторно используемое окно должно разделять с ним границу, указанную элементом direction. Следовательно, если, например, эталонное окно является корневым окном фрейма, а значение элемента direction равно left, повторно используемое окно должно находиться слева от фрейма. Это означает, что координата левой границы выбранного окна и эталонного окна совпадают.
Новое окно, однако, будет создано путем разделения эталонного окна таким образом, что выбранное окно будет разделять противоположную границу с эталонным окном. В нашем примере будет создано новое корневое окно с новым живым окном и эталонным окном в качестве его дочерних элементов. Координата правой границы выбранного окна тогда будет равна координате левой границы эталонного окна. Координата его левой границы будет равна координате левой границы нового корневого окна фрейма.
Четыре специальных значения для элементов direction позволяют неявно указать главное окно выбранного фрейма в качестве эталонного окна: leftmost (самое левое), top (верхнее), rightmost (самое правое) и bottom (нижнее). Это означает, что вместо, например, (direction . left) (window . main) можно просто указать (direction . leftmost). Существующий элемент alist window в таких случаях игнорируется.
Эта функция пытается отобразить buffer в окне ниже выбранного окна. Если под выбранным окном есть окно, и это окно уже отображает buffer, она повторно использует это окно.
Если такого окна нет, эта функция пытается создать новое окно, разделив выбранное, и отобразить buffer там. Она также попытается настроить размер этого окна, если alist содержит подходящий элемент window-height или window-width, см. выше.
Если разделение выбранного окна не удается и под выбранным окном есть невыделенное окно, показывающее другой буфер, эта функция пытается использовать это окно для отображения buffer.
Если alist содержит элемент window-min-height, эта функция гарантирует, что используемое окно имеет или может иметь высоту не меньше указанной в значении этого элемента. Обратите внимание, что это только гарантия. Для фактического изменения размера используемого окна alist также должен содержать соответствующий элемент window-height.
Эта функция пытается отобразить buffer в окне внизу выбранного фрейма.
Она либо пытается разделить окно внизу фрейма или корневое окно фрейма, либо повторно использовать существующее окно внизу выбранного фрейма.
Эта функция создает новый фрейм и отображает буфер в окне этого фрейма. Фактически создание фрейма выполняется путем вызова функции, указанной в pop-up-frame-function (см. Дополнительные параметры для отображения буферов). Если alist содержит элемент pop-up-frame-parameters, соответствующее значение добавляется к параметрам вновь созданного фрейма.
Эта функция отображает буфер на текущем фрейме, удаляя все остальные окна, чтобы он занимал весь фрейм.
Эта функция пытается отобразить buffer в дочернем фрейме (см. Дочерние фреймы) выбранного фрейма, либо повторно используя существующий дочерний фрейм, либо создавая новый. Если alist содержит ненулевой элемент child-frame-parameters, соответствующее значение является списком параметров фрейма для нового фрейма. Параметр parent-frame, задающий выбранный фрейм, предоставляется по умолчанию. Если дочерний фрейм должен стать дочерним для другого фрейма, в alist необходимо добавить соответствующий элемент.
Внешний вид дочерних фреймов во многом зависит от параметров, предоставленных через alist. Желательно использовать по крайней мере соотношения для задания размера (см. Параметры размера) и положения (см. Параметры положения) дочернего фрейма, а также добавить параметр keep-ratio (см. Параметры взаимодействия фреймов), чтобы убедиться, что дочерний фрейм остается видимым. Другие параметры, которые следует учитывать, см. в Дочерние фреймы.
Эта функция пытается отобразить buffer, найдя фрейм, который удовлетворяет предикату (по умолчанию любой фрейм, кроме выбранного).
Если эта функция выбирает окно на другом фрейме, она делает этот фрейм видимым и, если alist не содержит элемента inhibit-switch-frame, при необходимости поднимает этот фрейм.
Если alist содержит ненулевой элемент frame-predicate, его значение является функцией, принимающей один аргумент (фрейм) и возвращающей ненулевое значение, если фрейм является кандидатом; эта функция заменяет предикат по умолчанию.
Если alist содержит ненулевой элемент inhibit-same-window, выбранное окно не используется; таким образом, если выбранный фрейм имеет одно окно, оно не используется.
Если alist содержит ненулевой элемент allow-no-window, то эта функция не отображает buffer и возвращает символ fail. Это единственное исключение из соглашения о том, что функция действия возвращает либо nil, либо окно, показывающее buffer. Если alist не содержит такого элемента allow-no-window, эта функция возвращает nil.
Если эта функция возвращает fail, display-buffer пропустит выполнение любых дальнейших действий по отображению и немедленно вернет nil. Если эта функция возвращает nil, display-buffer продолжит выполнение следующего действия по отображению, если таковое имеется.
Предполагается, что когда вызывающий display-buffer указывает ненулевой элемент allow-no-window, он также способен обработать возвращаемое значение nil.
Две другие функции действий описаны в соответствующих разделах — display-buffer-in-side-window (см. Отображение буферов в боковых окнах) и display-buffer-in-atom-window (см. Атомарные окна).