Mover formulário para cima e para baixo no modo paredit


13

Eu tenho usado a Edição Estrutural do cursive (um modo pareditado para Intellij e Cursive) e encontrei um bom comando lá chamado move form-up (e para baixo).

Mover formulário para cima faz isso (este |é o ponto):

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

e Mover formulário para baixo é análogo:

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

É possível fazer isso no modo paredit do Emacs? Eu acho que não está no conjunto de parênteses básico (pelo menos não está descrito nesta folha de dicas)


Agradável. Agora é uma operação que eu poderia me ver fazendo.
PythonNut

2
FWIW, pelo menos para os dois exemplos que você mostra, plain C-M-tfaz a mesma coisa. Mas acho que o que você quer dizer é que a mesma forma continua sendo movida, em vez de trocar o progresso pelo próximo par de sexps.
Desenhou

Respostas:


13

Como o @Drew sugeriu, C-M-tfaz o que você quer. A regra é assim:

  • Coloque o ponto no meio de dois sexps.
  • Pressione C-M-t(que é executado transpose-sexp).
  • O sexp esquerdo é sempre movido para a direita junto com point. Isso é muito importante , caso contrário você ficará confuso sem fim.

Ou, você pode simplesmente pensar que isso não é transposição, mas simplesmente para avançar, você precisa colocar um ponto após o sexp que deseja mover.

No entanto, existe um conveniente: quando você deseja transpor o sexp esquerdo para trás, você usa o mesmo, C-M-tmas é fornecido com um argumento de prefixo negativo e isso é inconveniente. Outra questão é que esse ponto não segue o sexp esquerdo transposto para trás . Para resolver esse problema, criamos uma versão reversa de 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))

Em seguida, vincule-o ao C-M-yque está ao lado C-M-te é livre no Emacs padrão.

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

Aqui está uma demonstração; você notará que (MY-SEXP1)está à esquerda o tempo todo para avançar / retroceder:

insira a descrição da imagem aqui


5

É possível fazer isso com lispy , que é uma forma avançada de paredit-mode.

Para o seu caso de uso:

  • w se move para cima
  • s desce

A única coisa é que o cursor precisa estar em paren, como está no seu exemplo:

(+ 1 |(+ 2 3) 4)

Você também pode mover vários sexps de uma só vez com we s, se os marcar com uma região. Veja a documentação para mais informações.


;; Existe uma maneira de usar apenas esses dois comandos? ;; Eu pareço perder "M-left" e "M-right" ao fazê-lo: `(add-hook 'clojure-mode-hook (lambda () (modo lispy 1)) (local-set-key (kbd" M - <up> ") 'lispy-move-up) (chave de configuração local (kbd" M- <down> ")' lispy-move-down))` `
nha

1

Aqui está outro comando (da biblioteca misc-cmds.el) que faz praticamente o que você solicita. Basta vinculá-lo a uma única chave ( C-M-tou qualquer outra coisa). Use-o para mover um sexp para frente e para trás repetidamente.

Um prefixo negativo arg transpõe para trás, como transpose-sexp, mas também deixa point pronto para fazer outra transposição para trás. E ao repetir, um prefixo negativo arg apenas inverte a direção.

Então, se você ligar o comando para, digamos, C-oe, em seguida move o sexp que está à esquerda do ponto à direita três vezes, em seguida, para a esquerda duas vezes, depois para a direita uma vez.C-o C-o C-o C-- C-o C-o C-- C-o

Um prefixo numérico arg tem efeito apenas no primeiro uso, ou seja, não ao repetir - ao repetir, o movimento é sempre um sexp por vez.

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

(Nota: O comportamento de transpose-sexpsmudou em 24.4, daí o teste de versão aqui. Antes de 24.4, o ponto acabou no lugar certo para continuar (por exemplo, repita). Começando com 24.4, o ponto está no lugar errado para isso. uma regressão ou adiciona um recurso útil ou corrige algum outro bug provavelmente está nos olhos de quem vê. ;-) Arquivei o bug # 20698 do Emacs para isso, agora.)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.