it-swarm.com.de

Evil Mode Best Practice?

Ich verwende Vim seit Jahren als meinen Haupteditor und habe Emacs während dieser Zeit mehrmals ausprobiert. Dann entdeckte ich Evil und entschied, dass es meine Forderung nach schnellen Bewegungen gut genug erfüllt, um endlich zu Emacs überzugehen.

Wie integrieren Sie es mit all Ihren bösen Benutzern in die normalen Emacs-Funktionen? Sind Sie auf Konflikte zwischen diesem Modus und anderen gestoßen? Was sind Ihre Erfahrungen und Tipps zu diesem Thema?

104
Daniel Duan

Ich habe eine sehr individuelle Vim verwendet, und jetzt noch mehr angepasste Emacs. Ich denke, Sie finden jede Instanz von Keymapping in meiner Keymapping-Konfigurationsdatei https://github.com/mbriggs/.emacs.d-oldv2/blob/master/init/init-keymaps.el

Denken Sie daran, ich binde Sachen zurück, die echte Emacs-Nutzer als Häresie bezeichnen würden. Wenn Sie also "echte" Emacs lernen möchten (YMMV), würde ich das nicht tun. 

Eine Sache, die ich jedem Ex-Vimmer empfehlen könnte, ist dies

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

so dass esc eigentlich so ziemlich alles beendet (wie ausstehende Aufforderungen im Minibuffer)

69
Matt Briggs

Als jemand, der aus Emacs stammte, Vim ausprobierte und erkannte, dass es eine Menge Dinge zu gewinnen gab, experimentierte ich viel, als ich anfing, das Böse zu benutzen. Während die folgenden Kontroversen umstritten sind, wollte ich die emacs-Schlüssel behalten, die universeller in Terminal, Firefox, Kakao usw. verwendet werden, aber die vim-Bearbeitungsfunktionen nicht verlieren. Am Ende entschied ich mich, die folgenden Schlüssel in meinen .emacs erneut zu binden:

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

Leider überlappen sich diese mit den vim-Vorgängen "Verschieben um einen Bildschirm nach oben oder nach unten". Ich habe es jedoch mit dem folgenden bequemer gemacht:

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

Wenn Sie von vim kommen und einen schnellen Weg vom Einfügen in den Normalmodus mit "jk" (oder einer anderen Kombination aus zwei Anschlägen) wünschen, ist es am besten, den Text aus http: //www.emacswiki zu kopieren. org/emacs/download/key-chord.el und fügen Sie es in Ihre ~/.emacs.d/key-chord.el ein. Fügen Sie dann Ihren .emacs Folgendes hinzu:

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

Wenn Sie von vim kommen und der Meinung sind, dass das Kopieren in die Zwischenablage in emacs nicht sinnvoll ist, haben Sie wahrscheinlich recht. Nach dem Ausführen von Sudo apt-get install xsel können Sie jedoch Folgendes hilfreich finden:

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

Natürlich müssen Sie selbst entscheiden, ob sich eine dieser umstrittenen Änderungen lohnt, aber vielleicht werden Sie durch diese grundlegenden Änderungen inspiriert.

Bei einigen anderen wirklich coolen Funktionsimplementierungen, z. B. Löschen und Einfügen, Löschen ohne Kopieren in die Zwischenablage, effizienter 4x/16x-Bewegung, Verwendung von Zählungen für die Angabe des Einfügeregisters, Registereinstellungen, die tatsächlich für c/c ++ funktionieren, können Sie überprüfen die vollständigen .emacs, init.el, my-keymaps.el und my-functions.el versons auf meinem Git unter https://github.com/Russell91/emacs

34
RussellStewart

Ich war auch ein Viper/Vimpulse-Benutzer mit einer großen Konfigurationsmenge. Dann fand ich den Bösen-Modus.

Welche Erfahrungen und Tipps würdest du zu diesem Thema teilen?

Dies ist meine gesamte Konfiguration für den bösen Modus und funktioniert hervorragend für mich:

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

Haben Sie Konflikte zwischen diesem Modus und anderen festgestellt?

Nein, im Gegensatz zu Viper/Vimpulse, die in mehreren Modi Probleme verursachten.

30
Kenny Meyer

Ich begann vor einem Monat mit dem Bösen. davor habe ich versucht, Viper/Vimpulse ohne großen Erfolg zu verwenden. Um ehrlich zu sein, ist vimpulse ziemlich nett, aber es war etwas umständlich, es in verschiedenen Modi zu verwenden (z. B. im Kompilierungsmodus, in dem vimpulse immer verrückt wurde).

