2011-12-13 115 views
100

我一直在使用Vim作为我的主要编辑器多年,并在此期间尝试过几次Emacs。然后我发现Evil,并决定它满足我对快速移动的需求,以至于我终于可以转向Emacs。邪恶模式最佳实践?

因此,对于所有你邪恶的用户,你如何将它与普通的Emacs功能集成?您是否遇到过此模式与其他模式之间的任何冲突?你对这个主题有什么共享价值的经验/提示?

回答

67

我使用了高度自定义的vim​​,现在使用更多定制的emacs。我想你会在我的keymapping配置文件中找到keymapping的每个实例https://github.com/mbriggs/.emacs.d-oldv2/blob/master/init/init-keymaps.el

请记住,我正在重新绑定真正的emacs用户会认为是异端的东西,所以YMMV如果你想学习“真正的”emacs(I真的不)。

有一件事我会推荐给任何前vimmer是这个

;;; esc quits 
(defun minibuffer-keyboard-quit() 
    "Abort recursive edit. 
In Delete Selection mode, if the mark is active, just deactivate it; 
then it takes a second \\[keyboard-quit] to abort the minibuffer." 
    (interactive) 
    (if (and delete-selection-mode transient-mark-mode mark-active) 
     (setq deactivate-mark t) 
    (when (get-buffer "*Completions*") (delete-windows-on "*Completions*")) 
    (abort-recursive-edit))) 
