riempire il paragrafo contrassegna il file come modificato, anche se non ha fatto nulla


11

Ogni volta che chiamo fill-paragraph, il buffer è sempre contrassegnato come modificato, anche se il comando non ha avuto effetto (ovvero se il paragrafo è già stato riempito). Crea inoltre un'azione annullabile vuota (facilmente rilevabile con undo-tree-mode). Altri comandi che hanno il potenziale per apportare modifiche, come i comandi di rientro, non contrassegnano il buffer come modificato o creano un'azione annullabile se nulla è stato modificato. C'è un modo per fill-paragraphcontrassegnare il buffer modificato e creare un'azione annullabile solo se ha effettivamente cambiato qualcosa?


Non penso che sia corretto-- M-qnon contrassegna il buffer modificato per impostazione predefinita, almeno dai miei test. Quale modalità stai usando? Immagino che la modalità sia fill-paragraphin qualche modo sovrascritta .
shosti,

@shosti Sto usando la modalità Fondamentale. Il paragrafo deve essere lungo più di una riga (se correttamente compilato).
Lily Chung,

Ah OK, lo vedo ora.
shosti,

Risposte:


2

Si noti che questo problema è stato risolto per il nuovo Emacsen (v.26 in poi).


10

Il problema è che fill-paragraph(o meglio fill-region-as-paragraph) rimuoverà e reinserirà le nuove righe mentre si rompe il paragrafo. Non modificherà il buffer se esiste solo una riga. La no-op nella lista degli annullamenti a cui sei testimone è semplicemente fill-paragraphrimuovere e reinserire le nuove righe.

Non è banale evitarlo. Quello che segue è un trucco piuttosto brutto e altamente inefficiente per buffer di grandi dimensioni, ma forse funziona per te. Il comando imita fill-paragraph( M-q) con lo stesso comportamento, tranne per il fatto che memorizza il contenuto del buffer prima di chiamarlo, e successivamente, se il contenuto è rimasto lo stesso, ripristinerà lo stato di modifica e annullerà l'elenco prima della modifica. Per fare questo, ha bisogno di una copia (due, in realtà) del contenuto del buffer, quindi davvero, questo è abbastanza inefficiente. :-)

(defun my/fill-paragraph (&optional justify region)
  (interactive (progn
                 (barf-if-buffer-read-only)
                 (list (if current-prefix-arg 'full) t)))
  (let ((old-text (buffer-string))
        (old-modified (buffer-modified-p))
        (old-undo-list buffer-undo-list))
    (fill-paragraph justify region)
    (when (equal old-text (buffer-string))
      (setq buffer-undo-list old-undo-list)
      (set-buffer-modified-p old-modified))))

Puoi legarlo a M-q.


1
Sì, questo è stato a lungo un dolore. ;-) Mi chiedo (non ricordo) se una soluzione per questo è stata richiesta in precedenza. Sembra che sarebbe stato.
Drew

Hmmm. Mi chiedo se esiste una soluzione migliore che non deve controllare l'intero buffer, forse potrebbe in qualche modo controllare solo il paragrafo selezionato?
Lily Chung,

fill-paragraphfa una certa distinzione tra vari casi, ovvero si comporta in modo diverso a seconda di una regione attiva, funzioni di paragrafo di riempimento esistenti, ecc. Dovresti replicare quel comportamento per capire quali parti del buffer verranno effettivamente modificate. Possibile, ma difficile. :-)
Jorgen Schäfer,

@Drew C'è stata una lunga discussione al riguardo sulla mailing list dell'anno scorso: bug # 13949: 24.3.50; 'fill-paragraph' non dovrebbe sempre mettere il buffer come modificato
dkim

@dkim: Sì, ora ricordo. E nulla mai è venuto di esso ...
Drew

1

Risposta in ritardo, ma ecco una versione semplice che non modifica il buffer se il testo non cambia.

(defun my-fill-paragraph (&optional justify region)
  "Fill paragraph, but don't modify the buffer if filling doesn't
change the text.  See `fill-paragraph' for details."
  (interactive (progn
                 (barf-if-buffer-read-only)
                 (list (if current-prefix-arg 'full) t)))
  (if (buffer-modified-p)
      ;; if modified: use standard fill-paragraph
      (fill-paragraph justify region)
    ;; if unmodified: get a candidate filled version
    (save-excursion
      (let* ((col fill-column)
             (beg (progn (forward-paragraph -1)
                         (skip-syntax-forward " >")
                         (point)))
             (end (progn (forward-paragraph 1)
                         (skip-syntax-backward " >")
                         (point)))
             (old (buffer-substring-no-properties beg end))
             (new (with-temp-buffer
                    (setq fill-column col)
                    (insert old)
                    (fill-paragraph justify region)
                    (buffer-string))))
        ;; don't modify unless the old and new versions differ
        (unless (string-equal old new)
          (delete-region beg end)
          (insert new))))))

Adatta alcune delle idee nella risposta di @ JorgenSchäfer, ma funziona solo con il paragrafo corrente e solo in modo semplice e separato da spazi (vedi commenti sulla risposta di @ JorgenSchäfer sulle complicazioni sotto il cofano).

Si tratta dell'unico caso d'uso pertinente per i miei scopi (ovvero, l'uso interattivo con prosa "normale", nessuna regione attiva), quindi lo sto pubblicando nel caso in cui qualcuno voglia utilizzarlo o migliorarlo per casi d'uso più complicati .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.