файл знаків заповнення абзацу змінено, навіть якщо він нічого не зробив


11

Щоразу, коли я викликаю fill-paragraph, буфер завжди позначається як змінений, навіть якщо команда не мала ефекту (тобто якщо абзац вже заповнений). Це також створює порожню непридатну дію (легко виявляється за допомогою undo-tree-mode). Інші команди, які можуть вносити зміни, такі як команди відступу, не позначають буфер як змінений або створюють невідмінні дії, якщо нічого не було змінено. Чи є спосіб зробити fill-paragraphпозначення буфера модифікованим та створити непридатні дії, лише якщо він насправді щось змінив?


Я не думаю, що це правильно M-q- не позначає буфер, змінений за замовчуванням, принаймні з мого тестування. Який режим ви використовуєте? Я б здогадався, що режим fill-paragraphякимось чином перезаписується .
shosti

@shosti Я використовую Основний режим. Абзац повинен містити більше одного рядка (при належному заповненні).
Лілі Чунг

Ну добре, я це зараз бачу.
shosti

Відповіді:



10

Проблема полягає в тому, що fill-paragraph(а точніше, fill-region-as-paragraph) буде видаляти та вставляти нові рядки під час розбиття вашого абзацу. Він не змінить буфер, якщо є лише один рядок. Відмова в списку скасування, про який ви свідчите, лише fill-paragraphвидаляє та вставляє нові рядки.

Уникнути цього нетривіально. Далі йде досить поганий злом і дуже неефективний для великих буферів, але, можливо, він працює для вас. Команда імітує fill-paragraph( M-q) з однаковою поведінкою, за винятком того, що вона зберігає вміст буфера до виклику, а потім, якщо вміст залишився колишнім, він відновить стан модифікації та скасує список до зміни. Для цього йому потрібна копія (дві, фактично) вмісту буфера, так що насправді це досить неефективно. :-)

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

Ви можете зв’язати це M-q.


1
Так, це вже давно болить. ;-) Цікаво (не пригадую), чи вимагали виправлення цього раніше. Схоже, це було б.
Дрю

Хммм. Цікаво, чи є краще рішення, яке не повинно перевіряти весь буфер - можливо, воно могло б якось перевірити лише вибраний абзац?
Лілі Чунг,

fill-paragraphробить деяку різницю між різними випадками, тобто поводиться по-різному в залежності від активного регіону, існуючих функцій заповнення абзацу тощо. Вам доведеться повторити таку поведінку, щоб з'ясувати, які частини буфера насправді будуть змінені. Можливо, але хитро. :-)
Йорген Шефер

@Drew У минулому році в цьому списку розсилки було тривало обговорення: помилка № 13949: 24.3.50; 'абзац fill' не завжди повинен ставити буфер як змінений
dkim

@dkim: Так, зараз я пам’ятаю. І нічого з цього нічого не вийшло ...
Дрю

1

Пізня відповідь, але ось проста версія, яка не змінює буфер, якщо текст не змінюється.

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

Він адаптує деякі ідеї у відповіді @ JorgenSchäfer, але працює лише з поточним пунктом і лише простим, розділеним пробілом способом (див. Коментарі до відповіді @ JorgenSchäfer про ускладнення під кришкою).

Мова йде про єдиний випадок використання, який стосується моїх власних цілей (тобто, інтерактивне використання з "звичайною" прозою, не активний регіон), тому я публікую його на випадок, якщо хтось хоче його використати або покращити для складніших випадків використання. .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.