Apakah ada yang setara dengan perintah substitusi sed-style dari vim?

14

Salah satu hal yang saya lewatkan dari vim adalah bisa mengetikkan perintah substitusi yang akan bekerja pada banyak baris, misalnya:

:/begin/,/end/s/foo/bar/g

Perintah di atas menggantikan "foo" untuk "bar" dimulai dengan baris pertama yang berisi "mulai" dan berakhir dengan baris berikutnya setelah yang berisi "akhir".

Apakah ada cara untuk melakukan hal serupa di emacs?

Larry Coleman
sumber

Jawaban:

7

evilmenyediakan versi strip-down ex, jadi mungkin yang terbaik untuk menganggap bahwa itu bukan drop-in yang tepat. Namun, contoh yang Anda berikan berfungsi di luar kotak, asalkan titik tersebut sebelum baris pertama (yaitu, beginbaris dalam contoh Anda).

Dan
sumber
Dalam vim pencarian juga akan dimulai pada titik, sehingga kedengarannya seperti apa yang saya cari. Terima kasih!
Larry Coleman
8

Berikut adalah salah satu cara melakukannya yang hanya menggunakan fungsionalitas bawaan:

  1. Dengan titik di baris yang berisi kemunculan pertama begin, tekan C-SPC.

  2. Pindah ke kejadian berikutnya end:

    C-s end RET

  3. Ganti foodengan bar:

    M-% foo RET bar RET !

Ini memanfaatkan fakta yang query-replaceakan berfungsi pada wilayah aktif alih-alih seluruh buffer jika ada.


Tentu saja, Anda juga dapat mendefinisikan perintah khusus:

(defun replace-from-to (beg end str repl)
  (interactive "sBegin: \nsEnd: \nsString: \nsReplacement: ")
  (save-excursion
    (goto-char (point-min))
    (let ((start-pos (search-forward beg))
          (end-pos (search-forward end)))
      (replace-string str repl nil start-pos end-pos))))

Perintah ini akan selalu mencari dari awal buffer, jadi titiknya bisa setelah begin/ foo/ endketika Anda memintanya.

Siapkan kunci yang mengikat untuk itu melalui:

(global-set-key (kbd "C-c r") 'replace-from-to)
itu hanya
sumber
5

Secara umum, ini adalah sesuatu yang akan Anda gunakan narrow-to-region.

Anda memindahkan kursor (misalnya, dengan mencari) ke awal wilayah dan tekan C-SPC, lalu pindah ke ujung wilayah dan ketik M-x narrow-to-region. Sekarang Anda dapat mengeluarkan pencarian apa pun dan mengganti perintah yang Anda inginkan dan itu hanya akan berlaku untuk bagian penyempitan buffer. Setelah selesai, ketik M-x widenuntuk mengembalikan konten buffer.

Elias Mårtenson
sumber
4
Jika begin/ endadalah pembatas dalam bahasa pemrograman, Anda mungkin dapat menggunakan C-M-Spaceuntuk menjalankan mark-sexpuntuk memilih wilayah dalam satu perintah.
dgtized
1
Binding default: C-x n n( narrow-to-region) dan C-x n w( widen).
itsjeyd