evil mode emacs
¿La mejor práctica de Evil Mode? (7)
Yo uso evil-leader y uso ", xm" para reemplazar "Mx", así que rara vez presiono la tecla Alt. También hay general.el que admite múltiples claves de líder.
evil-matchit , presiona "%" para saltar entre par de etiquetas.
evil-nerd-commenter , presione "9, ci" para comentar / descomentar 9 líneas
evite usar la tecla ESC, puede presionar "kj" en su lugar.
¡Ten fe en el software libre! Nada es imposible con Evil, que combine el poder de Vim y Emacs. Por ejemplo, muchas personas suponen que las combinaciones de teclas Evil entran en conflicto con los complementos existentes de Emacs sin volver a enlazar. Eso está mal en realidad
He usado Vim como mi editor principal durante años y probé Emacs varias veces durante ese tiempo. Luego descubrí Evil y decidí que satisface mi demanda de movimiento rápido lo suficientemente bien como para finalmente poder pasar a Emacs.
Entonces, para todos los usuarios de Evil, ¿cómo lo integran con las funciones normales de Emacs? ¿Has encontrado algún conflicto entre este modo y otros? ¿Cuáles son sus experiencias / consejos para compartir sobre este tema?
Como alguien que vino de emacs, probé vim y se dio cuenta de que había muchas cosas que ganar, hice muchas pruebas cuando comencé a usar el mal. Si bien los siguientes son controvertidos, quería mantener las claves de emacs que se utilizan de forma más universal en terminal, firefox, cocoa, etc., pero no quería perder las capacidades de edición de vim. Terminé decidiendo volver a enlazar las siguientes claves en mis .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)))))
Desafortunadamente, estos se superponen con las operaciones de "mover una pantalla hacia arriba o hacia abajo". Sin embargo, me he sentido cómodo usando lo siguiente en su lugar:
(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)
))
Además, si vienes de vim y quieres una ruta rápida de inserción al modo normal usando "jk" (o cualquier otra combinación de 2 tiempos), la mejor manera es copiar el texto de http://www.emacswiki.org/emacs/download/key-chord.el y pégalo en tu ~ / .emacs.d / key-chord.el. Luego agrega lo siguiente a tus .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)
Además, si vienes de vim y crees que copiar en portapapeles en emacs no es bueno, probablemente tengas razón. Sin embargo, puede encontrar lo siguiente útil después de ejecutar 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)
Obviamente, tendrá que decidir por sí mismo si alguno de estos cambios controvertidos lo valen, pero tal vez estos cambios básicos lo inspiren.
Para otras implementaciones de funciones realmente interesantes, como eliminar y pegar, eliminar sin copiar al portapapeles, movimiento eficiente de 4x / 16x, uso de recuentos para especificación de registro de pasta, configuraciones de tabulación que realmente funcionan para c / c ++, y más, puede verificar las versiones completas de .emacs, init.el, my-keymaps.el y my-functions.el en mi git en https://github.com/Russell91/emacs
Empecé a usar Evil hace un mes; antes de eso, intenté usar viper / vimpulse sin mucho éxito. Para ser honesto, vimpulse es bastante agradable, pero usarlo con varios modos fue un poco problemático (por ejemplo, el modo de compilación donde vimpulse siempre se volvió loco) dejando emacs en algún modo entre vi-emacs-algo.
Cuando cambié al mal, finalmente comencé a explorar el poder completo de Emacs, y créanme, no me arrepentí. Evil funciona bien en todos los modos que utilicé (principalmente edición, compilación, scratch y eshell) e incluso leer información / man / help funciona sin ningún problema.
Excepto que, solo encontré la conmutación de búfer impar como solía hacer: b <0-9> en su lugar: b-TAB-then-complete-name o: bn. Sin embargo, tenga en cuenta que los desarrolladores de Evil intentan (en algunos casos) reducir las funcionalidades duplicadas, así que en su lugar:! (para ejecutar el comando de shell), debe usar M- nativo.
Si tiene ganas de agregar / redefinir algunos comandos ex personalizados, solo abra evil-maps.el y edítelo (¡intente eso en vim!).
El mal todavía es un proyecto joven pero prometedor y estoy esperando el día en que reemplazará a la víbora en la distribución oficial de Emacs.
Me gusta guardar el búfer cuando salgo del insert-mode
: (editado: no pidas guardar cuando no hay un archivo asociado para este búfer, como cuando está en un búfer o un búfer de magit)
(defun my-save ()
(if (buffer-file-name)
(evil-save))
)
(add-hook ''evil-insert-state-exit-hook ''my-save)
para más posibilidades: ver http://wikemacs.org/index.php/Evil
Comentarios bienvenidos para mejoras!
También solía ser un usuario de Viper / Vimpulse, con una gran cantidad de configuración. Entonces encontré Evil-mode.
¿Cuáles son sus experiencias / consejos para compartir sobre este tema?
Esta es toda mi configuración de modo malvado, y funciona muy bien para mí:
(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))
¿Has encontrado algún conflicto entre este modo y otros?
No, a diferencia de Viper / Vimpulse que causaba problemas en varios modos.
Viniendo desde el lado de emacs, prefiero mucho M-. ser ir a la definición, pero la función que se ejecuta en M-.
difiere en todos los modos. Podría anularlo de la manera habitual con (define-key evil-normal-state-map (kbd "M-.") ''foo)
donde foo
comprueba el modo principal actual y ejecuta la función apropiada, pero eso suena como'' d requiere un montón de hardcoding. Una solución más general es esta:
(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
)))
Aparte de eso, me gustan los plugins evil-surround (aunque creo que smartparens es una solución más completa) y evil-leader .
Solía usar el acorde de tecla para asignar jk a ESC como aprendí a hacer en vim, pero insistía en tratar kj como lo mismo que jk, así que en su lugar estoy usando lo siguiente:
(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))))
Yo uso (setq evil-move-cursor-back nil)
que no es muy vimmy (aunque aparentemente también puedes hacer que tu vimrc haga eso), nunca me acostumbré al movimiento del cursor hacia atrás luego de salir de insert.
Consejo práctico: use evil-local-mode-hook
para cosas como perezoso cargando mal-surround-mode, no ayudará a ponerlo en evil-mode-hook
. Así que si instalas el mal y el entorno perverso con la instalación del paquete, puedes hacer que comience cuando hagas Mx evil-mode
haciendo
(eval-after-load "evil-surround-autoloads"
''(add-hook ''evil-local-mode-hook #''evil-surround-mode))
(Por supuesto, si siempre ejecutas el modo malvado y siempre tienes el mal instalado, no hay necesidad de esas cosas de autocarga, pero prefiero que mis .emacs sean lo suficientemente generales como para poder usarlos en máquinas con emacsen antiguo o sin tener ninguno paquetes elpa instalados.)
Usé un vim altamente personalizado y ahora uso emacs aún más personalizados. Creo que encontrarás todas las instancias de keymapping en mi archivo de configuración de keymaps https://github.com/mbriggs/.emacs.d-oldv2/blob/master/init/init-keymaps.el
Tenga en cuenta que estoy volviendo a vincular cosas que los usuarios reales de emacs considerarían herejía, por lo tanto, YMMV si alguna vez quiere aprender emacs "reales" (realmente no).
Una cosa que recomendaría a cualquier ex vimmer es esta
;;; 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)
por lo que esc realmente sale prácticamente de cualquier cosa (como las solicitudes pendientes en el minibúfer)