Als ich zu Evil wechselte, begann ich endlich, die volle Emacs-Kraft zu erkunden, und glaubte mir, dass ich es nicht bereute. Evil funktioniert in allen Modi, die ich benutzt habe (meistens Editieren, Zusammenstellen, Scratch und Eshell) und sogar das Lesen von Info/Man/Help funktioniert problemlos.

Abgesehen davon fand ich nur ungerade Pufferwechsel, wie ich es tat: b <0-9> stattdessen: b-TAB-then-complete-name oder: bn. Beachten Sie jedoch, dass Evil-Entwickler (in einigen Fällen) versuchen, doppelte Funktionalitäten zu reduzieren, also stattdessen:! (zum Ausführen des Shell-Befehls) sollten Sie das native M-! verwenden.

Wenn Sie das Bedürfnis verspüren, einige benutzerdefinierte Ex-Befehle hinzuzufügen/neu zu definieren, öffnen Sie einfach evil-maps.el und bearbeiten Sie es (versuchen Sie es in vim!).

Das Böse ist noch ein junges, aber vielversprechendes Projekt und ich warte auf den Tag, an dem Viper in der offiziellen Emacs-Distribution ersetzt wird.

17
dennis

Ich speichere den Puffer gerne, wenn ich den insert-mode: Beende. (Bearbeitet: Bitte nicht zum Speichern, wenn für diesen Puffer keine zugeordnete Datei vorhanden ist, wie in einem Scratch- oder Magit-Puffer).

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

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

weitere Möglichkeiten: siehe http://wikemacs.org/index.php/Evil

Kommentare sind willkommen für Verbesserungen!

10
Ehvince
  1. Ich benutze evil-leader und benutze ", xm", um "M-x" zu ersetzen, also drücke ich selten die Alt-Taste. Es gibt auch general.el , das mehrere Leitertasten unterstützt.

  2. evil-matchit , drücke "%", um zwischen dem Tag-Paar zu springen.

  3. Übel-Nerd-Kommentator , drücke "9, ci", um 9 Zeilen zu kommentieren/unkommentieren

  4. vermeiden Sie die Verwendung der ESC-Taste. Sie können stattdessen "kj" drücken.

  5. Vertrauen Sie auf freie Software! Nichts ist unmöglich mit dem Bösen, das die Kraft von Vim und Emacs vereint. Zum Beispiel gehen viele Leute davon aus, dass Evil-Tastenkombinationen mit bestehenden Emacs-Plugins in Konflikt stehen, ohne dass eine erneute Bindung erforderlich ist. Das ist eigentlich falsch

8
chen bin

Von der Emacs-Seite kommend, bevorzuge ich M-. Gehe zu Definition, aber die Funktion, die auf M-. ausgeführt wird, unterscheidet sich zwischen den Modi. Ich könnte es auf normale Weise mit (define-key evil-normal-state-map (kbd "M-.") 'foo) überschreiben, wobei foo den aktuellen Major-Modus überprüft und die entsprechende Funktion ausführt. Das klingt jedoch so, als würde es viel Hardcoding erfordern. Eine allgemeinere Lösung ist diese:

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

Ansonsten mag ich die Plugins evil-surround (obwohl ich denke, dass Smartparens eine umfassendere Lösung ist) und evil-leader

Früher habe ich den Key-Akkord verwendet, um jk dem ESC zuzuordnen, wie ich es in vim gelernt habe, aber er bestand darauf, kj wie jk zu behandeln, also verwende ich stattdessen Folgendes:

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

Ich benutze (setq evil-move-cursor-back nil), was nicht sehr vimmy ist (obwohl Sie dies offensichtlich auch von Ihrem vimrc veranlassen können). Ich habe mich einfach nicht daran gewöhnt, dass sich der Cursor nach dem Beenden von insert zurückbewegt. 

Praktischer Tipp: Verwenden Sie evil-local-mode-hook für Dinge wie faules Laden des Bösen-Surround-Modus. Es hilft nicht, ihn in evil-mode-hook zu fassen. Wenn Sie böse und böse Surround mit package-install installieren, können Sie es starten lassen, wenn Sie M-x evil-mode tun, indem Sie dies tun 

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

(Natürlich, wenn Sie immer den Bösen-Modus ausführen und das Böse installiert haben, ist kein Autoload-Vorgang erforderlich. Ich ziehe es jedoch vor, dass meine .emacs allgemein genug sind, um sie auf Computern mit alten Emacsen oder ohne zu verwenden elpa-Pakete installiert.)

0
unhammer