Pindahkan formulir ke atas dan ke bawah pada mode paredit


13

Saya telah menggunakan Structural Editing kursif (mode seperti paredit untuk Intellij dan Cursive) dan saya menemukan perintah yang bagus di sana yang disebut move form-up (dan bawah).

Pindahkan formulir ke atas apakah ini ( |maksudnya):

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

dan Pindahkan formulir ke bawah adalah analog:

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

Apakah mungkin untuk melakukan ini pada Emacs paredit-mode? Saya pikir itu bukan pada set paredit dasar (setidaknya tidak dijelaskan pada lembar contekan ini


Bagus. Nah, itu operasi yang bisa kulihat sendiri.
PythonNut

2
FWIW, setidaknya untuk dua contoh yang Anda perlihatkan, polos C-M-tmelakukan hal yang sama. Tapi saya kira apa yang Anda maksudkan adalah bahwa bentuk yang sama terus dipindahkan, daripada memiliki kemajuan bertukar pasangan seks berikutnya.
Drew

Jawaban:


13

Seperti yang disarankan @Drew, C-M-tlakukan apa yang Anda inginkan. Aturannya seperti ini:

  • Tempatkan titik di tengah dua sexps.
  • Tekan C-M-t(yang menjalankan transpose-sexp).
  • Itu sexp kiri selalu bergerak ke kanan bersama dengan titik. Ini sangat penting , jika tidak, Anda akan bingung sampai akhir.

Atau, Anda dapat dengan mudah berpikir bahwa ini bukan transposing tetapi hanya untuk bergerak maju, Anda harus menempatkan titik setelah sexp yang ingin Anda bergerak.

Namun, ada satu kemudahan yaitu, ketika Anda ingin mengubah jenis kelamin kiri ke belakang, Anda menggunakan yang sama C-M-ttetapi disertakan dengan argumen awalan negatif dan ini tidak nyaman. Masalah lain adalah bahwa titik tidak akan mengikuti transpos mundur sexp kiri . Untuk mengatasi masalah ini, kami membuat versi terbalik dari 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))

Kemudian, ikat ke C-M-y yang di sebelahnya C-M-tdan gratis di Emacs default.

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

Ini demo; Anda akan melihat bahwa (MY-SEXP1)ada di sebelah kiri sepanjang waktu untuk bergerak maju / mundur:

masukkan deskripsi gambar di sini


5

Itu mungkin dilakukan dengan lispy , yang merupakan bentuk lanjutan dari paredit-mode.

Untuk kasus penggunaan Anda:

  • w bergerak ke atas
  • s bergerak ke bawah

Satu-satunya hal adalah kursor harus berada di paren, yang ada dalam contoh Anda:

(+ 1 |(+ 2 3) 4)

Anda juga dapat memindahkan beberapa sexps sekaligus dengan wdan s, jika Anda menandainya dengan suatu wilayah. Lihat dokumentasi untuk info lebih lanjut.


;; Apakah ada cara untuk hanya menggunakan kedua perintah itu? ;; Saya sepertinya kehilangan "M-left" dan "M-right" ketika melakukannya: `(add-hook 'clojure-mode-hook (lambda () (lispy-mode 1) (kunci-set-lokal) (kbd" M - <up> ") 'lispy-move-up) (set-lokal-kunci (kbd" M- <down> ")' lispy-move-down)))`
nha

1

Berikut adalah perintah lain (dari perpustakaan misc-cmds.el) yang melakukan cukup banyak apa yang Anda minta. Ikat saja ke satu tombol (C-M-t atau apa pun). Gunakan untuk menggerakkan sexp maju dan mundur berulang kali.

Argumen awalan negatif mentranspos mundur, seperti transpose-sexp , tetapi juga meninggalkan titik siap untuk melakukan transposisi mundur lain. Dan ketika mengulang, arg awalan negatif hanya membalik arah.

Jadi jika Anda mengikat perintah ke, katakanlah, C-olalu gerakkan sexp yang ada di sebelah kiri titik ke kanan tiga kali, lalu ke kiri dua kali, lalu ke kanan sekali.C-o C-o C-o C-- C-o C-o C-- C-o

Argumen numerik awalan hanya berpengaruh untuk penggunaan pertama, yaitu, tidak saat mengulang - saat mengulang, gerakan selalu satu jenis kelamin setiap kali.

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

(Catatan: Perilaku yang transpose-sexpsdiubah dalam 24.4, maka uji versi di sini. Sebelum 24.4, titik berakhir di tempat yang tepat untuk melanjutkan (mis. Ulangi). Mulai dengan 24.4, titik berada di tempat yang salah untuk itu. Apakah itu sebuah regresi atau menambahkan fitur yang berguna atau memperbaiki beberapa bug lain mungkin di mata yang melihatnya. ;-) Saya mengajukan bug Emacs # 20698 untuk ini, baru saja.)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.