el archivo de marcas de párrafo de relleno ha cambiado, incluso si no hizo nada

11

Cada vez que llamo fill-paragraph, el búfer siempre se marca como modificado, incluso si el comando no tuvo efecto (es decir, si el párrafo ya estaba lleno). También crea una acción vacía que se puede deshacer (se detecta fácilmente con undo-tree-mode). Otros comandos que tienen el potencial de realizar cambios, como los comandos de sangría, no marcan el búfer como modificado o crean una acción que no se puede deshacer si no se cambió nada. ¿Hay alguna forma de fill-paragraphmarcar el búfer modificado y crear una acción que no se puede deshacer solo si realmente cambió algo?

Lily Chung
fuente
No creo que esto sea correcto M-q: no marca el búfer cambiado de forma predeterminada, al menos desde mi prueba. ¿Qué modo estás usando? Supongo que el modo se sobrescribe fill-paragraphde alguna manera.
shosti
@shosti Estoy usando el modo Fundamental. El párrafo tiene que tener más de una línea de largo (cuando se llena correctamente).
Lily Chung
Ah ok ya lo veo ahora.
shosti

Respuestas:

2

Tenga en cuenta que esto se corrige para Emacsen más reciente (v.26 hacia arriba).

clemera
fuente
10

El problema es que fill-paragraph(o más bien fill-region-as-paragraph) eliminará y volverá a insertar nuevas líneas mientras desglosa su párrafo. No modificará el búfer si solo hay una línea. El no-op en la lista de deshacer que presencia es simplemente fill-paragrapheliminar y volver a insertar nuevas líneas.

No es trivial evitar esto. El siguiente es un truco bastante malo, y altamente ineficiente para grandes buffers, pero tal vez funcione para usted. El comando imita fill-paragraph( M-q) con el mismo comportamiento, excepto que almacena el contenido del búfer antes de llamarlo, y luego, si el contenido permaneció igual, restaurará el estado de modificación y la lista de deshacer antes del cambio. Para hacer esto, necesita una copia (dos, en realidad) del contenido del búfer, así que realmente, esto es bastante ineficiente. :-)

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

Puedes vincular eso a M-q.

Jorgen Schäfer
fuente
1
Sí, esto siempre ha sido un dolor. ;-) Me pregunto (no recuerdo) si ya se ha solicitado una solución para esto. Parece que hubiera sido.
Drew
Hmmm Me pregunto si hay una mejor solución que no tenga que verificar todo el búfer, ¿tal vez podría verificar solo el párrafo seleccionado de alguna manera?
Lily Chung
fill-paragraphhace alguna distinción entre varios casos, es decir, se comporta de manera diferente dependiendo de una región activa, funciones de párrafo de relleno existentes, etc. Tendría que replicar ese comportamiento para determinar qué partes del búfer se cambiarán realmente. Posible, pero complicado. :-)
Jorgen Schäfer
@Drew Hubo una larga discusión al respecto en la lista de correo el año pasado: error # 13949: 24.3.50; 'fill-párrafo' no siempre debe poner el búfer como modificado
dkim
@dkim: Sí, lo recuerdo ahora. Y nunca nada ha sido así ...
dibujó
1

Respuesta tardía, pero aquí hay una versión simple que no modifica el búfer si el texto no 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))))))

Adapta algunas de las ideas en la respuesta de @ JorgenSchäfer, pero funciona solo con el párrafo actual, y solo de una manera simple, separada por espacios en blanco (ver comentarios en la respuesta de @ JorgenSchäfer sobre complicaciones bajo el capó).

Este es el único caso de uso que es relevante para mis propios fines (es decir, uso interactivo con prosa "normal", sin región activa), así que lo publico en caso de que alguien quiera usarlo o mejorarlo para casos de uso más complicados .

Dan
fuente