Terus bergerak ke ujung garis

9

Default pengikatan kunci C-a/C-ehanya untuk satu hal, pindah ke awal / akhir baris, apakah ada paket yang dapat membuat Emacs bertindak seperti ini:

  1. Jika saya tidak berada di akhir baris, C-eakan pergi ke akhir baris, jika tidak, lanjutkan ke akhir baris berikutnya
  2. Jika saya tidak berada di awal baris, C-aakan pergi ke awal baris, jika tidak pergi ke awal baris berikutnya.

Intinya adalah Anda bisa terus memukul C-a/euntuk memulai / mengakhiri setiap baris tanpa menggerakkan jari Anda untuk mencapai C-n/p.

Dan dengan awalan ( C-u) mereka akan pergi ke awal / akhir garis di arah yang berlawanan.

CodyChan
sumber
Dalam komentar untuk jawaban di bawah @kaushalmodi menunjukkan bahwa saya mungkin telah salah menafsirkan pertanyaan Anda. Apakah Anda ingin C-a"naik" dan C-e"turun"? Dengan kata lain, apakah arti "baris berikutnya" sama dalam item 1 dan 2?
Constantine
@Constantine Saya benar-benar berpikir tentang masalah " C-anaik dan C-eturun" ketika saya memposting pertanyaan ini, tetapi kemudian saya berpikir jika seseorang memberikan defunsolusi seperti Anda, siapa pun akan tahu apa yang harus dilakukan jika dia suka C-a"naik" ..
CodyChan
BAIK; Saya pikir itu masih layak diperbaiki. Saya akan memperbarui jawabannya - itu hanya perubahan satu baris.
Constantine

Jawaban:

11

Saya tidak tahu tentang paket yang memungkinkan perilaku ini, tetapi inilah satu cara untuk melakukannya.

Tekan C-h k C-auntuk menemukan yang C-aterikat move-beginning-of-line; ini adalah fungsi yang perlu kita modifikasi --- atau gunakan saja untuk mengimplementasikan bagian "pindah ke awal". Demikian pula dengan yang C-h ksaya dapat temukan forward-line, yang akan digunakan untuk bergerak naik / turun.

Untuk dapat mengikat fungsi ke kunci, kita perlu membuatnya menjadi perintah , jadi kita perlu menggunakan interactiveformulir khusus (lihat Menggunakan Interaktif ). Untuk mengambil C-uargumen awalan, kita memerlukan "P"karakter kode.

Menggabungkan ini dengan bolp(periksa jika di awal baris) dan eolp(periksa jika di akhir baris), kita dapat menulis:

(defun my-move-beginning-of-line (arg)
  (interactive "P")
  (when (bolp) (previous-line (if arg -1 1)))
  (move-beginning-of-line nil))

(defun my-move-end-of-line (arg)
  (interactive "P")
  (when (eolp) (forward-line (if arg -1 1)))
  (move-end-of-line nil))

Sekarang kita dapat mengikat kembali C-adan C-emenyebutnya:

(global-set-key [remap move-beginning-of-line] #'my-move-beginning-of-line)
(global-set-key [remap move-end-of-line] #'my-move-end-of-line)

Atau, seseorang dapat menambahkan saran ke move-beginning-of-linedan move-end-of-line.

Constantine
sumber
Ini adalah penjelasan yang sangat bagus dan solusi yang elegan. Ada kesalahan ketik dalam my-move-beginning-of-linefungsi .. Haruskah (previous-line (if arg -1 1))atau (forward-line (if arg 1 -1))(1 dan -1 diaktifkan)?
Kaushal Modi
@kaushalmodi: dalam pertanyaan kedua item 1 dan 2 mengatakan "baris berikutnya", yang saya artikan sebagai "down". Jadi, mari kita tanyakan penulis pertanyaan! :-)
Constantine
Ah, saya menambahkan asumsi saya sendiri ke pertanyaan OP. Anda benar, dia tidak menentukan untuk pergi ke baris berikutnya saat menggunakan salah satu C-aatau C-e.
Kaushal Modi
@kaushalmodi: Ternyata Anda benar! Saya memperbarui jawaban untuk memperbaiki C-a.
Constantine
8

Perpustakaan misc-cmds.eltelah lama memiliki fitur ini.

Ini adalah perintah yang relevan, dan bindings kunci yang disarankan (binding ini dibuat di setup-keys.el).

(cond ((fboundp 'move-beginning-of-line)
       (substitute-key-definition 'move-beginning-of-line 'beginning-of-line+ global-map)
       (substitute-key-definition 'move-end-of-line 'end-of-line+ global-map))
      (t
       (substitute-key-definition 'beginning-of-line 'beginning-of-line+ global-map)
       (substitute-key-definition 'end-of-line 'end-of-line+ global-map)))
(when (boundp 'visual-line-mode-map)
  (define-key visual-line-mode-map [remap move-beginning-of-line] nil)
  (define-key visual-line-mode-map [remap move-end-of-line]       nil)
  (define-key visual-line-mode-map [home] 'beginning-of-line+)
  (define-key visual-line-mode-map [end]  'end-of-line+)
  (define-key visual-line-mode-map "\C-a" 'beginning-of-visual-line+)
  (define-key visual-line-mode-map "\C-e" 'end-of-visual-line+)))

Inilah yang C-h f end-of-line+dikatakan, sebagai salah satu contoh:

end-of-line+ is an interactive compiled Lisp function in
`misc-cmds.el'.

It is bound to C-e, end.

(end-of-line+ &optional N)

Move cursor to end of current line or end of next line if repeated.
This is similar to `end-of-line', but:
  If called interactively with no prefix arg:
     If the previous command was also `end-of-line+', then move to the
     end of the next line.  Else, move to the end of the current line.
  Otherwise, move to the end of the Nth next line (Nth previous line
     if N<0).  Command `end-of-line', by contrast, moves to the end of
     the (N-1)th next line.
Drew
sumber
Itu sangat elegan.
sanityinc
1

Dua fungsi berikut melakukan tindakan yang diinginkan.

(defun move-beginning-of-line-or-previous (&optional pre)
  "Move to the start of the line. If we are already at the start
of the line, move to the start of the previous line or, if called 
with a prefix argument, the next line."
  (interactive "P")
  (let* ((pos (point)))
    (move-beginning-of-line nil)
    (if (= (point) pos)
        (if pre
            (next-line)
          (previous-line)))))

(defun move-end-of-line-or-next (&optional pre)
  "Move to the end of the line. If we are already at the end of
the line, move to the end of the next line or, if called with a 
prefix argument, the previous line."
  (interactive "P")
  (let* ((pos (point)))
    (move-end-of-line nil)
    (if (= (point) pos)
        (if pre
            (previous-line)
          (next-line)))))
Patrick Steele
sumber