Перемістіть форму вгору і вниз в режимі паредитування


13

Я використовував скорочувальний "Структурний редагування" (режим, що нагадує паритет для Intellij та Cursive), і я знайшов там непогану команду під назвою переміщення форми (і вниз).

Перемістити форму вгору робить це ( |справа в тому):

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

і Переміщення форми вниз аналогічно:

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

Чи можливо це зробити в режимі Emacs paredit? Я думаю, що це не на базовому паритетному наборі (принаймні, це не описано на цій шпаргалці


Приємно. Тепер це операція, яку я міг бачити, як роблю.
PythonNut

2
FWIW, принаймні для двох наведених вами прикладів, очевидний C-M-tробить приблизно те саме. Але я здогадуюсь, що ви маєте на увазі те, що та сама форма продовжує переміщуватися, замість того, щоб змінювати перехід до наступної пари секпсів.
Дрю

Відповіді:


13

Як запропонував @Drew, C-M-tробить те, що ти хочеш. Правило таке:

  • Поставте крапку посередині двох сексів.
  • Натисніть C-M-t(що працює transpose-sexp).
  • Лівий Sexp завжди переміщається вправо разом з точкою. Це дуже важливо , інакше ви будете плутати без кінця.

Або ви можете просто подумати, що це не переміщення, а просто просування вперед, ви повинні поставити крапку після сексопу, який ви хочете рухати.

Однак є одна зручна, яка полягає в тому, що коли ви хочете перенести лівий sexp назад, ви використовуєте той самий, C-M-tале поставлений з негативним аргументом префікса, і це незручно. Інше питання полягає в тому, що точка не буде слідувати відсталому транспонованому лівому сексу . Щоб вирішити цю проблему, ми створюємо зворотну версію 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))

Потім прив’яжіть його до того, C-M-yщо знаходиться поруч, C-M-tі в програмі Emacs за замовчуванням безкоштовно.

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

Ось демонстрація; ви помітите, що (MY-SEXP1)ліворуч весь час рухається вперед / назад:

введіть тут опис зображення


5

Це можна зробити з lispy , що є вдосконаленою формою paredit-mode.

Для вашого випадку використання:

  • w рухається вгору
  • s рухається вниз

Єдине, що курсор повинен бути у батьків, що це у вашому прикладі:

(+ 1 |(+ 2 3) 4)

Ви також можете переміщати відразу кілька сексів wі s, якщо ви позначаєте їх областю. Докладнішу інформацію див. У документації .


;; Чи є спосіб використовувати лише ці дві команди? ;; Я, здається, втрачаю "M-ліворуч" і "M-right", роблячи це так: `(add-hock 'clojure-mode-гак (lambda () (lispy-mode 1) (local-set-key (kbd" M) - <вгору> ") 'Lispy-рух вгору) (локальний посаджені ключ (KBD" M- <вниз> ")' Lispy-рух вниз)))`
Nha

1

Ось ще одна команда (з бібліотеки misc-cmds.el), яка робить майже все, що вам потрібно. Просто прив’яжіть його до однієї клавіші ( C-M-tабо будь-якої іншої ). Використовуйте його для переміщення секса як вперед, так і назад кілька разів.

Негативний аргумент префікса переміщує назад, як transpose-sexp, але він також залишає точку готовою зробити ще одну зворотну транспозицію. А при повторенні негативний аргумент з префіксом просто перевертає напрямок.

Так що, якщо ви зв'яжете команду, скажімо, C-o, потім переміщує Sexp , що знаходиться зліва від точки до правої три рази, потім двічі вліво, потім вправо один раз.C-o C-o C-o C-- C-o C-o C-- C-o

Числовий префікс arg має ефект лише при першому вживанні, тобто не при повторенні - при повторенні рух завжди одночасний.

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

(Примітка. Поведінка transpose-sexpsзмінилася в 24.4, отже, і тест на версію тут. До 24.4, точка потрапила в потрібне місце для продовження (наприклад, повторення). Починаючи з 24.4, точка знаходиться в неправильному для цього місці. Чи це регресія або додає корисну функцію чи виправляє якусь іншу помилку, ймовірно, в очах спостерігача. ;-) Я подав помилку Emacs №20698 для цього, просто зараз.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.