2010-04-23 11 views
7

The documentation on Text Properties dice:Emacs: come gestire in modo intelligente il buffer modificato quando si impostano le proprietà del testo?

Poiché le proprietà del testo sono considerati parte del contenuto del buffer (o stringa), e possono interessare come un buffer appare sullo schermo, qualsiasi cambiamento di proprietà di testo tampone segna il buffer come modificato .

In primo luogo, non capisco quella politica. Qualcuno può spiegare? Gli oggetti di scena non vengono effettivamente salvati nel file, quando il buffer viene salvato. Quindi, perché contrassegnare il buffer come modificato? Per me, il buffer modificato indica "alcune modifiche non sono state ancora salvate". ma capire la politica è solo per il mio divertimento.

Ancora più importante, c'è un modo già stabilito che, nel codice, posso modificare le proprietà del testo di sintassi sul testo in un buffer, mantenendo il flag modificato dal buffer impostato su qualunque esso fosse, prima di tali modifiche? Sto pensando a qualcosa come save-excursion. Sarebbe abbastanza facile scrivere, ma questo sembra un caso comune e mi piacerebbe usare la funzione standard, se possibile.

Per ulteriori informazioni sullo scenario: dispongo di una modalità che esegue una scansione completa del testo e imposta le proprietà della tabella di sintassi sul testo. Dopo aver aperto un buffer, la scansione viene eseguita, ma si verifica un buffer con il set di modifiche del buffer su t.

Come sempre, grazie.

risposta

3

Wait! Ho trovato questo in 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

Bello, non l'ho visto. Un po 'più completo di quello in pabbrev. –

1

Forse è semplicemente perché sono considerati parte della stringa ... (come dicono i documenti). Ricorda, Emacs è buffer -centric, non file-centrico, quindi il fatto che i contenuti vengano salvati su disco è in qualche modo irrilevante (quando si pensa al buffer-centrico).

Inoltre, le proprietà sono irreversibili e sicuramente si adattano al fatto che il buffer sia contrassegnato come modificato.

Non so che c'è un modo standard di salvare lo stato del buffer modificato, ma lo faccio vedere uno nella pabbrev.el libreria:

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

non protegge contro nonlocal exits, quindi forse che ci si vuole aggiungere una chiamata a unwind-protect, in questo modo:

(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

eccellente, grazie. Avevo la parte 'set-buffer-modified-p', ma non la cosa' buffer-undo-list'. – Cheeso

+0

Ma aspetta! Questo è ancora utile, ma guarda la mia risposta. – Cheeso

5

Le versioni più recenti di Emacs includono la macro "con-silent-modifiche" per questo:

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

Il registro delle modifiche di Emacs per la versione 23.3 menziona l'introduzione di 'with-silent-modifications', ma la versione di build di Windows 23.3.1 manca ancora di tale definizione. Che strano. http://www.gnu.org/software/emacs/NEWS.23.3 – seh

Problemi correlati