Poruszaj się w górę iw dół w trybie paredit

13

Korzystałem z Cursive's Structural Editing (tryb podobny do kredytów dla Intellij i Cursive) i znalazłem tam fajne polecenie o nazwie move form-up (i dół).

Przenieś formularz w górę robi to (o |to chodzi):

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

i Przenieś formularz w dół jest analogiczny:

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

Czy można to zrobić w trybie paac Emacsa? Myślę, że nie ma go w podstawowym zestawie paredit (przynajmniej nie jest opisany w tym ściągu)

Rodrigo Flores
źródło
Ładny. To operacja, którą widziałem.
PythonNut
2
FWIW, przynajmniej dla dwóch pokazanych przykładów, zwykły C-M-trobi to samo. Ale myślę, że masz na myśli to, że ta sama forma jest nadal przenoszona, zamiast zamiany postępu na następną parę sexps.
Drew

Odpowiedzi:

13

Jak sugeruje @Drew, C-M-trobi to, co chcesz. Zasada jest następująca:

  • Umieść punkt w środku dwóch sexps.
  • Naciśnij C-M-t(który działa transpose-sexp).
  • Lewej s-wyrażenie jest zawsze przesunięty w prawo wraz z punktem. Jest to bardzo ważne , w przeciwnym razie będziesz zdezorientowany bez końca.

Lub możesz po prostu pomyśleć, że to nie jest transpozycja, ale po prostu iść do przodu, musisz umieścić punkt za seksem, który chcesz przenieść.

Jest jednak jedna wygoda, że ​​kiedy chcesz przetransponować lewą seksu wstecz, używasz tego samego, C-M-tale z argumentem przedrostka ujemnego i jest to niewygodne. Inną kwestią jest to, że punkt nie będzie podążał za transponowaną do tyłu lewą seksem . Aby rozwiązać ten problem, tworzymy odwrotną wersję 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))

Następnie powiąż go z, C-M-yktóry jest obok C-M-ti jest domyślnie darmowy w Emacsie.

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

Oto demo; zauważysz, że (MY-SEXP1)cały czas jest po lewej stronie, aby przejść do przodu / do tyłu:

wprowadź opis zdjęcia tutaj

Do zrobienia
źródło
5

Można to zrobić za pomocą lispy , która jest zaawansowaną formą paredit-mode.

W przypadku użycia:

  • w przesuwa się w górę
  • s przesuwa się w dół

Jedyną rzeczą jest to, że kursor musi znajdować się w paren, co jest w twoim przykładzie:

(+ 1 |(+ 2 3) 4)

Możesz również przenieść kilka sexps jednocześnie wi s, jeśli oznaczysz je regionem. Więcej informacji znajduje się w dokumentacji .

abo-abo
źródło
;; Czy istnieje sposób użycia tylko tych dwóch poleceń? ;; Wydaje mi się, że tracę przy tym „M-lewy” i „M-prawy”: `(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

Oto kolejne polecenie (z biblioteki misc-cmds.el), które robi właściwie to, o co prosisz. Po prostu powiąż go z jednym kluczem ( C-M-tlub czymkolwiek). Użyj go, aby kilkakrotnie przesuwać seksu zarówno do przodu, jak i do tyłu.

Negatywny przedrostek arg transponuje wstecz, jak transpose-sexp, ale pozostawia punkt gotowy do wykonania kolejnej transpozycji wstecznej. A podczas powtarzania arg ujemny przedrostek arg po prostu zmienia kierunek.

Jeśli więc powiążesz polecenie, powiedzmy, C-oa następnie trzykrotnie przesuwa sekwencję na lewo od punktu w prawo, następnie dwa razy w lewo, a następnie raz w prawo.C-o C-o C-o C-- C-o C-o C-- C-o

Przedrostek numeryczny arg ma wpływ tylko przy pierwszym użyciu, tj. Nie przy powtarzaniu - przy powtarzaniu ruch jest zawsze jedną sekwencją na raz.

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

(Uwaga: zachowanie transpose-sexpszmieniło się w 24.4, stąd test wersji tutaj. Przed 24.4 punkt znajdował się we właściwym miejscu, aby kontynuować (np. Powtórzenie). Począwszy od 24.4, punkt znajduje się w niewłaściwym miejscu. Czy to jest regresja lub dodanie przydatnej funkcji lub naprawienie jakiegoś innego błędu jest prawdopodobnie w oczach patrzącego; ;-) Właśnie teraz zgłosiłem błąd Emacsa # 20698 ).

Rysował
źródło