Berfungsi untuk menghapus semua komentar dari buffer, tanpa menggerakkan mereka untuk mematikan dering

9

Saya harus dapat menghapus semua komentar dari buffer dari kode elisp. Untuk saat ini, saya menggunakan:

(goto-char (point-min))
(comment-kill (count-lines (point-min) (point-max)))

Namun, comment-killadalah fungsi interaktif, dan penggunaan utamanya adalah untuk menghapus satu komentar pada suatu waktu. Selain itu, ia memiliki efek samping yang terlihat menyebalkan, karena ia menambahkan semua komentar yang dimatikannya ke cincin bunuh.

Apakah ada fungsi yang memungkinkan untuk menghapus (tidak membunuh) beberapa atau semua komentar dari buffer?

T. Verron
sumber
Anda bisa melakukan M-x flush-lines ^\s-*\/\/sesuatu untuk itu. Tidak sempurna, tetapi bisa bekerja beberapa kali.
wvxvw
@wvxvw Terima kasih atas sarannya! Namun, saya sempat mempertimbangkan untuk pergi dengan cara ini, dan menyimpulkan bahwa itu akan terlalu rumit: flush-line tidak akan melakukan, karena komentar mungkin tidak mengambil seluruh baris (ganti-regexp akan baik-baik saja kurasa); lebih menjengkelkan, ada beberapa sintaks untuk komentar, dan mereka dapat bersarang, membuatnya (mungkin) di luar jangkauan regexps.
T. Verron
Karena penasaran, apakah Anda ingin komentar dihapus secara permanen atau Anda hanya ingin mengeluarkannya sementara? Apakah Anda mungkin hanya ingin menyembunyikannya?
Drew

Jawaban:

11

Secara umum, tidak ada yang salah dengan menggunakan perintah sebagai bagian dari kode elisp. Fungsi-fungsi yang hanya dimaksudkan untuk penggunaan interaktif akan (atau seharusnya) memperingatkan Anda tentang hal itu. Lihat next-linemisalnya.

Untuk menghapus, alih-alih membunuh, pastikan kill-ringtidak berubah:

(goto-char (point-min))
(let (kill-ring)
  (comment-kill (count-lines (point-min) (point-max))))
Malabarba
sumber
Ya, saya mengerti. Masalah utama saya dengan perintah ini adalah kill-ring (yang Anda jawab), dan masalah optimisasi potensial (yang akan tetap potensial jika tidak ada yang dapat dibandingkan).
T. Verron
7

Jawaban @ Malabarba sepertinya solusi paling sederhana dan elegan. Namun, jika Anda melakukan ini cukup sehingga fungsinya terjamin, Anda juga dapat beradaptasi comment-killuntuk menghapus tanpa mengubah cincin bunuh. Berikut kode sumber comment-killdengan perubahan satu baris untuk didefinisikan comment-delete:

(defun comment-delete (arg)
  "Delete the first comment on this line, if any.  Don't touch
the kill ring.  With prefix ARG, delete comments on that many
lines starting with this one."
  (interactive "P")
  (comment-normalize-vars)
  (dotimes (_i (prefix-numeric-value arg))
    (save-excursion
      (beginning-of-line)
      (let ((cs (comment-search-forward (line-end-position) t)))
    (when cs
      (goto-char cs)
      (skip-syntax-backward " ")
      (setq cs (point))
      (comment-forward)
      ;; (kill-region cs (if (bolp) (1- (point)) (point))) ; original
      (delete-region cs (if (bolp) (1- (point)) (point)))  ; replace kill-region with delete-region
      (indent-according-to-mode))))
    (if arg (forward-line 1))))

Dan inilah fungsi (NB: minimal diuji) yang menyediakan beberapa fungsi tambahan, memungkinkan Anda untuk menghapus komentar pada baris saat ini, di wilayah aktif, atau di seluruh buffer:

(defun comment-delete-dwim (beg end arg)
  "Delete comments without touching the kill ring.  With active
region, delete comments in region.  With prefix, delete comments
in whole buffer.  With neither, delete comments on current line."
  (interactive "r\nP")
  (let ((lines (cond (arg
                      (count-lines (point-min) (point-max)))
                     ((region-active-p)
                      (count-lines beg end)))))
    (save-excursion
      (when lines
        (goto-char (if arg (point-min) beg)))
      (comment-delete (or lines 1)))))

Saya belum memeriksa masalah kinerja, tapi mungkin ada benjolan kecil karena tidak menyentuh cincin pembunuhan. Bagaimanapun, saya ragu Anda akan melihat masalah kinerja kecuali Anda bekerja dengan buffer yang benar-benar besar. Tetapi karena Anda tidak mungkin menggunakan fungsi ini sangat sering, sepertinya itu tidak akan sepadan dengan upaya untuk bekerja pada pengoptimalan.

Dan
sumber
Oh, fungsi yang dijalankan cukup sering, dan kadang-kadang pada buffer besar. Tetapi mesin yang menjadi bagiannya memiliki beberapa kemacetan yang lebih buruk, setidaknya untuk saat ini.
T. Verron