Combinando dois operadores no Emacs no modo Maligno

7

No vim eu remapeei > e < quando no modo visual para >gv e <gv respectivamente, assim:

vnoremap > >gv
vnoremap < <gv

Como o meu alvo para essa pergunta é pessoal experiente com o emacs e não com o vim, o que > e < fazem é recuar / selecionar texto visualmente selecionado. O que gv faz é selecionar novamente o texto selecionado anteriormente. Esses mapas causam > e < para indent / dedent e, em seguida, selecionam novamente o texto selecionado anteriormente.

Estou experimentando o emacs com o modo mal e gostaria de fazer o mesmo, mas estou tendo alguma dificuldade em descobrir exatamente como realizar a seleção automática.

Parece que preciso chamar de alguma forma evil-shift-right e evil-visual-restore sequencialmente, mas não sei como criar um mapa que faça as duas coisas, então tentei criar minha própria função, que chamaria sequencialmente e mapear em vez disso, mas não funcionou, possivelmente devido ao fato de que ambos são definidos, não como funções com defun , mas como operadores com evil-define-operator .

Eu tentei criar meus próprios operadores:

(evil-define-operator shift-left-reselect (beg end)
    (evil-shift-left beg end)
    (evil-visual-restore))

(evil-define-operator shift-right-reselect (beg end)
    (evil-shift-right beg end)
    (evil-visual-restore))

mas isso não restaura o visual como esperado. Uma facada no escuro me deu isso:

(evil-define-operator shift-left-reselect (beg end)
    (evil-shift-left beg end)
    ('evil-visual-restore))

(evil-define-operator shift-right-reselect (beg end)
    (evil-shift-right beg end)
    ('evil-visual-restore))

mas que seleciona uma linha adicional sempre que é necessário selecioná-la novamente.

Por enquanto, estou usando o seguinte, que só tem o problema de selecionar novamente uma linha adicional no operador < .

(evil-define-operator shift-right-reselect (beg end)
  (evil-shift-right beg end)
  (evil-visual-make-selection beg end))

(evil-define-operator shift-left-reselect (beg end)
  (evil-shift-left beg end)
  (evil-visual-make-selection beg end))

e eu os mapeei:

(define-key evil-visual-state-map ">" 'shift-right-reselect)
(define-key evil-visual-state-map "<" 'shift-left-reselect)

qualquer ajuda / ponteiros / dicas seria muito apreciada.

Obrigado antecipadamente.

editar:

Gostaria de poder essencialmente fazer isso:

(define-key evil-visual-state-map ">" (kbd ">gv"))
(define-key evil-visual-state-map "<" (kbd "<gv"))

Mas como não há um conceito de mapeamento padrão para > ou < , a ideia de um mapeamento recursivo não faz sentido, e isso tem todos os problemas que você espera de tal mapa. Os seguintes trabalhos, no entanto, são feios, pois exigem a adição de dois mapas descartáveis. Existe alguma maneira de evitar isso?

(define-key evil-visual-state-map "g>" 'evil-shift-right)
(define-key evil-visual-state-map "g<" 'evil-shift-left)
(define-key evil-visual-state-map ">" (kbd "g>gv"))
(define-key evil-visual-state-map "<" (kbd "g<gv"))

Se o tempo for suficiente, aproveito isso, crie uma resposta e aceite-a para que outras pessoas que encontrarem essa pergunta possam encontrá-la / usá-la com facilidade.

    
por mkomitee 02.09.2012 / 23:48

2 respostas

4

O comando evil-shift-right precisa de um argumento de início e fim, com a exigência de que o argumento inicial seja menor que o argumento final. Uma maneira de conseguir isso é o seguinte:

(define-key evil-visual-state-map ">" (lambda ()
    (interactive)
    ; ensure mark is less than point
    (when (> (mark) (point)) 
        (exchange-point-and-mark)
    )
    (evil-normal-state)
    (evil-shift-right (mark) (point))
    (evil-visual-restore) ; re-select last visual-mode selection
))

(define-key evil-visual-state-map "<" (lambda ()
    (interactive)
    ; ensure mark is less than point
    (when (> (mark) (point)) 
        (exchange-point-and-mark)
    )
    (evil-normal-state)
    (evil-shift-left (mark) (point))
    (evil-visual-restore) ; re-select last visual-mode selection
))
    
por 17.10.2012 / 21:43
2

Acabei usando o seguinte:

(define-key evil-visual-state-map (kbd "<") (lambda ()
  (interactive)
  (evil-shift-left (region-beginning) (region-end))
  (evil-normal-state)
  (evil-visual-restore)))
(define-key evil-visual-state-map (kbd ">") (lambda ()
  (interactive)
  (evil-shift-right (region-beginning) (region-end))
  (evil-normal-state)
  (evil-visual-restore)))
    
por 28.08.2013 / 01:50

Tags