Tiếp tục di chuyển đến cuối dòng


9

Mặc định của ràng buộc khóa C-a/C-echỉ dành cho một thứ, di chuyển đến đầu / cuối dòng, có gói nào có thể khiến Emacs hoạt động như thế này không:

  1. Nếu tôi không ở cuối dòng, C-esẽ đi đến cuối dòng, nếu không, hãy đi đến cuối dòng tiếp theo
  2. Nếu tôi không ở đầu dòng, C-asẽ đi đến đầu dòng, nếu không thì đi đến đầu dòng tiếp theo.

Vấn đề là bạn chỉ có thể tiếp tục nhấn C-a/eđể đi đến đầu / cuối của mỗi dòng mà không cần di chuyển ngón tay của bạn để đạt được C-n/p.

Và với một tiền tố ( C-u) họ sẽ đi đến đầu / cuối dòng theo hướng ngược lại.


Trong một bình luận cho một câu trả lời dưới đây @kaushalmodi chỉ ra rằng tôi có thể đã hiểu sai câu hỏi của bạn. Bạn có muốn C-ađi "lên" và C-eđi "xuống" không? Nói cách khác, ý nghĩa của "dòng tiếp theo" có giống nhau trong mục 1 và 2 không?
Constantine

@Constantine Tôi thực sự đã nghĩ về vấn đề " C-alên và C-exuống" khi tôi đăng câu hỏi này, nhưng sau đó tôi nghĩ nếu ai đó đưa ra defungiải pháp như bạn, bất cứ ai cũng sẽ biết phải làm gì nếu anh ta thích C-a"lên" ..
CodyChan

ĐỒNG Ý; Tôi nghĩ rằng nó vẫn còn giá trị sửa chữa. Tôi sẽ cập nhật câu trả lời - đó chỉ là thay đổi một dòng.
Constantine

Câu trả lời:


11

Tôi không biết gói nào có thể kích hoạt hành vi này, nhưng đây là một cách để thực hiện.

Nhấn C-h k C-ađể khám phá đó C-alà ràng buộc move-beginning-of-line; đây là chức năng chúng ta cần sửa đổi --- hoặc chỉ sử dụng để thực hiện phần "di chuyển đến đầu". Tương tự, với C-h ktôi có thể tìm thấy forward-line, sẽ được sử dụng để di chuyển lên / xuống.

Để có thể liên kết một chức năng với một khóa, chúng ta cần biến nó thành một lệnh , vì vậy chúng ta cần sử dụng interactivebiểu mẫu đặc biệt (xem Sử dụng Tương tác ). Để lấy C-uđối số tiền tố, chúng ta cần "P"ký tự mã.

Kết hợp điều này với bolp(kiểm tra xem ở đầu dòng) và eolp(kiểm tra xem ở cuối dòng), chúng ta có thể viết:

(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))

Bây giờ chúng ta có thể liên kết lại C-aC-egọi chúng:

(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)

Ngoài ra, người ta có thể thêm lời khuyên cho move-beginning-of-linemove-end-of-line.


Đây là một lời giải thích thực sự tốt và một giải pháp thanh lịch. Có một lỗi đánh máy trong my-move-beginning-of-linehàm .. Nó nên (previous-line (if arg -1 1))hay (forward-line (if arg 1 -1))(1 và -1 chuyển)?
Kaushal Modi

@kaushalmodi: trong câu hỏi cả hai mục 1 và 2 đều nói "dòng tiếp theo", mà tôi hiểu là "xuống". Vì vậy, hãy đặt câu hỏi của tác giả! :-)
Constantine

Ah, tôi đã thêm giả định của riêng mình vào câu hỏi của OP. Bạn nói đúng, anh ấy chỉ định đi đến dòng tiếp theo khi sử dụng C-ahoặc C-e.
Kaushal Modi

@kaushalmodi: Hóa ra bạn đã đúng! Tôi đã cập nhật câu trả lời để thực hiện C-a"lên".
Constantine

8

Thư viện misc-cmds.eltừ lâu đã có tính năng này.

Đây là các lệnh có liên quan và các ràng buộc khóa được đề xuất (các ràng buộc này được thực hiện 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+)))

Đây là những gì C-h f end-of-line+nói, như một ví dụ:

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.

Điều đó rất thanh lịch.
sanityinc

1

Hai chức năng sau đây thực hiện các hành động mong muốn.

(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)))))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.