Перемещение формы вверх и вниз в режиме паредита

13

Я использовал Cursive's Structural Editing (режим, подобный паредиту для Intellij и Cursive), и нашел там замечательную команду, которая называется move form-up (и down).

Перемещение формы вверх делает это ( |точка):

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

и перемещение формы вниз аналогично:

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

Возможно ли это сделать в Emacs paredit-mode? Я думаю, что это не на основном наборе 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-left" и "M-right" при этом: `(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

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

Отрицательный префикс arg транспонируется назад, как transpose-sexp, но он также оставляет точку готовой сделать другую обратную транспозицию. А при повторении отрицательный префикс arg просто меняет направление.

Поэтому, если вы связываете команду, скажем, с C-o, затем перемещаете сексп, который находится слева от точки, три раза вправо, затем влево дважды, затем один раз вправо.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 для этого, только сейчас.)

Нарисовалась
источник