Emacs: Как разумно обращаться с измененным буфером при настройке свойств текста? - PullRequest
7 голосов
/ 23 апреля 2010

Документация по свойствам текста гласит:

Поскольку свойства текста считаются частью содержимого буфера (или строки), и могут влиять на внешний вид буферана экране любое изменение свойств текста буфера помечает буфер как измененный.

Во-первых, я не понимаю эту политику.Кто-нибудь может объяснить?Текстовые реквизиты фактически не сохраняются в файле при сохранении буфера.Так зачем помечать буфер как измененный?Для меня измененный буфер означает «некоторые изменения еще не сохранены».но понимание политики только для моего собственного удовольствия.

Что еще более важно, существует ли уже установленный способ, которым в коде я могу изменять свойства текста синтаксиса для текста в буфере, сохраняя флаг измененного буфера равным тому, каким он был доизменения?Я думаю о чем-то вроде save-excursion.Это было бы довольно легко написать, но это похоже на обычный случай, и я хотел бы использовать стандартную функцию, если это возможно.

Для большей информации о сценарии - у меня есть режим, который выполняет полный текстсканирует и устанавливает свойства синтаксической таблицы для текста.После открытия буфера сканирование выполняется, но в результате получается буфер с измененным буфером, установленным на t.

Как всегда, спасибо.

Ответы [ 3 ]

5 голосов
/ 16 марта 2011

Более новые версии Emacs включают макрос "with-silent-Modification" для этого:

C-h f with-silent-modifications
------------------------------------------------------
with-silent-modifications is a Lisp macro in `subr.el'.

(with-silent-modifications &rest BODY)

Execute BODY, pretending it does not modify the buffer.
If BODY performs real modifications to the buffer's text, other
than cosmetic ones, undo data may become corrupted.
Typically used around modifications of text-properties which do not really
affect the buffer's content.
3 голосов
/ 23 апреля 2010

Подождите! Я нашел это в cc-defs.el

;; The following is essentially `save-buffer-state' from lazy-lock.el.
;; It ought to be a standard macro.
(defmacro c-save-buffer-state (varlist &rest body)
  "Bind variables according to VARLIST (in `let*' style) and eval BODY,
then restore the buffer state under the assumption that no significant
modification has been made in BODY.  A change is considered
significant if it affects the buffer text in any way that isn't
completely restored again.  Changes in text properties like `face' or
`syntax-table' are considered insignificant.  This macro allows text
properties to be changed, even in a read-only buffer.

This macro should be placed around all calculations which set
\"insignificant\" text properties in a buffer, even when the buffer is
known to be writeable.  That way, these text properties remain set
even if the user undoes the command which set them.

This macro should ALWAYS be placed around \"temporary\" internal buffer
changes \(like adding a newline to calculate a text-property then
deleting it again\), so that the user never sees them on his
`buffer-undo-list'.  See also `c-tentative-buffer-changes'.

However, any user-visible changes to the buffer \(like auto-newlines\)
must not be within a `c-save-buffer-state', since the user then
wouldn't be able to undo them.

The return value is the value of the last form in BODY."
  `(let* ((modified (buffer-modified-p)) (buffer-undo-list t)
          (inhibit-read-only t) (inhibit-point-motion-hooks t)
          before-change-functions after-change-functions
          deactivate-mark
          buffer-file-name buffer-file-truename ; Prevent primitives checking
                                                ; for file modification
          ,@varlist)
     (unwind-protect
         (progn ,@body)
       (and (not modified)
            (buffer-modified-p)
            (set-buffer-modified-p nil)))))
1 голос
/ 23 апреля 2010

Возможно, это просто потому, что они считаются частью строки ... (как говорят документы).Помните, что Emacs ориентирован на буфер , а не ориентирован на файл, поэтому тот факт, что содержимое сохраняется на диск, несколько не имеет значения (если думать о буфере ориентированный).

Кроме тогосвойства не могут быть отменены, и это определенно подходит для того, чтобы буфер помечался как измененный.

Я не знаю, что существует стандартный способ сохранения состояния, модифицированного буфером, но я вижу один в pabbrev.el библиотека:

(defmacro pabbrev-save-buffer-modified-p (&rest body)
  "Eval BODY without affected buffer modification status"
  `(let ((buffer-modified (buffer-modified-p))
         (buffer-undo-list t))
     ,@body
     (set-buffer-modified-p buffer-modified)))

Она не защищает от нелокальных выходов , поэтому, возможно, вы захотите добавить вызов к unwind-protect, вот так:

(defmacro save-buffer-modified-p (&rest body)
  "Eval BODY without affected buffer modification status"
  `(let ((buffer-modified (buffer-modified-p))
         (buffer-undo-list t))
     (unwind-protect
         ,@body
       (set-buffer-modified-p buffer-modified))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...