Meilleure pratique du mode maléfique? [fermé]

104

J'utilise Vim comme éditeur principal depuis des années et j'ai essayé Emacs plusieurs fois pendant cette période. Ensuite, j'ai découvert Evil et j'ai décidé qu'il répondait suffisamment bien à ma demande de mouvement rapide pour que je puisse enfin passer à Emacs.

Alors, à tous les utilisateurs d'Evil, comment l'intégrer aux fonctions normales d'Emacs? Avez-vous rencontré des conflits entre ce mode et d'autres? Quelles sont vos expériences / conseils dignes d'être partagés sur ce sujet?

Daniel Duan
la source

Réponses:

71

J'ai utilisé un vim hautement personnalisé, et j'utilise maintenant un emacs encore plus personnalisé. Je pense que vous trouverez chaque instance de keymapping dans mon fichier de configuration de keymapping https://github.com/mbriggs/.emacs.d-oldv2/blob/master/init/init-keymaps.el

Gardez à l'esprit que je suis en train de relier des choses que les vrais utilisateurs d'emacs considéreraient comme une hérésie, donc YMMV si jamais vous voulez apprendre de «vrais» emacs (je ne le fais vraiment pas).

Une chose que je recommanderais à tout ex vimmer est la suivante

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

de sorte que esc ferme pratiquement tout (comme les invites en attente dans le mini-tampon)

Matt Briggs
la source
7
La définition de minibuffer-keyboard-quit peut être trouvée ici: github.com/davvil/.emacs.d/blob/master/init.el
Adam Bell
1
@Adam désolé pour ça>.> J'ai beaucoup de choses installées, parfois j'utilise une fonction que je pense intégrée, mais qui vient en fait d'ailleurs
Matt Briggs
3
Je trouve que cela ne fonctionne pas pour moi. J'utilise le dernier Emacs 24.4, est-ce que quelqu'un vit la même chose?
Dzung Nguyen
1
Le lien est rompu. Je crois que c'est le nouveau: github.com/mbriggs/.emacs.d/blob/master/config/keybinds.el
Sean Leather
1
@SeanLeather Réponse mise à jour à un lien de travail.
Christopher Bottoms
34

En tant que quelqu'un qui venait d'emacs, a essayé vim et s'est rendu compte qu'il y avait un grand nombre de choses à gagner, j'ai fait beaucoup d'expérimentation lorsque j'ai commencé à utiliser le mal. Bien que ce qui suit soit controversé, je voulais conserver les clés emacs qui sont utilisées plus universellement dans les terminaux, firefox, cacao, etc ..., mais je ne voulais pas perdre les capacités d'édition de vim. J'ai fini par décider de relier les clés suivantes dans mon .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)))))

Malheureusement, ceux-ci se chevauchent avec les opérations de vim "déplacer un écran vers le haut ou vers le bas". Cependant, je me suis familiarisé avec l'utilisation des éléments suivants à la place:

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

De plus, si vous venez de vim et que vous voulez un chemin rapide de l'insertion au mode normal en utilisant "jk" (ou toute autre combinaison de 2 temps), le meilleur moyen est de copier le texte de http://www.emacswiki.org/ emacs / download / key-chord.el et collez-le dans votre ~ / .emacs.d / key-chord.el. Ajoutez ensuite ce qui suit à votre .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)

De plus, si vous venez de vim et que vous pensez que la copie dans le presse-papiers dans emacs n'est pas bonne, vous avez probablement raison. Cependant, vous pouvez trouver ce qui suit utile après avoir exécuté 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)

Évidemment, vous devrez décider vous-même si l'un de ces changements controversés en vaut la peine, mais peut-être que ces changements de base vous inspireront.

Pour d'autres implémentations de fonctions vraiment intéressantes, telles que supprimer et coller, supprimer sans copier dans le presse-papiers, un mouvement 4x / 16x efficace, l'utilisation de décomptes pour la spécification de registre de collage, les paramètres de tabulation qui fonctionnent réellement pour c / c ++, et plus encore, vous pouvez vérifier les versions complètes .emacs, init.el, my-keymaps.el et my-functions.el sur mon git à https://github.com/Russell91/emacs

