Mover el formulario hacia arriba y hacia abajo en modo de crédito

13

He estado usando la Edición Estructural de cursive (un modo similar a un crédito para Intellij y Cursive) y encontré un buen comando llamado move form-up (and down).

Mover hacia arriba hace esto (el |es el punto):

(+ 1 |(+ 2 3) 4) => (+ (+ 2 3) 1 4)

y Move form down es análogo:

(+ 1 |(+ 2 3) 4) => (+ 1 4 (+ 2 3))

¿Es posible hacer esto en el modo de crédito Emacs? Creo que no está en el conjunto básico de crédito (al menos no se describe en esta hoja de trucos)

Rodrigo Flores
fuente
Agradable. Ahora esa es una operación que podría verme haciendo.
PythonNut
2
FWIW, al menos para los dos ejemplos que muestra, simplemente C-M-thace lo mismo. Pero supongo que lo que quieres decir es que se sigue moviendo la misma forma, en lugar de tener que cambiar el progreso al siguiente par de sexps.
Dibujó

Respuestas:

13

Como sugirió @Drew, C-M-thace lo que quieres. La regla es así:

  • Poner punto en medio de dos sexps.
  • Presione C-M-t(que se ejecuta transpose-sexp).
  • El sexp izquierdo siempre se mueve hacia la derecha junto con el punto. Esto es muy importante , de lo contrario se confundirá sin fin.

O simplemente puede pensar que esto no es transposición, sino simplemente avanzar, debe colocar un punto después del sexp que desea mover.

Sin embargo, hay uno conveniente que es, cuando desea transponer el sexp izquierdo hacia atrás, usa el mismo C-M-tpero se le proporciona un argumento de prefijo negativo y esto es inconveniente. Otro problema es que ese punto no seguirá al sexp izquierdo transpuesto hacia atrás . Para resolver este problema, creamos una versión inversa de transpose-sexps:

(defun reverse-transpose-sexps (arg)
  (interactive "*p")
  (transpose-sexps (- arg))
  ;; when transpose-sexps can no longer transpose, it throws an error and code
  ;; below this line won't be executed. So, we don't have to worry about side
  ;; effects of backward-sexp and forward-sexp.
  (backward-sexp (1+ arg))
  (forward-sexp 1))

Luego, únelo al C-M-yque está al lado C-M-ty es gratis en Emacs predeterminado.

(global-set-key (kbd "C-M-y") 'reverse-tranpose-sexps)

Aquí hay una demostración; notarás que (MY-SEXP1)está a la izquierda todo el tiempo para avanzar / retroceder:

ingrese la descripción de la imagen aquí

Tu Do
fuente
5

Es posible hacerlo con lispy , que es una forma avanzada de paredit-mode.

Para su caso de uso:

  • w se mueve hacia arriba
  • s se mueve hacia abajo

Lo único es que el cursor tiene que estar en paren, que es en su ejemplo:

(+ 1 |(+ 2 3) 4)

También puede mover varios sexps a la vez con wy s, si los marca con una región. Vea la documentación para más información.

abo-abo
fuente
;; ¿Hay alguna manera de usar solo esos dos comandos? ;; Parece que pierdo "M-left" y "M-right" al hacerlo: `(add-hook 'clojure-mode-hook (lambda () (lispy-mode 1) (local-set-key (kbd" M) - <up> ") 'lispy-move-up) (local-set-key (kbd" M- <down> ")' lispy-move-down)))`
nha
1

Aquí hay otro comando (de la biblioteca misc-cmds.el) que hace más o menos lo que solicitas. Simplemente vincúlelo a una sola tecla ( C-M-to lo que sea) Úselo para mover un sexp hacia adelante y hacia atrás repetidamente.

Un prefijo negativo arg se transpone hacia atrás, como transpose-sexp, pero también deja el punto listo para hacer otra transposición hacia atrás. Y cuando se repite, un prefijo negativo arg simplemente cambia la dirección.

Entonces, si vincula el comando para, digamos, C-oluego mueve el sexp que está a la izquierda del punto a la derecha tres veces, luego a la izquierda dos veces, luego a la derecha una vez.C-o C-o C-o C-- C-o C-o C-- C-o

Un argumento de prefijo numérico tiene un efecto solo para el primer uso, es decir, no cuando se repite; cuando se repite, el movimiento siempre es un sexp a la vez.

(defun reversible-transpose-sexps (arg)
  "Reversible and repeatable `transpose-sexp'.
Like `transpose-sexps', but:
 1. Leaves point after the moved sexp.
 2. When repeated, a negative prefix arg flips the direction."
  (interactive "p")
  (when (eq last-command 'rev-transp-sexps-back) (setq arg  (- arg)))
  (transpose-sexps arg)
  (unless (natnump arg)
    (when (or (> emacs-major-version 24)
              (and (= emacs-major-version 24)  (> emacs-minor-version 3)))
      (backward-sexp (abs arg)) (skip-syntax-backward " ."))
    (setq this-command  'rev-transp-sexps-back)))

(Nota: El comportamiento transpose-sexpscambió en 24.4, de ahí la prueba de versión aquí. Antes de 24.4, el punto terminó en el lugar correcto para continuar (por ejemplo, repetir). Comenzando con 24.4, el punto está en el lugar equivocado para eso. una regresión o agrega una característica útil o corrige algún otro error presumiblemente está en el ojo del espectador. ;-) Presenté el error Emacs # 20698 para esto, justo ahora).

Dibujó
fuente