Bewegen Sie sich weiter bis zum Ende der Zeilen

9

Die Standardeinstellung für die Schlüsselbindung C-a/C-eist nur für eine Sache: Verschieben Sie zum Anfang / Ende der Zeile. Gibt es ein Paket, das Emacs dazu bringen kann, sich so zu verhalten:

  1. Wenn ich nicht am Ende einer Zeile bin, C-egehe ich zum Ende der Zeile, andernfalls gehe ich zum Ende der nächsten Zeile
  2. Wenn ich nicht am Anfang einer Zeile bin, C-agehe ich zum Anfang der Zeile, andernfalls gehe ich zum Anfang der nächsten Zeile.

Der Punkt ist, dass Sie einfach weiter schlagen können C-a/e, um zum Anfang / Ende jeder Linie zu gelangen, ohne Ihren Finger zu bewegen, um zu erreichen C-n/p.

Und mit einem Präfix ( C-u) gehen sie in entgegengesetzter Richtung zum Anfang / Ende der Zeile.

CodyChan
quelle
In einem Kommentar zu einer Antwort unten weist @kaushalmodi darauf hin, dass ich Ihre Frage möglicherweise falsch interpretiert habe. Willst du C-a"hoch" und C-e"runter" gehen? Mit anderen Worten, ist die Bedeutung von "nächste Zeile" in den Punkten 1 und 2 gleich?
Konstantin
@Constantine Ich habe tatsächlich über das Problem " C-anach oben und C-enach unten" nachgedacht, als ich diese Frage gestellt habe, aber dann dachte ich, wenn jemand eine defunLösung wie Sie gibt, weiß jeder, was zu tun ist, wenn er C-a"nach oben" möchte .
CodyChan
IN ORDNUNG; Ich denke, es lohnt sich immer noch, das Problem zu beheben. Ich werde die Antwort aktualisieren - es ist nur eine einzeilige Änderung.
Konstantin

Antworten:

11

Ich kenne kein Paket, das dieses Verhalten ermöglichen würde, aber hier ist eine Möglichkeit, dies zu tun.

Drücken Sie, C-h k C-aum herauszufinden, dass dies C-agebunden ist move-beginning-of-line. Dies ist die Funktion, die wir ändern müssen --- oder nur verwenden, um den Teil "Zum Anfang bewegen" zu implementieren. Ebenso kann C-h kich mit finden forward-line, welche verwendet werden, um sich auf / ab zu bewegen.

Um eine Funktion an einen Schlüssel binden zu können, müssen wir sie zu einem Befehl machen , daher müssen wir das interactivespezielle Formular verwenden (siehe Verwenden von Interactive ). Um das C-uPräfixargument zu verwenden, benötigen wir das "P"Codezeichen.

Wenn wir dies kombinieren mit bolp(prüfen, ob am Anfang einer Zeile) und eolp(prüfen, ob am Ende einer Zeile), können wir schreiben:

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

Jetzt können wir diese neu binden C-aund C-eaufrufen:

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

Alternativ könnte man Ratschläge zu move-beginning-of-lineund hinzufügenmove-end-of-line .

Konstantin
quelle
Dies ist eine wirklich gute Erklärung und eine elegante Lösung. Es gibt einen Tippfehler in der my-move-beginning-of-lineFunktion. Sollte es sein (previous-line (if arg -1 1))oder (forward-line (if arg 1 -1))(1 und -1 umgeschaltet)?
Kaushal Modi
@kaushalmodi: In der Frage sagen beide Punkte 1 und 2 "nächste Zeile", was ich als "unten" interpretiert habe. Fragen wir also den Autor der Frage! :-)
Constantine
Ah, ich habe meine eigene Annahme zur Frage des OP hinzugefügt. Sie haben Recht, er gibt an, in die nächste Zeile zu gehen, wenn er entweder C-aoder verwendet C-e.
Kaushal Modi
@kaushalmodi: Es stellt sich heraus, dass Sie Recht hatten! Ich habe die Antwort aktualisiert, C-aum "up" zu machen .
Konstantin
8

Bibliothek misc-cmds.elhat diese Funktion schon lange.

Dies sind die relevanten Befehle und vorgeschlagenen Tastenkombinationen (diese Bindungen werden in hergestellt 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+)))

Hier ist, was C-h f end-of-line+als ein Beispiel sagt:

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
quelle
Das ist sehr elegant.
Sanityinc
1

Die folgenden zwei Funktionen führen die gewünschten Aktionen aus.

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