邪恶模式最佳实践?

多年来,我一直使用Vim作为我的主编,并在那段时间尝试了几次Emacs。 然后我发现了邪恶,并决定满足我对快速移动的要求,以至于我终于可以转向Emacs了。

所以,对于所有的恶魔用户,你如何将它与普通的Emacsfunction整合? 你有没有遇到这种模式和其他人之间的任何冲突? 什么是你的共享值得体验/这个话题的提示?

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

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

有一件事我会推荐给任何ex 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实际上完全退出了任何东西(比如minibuffer中的挂起提示)

作为来自emacs的人,尝试了vim,意识到有很多东西需要获得,我在开始使用邪恶时做了很多实验。 虽然以下是有争议的,我想保持terminal,firefox,cocoa等更普遍使用的emacs键,但不想失去vim编辑function。 我最终决定重新绑定我的.emacs中的以下键:

 (define-key evil-normal-state-map "\Ce" 'evil-end-of-line) (define-key evil-insert-state-map "\Ce" 'end-of-line) (define-key evil-visual-state-map "\Ce" 'evil-end-of-line) (define-key evil-motion-state-map "\Ce" 'evil-end-of-line) (define-key evil-normal-state-map "\Cf" 'evil-forward-char) (define-key evil-insert-state-map "\Cf" 'evil-forward-char) (define-key evil-insert-state-map "\Cf" 'evil-forward-char) (define-key evil-normal-state-map "\Cb" 'evil-backward-char) (define-key evil-insert-state-map "\Cb" 'evil-backward-char) (define-key evil-visual-state-map "\Cb" 'evil-backward-char) (define-key evil-normal-state-map "\Cd" 'evil-delete-char) (define-key evil-insert-state-map "\Cd" 'evil-delete-char) (define-key evil-visual-state-map "\Cd" 'evil-delete-char) (define-key evil-normal-state-map "\Cn" 'evil-next-line) (define-key evil-insert-state-map "\Cn" 'evil-next-line) (define-key evil-visual-state-map "\Cn" 'evil-next-line) (define-key evil-normal-state-map "\Cp" 'evil-previous-line) (define-key evil-insert-state-map "\Cp" 'evil-previous-line) (define-key evil-visual-state-map "\Cp" 'evil-previous-line) (define-key evil-normal-state-map "\Cw" 'evil-delete) (define-key evil-insert-state-map "\Cw" 'evil-delete) (define-key evil-visual-state-map "\Cw" 'evil-delete) (define-key evil-normal-state-map "\Cy" 'yank) (define-key evil-insert-state-map "\Cy" 'yank) (define-key evil-visual-state-map "\Cy" 'yank) (define-key evil-normal-state-map "\Ck" 'kill-line) (define-key evil-insert-state-map "\Ck" 'kill-line) (define-key evil-visual-state-map "\Ck" '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笔画组合)从插入到正常模式的快速path,最好的方法是从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 (eg "~/.emacs.d") (require 'key-chord) (key-chord-mode 1) (key-chord-define-global "jk" 'evil-normal-state) 

另外,如果你是从vim过来的,而你认为​​emacs中的复制到剪贴板不好,你可能是对的。 但是,运行sudo apt-get install 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) 

显然,你必须自己决定这些有争议的变化是否值得,但也许这些基本的变化会激励你。

对于一些其他非常酷的function实现,比如删除和粘贴,删除而不复制到剪贴板,高效的4x / 16x移动,粘贴寄存器规格的使用计数,实际用于c / c ++的选项卡设置等,您可以检查在我的git上完整的.emacs,init.el,my-keymaps.el和my-functions.el版本在https://github.com/Russell91/emacs

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

什么是你的共享值得体验/这个话题的提示?

这是我整个邪恶的模式configuration,它对我很好:

 (require 'evil) (evil-mode 1) ;; Remap org-mode meta keys for convenience (mapcar (lambda (state) (evil-declare-key state org-mode-map (kbd "Ml") 'org-metaright (kbd "Mh") 'org-metaleft (kbd "Mk") 'org-metaup (kbd "Mj") 'org-metadown (kbd "ML") 'org-shiftmetaright (kbd "MH") 'org-shiftmetaleft (kbd "MK") 'org-shiftmetaup (kbd "MJ") 'org-shiftmetadown)) '(normal insert)) 

你有没有遇到这种模式和其他人之间的任何冲突?

不,与Viper / Vimpulse相比,它在几种模式下造成麻烦。

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

当我转向邪恶时,我终于开始探索完整的Emacs电源,相信我,我没有后悔。 邪恶在我使用的所有模式(主要是编辑,编辑,抓取和eshell)很好地工作,甚至阅读信息/人/帮助工作没有任何问题。

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

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

邪恶仍然年轻,但有希望的项目,我正在等待的一天,将取代正式的Emacs发行毒蛇。

当我退出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

评论欢迎改进!

  1. 我使用邪恶的领导,并使用“,XM”来代替“Mx”,所以我很less按下Alt键。 还有general.el支持多个领导键。

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

  3. 邪恶书呆子评论员 ,按“9,ci”评论/取消评论9行

  4. 避免使用ESC键,您可以按“kj”来代替。

  5. 对自由软件有信心! Evil结合了Vim和Emacs的力量,没有什么是不可能的。 例如,许多人认为邪恶的键绑定与现有的插件Emacs冲突,而不会重新绑定。 实际上这是错误的

从emacs方面来说,我非常喜欢M-。 去定义,而是运行在M-.上的函数M-. 各种模式不同。 我可以使用(define-key evil-normal-state-map (kbd "M-.") 'foo)以常规方式覆盖它,其中foo检查当前的主要模式并运行适当的函数, d需要大量的硬编码。 更通用的解决scheme是:

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

除此之外,我喜欢插件邪恶环绕 (虽然我觉得smartparens是一个更完整的解决scheme)和邪恶的领导者 。

我曾经用key-chord将jk映射到ESC,就像我在vim中学到的一样,但它坚持把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 。 所以,如果你用软件包安装来安装邪恶和邪恶的环境,你可以通过做Mx evil-mode来启动它

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

(当然,如果你总是运行邪恶模式,并且总是装上邪恶的东西,那么就没有必要使用自动加载的东西,但是我更喜欢让我的.emacs足够通用,以便可以在具有旧版本的emacsen的机器上使用它,安装elpa软件包。)