RussellStewart
la source
2
tout cela est super, j'en ai ajouté dans les wikemacs: wikemacs.org/index.php/Evil#Configuration
Ehvince
Je comprends votre volonté de réutiliser vos habitudes d'emacs. Pour travailler dans Firefox, je recommande vivement d'essayer l'addon Vimperator, qui apporte de nombreuses fonctionnalités de type vim à votre navigation. Cependant, il utilise les commandes de mouvement vim par défaut (comme c'est le cas pour la lesscommande et d'autres).
Jan Vlcinsky
Comme vous, je n'aime pas la liaison maléfique en mode insert-state-mode, donc je relie simplement "i" dans normal-state-map à 'evil-emacs-state.
user49117
Au lieu de remplacer le clavier de evil, je le supprime, donc il revient au réglage du clavier des emacs normaux, exemple(dolist (m (list evil-normal-state-map evil-motion-state-map evil-insert-state-map)) (define-key m "\C-e" 'nil))
Bach Lien
30

J'étais aussi un utilisateur de Viper / Vimpulse, avec une énorme quantité de configuration. Puis j'ai trouvé Evil-mode.

Quelles sont vos expériences / conseils dignes d'être partagés sur ce sujet?

C'est toute ma configuration en mode maléfique, et cela fonctionne très bien pour moi:

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

Avez-vous rencontré des conflits entre ce mode et d'autres?

Non, contrairement à Viper / Vimpulse qui causait des problèmes dans plusieurs modes.

Kenny Meyer
la source
J'obtiens cette erreur: progn: La valeur du symbole en tant que variable est void: state Où l'état est-il défini?
justingordon
Vous pouvez essayerevil-emacs-state
Kenny Meyer
2
Pouvez-vous préciser où vous mettez cela?
justingordon
1
C'est fantastique, j'ai cherché exactement ça. Des votes positifs à profusion!
jplindstrom
1
Jetez un œil à ce github.com/edwtjo/evil-org-mode
avendael
17

J'ai commencé à utiliser Evil il y a un mois; avant cela, j'ai essayé d'utiliser viper / vimpulse sans grand succès. Pour être honnête, vimpulse est assez sympa, mais l'utiliser avec différents modes était un peu gênant (par exemple le mode de compilation où vimpulse devenait toujours fou) laissant emacs dans un certain mode entre vi-emacs-quelque chose.

Quand je suis passé à Evil, j'ai finalement commencé à explorer toute la puissance d'Emacs, et croyez-moi, je n'ai pas regretté. Evil fonctionne bien dans tous les modes que j'ai utilisés (principalement édition, compilation, scratch et eshell) et même la lecture d'informations / man / help fonctionne sans aucun problème.

Sauf que, je n'ai trouvé que la commutation de tampon bizarre comme je le faisais: b <0-9> à la place: b-TAB-then-complete-name ou: bn. Notez cependant que les développeurs d'Evil essaient (dans certains cas) de réduire les fonctionnalités en double, donc à la place:! (pour exécuter la commande shell), vous devez utiliser M- !.

Si vous avez envie d'ajouter / redéfinir certaines commandes ex personnalisées, ouvrez simplement evil-maps.el et modifiez-le (essayez cela dans vim!).

Evil est encore un projet jeune mais prometteur et j'attends le jour où il remplacera viper dans la distribution officielle d'Emacs.

Dennis
la source
4
Est-ce supposé impliquer qu'il n'est pas possible d'ajouter / redéfinir des commandes dans vim?
John Tyree
1
@JohnTyree Les commandes définies par l'utilisateur doivent commencer par une lettre majuscule dans Vim, alors que toutes les commandes intégrées commencent par une lettre minuscule.
Austin Taylor
10

J'aime sauvegarder le buffer quand je quitte le insert-mode: (édité: ne pas demander d'enregistrer quand il n'y a pas de fichier associé pour ce buffer, comme dans un scratch ou un buffer magit)

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

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

pour plus de possibilités: voir http://wikemacs.org/index.php/Evil

Commentaires bienvenus pour des améliorations!

Ehvince
la source
Merci. BTW, votre lien est rompu.
Amos
Merci aussi. Wikemacs reviendra. Le site est en maintenance, je l'espère pas trop longtemps.
Ehvince
9
  1. J'utilise evil-leader et utilise ", xm" pour remplacer "Mx", donc j'appuie rarement sur la touche Alt. Il existe également general.el qui prend en charge plusieurs clés de tête.

  2. evil-matchit , appuyez sur "%" pour passer d'une paire de balises à l'autre.

  3. evil-nerd-commenter , appuyez sur "9, ci" pour commenter / décommenter 9 lignes

  4. évitez d'utiliser la touche ESC, vous pouvez appuyer sur "kj" à la place.

  5. Faites confiance au logiciel libre! Rien n'est impossible avec Evil qui allie la puissance de Vim et Emacs. Par exemple, beaucoup de gens supposent que les raccourcis clavier Evil sont en conflit avec les plugins Emacs existants sans relier lourd. C'est faux en fait

chen bin
la source
0

Venant du côté emacs, je préfère nettement M-. pour être défini, mais la fonction qui s'exécute M-.diffère selon les modes. Je pourrais le remplacer de la manière habituelle avec (define-key evil-normal-state-map (kbd "M-.") 'foo)where foovérifie le mode majeur actuel et exécute la fonction appropriée, mais cela semble nécessiter beaucoup de codage en dur. Une solution plus générale est la suivante:

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

A part ça, j'aime les plugins evil-surround (même si je pense que smartparens est une solution plus complète) et evil-leader .

J'avais l'habitude d'utiliser l'accord de clé pour mapper jk à ESC comme j'ai appris à le faire dans vim, mais il insistait pour traiter kj comme étant le même que jk, donc à la place, j'utilise ce qui suit:

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

j'utilise (setq evil-move-cursor-back nil) ce qui n'est pas très vimmy (bien qu'apparemment vous puissiez faire en sorte que votre vimrc le fasse également), je ne me suis jamais habitué au recul du curseur après la sortie d'insert.

Astuce pratique: utilisez evil-local-mode-hookpour des trucs comme le chargement paresseux du mode evil-surround, cela n'aidera pas à le mettre en clair evil-mode-hook. Donc, si vous installez evil et evil-surround avec package-install, vous pouvez le faire démarrer lorsque vous le faites M-x evil-modeen faisant

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

(Bien sûr, si vous exécutez toujours le mode maléfique et que vous avez toujours mal installé, il n'y a pas besoin de ce chargement automatique, mais je préfère que mes .emacs soient suffisamment généraux pour que je puisse l'utiliser sur des machines avec de vieux emacsen ou sans en avoir packages elpa installés.)

marteler
la source