При удалении последнего родственного окна 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. Описываемая ниже переменная позволяет это сделать.
Эта переменная управляет тем, должно ли разбиение окна создавать новое родительское окно. Распознаются следующие значения:
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.
Эта функция устанавливает ограничение комбинации окна
window в значение limit. Это значение можно получить с помощью
функции window-combination-limit. См. ниже о её эффектах;
отметим, что она имеет смысл только для внутренних окон. Функция
split-window автоматически вызывает эту функцию, передавая ей
t в качестве limit, при условии, что значение переменной
window-combination-limit равно t в момент её вызова.
Эта функция возвращает ограничение комбинации для window.
Ограничение комбинации имеет смысл только для внутреннего окна. Если оно
равно nil, то Emacs разрешено автоматически удалять
window в ответ на удаление окна, чтобы сгруппировать
дочерние окна window с его родственными окнами для образования
новой комбинации окон. Если ограничение комбинации равно t,
дочерние окна window никогда не перекомбинируются автоматически с его
родственными окнами.
Если в конфигурации, показанной в начале этого раздела,
ограничение комбинации W4 (родительского окна W6 и
W7) равно t, удаление W5 не приведёт к неявному
удалению W4.
В качестве альтернативы описанные выше проблемы можно избежать, всегда изменяя размер всех окон в одной комбинации всякий раз, когда одно из её окон разбивается или удаляется. Это также позволяет разбивать окна, которые в противном случае были бы слишком малы для такой операции.
Если эта переменная равна nil, split-window может разбить
окно (обозначаемое как window), только если область экрана
window достаточно велика, чтобы вместить и его само, и новое окно.
Если эта переменная равна t, split-window пытается изменить
размер всех окон, которые являются частью той же комбинации, что и
window, чтобы разместить новое окно. В частности, это может позволить
split-window выполнить разбиение, даже если window является
окном фиксированного размера или слишком мало для обычного разбиения.
Кроме того, последующее изменение размера или удаление window может
изменить размер всех остальных окон в его комбинации.
Значение по умолчанию — nil. Другие значения зарезервированы для
будущего использования. Конкретная операция разбиения может игнорировать
значение этой переменной, если на неё влияет ненулевое значение
window-combination-limit.
Чтобы проиллюстрировать эффект 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 приведёт к пропорциональному распределению его пространства между двумя оставшимися живыми окнами.