isi tanda paragraf file seperti yang diubah, meskipun itu tidak melakukan apa-apa

11

Setiap kali saya menelepon fill-paragraph, buffer selalu ditandai sebagai dimodifikasi, bahkan jika perintah tidak berpengaruh (yaitu jika paragraf sudah diisi). Ini juga menciptakan tindakan kosong yang tidak dapat dibatalkan (mudah dideteksi dengan undo-tree-mode). Perintah lain yang berpotensi membuat perubahan, seperti perintah indentasi, jangan tandai buffer sebagai dimodifikasi atau buat tindakan yang tidak dapat diurungkan jika tidak ada yang berubah. Apakah ada cara untuk fill-paragraphmenandai buffer yang dimodifikasi dan membuat tindakan yang tidak dapat dihentikan hanya jika benar-benar mengubah sesuatu?

Lily Chung
sumber
Saya tidak berpikir ini M-qbenar - tidak menandai buffer diubah secara default, setidaknya dari pengujian saya. Mode apa yang Anda gunakan? Saya kira mode menimpa fill-paragraphdalam beberapa cara.
shosti
@shosti Saya menggunakan mode Fundamental. Paragraf harus lebih dari satu baris (bila diisi dengan benar).
Lily Chung
Ah oke saya melihatnya sekarang.
shosti

Jawaban:

2

Perhatikan bahwa ini diperbaiki untuk Emacsen yang lebih baru (v.26 ke atas).

clemera
sumber
10

Masalahnya adalah fill-paragraph(atau lebih tepatnya, fill-region-as-paragraph) akan menghapus dan memasukkan kembali baris baru saat paragraf Anda rusak. Itu tidak akan mengubah buffer jika hanya ada satu baris. No-op dalam daftar undo yang Anda saksikan hanya fill-paragraphmenghapus dan memasukkan kembali baris baru.

Tidak sepele untuk menghindari ini. Berikut ini adalah peretasan yang sangat buruk, dan sangat tidak efisien untuk buffer besar, tetapi mungkin berhasil untuk Anda. Perintah meniru fill-paragraph( M-q) dengan perilaku yang identik, kecuali ia menyimpan isi buffer sebelum memanggilnya, dan setelah itu, jika konten tetap sama, itu akan mengembalikan keadaan modifikasi dan membatalkan daftar dari sebelum perubahan. Untuk melakukan ini, diperlukan salinan (dua, sebenarnya) dari konten buffer, jadi sungguh, ini sangat tidak efisien. :-)

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

Anda dapat mengikat itu M-q.

Jorgen Schäfer
sumber
1
Ya, ini sudah lama menyakitkan. ;-) Saya ingin tahu (saya tidak ingat) apakah perbaikan untuk ini telah diminta sebelumnya. Sepertinya itu akan terjadi.
Drew
Hmmm. Saya bertanya-tanya apakah ada solusi yang lebih baik yang tidak harus memeriksa seluruh buffer - mungkin bisa saja hanya memeriksa paragraf yang dipilih?
Lily Chung
fill-paragraphapakah ada perbedaan antara berbagai kasus, yaitu berperilaku berbeda tergantung pada wilayah aktif, fungsi paragraf isi yang ada, dll. Anda harus meniru perilaku itu untuk mengetahui bagian buffer yang mana yang akan diubah. Mungkin, tapi rumit. :-)
Jorgen Schäfer
@Drew Ada diskusi panjang tentang hal itu di milis tahun lalu: bug # 13949: 24.3.50; 'fill-paragraf' tidak harus selalu menempatkan buffer sebagai diubah
dkim
@dkim: Ya, saya ingat sekarang. Dan tidak ada yang datang darinya ...
Drew
1

Jawaban telat, tapi ini versi sederhana yang tidak mengubah buffer jika teksnya tidak berubah.

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

Ini mengadaptasi beberapa ide dalam jawaban @ JorgenSchäfer, tetapi hanya bekerja dengan paragraf saat ini, dan hanya dengan cara sederhana, dipisahkan dengan spasi putih (lihat komentar pada jawaban @ JorgenSchäfer tentang komplikasi di bawah tenda).

Ini adalah satu-satunya kasus penggunaan yang relevan untuk keperluan saya sendiri (yaitu, penggunaan interaktif dengan prosa "normal", tidak ada wilayah aktif), jadi saya mempostingnya jika ada yang ingin menggunakannya atau memperbaikinya untuk kasus penggunaan yang lebih rumit .

Dan
sumber