Sigue moviéndote hasta el final de las líneas

9

El valor predeterminado de la combinación de teclas C-a/C-ees solo para una cosa, mover al principio / final de la línea, ¿hay algún paquete que pueda hacer que Emacs actúe así?

  1. Si no estoy al final de una línea, C-eiré al final de la línea, de lo contrario, iré al final de la siguiente línea
  2. Si no estoy al comienzo de una línea, C-airé al comienzo de la línea, de lo contrario iré al comienzo de la siguiente línea.

El punto es que puedes seguir golpeando C-a/epara ir al principio / final de cada línea sin mover el dedo para alcanzar C-n/p.

Y con un prefijo ( C-u) irán al principio / final de la línea en la dirección opuesta.

CodyChan
fuente
En un comentario a una respuesta a continuación, @kaushalmodi señala que es posible que haya interpretado mal su pregunta. ¿Quieres C-a"subir" y C-e"bajar"? En otras palabras, ¿el significado de "línea siguiente" es el mismo en los ítems 1 y 2?
Constantino
@Constantine De hecho, me hizo pensar en el " C-apara arriba y C-epara abajo" problema cuando he publicado esta pregunta, pero luego pensé que si alguien le dio defunsolución como usted, nadie sabría qué hacer si le gusta C-aa "arriba" ..
CodyChan
OKAY; Creo que aún vale la pena arreglarlo. Actualizaré la respuesta: es solo un cambio de una línea.
Constantino

Respuestas:

11

No conozco un paquete que permita este comportamiento, pero aquí hay una forma de hacerlo.

Presione C-h k C-apara descubrir que C-aestá obligado a move-beginning-of-line; esta es la función que necesitamos modificar --- o simplemente usar para implementar la parte "mover al principio". Del mismo modo, con C-h kI can find forward-line, que se usará para subir / bajar.

Para poder vincular una función a una tecla, debemos convertirla en un comando , por lo que debemos usar el interactiveformulario especial (consulte Uso de Interactive ). Para tomar el C-uargumento prefijo necesitamos el "P"carácter del código.

Combinando esto con bolp(verifique si al principio de una línea) y eolp(verifique si está al final de una línea), podemos escribir:

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

Ahora podemos volver a vincular C-ay C-ellamar a estos:

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

Alternativamente, uno podría agregar consejos a move-beginning-of-liney move-end-of-line.

Constantina
fuente
Esta es una muy buena explicación y una solución elegante. Hay un error tipográfico en la my-move-beginning-of-linefunción. ¿Debería ser (previous-line (if arg -1 1))o (forward-line (if arg 1 -1))(1 y -1 conmutado)?
Kaushal Modi
@kaushalmodi: en la pregunta, los elementos 1 y 2 dicen "línea siguiente", que interpreté como "abajo". Entonces, ¡preguntemos al autor de la pregunta! :-)
Constantine
Ah, agregué mi propia suposición a la pregunta del OP. Tiene razón, él especifica ir a la siguiente línea cuando usa cualquiera C-ao C-e.
Kaushal Modi
@kaushalmodi: ¡Resulta que tenías razón! Actualicé la respuesta para hacer C-a"subir".
Constantino
8

La biblioteca misc-cmds.elsiempre ha tenido esta característica.

Estos son los comandos relevantes y los enlaces de teclas sugeridos (estos enlaces se hacen en 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+)))

Aquí está lo que C-h f end-of-line+dice, como un ejemplo:

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.
Dibujó
fuente
Eso es muy elegante.
sanityinc
1

Las siguientes dos funciones realizan las acciones deseadas.

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