Воскрешение окон
После удаления окна (см. Удаление окон) его больше нельзя использовать в функциях, которым требуется действительное окно в качестве аргумента, даже если на это окно всё ещё ссылается какая-либо переменная Lisp. Когда последняя ссылка на окно перестаёт существовать, объект Lisp, представляющий окно, в конечном итоге будет повторно использован сборщиком мусора (см. Сборка мусора).
Есть два способа воскресить удалённое окно, объект которого ещё не был повторно использован сборщиком: первый — сохранить ссылку на это окно в сохранённой конфигурации окон (см. Конфигурации окон), а затем вызвать set-window-configuration, передав эту конфигурацию в качестве аргумента. Второй способ — сохранить ссылку на это окно в переменной или связать её через let, а затем использовать эту ссылку в качестве аргумента refer в split-window (см. Разделение окон).
Основное различие между этими способами состоит в том, что set-window-configuration восстанавливает расположение окон во фрейме таким, каким оно было до удаления окна. Подход с split-window, напротив, позволяет произвольно изменять расположение.
Рассмотрим следующий пример, в котором изначально фрейм содержит одно окно с буфером *scratch*:
(let* ((old (selected-window))
(new (split-window old nil 'right))
overlay)
(with-current-buffer (get-buffer-create "*Messages*")
(set-window-buffer new (current-buffer))
(setq overlay (make-overlay (point-min) (point-max)))
(overlay-put overlay 'face 'highlight)
(overlay-put overlay 'window new)
(message "new %s parent %s" new (window-parent new))
(sit-for 3))
(delete-window new)
(setq new (split-window old nil 'left))
(set-window-buffer new (get-buffer-create "*Messages*"))
(format "new %s parent %s" new (window-parent new)))
При выполнении этого кода в *scratch* окно с буфером *scratch* сначала разделится, чтобы отобразить *Messages* в новом окне справа. Кроме того, будет создан оверлей со свойством окна для подсветки текста *Messages* в новом окне и выведено сообщение с указанием нового окна и его родителя в дереве окон. Затем новое окно удаляется и воскрешается слева от окна *scratch*; при этом снова выводится сообщение с указанием нового окна и его родителя в дереве окон.
Обратите внимание, что после перемещения окна *Messages* влево изменились и новое окно, и его родитель. Подсветка также исчезает, поскольку все свойства, заданные для нового окна справа, теряются, когда новое окно создаётся заново слева.
В следующем примере вместо этого используется аргумент refer функции split-window.
(let* ((old (selected-window))
(new (split-window old nil 'right))
overlay)
(with-current-buffer (get-buffer-create "*Messages*")
(set-window-buffer new (current-buffer))
(setq overlay (make-overlay (point-min) (point-max)))
(overlay-put overlay 'face 'highlight)
(overlay-put overlay 'window new)
(message "new %s parent %s" new (window-parent new))
(sit-for 3))
(delete-window new)
(split-window old nil 'left nil new)
(format "new %s parent %s" new (window-parent new)))
Обратите внимание, что все свойства воскрешённого окна, например его оформление и параметры, а также любые оверлеи со свойством окна, сохраняются так, словно это окно никогда не удалялось. Изменились только его положение в дереве окон и, как следствие, значения, возвращаемые функцией window-left-child для родительского окна, а также значения, возвращаемые функциями window-prev-sibling и window-next-sibling для окна и его соседнего окна.
В следующем примере и новое окно справа, и его родитель передаются через аргумент refer функции split-window.
(let* ((old (selected-window))
(new (split-window old nil 'right))
(parent (window-parent new))
overlay)
(with-current-buffer (get-buffer-create "*Messages*")
(set-window-buffer new (current-buffer))
(setq overlay (make-overlay (point-min) (point-max)))
(overlay-put overlay 'face 'highlight)
(overlay-put overlay 'window new)
(message "new %s parent %s" new (window-parent new))
(sit-for 3))
(delete-window new)
(split-window old nil 'left nil (cons new parent))
(format "new %s parent %s" new (window-parent new)))
Обратите внимание, что родительское окно было воскрешено вместе с новым окном.
Воскрешение удалённых окон полезно для сохранения их идентичности при выполнении действий, в которых она должна сохраняться, например при перемещении окон во фрейме или их временном скрытии. Все свойства такого окна, например его оформление, ранее отображавшийся в нём буфер, начальная и текущая позиции этого буфера в окне, состояние закрепления окна или тип его курсора, остаются нетронутыми, и создавать их заново не требуется. Для внутренних окон сохраняется значение ограничения на объединение окон, поэтому окно можно объединить повторно (см. Повторное объединение окон), как и раньше.
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/Resurrecting-Windows.html