Часто бывает полезно временно перемещать точку в локальной части программы. Это называется экскурсией (excursion) и выполняется с помощью специальной формы save-excursion. Эта конструкция запоминает исходный идентификатор текущего буфера и значение точки в нём, а затем восстанавливает их после завершения экскурсии. Это стандартный способ перемещения точки в одной части программы без влияния на остальную часть программы; она используется тысячи раз в исходных текстах Lisp в Emacs.
Если вам нужно только сохранить и восстановить идентификатор текущего буфера, используйте save-current-buffer или with-current-buffer (см. Текущий буфер). Если вам нужно сохранить или восстановить конфигурации окон, обратитесь к формам, описанным в Конфигурации окон и в Конфигурации фреймов.
Эта специальная форма сохраняет идентификатор текущего буфера и значение точки в нём, вычисляет body и, наконец, восстанавливает буфер и сохранённое значение точки. Оба сохранённых значения восстанавливаются даже в случае аномального выхода через throw или ошибку (см. Нелокальные выходы).
Значение, возвращаемое save-excursion, является результатом последней формы в body или nil, если формы тела не заданы.
Поскольку save-excursion сохраняет точку только для буфера, который был текущим на момент начала экскурсии, любые изменения точки в других буферах во время экскурсии останутся в силе после её завершения. Это часто приводит к непреднамеренным последствиям, поэтому байт-компилятор выдаёт предупреждение, если вы вызываете set-buffer во время экскурсии:
Предупреждение: используйте ‘with-current-buffer’ вместо
save-excursion+set-buffer
Чтобы избежать таких проблем, следует вызывать save-excursion только после установки нужного текущего буфера, как в следующем примере:
(defun append-string-to-buffer (string buffer)
"Добавить STRING в конец BUFFER."
(with-current-buffer buffer
(save-excursion
(goto-char (point-max))
(insert string))))
Аналогично, save-excursion не восстанавливает соответствия окон и буферов, изменённые такими функциями, как switch-to-buffer.
Предупреждение: Обычная вставка текста рядом с сохранённым значением точки перемещает сохранённое значение так же, как перемещаются все маркеры. Точнее, сохранённое значение является маркером с типом вставки nil. См. Типы вставки маркеров. Следовательно, при восстановлении сохранённого значения точки оно обычно оказывается перед вставленным текстом.
Этот макрос подобен save-excursion, но также сохраняет и восстанавливает положение метки и mark-active. Этот макрос делает то, что save-excursion делал до Emacs 25.1.