2010-04-23 8 views
7

The documentation on Text Properties dice:Emacs: ¿Cómo se maneja inteligentemente el buffer modificado cuando se configuran las propiedades del texto?

Dado que las propiedades del texto se consideran parte de los contenidos de la memoria intermedia (o cadena), y pueden afectar la manera en un buffer se ve en la pantalla, cualquier cambio en las propiedades del texto tampón marca el búfer como modificado .

En primer lugar, no entiendo esa política. ¿Alguien puede explicar? Los accesorios de texto no se guardan realmente en el archivo, cuando se guarda el búfer. Entonces, ¿por qué marcar el buffer como modificado? Para mí, buffer-modified indica "algunos cambios aún no se han guardado". pero entender la política es solo para mi propia diversión.

Más importante aún, ¿existe una forma establecida de que, en el código, puedo cambiar las propiedades del texto de sintaxis en el búfer, manteniendo la bandera modificada en el búfer establecida en lo que sea antes de esos cambios? Estoy pensando en algo como save-excursion. Sería bastante fácil escribir, pero parece un caso común y me gustaría usar la función estándar, si es posible.

Para obtener más información sobre el escenario, tengo un modo que realiza un escaneo de texto completo y establece propiedades de tabla de sintaxis en el texto. Después de abrir un búfer, el análisis se ejecuta, pero da como resultado un búfer con el conjunto modificado por el búfer en t.

Como siempre, gracias.

Respuesta

3

espera! He encontrado esto en 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))))) 
+0

Bien, no lo vi. Un poco más completo que el de pabbrev. –

1

Quizás es simplemente porque se consideran una parte de la cadena ... (como dicen los documentos). Recuerde, Emacs es buffer -centric, no centrado en archivos, por lo que el hecho de que el contenido se guarde en el disco es algo irrelevante (cuando se piensa en buffer-centric).

Además, las propiedades no se pueden modificar, y eso definitivamente se ajusta a tener el buffer marcado como modificado.

No sé que hay una forma estándar de salvar el estado del buffer modificado, pero sí ver uno en la biblioteca 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))) 

no protege contra nonlocal exits, así que quizás te gustaría añadir una llamada a unwind-protect, así:

(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)))) 
+0

Excelente, gracias. Tenía la parte 'set-buffer-modified-p', pero no la de' buffer-undo-list'. – Cheeso

+0

¡Pero espera! Esto sigue siendo útil, pero mira mi respuesta. – Cheeso

5

Las nuevas versiones de Emacs incluyen la macro "con-silent-modificaciones" para esto:

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. 
+0

El registro de cambios de Emacs para la versión 23.3 menciona haber introducido 'with-silent-modifications', pero la versión de compilación de Windows 23.3.1 aún carece de esa definición. Que extraño. http://www.gnu.org/software/emacs/NEWS.23.3 – seh

Cuestiones relacionadas