2011-05-18 11 views
0

看來,當vimpulse運行時,autopair只能部分起作用,即在空括號對中按下退格將不再刪除右括號但僅打開一個(這意味着退格現在作爲普通的退格鍵)。一個例子:如何將vimpulse與autopair.el一起使用

(當Vimpulse和autopair都是活性的,和當前的模式是INSERT模式, 「|」 表示光標)

開始:(|)

現在按 「退格」

預期結果: (包括打開和關閉括號被刪除)

實際結果:|)(開場僅支架被移除)

我知道這已經與vimpulse(或者更確切地說,毒蛇模式)重新映射的事實辦[ backspace]從delete-backward-char到別的東西(我認爲是viper-delete-backward-char)。但我找不到解決辦法。

有人能找到解決方案嗎? (這樣當支架爲空並且光標位於其間時,退格鍵將移除打開和關閉支架)。

謝謝!

回答

0

我會回答這個問題我自己。

我找不出一種「正統」方式來解決問題,我想出了一個黑客攻擊。

建議在viper插入模式(viper-del-backward-char-in-insert)中綁定的函數檢查光標當前是否在匹配對中,如果是,則刪除光標後的字符在調用實際功能之前。這也考慮到可能由前綴字符(反斜槓)引起的問題。

在加載viper模式或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) 

這是一個黑客,但它可能是我現在可以做的最好的。

0

我覺得這樣的事情在你的init文件將工作:

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

謝謝jtahlborn,但它不起作用。首先,autopair-emulation-alist不是鍵盤映射,因此會導致錯誤。因此,我試圖破解autopair.el並在autopair keymap中添加(定義鍵映射[remap viper-delete-backward-char]'autopair-backspace)。仍然沒有運氣。 – xyc0562 2011-05-19 01:48:49

+0

@ xyc0562 - 完成之後,是否將綁定到「autopair-backspace」方法的刪除鍵? – jtahlborn 2011-05-19 03:03:03

+0

@ jtahlborn - 它一直被綁定到和「DEL」,如「描述函數」所示。但問題是,既不也不是「DEL」如果vimpulse是在 – xyc0562 2011-05-19 04:11:43

0

這是我更新的解決方案。把下面的在你的.emacs後檔加載autopair和vimpulse代碼:

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

它移動autopair的鍵盤映射在毒蛇之一的前面,給它更高的優先級。 也許您必須熟悉訂單號(這裏是400),具體取決於您是否使用其他仿真模式。 結果可以用C-x v emulation-mode-map-alists查詢。在我的情況:

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

現在,autopair-emulation-alistviper--key-maps上市之前。

+0

謝謝,baumichel,這在評估後立即生效。但問題是,每次切換到命令模式並返回到插入模式時,它都不再工作。也許我們需要添加一些鉤子或建議一些Viper或Vimpulse函數來使其工作?我嘗試了其中的一些,但都沒有成功。 – xyc0562 2011-06-06 06:00:25

+0

嗨xyc0562。你找到解決方案嗎? – 2011-07-04 13:04:29

0

baumichel找到了把戲。我只是添加一個快速片段的幫助:

首先,作爲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刪除所有viper鍵盤映射在ALIST的前面,所以執行:

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

這對我很有用!我對這兩個vimpulseautopair嵌入eval-after-load評估這些片段。

我的想法是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)))。像viper,CUA等舊套餐應該更好地維護,因爲我們的設置在Emacs多年後變得醜陋。

相關問題