Объединение окон
При удалении последнего окна-соседа окна W удаляется и его родительское окно, а W занимает его место в дереве окон. Это означает, что W необходимо объединить с окнами-соседями родительского окна, чтобы сформировать новую комбинацию окон (см. Окна и кадры). В некоторых случаях удаление активного окна может повлечь за собой удаление даже двух внутренних окон.
______________________________________
| ______ ____________________________ |
|| || __________________________ ||
|| ||| ___________ ___________ |||
|| |||| || ||||
|| ||||____W6_____||_____W7____||||
|| |||____________W4____________|||
|| || __________________________ ||
|| ||| |||
|| ||| |||
|| |||____________W5____________|||
||__W2__||_____________W3_____________ |
|__________________W1__________________|
Удаление W5 в этой конфигурации обычно приводит к удалению W3 и W4. Оставшиеся активные окна W2, W6 и W7 объединяются в новую горизонтальную комбинацию с родительским окном W1.
Однако иногда имеет смысл не удалять родительское окно, например W4. В частности, родительское окно не следует удалять, если оно использовалось для сохранения комбинации, вложенной в комбинацию того же типа. Такое вложение полезно, чтобы при разделении окна и последующем удалении нового окна Emacs восстанавливал расположение связанного кадра, существовавшее до разделения.
Рассмотрим сценарий, в котором изначально имеются два активных окна W2 и W3, а также их родительское окно W1.
______________________________________
| ____________________________________ |
|| ||
|| ||
|| ||
|| ||
|| ||
|| ||
||_________________W2_________________||
| ____________________________________ |
|| ||
|| ||
||_________________W3_________________||
|__________________W1__________________|
Разделим W2, чтобы создать новое окно W4, как показано ниже.
______________________________________
| ____________________________________ |
|| ||
|| ||
||_________________W2_________________||
| ____________________________________ |
|| ||
|| ||
||_________________W4_________________||
| ____________________________________ |
|| ||
|| ||
||_________________W3_________________||
|__________________W1__________________|
Теперь при вертикальном увеличении окна Emacs пытается получить соответствующее пространство от его нижнего окна-соседа, если такое окно существует. В нашем сценарии увеличение W4 приведет к тому, что оно займет пространство у W3.
______________________________________
| ____________________________________ |
|| ||
|| ||
||_________________W2_________________||
| ____________________________________ |
|| ||
|| ||
|| ||
|| ||
||_________________W4_________________||
| ____________________________________ |
||_________________W3_________________||
|__________________W1__________________|
Теперь при удалении W4 все занимаемое им пространство перейдет к W2, в том числе пространство, ранее занятое у W3.
______________________________________
| ____________________________________ |
|| ||
|| ||
|| ||
|| ||
|| ||
|| ||
|| ||
|| ||
||_________________W2_________________||
| ____________________________________ |
||_________________W3_________________||
|__________________W1__________________|
Это может показаться нелогичным, особенно если W4 использовалось лишь временно для отображения буфера (см. Временное отображение), а вы хотите продолжить работу с исходным расположением окон.
Это поведение можно исправить, создав новое родительское окно при разделении W2. Описанная далее переменная позволяет это сделать.
- Пользовательский параметр: window-combination-limit
-
Эта переменная определяет, будет ли при разделении окна создаваться новое родительское окно. Допустимы следующие значения:
nil-
Это означает, что новому активному окну разрешено использовать существующее родительское окно, если оно есть, при условии, что разделение выполняется в том же направлении, что и существующая комбинация окон (в противном случае в любом случае создается новое внутреннее окно).
window-size-
Это означает, что
display-bufferсоздает новое родительское окно при разделении окна, если ему передана записьwindow-heightилиwindow-widthв аргументе alist (см. Функции действий при отображении буферов). В противном случае разделение окон ведет себя так же, как при значенииnil. temp-buffer-resize-
В этом случае
with-temp-buffer-windowсоздает новое родительское окно при разделении окна, если включен параметрtemp-buffer-resize-mode(см. Временное отображение). В противном случае разделение окон ведет себя так же, как при значенииnil. temp-buffer-
В этом случае
with-temp-buffer-windowвсегда создает новое родительское окно при разделении существующего окна (см. Временное отображение). В противном случае разделение окон ведет себя так же, как при значенииnil. display-buffer-
Это означает, что при разделении окна функцией
display-buffer(см. Выбор окна для отображения буфера) всегда создается новое родительское окно. В противном случае разделение окон ведет себя так же, как при значенииnil. tЭто означает, что при разделении окна всегда создается новое родительское окно. Таким образом, если значение этой переменной всегда равно
t, то каждое дерево окон всегда является бинарным деревом (деревом, в котором у каждого окна, кроме корневого, ровно один сосед).
По умолчанию используется значение
window-size. Другие значения зарезервированы для будущего использования.Если в результате настройки этой переменной функция
split-windowсоздает новое родительское окно, она также вызывает для вновь созданного внутреннего окна функциюset-window-combination-limit(см. ниже). Это влияет на перестройку дерева окон при удалении дочерних окон (см. ниже).
Если window-combination-limit имеет значение t, разделение W2 в исходной конфигурации нашего сценария привело бы к следующему результату:
______________________________________
| ____________________________________ |
|| __________________________________ ||
||| |||
|||________________W2________________|||
|| __________________________________ ||
||| |||
|||________________W4________________|||
||_________________W5_________________||
| ____________________________________ |
|| ||
|| ||
||_________________W3_________________||
|__________________W1__________________|
Создано новое внутреннее окно W5; его дочерними окнами стали W2 и новое активное окно W4. Теперь W2 — единственное окно-сосед W4, поэтому при увеличении W4 будет предпринята попытка уменьшить W2, не затрагивая W3. Обратите внимание, что W5 представляет собой вертикальную комбинацию двух окон, вложенную в вертикальную комбинацию W1.
- Функция: set-window-combination-limit window limit
Эта функция задает для окна window предел объединения , равный limit. Это значение можно получить с помощью функции
window-combination-limit. О последствиях этого значения см. ниже; обратите внимание, что оно имеет смысл только для внутренних окон. Функцияsplit-windowавтоматически вызывает эту функцию, передавая ейtв качестве limit, если при ее вызове переменнаяwindow-combination-limitимеет значениеt.
- Функция: window-combination-limit window
-
Эта функция возвращает предел объединения для window.
Предел объединения имеет смысл только для внутреннего окна. Если он равен
nil, Emacs может автоматически удалить window в ответ на удаление окна, чтобы объединить дочерние окна window с окнами-соседями и сформировать новую комбинацию окон. Если предел объединения равенt, дочерние окна window никогда не объединяются автоматически с его окнами-соседями.Если в конфигурации, показанной в начале этого раздела, предел объединения для W4 (родительского окна W6 и W7) равен
t, удаление W5 не приведет к неявному удалению W4.
Этих проблем можно избежать и другим способом: всегда изменять размеры всех окон одной комбинации, когда одно из них разделяется или удаляется. Это также позволяет разделять окна, которые в противном случае были бы слишком малы для такой операции.
- Пользовательский параметр: window-combination-resize
-
Если эта переменная равна
nil, функцияsplit-windowможет разделить окно (обозначенное window) только в том случае, если его область на экране достаточно велика, чтобы вместить и само окно, и новое окно.Если эта переменная равна
t, функцияsplit-windowпытается изменить размеры всех окон, входящих в ту же комбинацию, что и window, чтобы разместить новое окно. В частности, это может позволить функцииsplit-windowуспешно выполниться, даже если window имеет фиксированный размер или слишком мало для обычного разделения. Кроме того, последующее изменение размера или удаление window может повлечь за собой изменение размеров всех остальных окон в его комбинации.По умолчанию используется значение
nil. Другие значения зарезервированы для будущего использования. При конкретной операции разделения значение этой переменной может игнорироваться, если на нее влияет значениеwindow-combination-limit, отличное отnil.Если вы планируете использовать последовательность вызовов
split-windowдля создания заданного расположения окон в кадре, временно задайте для этой переменной значениеnil. Функцияwindow-state-put(см. Конфигурации окон) и функции изменения расположения окон (см. Изменение расположения окон) поступают именно так, чтобы восстановить предыдущее расположение окон кадра или систематически изменить его.
Чтобы проиллюстрировать действие window-combination-resize, рассмотрим следующее расположение окон кадра.
______________________________________
| ____________________________________ |
|| ||
|| ||
|| ||
|| ||
||_________________W2_________________||
| ____________________________________ |
|| ||
|| ||
|| ||
|| ||
||_________________W3_________________||
|__________________W1__________________|
Если window-combination-resize имеет значение nil, разделение окна W3 не меняет размер W2:
______________________________________
| ____________________________________ |
|| ||
|| ||
|| ||
|| ||
||_________________W2_________________||
| ____________________________________ |
|| ||
||_________________W3_________________||
| ____________________________________ |
|| ||
||_________________W4_________________||
|__________________W1__________________|
Если window-combination-resize имеет значение t, разделение W3 вместо этого оставляет все три активных окна примерно одинаковой высоты:
______________________________________
| ____________________________________ |
|| ||
|| ||
||_________________W2_________________||
| ____________________________________ |
|| ||
|| ||
||_________________W3_________________||
| ____________________________________ |
|| ||
|| ||
||_________________W4_________________||
|__________________W1__________________|
При удалении любого из активных окон W2, W3 или W4 его пространство будет пропорционально распределено между двумя оставшимися активными окнами.
Следующие две функции позволяют явно создать новое родительское окно для нескольких соседних окон и отменить это действие.
- Функция: combine-windows first last
-
Эта функция объединяет окна от first до last включительно. first и last должны быть допустимыми окнами одной комбинации, то есть иметь одно и то же родительское окно. Если у first нет предыдущего окна-соседа, а у last — следующего, функция возвращает это родительское окно. В противном случае она создает новое родительское окно, первым дочерним окном которого становится first, а последним — last, помещает это родительское окно в дерево вместо окон начиная с first и заканчивая last и возвращает новое родительское окно.
Эта функция полезна для работы с несколькими окнами-соседями одного родительского окна как с единым целым. Рассмотрим три расположенных бок о бок окна-соседа w1, w2 и w3. Чтобы создать окно под w1 и w2, но не под w3, сначала объедините w1 и w2 с помощью этой функции, а затем разделите возвращенное ею окно. Также можно вызвать
window-state-get(см. Конфигурации окон) для значения, возвращенного функциейcombine-windows, чтобы получить объединенное состояние w1 и w2.
- Функция: uncombine-window window
-
Эта функция разъединяет указанное окно window. window должно быть внутренним окном, родительское окно которого также является внутренним окном того же типа. Это означает, что window и его родительское окно должны представлять собой либо обе горизонтальные, либо обе вертикальные комбинации окон. В таком случае функция делает дочерние окна window дочерними окнами родителя window и возвращает
t. В противном случае текущая конфигурация кадра window остается неизменной, а функция возвращаетnil.Эта функция полезна для отмены действия
combine-windows. Например, чтобы вычислить состояние двух соседних окон w1 и w2, выполните следующие действия: сначала вызовитеcombine-windowsс аргументами w1 и w2 и сохраните результат в w. Затем вызовитеwindow-state-getс аргументом w. Наконец, вызовитеuncombine-windowс аргументом w, чтобы получить конфигурацию окон, существовавшую до вызоваcombine-windows.
Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Recombining-Windows.html