如何与autopair.el一起使用vimpulse

时间:2011-05-18 08:47:52

标签: emacs

似乎当vimpulse正在运行时,autopair只能部分工作,因为在空括号对中按下退格键将不再删除右括号,而只删除开始的一个(这意味着退格现在可以作为正常的退格键)。一个例子:

(当Vimpulse和autopair都处于活动状态时,当前模式为INSERT模式,“|”表示光标)

开始:( |)

现在按“退格”

预期结果:| (删除了开括号和右括号)

实际结果:|)(仅删除左括号)

我知道这与vimpulse(或者更确切地说是viper-mode)从delete-backward-char重新映射[backspace]到其他东西(我认为是viper-delete-backward-char)这一事实有关。但我无法找到解决方法。

有人可以找到解决方案吗? (这样当支架为空且光标位于其间时,退格键将移除开合括号。)

谢谢!

4 个答案:

答案 0 :(得分:0)

我认为你的init文件中的这样的东西会起作用:

(add-hook 'autopair-mode-hook 
  '(lambda ()
    (define-key autopair-emulation-alist [remap viper-delete-backward-char] 'autopair-backspace)))

答案 1 :(得分:0)

我会自己回答这个问题。

我无法找出解决问题的“正统”方法,我想出了一个黑客。

建议在viper插入模式(viper-del-backward-char-in-insert)中绑定的函数检查游标当前是否在匹配对中,如果是,则删除游标之后的字符调用实际函数。这也考虑了由前缀字符(反斜杠)引起的可能问题。

在viper-mode或vimpulse加载后,只需将下面的代码复制到.emacs文件中。

(defun not-escaped (escape-char)

  "Character immediately before cursor is not prefixed by escape-char"
  (let ((count 0))
    (save-excursion
      (if (char-before)
          (backward-char))
      (while (and (char-before)
                  (= (char-before) escape-char))
        (setq count (+ count 1))
        (backward-char))
      (if (= 0
             (% count 2))
          t
        nil))))

(defun in-matched-empty-pair (pair-list)
  "tell if cursor is in an empty pair in pair-list"
  (let ((next-char (char-after))
        (prev-char (char-before))
        (matched nil)
        (pair)
        (pair-left)
        (pair-right))
    (if (and next-char
             prev-char)
          (while (and (setq pair
                       (pop pair-list))
                      (not matched))
            (setq pair-left (pop pair)
                  pair-right (pop pair))
            (if (= next-char pair-right)
                (if (and
                     (= prev-char pair-left)
                     (not-escaped ?\\))
                    (setq matched t)))))
    (if matched
        t
      nil)))

(defvar viper-workaround-pairs
      '(
        (?\" ?\")
        (?\' ?\')
        (?\` ?\`)
        (?\( ?\))
        (?\[ ?\])
        (?\{ ?\})
        ))

;; Workaround for integration problem with autopair
(defadvice viper-del-backward-char-in-insert (before viper-auto-delete-pair-backward())
  (if (in-matched-empty-pair viper-workaround-pairs)
      (delete-char 1)))

;; Activate advice
(ad-activate 'viper-del-backward-char-in-insert)

这是一个黑客,但它可能是我现在能做的最好的。

答案 2 :(得分:0)

这是我更新的解决方案。将以下内容放在.emacs文件加载autopair和vimpulse的代码之后:

(add-to-ordered-list 'emulation-mode-map-alists (car (last emulation-mode-map-alists)) 400)

它在viper的前面移动autopair的键盘映射,赋予它更高的优先级。 也许您必须熟悉订单号(此处为400),具体取决于您是否使用其他仿真模式。 可以使用C-x v emulation-mode-map-alists检查结果。就我而言:

(viper--intercept-key-maps cua--keymap-alist autopair-emulation-alist viper--key-maps)

现在,autopair-emulation-alist应列在viper--key-maps之前。

答案 3 :(得分:0)

鲍米歇尔找到了诀窍。我只需添加一个快速代码段来提供帮助:

首先,由于autopair-mode只是附加autopair-emulation-alist,所以评估:

(defadvice viper-change-state-to-insert (after autopair nil activate)
  (add-to-ordered-list 'emulation-mode-map-alists 'autopair-emulation-alist 300))

然后,请记住vimpulse-normalize-minor-mode-map-alist删除了alist前面的所有viper个键映射,因此请执行:

(defadvice vimpulse-normalize-minor-mode-map-alist (after order-viper--key-maps nil activate)
   (add-to-ordered-list 'emulation-mode-map-alists 'viper--key-maps 500))

这对我有用!我评估了eval-after-loadvimpulse嵌入式autopair中的这些摘要。

我的想法是,Emacs dev应该重新考虑emulation-mode-map-alists并使用属性列表索引优先级顺序,如下所示:((:name viper--key-maps :after (cua--keymap-alist autopair-emulation-alist)) (:name viper--intercept-key-maps :before (cua--keymap-alist autopair-emulation-alist)))。像viperCUA等旧包应该得到更好的维护,因为我们的设置在使用Emacs多年后变得难看。