Bewegen Sie das Formular im Paredit-Modus nach oben und unten

13

Ich habe die strukturelle Bearbeitung von Cursive (ein paredit-ähnlicher Modus für Intellij und Cursive) verwendet und dort einen netten Befehl gefunden, der sich Form aufwärts (und abwärts) nennt.

Formular nach oben verschieben bewirkt Folgendes (das |ist der Punkt):

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

und Form nach unten verschieben ist analog:

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

Ist es möglich, dies im Emacs Paredit-Modus zu tun? Ich denke, es ist nicht in der Grundausstattung enthalten (zumindest ist es auf diesem Spickzettel nicht beschrieben)

Rodrigo Flores
quelle
Nett. Das ist eine Operation, die ich mir vorstellen konnte.
PythonNut
2
FWIW tut zumindest für die beiden Beispiele, die Sie zeigen, C-M-tungefähr dasselbe. Aber ich denke, Sie meinen, dass dieselbe Form weiterhin verschoben wird, anstatt den Fortschritt auf das nächste Paar Sexps auszutauschen.
Drew

Antworten:

13

Wie @Drew vorgeschlagen hat, C-M-tmacht was Sie wollen. Die Regel ist wie folgt:

  • Stelle den Punkt in die Mitte von zwei Sexps.
  • Drücken Sie C-M-t(was läuft transpose-sexp).
  • Das linke Geschlecht wird immer zusammen mit dem Punkt nach rechts verschoben. Dies ist sehr wichtig , sonst werden Sie zu keinem Ende verwirrt.

Oder Sie können einfach denken, dass dies nicht transponierend ist, sondern dass Sie, um sich vorwärts zu bewegen, einen Punkt hinter dem Sexp platzieren müssen, den Sie bewegen möchten.

Es gibt jedoch einen Vorteil: Wenn Sie das linke Geschlecht rückwärts transponieren möchten, verwenden Sie dasselbe C-M-tArgument , das jedoch mit einem negativen Präfix versehen ist. Dies ist unpraktisch. Ein weiteres Problem ist, dass der Punkt nicht dem rückwärts transponierten linken Geschlecht folgt . Um dieses Problem zu lösen, erstellen wir eine umgekehrte Version von 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))

Binden Sie es dann an den, C-M-yder sich neben C-M-tEmacs befindet und in der Standardeinstellung frei ist.

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

Hier ist eine Demo; Sie werden feststellen, dass (MY-SEXP1)sich die ganze Zeit über links befindet, um vorwärts / rückwärts bewegt zu werden:

Bildbeschreibung hier eingeben

Tu Do
quelle
5

Es ist möglich, dies mit Lispy zu tun , was eine fortgeschrittene Form von Lispy ist paredit-mode.

Für Ihren Anwendungsfall:

  • w geht hoch
  • s bewegt sich nach unten

Das Einzige ist, dass der Cursor auf paren stehen muss, wie es in Ihrem Beispiel der Fall ist:

(+ 1 |(+ 2 3) 4)

Sie können auch mehrere Sexps gleichzeitig mit wund verschieben s, wenn Sie sie mit einer Region markieren. Weitere Informationen finden Sie in der Dokumentation .

abo-abo
quelle
;; Gibt es eine Möglichkeit, nur diese beiden Befehle zu verwenden? ;; Ich scheine dabei "M-links" und "M-rechts" zu verlieren: `(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

Hier ist ein weiterer Befehl (aus der Bibliothek misc-cmds.el), der ziemlich genau das tut, was Sie verlangen. Binden Sie es einfach an einen einzelnen Schlüssel ( C-M-toder was auch immer). Verwenden Sie diese Option, um ein Sexp wiederholt vorwärts und rückwärts zu bewegen.

Ein negatives Präfix arg transponiert rückwärts, transpose-sexpaber es lässt point auch bereit, eine weitere Rückwärtstransposition durchzuführen. Und beim Wiederholen kehrt ein negatives Präfix arg nur die Richtung um.

Wenn Sie also den Befehl beispielsweise an binden, C-owird das Sexp, das sich links vom Punkt befindet, dreimal nach rechts, dann zweimal nach links und dann einmal nach rechts verschoben.C-o C-o C-o C-- C-o C-o C-- C-o

Ein numerisches Präfix arg wirkt sich nur beim ersten Gebrauch aus, dh nicht bei Wiederholungen - bei Wiederholungen ist die Bewegung immer ein Geschlecht auf einmal.

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

(Hinweis: Das Verhalten von transpose-sexpsin 24.4 geändert, daher hier der Versions-Test. Vor 24.4 endete der Punkt an der richtigen Stelle, um fortzufahren (z. B. Wiederholen). Ab 24.4 ist der Punkt dafür an der falschen Stelle Eine Regression oder das Hinzufügen einer nützlichen Funktion oder das Beheben eines anderen Fehlers liegt vermutlich im Auge des Betrachters. ;-) Ich habe Emacs- Fehler # 20698 dafür eingereicht , gerade eben.)

Drew
quelle