Bagaimana cara memilih daerah yang tidak berdekatan di Emacs?

31

Misalkan saya sudah memilih beberapa teks dalam buffer saat ini. Apakah mungkin untuk memilih rangkaian teks lainnya, sambil tetap mempertahankan pilihan sebelumnya (dan seterusnya)?

Ditambahkan : Salah satu motivasi untuk fungsi ini adalah sebagai berikut: Asumsikan bahwa saya memiliki beberapa teks yang terlihat seperti ini:

paragraph 1 ...

paragraph 2 ...

paragraph 3 ...

paragraph 4 ...

paragraph 5 ...

Saya ingin menghapus beberapa paragraf (mis. 2, 4 dan 6) dan menyisipkannya sebelum paragraf 1.

Nama
sumber
1
Ada pilihan kedua .
wasamasa
2
Ada paket multiselect: skamphausen.de/cgi-bin/ska/multiselect Ini terlihat seperti hack cepat.
Tobias
Bergantung pada ukuran apa yang Anda pilih dan mengapa, multiple-cursorsdapat memberi Anda solusi.
Jordon Biondo
@wasamasa saya mengikuti instruksi yang diberikan di tautan yang Anda berikan. Setelah pemilihan pertama, saya memilih wilayah kedua saya menyimpan kunci Meta. Itu dipilih, tetapi ada dua masalah: (1) pilihan kedua tampaknya bukan pilihan nyata, karena menyalin atau menghapus tidak berfungsi. (2) tidak mungkin untuk memilih pilihan ketiga dengan cara ini.
Nama
1
Wiki Emacs memiliki bagian yang bagus tentang pemilihan sekunder . Berbagai perangkat tambahan membuatnya lebih dapat digunakan dari keyboard, misalnya.
Drew

Jawaban:

43

Anda dapat menggunakan append-next-kill(terikat C-M-wsecara default) untuk mengakumulasi teks yang ingin Anda masukkan di atas paragraph 1:

  1. Bunuh paragraph 2seperti biasa.

  2. Tandai paragraph 4dan tekan C-M-wsebelum membunuhnya. Ulangi langkah ini untuk semua paragraf yang ingin Anda pindahkan sebelumnya paragraph 1.

Setelah selesai, Anda dapat menarik teks akumulasi sebelumnya paragraph 1.

itu hanya
sumber
5
Bahkan dengan hal-hal dasar, selalu ada beberapa hal baru untuk dipelajari! Ini sangat berguna, karena saya biasanya membuang banyak penekanan tombol dengan melakukan perjalanan ke cincin bunuh ketika saya perlu melakukan ini. Seandainya saya bisa memperbaiki ini lagi ...
Makna Nama
9

Anda dapat menggunakan register yang dikombinasikan dengan cincin tanda. Dorong tanda saat ini dengan C-<SPC> C-<SPC>, pulihkan dengan C-u C-<SPC>, atau simpan dalam register, katakan b, via C-x r <SPC> b, dan lompati kembali nanti C-x r j b.

Sekarang tandai wilayah lain. C-u C-x r s aakan menyalin wilayah yang ditandai untuk mendaftar adan menghapus teks. Kemudian tandai wilayah berikutnya dan C-u C-x r + aakan menambahkan pilihan lain ke register itu adan menghapusnya.

Anda kemudian dapat memasukkan konten dengan C-x r i a.

Lihat bagian "Menyimpan Teks di Register" pada manual Emacs.

Andrew Swann
sumber
5

Dukungan wilayah-persegi panjang baru di Emacs-24.4 sebenarnya memperkenalkan (sebagian besar) infrastruktur yang diperlukan untuk fungsi ini [setelah semua, wilayah persegi panjang adalah wilayah yang tidak bersebelahan].

Jadi, sekarang mungkin untuk mengimplementasikan paket "wilayah terpisah" yang hanya menyediakan fungsionalitas yang Anda minta.

Memang, banyak perintah Emacs masih belum diadaptasi untuk menggunakan infrastruktur baru (mis. Perintah seperti upcase-region, atau undo-in-region, query-replace, ...) dan karenanya belum bekerja dengan baik pada persegi panjang. (jadi mereka juga tidak akan bekerja dengan baik pada "wilayah terpisah"), tetapi ini adalah bug yang semestinya diperbaiki dari waktu ke waktu.

Stefan
sumber
4

Instal browse-kill-ring.el

menyalin dan membunuh semua wilayah yang diminati.

Harus menunjukkan di mana penyisipan ulang harus dimulai.

M-x browse-kill-ring RET akan membuka buffer dan menempatkan kursor di dalamnya.

Ketik nuntuk melakukan perjalanan.

RET akan ada masukkan chunk pada titik di buffer asli / lainnya.

Andreas Röhler
sumber
3

Jika garis yang ingin Anda manipulasi dapat dibedakan melalui pencocokan regex, Anda dapat menggunakan mode-terjadi untuk melihatnya di jendela baru. Anda kemudian dapat menggunakan mode terjadi-edit untuk mengeditnya, dengan buffer asli mencerminkan perubahan yang Anda buat di buffer Occur.

Ini berfungsi sangat baik, misalnya, dalam kombinasi dengan mode multi-kursor : karena garis yang Anda pilih untuk muncul di buffer Occur ditampilkan secara berdekatan terlepas dari seberapa jauh mereka berada di buffer asli, Anda dapat menandai semuanya atau subset lalu aktifkan mc/edit-linesdan edit semuanya sekaligus. (Ya, saya tahu beberapa kursor dapat melakukan ini dengan sendirinya mc/mark-all-like-this, tetapi senang memiliki opsi.)