(define-key evil-normal-state-map [escape] 'keyboard-quit) 
(define-key evil-visual-state-map [escape] 'keyboard-quit) 
(define-key minibuffer-local-map [escape] 'minibuffer-keyboard-quit) 
(define-key minibuffer-local-ns-map [escape] 'minibuffer-keyboard-quit) 
(define-key minibuffer-local-completion-map [escape] 'minibuffer-keyboard-quit) 
(define-key minibuffer-local-must-match-map [escape] 'minibuffer-keyboard-quit) 
(define-key minibuffer-local-isearch-map [escape] 'minibuffer-keyboard-quit) 

使ESC实际上退出相当多的东西(如在迷你挂起提示)

+6

minibuffer-keyboard-quit的定义可以在这里找到:https://github.com/davvil/.emacs.d/ blob/master/init.el –

+1

@Adam对此抱歉>。我安装了很多东西,有时我使用了一个我认为是内置的函数,但实际上来自其他地方 –

+3

我发现这并不是'为我工作。我使用最新的Emacs 24.4,有没有人遇到过相同的问题? – nXqd

16

一个月前我开始使用邪恶;在此之前,我试图用viper/vimpulse没有太多的成功。说实话,vimpulse是相当不错的,但在各种模式下使用它有点麻烦(例如,vimpulse总是疯狂的编译模式),使得emacs在vi-emacs之间的某种模式下 - 某种东西。

当我切换到恶魔时,我终于开始探索完整的Emacs电源,相信我,我没有后悔。邪恶在我使用的所有模式(主要是编辑,编辑,抓取和eshell)中很好地工作,甚至读取info/man/help也没有任何问题。

除此之外,我只发现缓冲区开关奇数,因为我曾经这样做:b < 0-9>改为:b-TAB-then-complete-name或:bn。但请注意,邪恶开发人员尝试(在某些情况下)减少重复功能,所以相反:! (对于exec shell命令),你应该使用本地M- !.

如果您发现要添加/重新定义某些自定义ex命令,只需打开evil-maps.el并编辑它(在vim中尝试)。

邪恶仍然是年轻但很有前途的项目,我正在等待在Emacs官方发行版中取代毒蛇的那一天。

+4

这是否意味着它不可能在vim中添加/重新定义命令? –

+1

@JohnTyree用户定义的命令需要在Vim中以大写字母开头,而所有内置命令都以小写字母开头。 –

29

我也曾经是一名Viper/Vimpulse用户,拥有庞大的配置量。然后我发现了邪恶模式。

What's your sharing-worthy experiences/tips on this topic?

这是我的整个邪恶的模式配置,它为我的伟大工程:

(require 'evil) 
(evil-mode 1) 

;; Remap org-mode meta keys for convenience 
(mapcar (lambda (state) 
    (evil-declare-key state org-mode-map 
     (kbd "M-l") 'org-metaright 
     (kbd "M-h") 'org-metaleft 
     (kbd "M-k") 'org-metaup 
     (kbd "M-j") 'org-metadown 
     (kbd "M-L") 'org-shiftmetaright 
     (kbd "M-H") 'org-shiftmetaleft 
     (kbd "M-K") 'org-shiftmetaup 
     (kbd "M-J") 'org-shiftmetadown)) 
    '(normal insert)) 

Have you encounter any conflicts between this mode and others?

没有,相反,蝰蛇/ Vimpulse这是在几种模式造成麻烦。

+0

我得到这个错误: progn:作为变量的符号值是void:状态 状态定义在哪里? – justingordon

+0

你可以试试'evil-emacs-state' –

+2

你能澄清一下你把它放在哪里吗? – justingordon

34

正如有人谁从emacs的来了,试图vim,并意识到有很多事情要获得,我在开始使用邪恶时做了很多实验。虽然以下是有争议的,但我想保留在终端,firefox,cocoa等中更普遍使用的emacs密钥,但不想失去vim编辑功能。我最终决定重新绑定我的下列密钥。emacs:

(define-key evil-normal-state-map "\C-e" 'evil-end-of-line) 
(define-key evil-insert-state-map "\C-e" 'end-of-line) 
(define-key evil-visual-state-map "\C-e" 'evil-end-of-line) 
(define-key evil-motion-state-map "\C-e" 'evil-end-of-line) 
(define-key evil-normal-state-map "\C-f" 'evil-forward-char) 
(define-key evil-insert-state-map "\C-f" 'evil-forward-char) 
(define-key evil-insert-state-map "\C-f" 'evil-forward-char) 
(define-key evil-normal-state-map "\C-b" 'evil-backward-char) 
(define-key evil-insert-state-map "\C-b" 'evil-backward-char) 
(define-key evil-visual-state-map "\C-b" 'evil-backward-char) 
(define-key evil-normal-state-map "\C-d" 'evil-delete-char) 
(define-key evil-insert-state-map "\C-d" 'evil-delete-char) 
(define-key evil-visual-state-map "\C-d" 'evil-delete-char) 
(define-key evil-normal-state-map "\C-n" 'evil-next-line) 
(define-key evil-insert-state-map "\C-n" 'evil-next-line) 
(define-key evil-visual-state-map "\C-n" 'evil-next-line) 
(define-key evil-normal-state-map "\C-p" 'evil-previous-line) 
(define-key evil-insert-state-map "\C-p" 'evil-previous-line) 
(define-key evil-visual-state-map "\C-p" 'evil-previous-line) 
(define-key evil-normal-state-map "\C-w" 'evil-delete) 
(define-key evil-insert-state-map "\C-w" 'evil-delete) 
(define-key evil-visual-state-map "\C-w" 'evil-delete) 
(define-key evil-normal-state-map "\C-y" 'yank) 
(define-key evil-insert-state-map "\C-y" 'yank) 
(define-key evil-visual-state-map "\C-y" 'yank) 
(define-key evil-normal-state-map "\C-k" 'kill-line) 
(define-key evil-insert-state-map "\C-k" 'kill-line) 
(define-key evil-visual-state-map "\C-k" 'kill-line) 
(define-key evil-normal-state-map "Q" 'call-last-kbd-macro) 
(define-key evil-visual-state-map "Q" 'call-last-kbd-macro) 
(define-key evil-normal-state-map (kbd "TAB") 'evil-undefine) 

(defun evil-undefine() 
(interactive) 
(let (evil-mode-map-alist) 
    (call-interactively (key-binding (this-command-keys))))) 

不幸的是,这些重叠与vim“向上或向下移动一个屏幕”的操作。而不是不过,我已经使用变得舒适了以下内容:

(define-key evil-normal-state-map (kbd "DEL") (lambda() 
        (interactive) 
        (previous-line 10) 
        (evil-scroll-line-up 10) 
        )) 

(define-key evil-normal-state-map (kbd "=") (lambda() 
         (interactive) 
         (next-line 10) 
         (evil-scroll-line-down 10) 
        )) 

另外,如果您是从VIM使用“JK”(或任何其他2冲程组合)来了,希望得到一个快速的路径从插入到正常模式时,最好的方法是复制http://www.emacswiki.org/emacs/download/key-chord.el中的文本并将其粘贴到您的〜/ .emacs.d/key-chord.el中。然后添加以下到您的.emacs:

;load a file named key-chord.el from some directory in the load-path (e.g. "~/.emacs.d") 
(require 'key-chord) 
(key-chord-mode 1) 
(key-chord-define-global "jk" 'evil-normal-state) 

另外,如果你是从VIM来了,你认为复制到剪贴板中的emacs是不行的,你可能是正确的。但是,您可能运行sudo易于得到安装XSEL后发现下面的有用:

(defun copy-to-clipboard() 
    (interactive) 
    (if (display-graphic-p) 
     (progn 
     (message "Yanked region to x-clipboard!") 
     (call-interactively 'clipboard-kill-ring-save) 
     ) 
    (if (region-active-p) 
     (progn 
      (shell-command-on-region (region-beginning) (region-end) "xsel -i -b") 
      (message "Yanked region to clipboard!") 
      (deactivate-mark)) 
     (message "No region active; can't yank to clipboard!"))) 
) 

(evil-define-command paste-from-clipboard() 
    (if (display-graphic-p) 
     (progn 
     (clipboard-yank) 
     (message "graphics active") 
     ) 
    (insert (shell-command-to-string "xsel -o -b")) 
    ) 
) 

(global-set-key [f8] 'copy-to-clipboard) 
(global-set-key [f9] 'paste-from-clipboard) 

很明显,你必须自己决定任何这些有争议的变化是值得的,但也许这些基本的变化将激励您。

对于其他非常酷的功能实现,如删除和粘贴,删除而不复制到剪贴板,高效的4x/16x移动,使用粘贴寄存器规格的计数,实​​际适用于c/C++的选项卡设置等等,你可以在https://github.com/Russell91/emacs

+2

所有这一切都很好,我在wikemacs中添加了一些内容:http://wikemacs.org/index.php/Evil#Configuration – Ehvince

+0

我明白你的意愿将重用你的emacs习惯。为了在Firefox中工作,我强烈建议尝试使用Vimperator插件,这会为您的浏览带来许多类似vim的功能。但是,它默认使用vim移动命令(“少”命令等)。 –

+0

和你一样,我不喜欢插入状态模式下的邪恶绑定,所以我只是在正常状态映射中将“i”重新绑定到'evil-emacs-state。 – user49117

10

检查出完整的.emacs,init.el,我-keymaps.el,和我-functions.el我混帐versons我喜欢保存缓冲区,当我退出insert-mode: (编辑:当没有关联文件的时候,不要求保存这个缓冲区,就像在一个scratch或者magit缓冲区中一样)

(defun my-save() 
    (if (buffer-file-name) 
    (evil-save)) 
) 

    (add-hook 'evil-insert-state-exit-hook 'my-save) 

更多可能性:请参阅http://wikemacs.org/index.php/Evil

评论欢迎您的加入!

+0

谢谢。顺便说一句,你的链接被打破。 – Amos

+0

也谢谢。 Wikemacs会回来。该网站正在维护,希望不会再太长。 – Ehvince

8
  1. 我使用evil-leader并使用“,xm”来代替“M-x”,所以我很少按下Alt键。还有支持多个领导密钥的general.el

  2. evil-matchit,按“%”在标签对之间跳转。

  3. evil-nerd-commenter,按 “9,CI” 评论/取消注释9线

  4. 忌用ESC键,就可以代替press "kj"

  5. 对自由软件有信心! Evil结合了Vim和Emacs的力量,没有什么是不可能的。例如,许多人认为邪恶的键绑定与现有的插件Emacs相冲突而没有大量的重新绑定。 That's wrong actually

0

从emacs方面来说,我非常喜欢M-。要定义,但在M-.上运行的功能因模式而异。我可以通过(define-key evil-normal-state-map (kbd "M-.") 'foo)以普通的方式覆盖它,其中foo检查当前的主要模式并运行相应的功能,但听起来好像需要大量的硬编码。一个更普遍的解决方案是这样的:

(defun evil-emacs-key-binding (key) 
    (evil-execute-in-emacs-state) 
    (key-binding key)) 

(defmacro evil-revert-key-binding (state-map key) 
    `(define-key ,state-map ,key (lambda() 
           (interactive) 
           (call-interactively 
            (evil-emacs-key-binding ,key))))) 

(eval-after-load "evil-autoloads" 
    '(add-hook 'evil-after-load-hook 
     (lambda() 
      (evil-revert-key-binding evil-normal-state-map (kbd "M-.")) 
      ;; and so on 
     ))) 

其他,我喜欢的插件evil-surround(虽然我觉得smartparens是一个更完整的解决方案)和evil-leader

我用钥匙弦就像我已经学会在vim做JK映射到ESC,但它坚持治疗KJ一样的JK,所以不是我使用下列内容:

(defun evil-escape-if-next-char (trigger) 
    "Watches the next letter. If `trigger', then switch to normal mode, 
otherwise keep the previously inserted key and forward unpressed 
key to `unread-command-events'." 
    (self-insert-command 1) 
    (let ((next-key (read-event))) 
    (if (eq trigger next-key) 
     (progn 
      (delete-char -1) 
      (evil-normal-state)) 
     (setq unread-command-events (cons next-key unread-command-events))))) 

(defun evil-escape-if-next-char-is-k (arg) 
    (interactive "p") 
    (if (= arg 1) 
     (evil-escape-if-next-char ?k) 
    (self-insert-command arg))) 

(eval-after-load "evil-autoloads" 
    '(add-hook 'evil-after-load-hook 
      (lambda() 
       ;; … other stuff … 
       (define-key evil-insert-state-map (kbd "j") 'evil-escape-if-next-char-is-k)))) 

我使用的是(setq evil-move-cursor-back nil)这不是非常的vimmy(虽然很明显你可以让你的vimrc做到这一点),但我从来没有习惯在退出插入后退回光标。

实用提示:使用evil-local-mode-hook来加载恶意环绕模式,这不会使它成为普通的evil-mode-hook。所以,如果你安装的邪恶和邪恶的环绕包安装的,你可以把它启动的时候,你做

(eval-after-load "evil-surround-autoloads" 
    '(add-hook 'evil-local-mode-hook #'evil-surround-mode)) 

(当然做M-x evil-mode,如果你总是运行邪恶的模式,并始终让邪恶的安装,有不需要那种自动加载的东西,但我更喜欢让我的.emacs足够普遍,以至于我可以在具有旧emacsen的机器上使用它,或者没有安装任何elpa软件包。)