Przechodź do końca linii

9

Domyślne wiązanie klawiszy C-a/C-ejest tylko dla jednej rzeczy, przejdź na początek / koniec linii, czy jest jakiś pakiet, który może sprawić, że Emacs będzie działał w ten sposób:

  1. Jeśli nie będę na końcu linii, C-eprzejdę do końca linii, w przeciwnym razie przejdź do końca następnej linii
  2. Jeśli nie jestem na początku linii, C-aprzejdę na początek linii, w przeciwnym razie przejdź do początku następnej linii.

Chodzi o to, że możesz po prostu naciskać, C-a/eaby przejść do początku / końca każdej linii, nie ruszając palcem, aby sięgnąć C-n/p.

I z prefiksem ( C-u) będą przechodzić na początek / koniec linii w przeciwnym kierunku.

CodyChan
źródło
W komentarzu do odpowiedzi poniżej @kaushalmodi wskazuje, że mogłem źle zinterpretować twoje pytanie. Czy chcesz C-aiść „w górę” i C-e„w dół”? Innymi słowy, czy znaczenie „następnego wiersza” jest takie samo w punktach 1 i 2?
Constantine,
@ Constantine Właściwie pomyślałem o problemie „ C-aw górę i C-ew dół”, kiedy opublikowałem to pytanie, ale pomyślałem, że jeśli ktoś defundałby takie rozwiązanie jak ty, każdy wiedziałby, co zrobić, jeśli lubi C-a„w górę” ..
CodyChan
OK; Myślę, że nadal warto to naprawić. Zaktualizuję odpowiedź - to tylko zmiana jednego wiersza.
Constantine

Odpowiedzi:

11

Nie znam pakietu, który umożliwiłby takie zachowanie, ale jest jeden sposób, aby to zrobić.

Naciśnij, C-h k C-aaby odkryć, że C-ajest to związane move-beginning-of-line; jest to funkcja, którą musimy zmodyfikować --- lub po prostu użyć do implementacji części „przejście do początku”. Podobnie z C-h kI can find forward-line, który będzie używany do poruszania się w górę / w dół.

Aby móc przypisać funkcję do klawisza, musimy uczynić go poleceniem , dlatego musimy użyć interactivespecjalnego formularza (patrz Korzystanie z interaktywnego ). Aby wziąć C-uargument przedrostka, potrzebujemy "P"znaku kodu.

Łącząc to z bolp(sprawdź, czy na początku linii) i eolp(sprawdź, czy na końcu linii), możemy napisać:

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

Teraz możemy ponownie powiązać C-ai C-ewywołać je:

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

Alternatywnie można dodać porady do move-beginning-of-linei move-end-of-line.

Konstantyn
źródło
To naprawdę dobre wytłumaczenie i eleganckie rozwiązanie. W funkcji jest literówka my-move-beginning-of-line. Czy powinno to być (previous-line (if arg -1 1))lub (forward-line (if arg 1 -1))(przełączane 1 i -1)?
Kaushal Modi,
@kaushalmodi: w pytaniu oba punkty 1 i 2 mówią „następny wiersz”, co zinterpretowałem jako „dół”. Zapytajmy autora pytania! :-)
Constantine,
Ach, dodałem własne założenie do pytania PO. Masz rację, że nie precyzuje, aby przejść do następnego wiersza przy użyciu albo C-aalbo C-e.
Kaushal Modi,
@kaushalmodi: Okazuje się, że miałeś rację! Zaktualizowałem odpowiedź, aby C-aprzejść do „góry”.
Constantine
8

Biblioteka misc-cmds.elod dawna ma tę funkcję.

Są to odpowiednie polecenia i sugerowane powiązania klawiszy (te powiązania zostały utworzone 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+)))

Oto, co C-h f end-of-line+mówi, jako jeden przykład:

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.
Rysował
źródło
To bardzo eleganckie.
sanityinc
1

Poniższe dwie funkcje wykonują pożądane czynności.

(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
źródło