Cara membungkus teks yang diberikan di sekitar wilayah

11

Saya sering mengalami situasi di mana saya perlu menerapkan teks di sekitar suatu wilayah. Untuk HTML dan kasus sederhana sudah ada perpustakaan untuk ini. Tetapi bagaimana dengan kasus umum? Saya ingin ditanya apa yang akan saya masukkan mulai dan akhir dari wilayah ini.

nperson325681
sumber
Apakah Anda ingin menggunakannya untuk memasukkan konten sewenang-wenang sekali, atau beberapa pasang, berkali-kali? Dalam kasus terakhir, perpustakaan seperti smartparens terbukti bermanfaat, dan mereka dapat diperluas dengan pasangan khusus. Misalnya, Anda bisa menambahkan pasangan <?php... ?>, dan kemudian, ketika Anda memilih wilayah dan jenis <?php(atau pengikat tombol), buat pasangan itu dibungkus dengan pasangan. Tetapi afaik tidak ada cara mudah untuk menggunakan perpustakaan ini jika Anda memiliki banyak pasangan satu-shot.
T. Verron
@ T. Verron: Saya tahu itu ada. Tetapi untuk saat-saat ketika ada kebutuhan unik untuk pergi melalui kode dan menandai hal-hal fungsi tunggal, umum, dapat digunakan kembali paling cocok
nperson325681

Jawaban:

6

Saya mencari di Google dan menemukan posting ini oleh John D. Cook . Dia menunjukkan bagaimana membangun fungsi interaktif sederhana untuk mendapatkan tag HTML / XML di seluruh wilayah dengan mudah. Dari sana saya memodifikasi fungsi untuk bertanya dua kali.

(defun tag-word-or-region (text-begin text-end)
  "Surround current word or region with given text."
  (interactive "sStart tag: \nsEnd tag: ")
  (let (pos1 pos2 bds)
    (if (and transient-mark-mode mark-active)
        (progn
          (goto-char (region-end))
          (insert text-end)
          (goto-char (region-beginning))
          (insert text-begin))
      (progn
        (setq bds (bounds-of-thing-at-point 'symbol))
        (goto-char (cdr bds))
        (insert text-end)
        (goto-char (car bds))
        (insert text-begin)))))

Lebih penting lagi, fungsi ini dapat juga digunakan sebagai alat bantu, misalnya ketika Anda ingin mengikat kunci untuk memetakan beberapa bit teks tertentu.

(defun tag-php ()
  (interactive)
  (tag-word-or-region "<?php " "?>"))
nperson325681
sumber
Btw, cara ini menangani beberapa kasus batas tidak optimal; pencarian awal kadang-kadang bisa gagal dan meninggalkan kedua tag di akhir. Bisa jadi evilsaya menggunakan yang mengganggu di sini. Mungkin fungsi tipe interactive "r" bekerja lebih kuat?
nperson325681
4

Saya akan menyarankan pendekatan yang berbeda. Ketika ada suatu wilayah, menurut definisi pointharus di awal (atau akhir) dari wilayah tersebut, dan markakan berada di akhir (atau awal). Yang berarti Anda dapat memasukkan teks yang Anda inginkan di titik, dan kemudian menggunakan exchange-point-and-mark, yaitu C-x C-x, untuk melompat ke ujung wilayah lain. Masukkan bagian kedua bungkus Anda dan Anda selesai.

Anda tidak diminta secara eksplisit diminta untuk memasukkan teks, tetapi saya tidak bisa membayangkan akan ada cara untuk mencapai hal yang sama dengan sedikit usaha.

Tyler
sumber
Jika teks awal dan akhir sama, saya ingin tahu apakah sesuatu seperti multiple-cursorsdapat diubah untuk menyisipkan teks secara bersamaan di awal dan akhir wilayah aktif.
glukas
Kedengarannya seperti cara manual yang terpaksa dilakukan oleh pengguna editor yang lebih rendah. Lagi pula saya membaca penggunaan makro sebagai subteks dari jawaban Anda, harus mengatakan. Saya suka gaya Anda
nperson325681
1
@progo - Terima kasih :) Kedengarannya seperti pendekatan yang lebih manual, tetapi sebenarnya menggunakan lebih sedikit penekanan tombol dari alternatif Anda. Dengan pendekatan ini, selain dari teks pembungkus, Anda hanya perlu C-x C-x. Dengan jawaban Anda, Anda perlu memanggil fungsi Anda ( C-c something), dan Anda juga harus menekan returnsetelah setiap entri. Jadi, apa pun yang Anda lakukan, Anda memiliki dua penekanan tombol lagi. Yang mengatakan, itu tidak membantu jika Anda menginginkan sesuatu untuk dipanggil dari elisp.
Tyler
3

Hanya demi variasi:

Cara lain untuk melakukan ini dengan teks awal dan akhir sewenang-wenang adalah dengan menggunakan replace-regexpdi wilayah: cocokkan .+dan ganti dengan before \& after, atau teks apa pun yang ingin Anda gunakan untuk beforedan after.

Anda bisa menulis perintah lakukan untuk ini, tapi saya sedang memikirkan kasus di mana dalam file yang diberikan Anda ingin menerapkan teks awal / akhir yang sama di beberapa tempat. Anda dapat merekam makro atau cukup gunakan riwayat minibuffer untuk mengulangi di wilayah lain.

Tentu saja jika teks yang ingin Anda bungkus dapat diekspresikan sebagai ekspresi reguler maka Anda bahkan tidak perlu memilih wilayah dan dapat melakukan query-replace-regexppada buffer, tetapi mungkin teks yang ingin Anda bungkus tidak konsisten.

glukas
sumber