Bagaimana cara bolak-balik antara dua lokasi dalam buffer

38

Terkadang saya sering menemukan diri saya berganti-ganti antara dua fungsi yang saya edit bersama satu sama lain. Dalam situasi ini, sangat membosankan dan menyakitkan untuk terus melakukan C-s <functionname>untuk beralih ke fungsi lain dan kemudian menemukan tempat yang tepat yang saya edit sebelumnya.

Bagaimana cara mengatur penanda dan kemudian melompat-lompat antara dua lokasi di buffer dengan mudah?

Vedaad Shakib
sumber
3
Kamu melakukannya dengan salah. Anda harus memiliki tampilan pemisahan vertikal sehingga Anda melihat kedua fungsi pada saat yang sama.
Kapten
8
Saya tidak setuju bahwa OP "melakukan kesalahan." Meskipun jendela terpisah akan sangat membantu, OP masih harus melompat bolak-balik di antara jendela saat mengedit kedua fungsi. Selain itu, pertanyaannya lebih umum daripada kasus penggunaan khusus: OP ingin dapat melompat ke lokasi yang berbeda dalam buffer dengan cepat. Banyak jawaban di bawah ini memberikan sejumlah cara berguna untuk melakukannya.
Dan
@Dan Itu pria keren, dan saya setuju dengan Anda, tetapi tanggapan saya tidak dimaksudkan untuk menyelesaikan masalahnya - hanya untuk menunjukkan bahwa ada cara alternatif.
Kapten
4
@ KaptenCodeman, tidak apa-apa, meskipun jawaban T. Vernon di bawah ini memang memberikan alternatif jendela terpisah. Silakan perlakukan komentar saya sebagai permintaan yang lebih umum untuk bahasa proaktif dalam posting.
Dan
1
@ KaptenCodeman Anda memang benar. Saya tidak menyadari bahwa emacs mendukung tampilan split vertikal. Karena itu, saya telah menerima jawaban yang merinci penggunaan tampilan split vertikal ini.
Vedaad Shakib

Jawaban:

20

Jendela Emacs

C-x 2akan membuka jendela lain (= pisahkan frame) di bawah yang sekarang, terpasang pada buffer yang sama. Anda dapat memindahkan titik di kedua jendela tanpa memengaruhi yang lain.

Anda dapat berpindah dari satu jendela ke jendela lainnya menggunakan C-x o. Built-in windmove perpustakaan menyediakan beberapa fungsi yang membuat navigasi antara jendela lebih mudah.

Jika metode ini cocok untuk Anda, Anda mungkin juga ingin melihat buffer tidak langsung .

masukkan deskripsi gambar di sini

T. Verron
sumber
Mungkin Anda harus menambahkan beberapa baris lagi tentang menggunakan buffer tidak langsung: ini benar-benar lebih bermanfaat (dan hanya sedikit lebih kompleks) daripada hanya menggunakan jendela lain.
ffevotte
@ Francesco Saya mengerti maksud Anda sekarang (dengan jawaban lain tentang buffer tidak langsung), memang itu opsi yang sangat mudah digunakan juga. Itu bukan penggunaan yang ada dalam pikiran saya: penggunaan buffer tidak langsung saya tidak menggantikan menggunakan jendela yang berbeda, tetapi memungkinkan untuk mengubah tampilan dengan penyempitan, misalnya. Saya akan menambahkan beberapa kata ke jawabannya ketika saya menemukan waktu.
T. Verron
56

Register:

C-xrSPCberjalan point-to-register
C-xrjberjalanjump-to-register

Ketikkan karakter apa saja untuk menentukan register saat diminta. 1

Bookmark:

C-xrmberjalan bookmark-set
C-xrbberjalanbookmark-jump

Tandai cincin:

C-SPCC-SPCmendorong posisi saat ini ke cincin tanda (tanpa membiarkannya aktif).
C-uC-SPCmuncul cincin tanda, melompat ke posisi sebelumnya. Anda dapat menggunakan ini berulang kali untuk menavigasi ke seluruh dering.

Perhatikan bahwa beberapa perintah (terutama yang dapat memindahkan Anda ke tempat yang tidak diketahui atau jarak sewenang-wenang dari lokasi asli Anda) akan secara otomatis mendorong ke tanda dering sehingga Anda dapat menggunakannya C-uC-SPCuntuk kembali setelahnya. Ini termasuk isearch, jadi setelah menggunakan C-suntuk pergi ke suatu tempat, Anda dapat dengan mudah melompat kembali.

