salin konten buffer saat ini dalam buffer temp dan operasikan

8

Saya perlu menyalin isi buffer saat ini ke buffer temp, mengatur buffer itu ke mode utama tertentu untuk mengambil keuntungan dari manfaatnya dan mendapatkan informasi yang saya butuhkan kembali ke logika utama.

Apakah ini benar-benar kegilaan? Dan jika tidak, apa struktur untuk ini?

Trevoke
sumber

Jawaban:

10

Jika Anda ingin menyalin beberapa informasi ke buffer lain, dan sejak saat itu biarkan buffer berkembang secara independen, Anda dapat melakukan hal itu .

Tetapi jika Anda ingin buffer lain untuk mencerminkan konten asli secara real time, maka Emacs menyediakan ini dengan buffer tidak langsung . Buffer tidak langsung adalah buffer lain yang memiliki konten yang sama seperti aslinya (modifikasi dalam satu buffer tercermin dalam buffer lain), tetapi pengaturan berbeda: mode utama berbeda, mode kecil berbeda, variabel lokal berbeda, titik berbeda, tanda berbeda , penyempitan yang berbeda, dll.

Jadi, Anda dapat melihat sebagian buffer dalam mode utama yang berbeda, sambil melacak modifikasi di buffer asli dan memantulkan modifikasi kembali ke buffer asli. Pertama buat buffer tidak langsung dengan M-x clone-indirect buffer; ada juga clone-indirect-buffer-other-windowyang terikat C-x 4 c( C-x 4awalan jendela, dan cuntuk klon ). Di buffer kloning, persempit ke wilayah yang Anda inginkan: pilih bagian yang menarik dan jalankan C-x n n( narrow-to-region). Ubah mode utama seperti yang diinginkan.

Anda dapat mengotomatiskannya dengan perintah seperti ini untuk penggunaan interaktif:

(defun edit-region-in-foo-mode (beg end)
  (interactive "@r")
  (let ((new-buffer (clone-indirect-buffer nil t)))
    (narrow-to-region beg end)
    (foo-mode)))

Untuk penggunaan pemrograman:

(defmacro with-indirect-buffer-in-foo-mode (beg end &rest body)
  `(with-current-buffer (clone-indirect-buffer nil nil)
     (narrow-to-region beg end)
     (foo-mode)
     (unwind-protect
         ,body
       (kill-buffer (current-buffer)))))
Gilles 'SANGAT berhenti menjadi jahat'
sumber
8

Sesuatu seperti ini:

(let ((old-buffer (current-buffer)))
  (with-temp-buffer
    (insert-buffer-substring old-buffer)
    (my-favourite-major-mode 1)
    (extract-needed-information)))
legoscia
sumber
2
Menulis hampir persis seperti itu. Hanya membungkusnya dalam defun jika Anda harus dapat menyebutnya secara sewenang
Jonathan Leech-Pepin
Itu terlihat cukup bagus. Saya akan menunggu sedikit, kalau-kalau ada sesuatu yang lebih baik untuk ditandai sebagai diterima, tapi saya pikir ini dia :)
Trevoke
Saya sebenarnya menyarankan M-x copy-to-buffer, lalu saya merah jawaban @legoscia, yang mungkin apa yang Anda inginkan. jika proses ekstraksi & mode utama sama, suatu fungsi akan lebih baik
Nsukami _
2

Saya menyukai apa yang ditulis @Gilles. Saya memodifikasi apa yang ditulis @Gilles untuk menanyakan kepada pengguna mode apa yang ingin mereka gunakan. Anda dapat mengedit apa yang saya tulis untuk memberikan mode apa pun yang Anda inginkan atau bahkan mengubah panggilan untuk menyelesaikan membaca sehingga itu akan memungkinkan Anda untuk memberikan mode yang tidak disediakan dalam daftar default.

(defun edit-region-in-mode (beg end)
  "Create an indirect buffer cloned from the current buffer and
  narrowed to the highlighted region. The cloned indirect buffer
  will have org-mode active. Changes to the indirect buffer will
  be updated in real time in the originating buffer. This is
  useful, for instance, when you are in a non-org-mode mode and
  want to edit table data or in a non-emacs-lisp mode and want to
  write some elisp utilizing code formatting and highlighting."
  (interactive "@r")
  (let ((new-buffer (clone-indirect-buffer nil t)))
    (narrow-to-region beg end)
    (funcall
     (intern
      (completing-read
       "Choose the mode you want to use when editing the highlighted region: "
       '(org-mode emacs-lisp-mode lisp-mode haskell-mode julia-mode
          python-mode mathematica-mode matlab-mode c++-mode))))))
Joe
sumber
1

Untuk kasus penggunaan yang serupa, saya telah menulis fungsi elisp modi/switch-to-scratch-and-backyang memungkinkan Anda untuk beralih dengan cepat antara buffer FILE dan buffer * scratch * yang memiliki mode-utama yang sama dengan buffer FILE. Fungsi hyperlink di atas akan mengarahkan Anda ke pertanyaan SE emacs yang ada.

Inilah cara Anda menggunakan fungsi itu:

  • Buat fungsi pembungkus untuk menyalin buffer yang ada, buat buffer * scratch * dengan mode mayor yang sama dan tempel konten yang disalin.

Berikut adalah contoh fungsi wrapper

(defun copy-current-buffer-to-scratch ()
 "Copied the current buffer, open scratch, paste it there."
  (interactive)
  (kill-ring-save (point-min) (point-max))
  (modi/switch-to-scratch-and-back)
  (yank))
  • Anda sekarang dapat mengikat ini copy-current-buffer-to-scratchke kunci jika Anda ingin dan menjalankannya akan memberi Anda * awal * buffer dengan konten dari buffer kerja Anda.
  • Setelah Anda puas dengan pengeditan di buffer awal, Anda harus menyalin kembali bagian yang diperlukan secara manual ke buffer asli.

Ini hanyalah cara lain untuk melakukan apa yang Anda inginkan; Anda mungkin ingin menggunakan buffer tidak langsung yang dibicarakan oleh solusi @Gilles. Pendekatan ini berguna jika Anda perlu melakukan beberapa pengeditan berat dalam buffer sementara tanpa mempertaruhkan penghematan yang tidak disengaja di buffer asli hingga Anda telah mencapai solusi stabil.

Contoh use case sedang mencoba fungsi elisp eksperimental sebelum menyimpannya ke emacs init Anda.

Kaushal Modi
sumber