Operasi pengeditan lainnya yang akan lebih mudah dilakukan jika Anda hanya melihat baris yang ingin Anda kerjakan, seperti menyiapkan pencarian dan penggantian regex yang rumit, atau makro yang perlu dijalankan pada setiap baris buffer pada gilirannya, bisa juga dilakukan dengan cara ini.

dodgethesteamroller
sumber
3

Ini menanggapi pertanyaan umum Anda, tetapi tidak terutama untuk kasus penggunaan yang Anda sebutkan (memindahkan bit kode).

Emacs sekarang memiliki apa yang disebutnya wilayah yang tidak bersebelahan , yang merupakan jenis seleksi yang Anda tanyakan. Vanilla Emacs tidak menyediakan cara khusus untuk membuat wilayah yang tidak bersebelahan, kecuali jika itu adalah persegi panjang . Tapi perpustakaan Zona tidak.

Zona Perpustakaan memungkinkan Anda menentukan beberapa zona dalam buffer Anda. Sebuah daftar zona adalah daerah noncontiguous . Anda juga bisa menganggapnya sebagai beberapa wilayah, tergantung pada bagaimana Anda ingin menggunakannya. Anda dapat memiliki beberapa daftar zona yang ditentukan kapan saja, masing-masing ditugaskan ke variabel zona yang berbeda, dan Anda dapat beralih di antaranya.

Jika Anda juga menggunakan perpustakaan Bookmark + maka Anda dapat menyimpan daftar zona secara terus-menerus dan mengembalikannya di sesi Emacs nanti. Bookmark + juga memungkinkan Anda menetapkan tag sewenang-wenang ke bookmark. Ini berarti Anda dapat menandai daftar zona.

Zona-zona dalam daftar zona tertentu biasanya di buffer yang sama, tetapi mereka tidak perlu. Dalam hal ini, daftar zona lebih umum daripada wilayah yang tidak berdekatan. Ini juga lebih umum karena setiap zona dapat berisi informasi tambahan, selain hanya batas zona, dan dapat memiliki pengidentifikasi.

Ada beberapa cara untuk membuat zona. Salah satu yang paling mudah adalah dengan menggunakannya C-x n a: ia mendefinisikan zona dari wilayah aktif, dan menambahkannya ke set zona saat ini. ( C-x n n( narrow-to-region) juga melakukan ini, selain penyempitan.)

Ini adalah beberapa hal yang dapat Anda lakukan dengan satu set (daftar) zona:

  • Sortir mereka.
  • Menyatukan (menyatu) zona yang berdekatan atau tumpang tindih (yang termasuk menyortirnya).
  • Persimpangan mereka.
  • Persempit buffer ke zona dalam daftar. Siklus di antara penyempitan. Lihat Banyak Penyempitan .
  • Pilih zona dalam daftar sebagai wilayah aktif. Siklus antar wilayah.
  • Cari mereka (mereka secara otomatis bersatu terlebih dahulu). Untuk ini, Anda perlu pustaka Isearch + .
  • Permintaan-ganti mereka.
  • Sorot dan sorot mereka. (Untuk ini, Anda memerlukan Sorotan perpustakaan atau perpustakaan facemenu+.el.

Lihat juga Narrow Indirect , yang memungkinkan Anda membuat buffer tidak langsung yang merupakan klon dari buffer yang diberikan dan yang dipersempit ke bagian yang berbeda.

Drew
sumber
2

Pilihan lain: Transposing paragraf

Demi kelengkapan, Anda dapat mencapai pemesanan ulang paragraf (berurutan) dengan wilayah yang ditandai dan M-0 M-x transpose-paragraph(argumen nol membuat tra-parswap paragraf di mana titik dan tanda berada, yaitu wilayah dimulai dan berakhir)!

Ngomong-ngomong ini berfungsi untuk semua transpose-.*perintah (-words, -sexp, -sentences, ...) dan sangat berguna dalam banyak situasi.

Dieter.Wilhelm
sumber
2

Cara lain adalah dengan menggunakan paket keberatan (saya penulis). Anda dapat menandai objek teks apa pun dengan mtitik dipindahkan ke objek berikutnya dari tipe saat ini secara otomatis. Hapus tanda objek apa pun dengan menavigasi ke sana dan tekan m lagi. Berikut ini adalah contoh screencast (menunjukkan garis tanda tetapi berfungsi untuk objek lain seperti paragraf, defun ... juga):

masukkan deskripsi gambar di sini

clemera
sumber
Ketika saya mencoba menginstal paket ini dari Melpa saya mendapatkan kesalahan package-install-from-archive: http://melpa.milkbox.net/packages/objed-20181201.1346.tar: Not found.
Nama
@Nama Kedengarannya seperti perlu memperbarui daftar paket Anda. Coba M-x package-refresh-contentskemudian M-x package-install.
clemera
@Nama Apakah itu berfungsi sekarang? Beri tahu saya jika Anda memiliki pertanyaan lebih lanjut.
clemera
Saya dapat menginstal paket. Tampaknya berfungsi dengan baik, saya belum menguji semua fitur-fiturnya. Terima kasih.
Nama