Tukar titik dan tandai:

Dan seperti komentar Tu Do, C-xC-xlari exchange-point-and-markyang sangat berguna untuk melompat di antara dua lokasi. Ini juga mengaktifkan tanda / wilayah, tetapi Anda dapat menggunakan C-SPCuntuk menghapus sorotan.


1 Jika Anda memanfaatkan fungsi register di elisp, gunakan simbol yang tidak bertentangan untuk nama, daripada char, sehingga Anda tidak dapat berkonflik dengan register yang diatur secara interaktif (kecuali, tentu saja, Anda ingin melakukan bahwa).

phils
sumber
2
Anda harus menambahkan C-x C-xjuga, karena dapat melompat bolak-balik antara dua posisi. C-u C-SPCmuncul cincin tanda dan jalankan lagi akan memindahkan titik di tempat lain.
Tu Do
18

Selain jawaban phils, ada beberapa opsi lagi:

  • helm-all-mark-rings : Ini memungkinkan Anda untuk melihat konten dari cincin tanda lokal dan global dalam antarmuka yang ramah, sehingga Anda selalu dapat melompat kembali ke tempat Anda berada. Anda dapat menekan tanda dengan C-SPC C-SPC. Demo:

helm-semua-tanda-cincin

  • helm-semantic-or-imenu : Daftar semua definisi yang tersedia di file saat ini. Jika kursor ada di dalam definisi, ketika mengaktifkan stabilo memilih dulu definisi itu.

  • sr-speedbar : Peramban file yang mencantumkan definisi di setiap file. Ini mirip dengan garis pohon di IDE.

Tu Do
sumber
9

Selain register dan spidol (lihat jawaban @ phils tentang keduanya dan yang lain, Icicles menjawab tentang spidol), bookmark , terutama bookmark otomatis atau temporer, dapat membantu untuk ini. Anda memerlukan Bookmark perpustakaan + untuk jenis bookmark khusus ini.

  • Sebuah autonamed bookmark adalah salah satu yang Anda tidak perlu nama. Cepat untuk membuat dan menghapus: cukup tekan tombol. Kunci yang sama membuat atau menghapus bookmark di titik. (Secara default, ini terikat C-x p RET, tetapi Anda tentu saja dapat menggunakan kunci apa saja.)

  • Bookmark yang diautonisasi, seperti bookmark secara umum, persisten. Tapi Anda dapat menghapusnya secara otomatis.

  • Anda juga dapat membuat bookmark sementara atau membuat bookmark yang ada sementara. Anda dapat, misalnya, memilih untuk membuat penanda otomatis menjadi sementara.

  • Anda dapat dengan cepat menggilir satu set bookmark yang diberikan. Misalnya, untuk menggilir di antara penanda yang diautonkan, gunakan perintah bmkp-next-autonamed-bookmark-repeatdan bmkp-previous-autonamed-bookmark-repeat(ikat ke kunci).

  • Anda dapat menyorot lokasi yang ditandai dengan berbagai cara, sehingga mudah dikenali.

Drew
sumber
7

Berkenaan dengan buffer tidak langsung yang disebutkan dalam jawaban yang diterima ...

M-x clone-indirect-bufferakan membuat buffer tidak langsung untuk buffer saat ini. Nama buffer baru akan ditambahkan '<2>' (atau jumlah yang lebih besar jika Anda sudah memiliki nama buffer duplikat). Buffer baru dibuka di jendela baru. Anda dapat beralih kembali ke satu jendela menggunakan C-x 0atau C-x 1.

Dengan M-x winner-modeAnda dapat dengan mudah beralih di antara dua lokasi. C-c <left>/ M-x winner-undodan C-c <right>/ M-x winner-redoberalih antar konfigurasi jendela. Dalam hal ini konfigurasi akan menjadi posisi di dua buffer yang melihat satu file.

Catatan: winner-undodan winner-redofungsinya berfungsi pada daftar konfigurasi. Jika konfigurasi diubah, mis. Titik bergerak, maka konfigurasi saat ini menjadi kepala daftar dan winner-redotidak valid, dalam hal ini winner-undoakan mengembalikan posisi sebelumnya.

