在 Emacs 中组合两个操作符

mko*_*tee 7 vim emacs elisp

在 vim 中,我重新映射了><在可视模式下分别映射到>gv<gv,如下所示:

vnoremap > >gv
vnoremap < <gv
Run Code Online (Sandbox Code Playgroud)

由于我的目标这个问题与emacs的经历乡亲,而不是VIM,什么><做的是缩进/ DEDENT语言视觉上选定的文本。什么gv是重新选择以前选择的文本。这些映射导致><缩进/缩进,然后重新选择先前选择的文本。

我正在尝试使用邪恶模式的 emacs,我也想做同样的事情,但是我在弄清楚如何准确地完成自动重新选择时遇到了一些困难。

看起来我需要以某种方式调用evil-shift-rightevil-visual-restore顺序,但我不知道如何创建一个可以同时调用和映射的映射,所以我尝试创建自己的函数,该函数将依次调用和映射,但它没有用,可能是因为它们都被定义为函数,defun而是作为运算符evil-define-operator

我尝试创建自己的运算符:

(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))
Run Code Online (Sandbox Code Playgroud)

但这并没有像预期的那样恢复视觉。黑暗中的刺伤给了我这个:

(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))
Run Code Online (Sandbox Code Playgroud)

但是只要它应该重新选择,就会选择额外的一行。

现在我一直在使用以下内容,它只有在重新选择<运算符中的附加行的问题。

(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))
Run Code Online (Sandbox Code Playgroud)

我已经映射了它们:

(define-key evil-visual-state-map ">" 'shift-right-reselect)
(define-key evil-visual-state-map "<" 'shift-left-reselect)
Run Code Online (Sandbox Code Playgroud)

任何帮助/指针/提示将不胜感激。

提前致谢。

编辑:

我希望能够基本上做到这一点:

(define-key evil-visual-state-map ">" (kbd ">gv"))
(define-key evil-visual-state-map "<" (kbd "<gv"))
Run Code Online (Sandbox Code Playgroud)

但是由于没有默认映射的概念><递归映射的想法没有任何意义,并且这具有您对此类映射所期望的所有问题。然而,以下工作,但它是丑陋的,因为它需要添加两个扔掉的地图。有什么办法可以避免这样做吗?

(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"))
Run Code Online (Sandbox Code Playgroud)

如果有足够的时间,我会接受这个,创建一个答案并接受它,以便其他发现这个问题的人可以轻松找到/使用它。

Mar*_*ark 4

evil-shift-right命令需要开始和结束参数,并要求开始参数小于结束参数。实现此目的的一种方法如下:

(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
))
Run Code Online (Sandbox Code Playgroud)