web-dev-qa-db-fra.com

Meilleure pratique du mauvais mode?

J'utilise Vim comme principal éditeur depuis des années et j'ai essayé plusieurs fois à Emacs au cours de cette période. Puis, j'ai découvert Evil et j'ai décidé que cela répondait suffisamment à ma demande de mouvement rapide pour pouvoir enfin passer à Emacs.

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

104
Daniel Duan

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

Gardez à l'esprit, je suis en train de relier des choses que de vrais utilisateurs d'Emacs considéreraient comme une hérésie, alors YMMV si vous voulez jamais apprendre de "vrais" Emacs (ce n'est vraiment pas le cas). 

Une chose que je recommanderais à tous les anciens

;;; 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 quitte en fait à peu près n'importe quoi (comme les invites en attente dans le mini-tampon)

69
Matt Briggs

En tant que personne venant d’emacs, qui a essayé vim et réalisé qu’il y avait un grand nombre de choses à gagner, j’ai fait beaucoup d’expériences lorsque j’ai commencé à utiliser le mal. Bien que les points suivants soient controversés, je souhaitais conserver les clés emacs utilisées de manière plus universelle 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 mes fichiers .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, ces opérations se chevauchent avec les opérations de vim "déplacer un écran vers le haut ou le bas". Cependant, je me suis habitué à utiliser les éléments suivants:

(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 même, si vous venez de vim et que vous voulez un chemin rapide du mode d'insertion au mode normal à l'aide de "jk" (ou de 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 à vos .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 copier dans le presse-papiers d’Emacs n’est pas bon, vous avez probablement raison. Cependant, les éléments suivants peuvent vous être utiles 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 fondamentaux vous inspireront.

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

34
RussellStewart

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

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

Ceci est toute ma configuration en mode pervers, 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 les autres? 

Non, contrairement à Viper/Vimpulse qui posait problème dans plusieurs modes.

30
Kenny Meyer

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 gentil, mais l’utiliser avec différents modes était un peu gênant (par exemple, le mode compilation où vimpulse devenait toujours fou), laissant emacs dans un mode entre vi-emacs-quelque chose.

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

Sauf que, j’ai trouvé le changement de tampon aussi étrange que je le faisais auparavant: b <0-9> à la place: b-TAB-then-complete-name ou: bn. Notez cependant que les développeurs Evil tentent (dans certains cas) de réduire les fonctionnalités en double, donc:! (pour exécuter la commande Shell), vous devez utiliser M- !. en natif.

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

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

17
dennis

J'aime enregistrer le tampon lorsque je quitte le insert-mode: (Modifié: ne demandez pas à enregistrer s'il n'existe aucun fichier associé à ce tampon, comme dans un scratch ou un tampon 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!

10
Ehvince
  1. J'utilise evil-leader et j'utilise ", xm" pour remplacer "M-x", aussi j'appuie rarement sur la touche Alt. Il existe également general.el qui prend en charge plusieurs clés de chef.

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

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

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

  5. Ayez confiance dans le logiciel libre! Rien n’est impossible avec Evil qui combine le pouvoir de Vim et d’Emacs. Par exemple, beaucoup de gens supposent que les associations de touches Evil sont en conflit avec les plugins existants Emacs sans une nouvelle liaison. C'est faux en fait

8
chen bin

Venant du côté Emacs, je préfère de loin M-. être défini, mais la fonction qui s'exécute sur 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), où foo vé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
        )))

En dehors de cela, j'aime bien les plugins evil-surround (même si j'estime que smartparens est une solution plus complète) et evil-leader

J'avais l'habitude d'utiliser des accords clés pour mapper jk sur ESC, comme j'ai appris à le faire dans vim, mais il insistait pour que kj soit traité de la même manière que jk. C'est pourquoi, j'utilise plutôt les éléments suivants:

(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) qui n'est pas très vimmy (même si, apparemment, vous pouvez faire en sorte que votre vimrc le fasse aussi), je ne me suis jamais habitué à ce que le curseur revienne en arrière après avoir quitté l'insertion. 

Conseil pratique: utilisez evil-local-mode-hook pour des tâches telles que le chargement paresseux de mal-surround-mode, cela ne vous aidera pas à le mettre en clair evil-mode-hook. Donc, si vous installez le mal et le mal-entourent avec package-install, vous pouvez le faire démarrer quand vous faites M-x evil-mode en faisant 

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

(Bien sûr, si vous utilisez toujours le mauvais mode et que vous avez toujours le mal installé, vous n'avez pas besoin de ce chargement automatique, mais je préfère que mon .emac soit suffisamment général pour pouvoir l'utiliser sur des machines avec le vieil emacsen ou sans aucun paquets elpa installés.)

0
unhammer