Untuk situasi OP ini mengarah ke proses berikut;

  1. Aktifkan mode pemenang M-x winner-mode
  2. Kunjungi file (nama file: File1.txt, nama buffer: File1.txt)
  3. M-x clone-indirect-buffer (nama penyangga tidak langsung baru: File1.txt <2>)
  4. Jadikan jendela saat ini sebagai satu-satunya jendela C-x 1
  5. Temukan lokasi edit pertama, buat perubahan.
  6. Beralih ke file kunjungan buffer asli, C-x b(default akan menjadi buffer asli kecuali jika beralih ke buffer lain terjadi sejak langkah 3). Ini menciptakan konfigurasi baru agar pemenang dapat kembali.
  7. Temukan lokasi edit alternatif, buat perubahan.

Beralih ke lokasi edit sebelumnya (konfigurasi jendela) tergantung pada apakah perubahan dibuat pada konfigurasi jendela di antara switch;

  • Jika perubahan dilakukan, ganti menggunakan C-c <left>/ M-x winner-undo.
  • Jika tidak ada perubahan, gunakan C-c <left>/ M-x winner-undountuk kembali dan C-c <right>/ M-x winner-redountuk maju.

Perubahan adalah apa pun selain yang lain winner-undoatau winner-redo.

pengguna2542
sumber
3

jika Anda menggunakan evil-mode, layer vim, maka C-odan C-iakan bekerja sama.

Mereka menjalankan perintah evil-jump-backward/ forward. C-omelompat ke posisi yang lebih lama di daftar lompat, yang diatur secara otomatis (tanda ditetapkan pada perintah gerak). C-iberjalan terbalik Kita juga bisa menggunakan TABsetelah C-oalih-alih C-i. Jadi menggunakan kedua fungsi akan membawa Anda bolak-balik di buffer Anda saat ini.

Jika Anda ingin fitur ini menjadi cross-buffer, periksa evil-jumpers: http://melpa.org/#/evil-jumper

«
Evil-jumper adalah add-on untuk mode kejahatan yang menggantikan implementasi daftar lompatan sedemikian rupa sehingga meniru lebih dekat dengan perilaku Vim. Secara khusus, itu akan melewati batas buffer dan menghidupkan kembali buffer yang mati jika perlu. Daftar lompatan juga dapat disimpan ke file dan dikembalikan di antara sesi. »

Catatan: Saya mempelajarinya di wiki ini

Ehvince
sumber
Ini tidak memberikan jawaban untuk pertanyaan itu. Untuk mengkritik atau meminta klarifikasi dari penulis, tinggalkan komentar di bawah posting mereka.
Dan
1
Doh, dan dengan komentar otomatis itu, maksud saya sebenarnya jawabannya sepertinya dimaksudkan untuk mengomentari jawaban lain. Jika Anda ingin ini menjadi jawaban sendiri, dapatkah Anda memperluas sedikit tentang apa C-odan C-ilakukan?
Dan
Kamu benar ! selesai
Ehvince
2

Jika Anda menggunakan Icicles maka Anda dapat dengan cepat menavigasi di antara penanda di mark-ringsetiap buffer atau global-mark-ring(yang memiliki satu penanda di setiap buffer).

Anda melakukan ini menggunakan multi-perintah C-- C-SPC (untuk buffer mark-ring) atau C-- C-x C-SPC(untuk global-mark-ring). Setelah menekan tombol satu kali, Anda menggunakan kunci bersepeda Icicles biasa , dll., Untuk bergerak di antara penanda cincin.

(Kunci yang sama tanpa arg awalan mengatur tanda ( set-mark-command) dan pop tanda global ( pop-global-mark), masing-masing, seperti yang mereka lakukan di vanilla Emacs.)

Teks baris masing-masing penanda digunakan sebagai kandidat penyelesaian. Saat Anda mengetik, input minibuffer Anda mempersempit kandidat menjadi kandidat yang cocok (mis., Pencocokan substring atau regexp). Anda dapat dengan cepat berputar di antara marker yang cocok atau mengunjungi salah satu dari mereka secara langsung. Anda bahkan dapat mengubah urutan pengurutan ( C-,) untuk bersepeda.

Drew
sumber
2

Kemungkinan minimal tapi sering membantu - ketika Anda hanya ingin mengintip fungsi lainnya - adalah pengaturan

(setq scroll-preserve-screen-position t)

yang membawa Anda kembali ke posisi kursor awal yang tepat saat beralih di antara C-vdan M-v.

Dieter.Wilhelm
sumber
1

evil-modemengimplementasikan penanda gaya Vim . Anda dapat mengatur penanda dengan ( m, yaitu, evil-set-marker) dan melompat ke tanda dengan backtick `( evil-goto-mark) atau ke garis tanda '( evil-goto-mark-line).

Oleh karena itu, Anda dapat membuat tanda "a" di lokasi pertama dengan ma, membuat tanda "b" di lokasi kedua dengan ma, dan kemudian 'amelompat untuk menandai "a" dan 'buntuk melompat ke tanda "b".

Dan
sumber
1

gunakan imenu dan kode di bawah ini

(defvar rimenu-position-pair nil "positions before and after imenu jump")
(add-hook 'imenu-after-jump-hook
          (lambda ()
            (let ((start-point (marker-position (car mark-ring)))
                  (end-point (point)))
              (setq rimenu-position-pair (list start-point end-point)))))

(defun rimenu-jump ()
  "jump to the closest before/after position of latest imenu jump"
  (interactive)
  (when rimenu-position-pair
    (let ((p1 (car rimenu-position-pair))
          (p2 (cadr rimenu-position-pair)))

      ;; jump to the far way point of the rimenu-position-pair
      (if (< (abs (- (point) p1))
             (abs (- (point) p2)))
          (goto-char p2)
          (goto-char p1))
      )))
chen bin
sumber
1

Selama 20 tahun terakhir, saya telah menggunakan dua permata ini:

(defun ska-point-to-register ()
  "Store cursorposition _fast_ in a register. Use ska-jump-to-register
to jump back to the stored position."
  (interactive)
  (point-to-register 8))

(defun ska-jump-to-register ()
  "Switches between current cursorposition and position
that was stored with ska-point-to-register."
  (interactive)
  (let ((tmp (point-marker)))
    (jump-to-register 8)
    (set-register 8 tmp)))

Saya mengikat mereka ke C-. dan C-, masing-masing dan menggunakannya secara konstan tanpa menyadarinya lagi.

Ya, register dan spidol dan semacamnya jauh lebih fleksibel dan kuat, tetapi tetap saja, ini adalah salah satu dari mereka yang kecil, penolong cepat yang membuat saya tidak mungkin beralih ke editor lain.

Stefan Kamphausen
sumber
1
Wow, Anda sudah menggunakan ini lebih lama dari yang saya hidup.
Vedaad Shakib
Saya kira ini tidak akan terjadi di dunia Node atau Visual Studio Code dulu, tapi siapa yang tahu ... :-) Senang melihat orang-orang muda dan pintar masih mengambil Emacs. Oh, dan, saya belum 50 ;-)
Stefan Kamphausen
Ini sangat mengagumkan. Saya telah mencoba menemukan cara untuk beralih antara dua lokasi acak dengan mode tanda-transien diaktifkan, dan ini menyelesaikan masalah dengan sangat baik :) Terima kasih.
PlagueHammer
0

Anda juga dapat memanfaatkan makro, karena mereka dapat dengan cepat terikat pada tombol yang mudah digunakan.

Misalnya, rekam lompatan ke posisi N menggunakan <F3> M-g g N <F4>dan tetapkan ke tombol F5 dengan C-x C-k b <F5>. Kemudian lakukan hal yang sama dengan posisi M dan F6. Mulai sekarang Anda dapat dengan mudah mengganti F5 dan F6 untuk melompat antara N dan M.

Bahkan lebih sederhana, karena <F4>mengeksekusi makro yang terakhir direkam dan <C-u> F4yang berikutnya, yang terakhir, Anda dapat melewati langkah pengikatan kunci dan cukup berganti posisi menggunakan <F4>dan <C-u> F4.


Kemungkinan lain yang agak radikal adalah membuat buffer tidak langsung di jendela lain <C-x> 4 c. Buffer ini memiliki konten yang sama tetapi mungkin memiliki posisi titik yang berbeda. Sekarang cukup bergantian antara windows dengan <C-x> ocara biasa.

memeplex
sumber