Best Practice für den bösen Modus? [geschlossen]

104

Ich benutze Vim seit Jahren als meinen primären Editor und habe Emacs in dieser Zeit mehrmals ausprobiert. Dann entdeckte ich das Böse und entschied, dass es meine Forderung nach schnellen Bewegungen gut genug erfüllt, um endlich zu Emacs übergehen zu können.

Wie können Sie es allen Evil-Benutzern in normale Emacs-Funktionen integrieren? Haben Sie Konflikte zwischen diesem Modus und anderen festgestellt? Was sind Ihre teilungswürdigen Erfahrungen / Tipps zu diesem Thema?

Daniel Duan
quelle

Antworten:

71

Ich habe ein hochgradig angepasstes Vim verwendet und verwende jetzt ein noch stärker angepasstes 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 Dinge neu, die echte Emacs-Benutzer als Häresie betrachten würden, also YMMV, wenn Sie jemals "echte" Emacs lernen möchten (ich wirklich nicht).

Eine Sache, die ich jedem Ex-Vimmer empfehlen würde, ist diese

;;; 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 tatsächlich so ziemlich alles beendet (wie ausstehende Eingabeaufforderungen im Minibuffer)

Matt Briggs
quelle
7
Die Definition für Minibuffer-Keyboard-Quit finden Sie hier: github.com/davvil/.emacs.d/blob/master/init.el
Adam Bell
1
@Adam tut mir leid>.> Ich habe eine Menge Sachen installiert, manchmal benutze ich eine Funktion, von der ich denke, dass sie eingebaut ist, aber tatsächlich von woanders kommt
Matt Briggs
3
Ich finde, dass das bei mir nicht funktioniert. Ich benutze den neuesten Emacs 24.4. Hat jemand das gleiche erlebt?
Dzung Nguyen
1
Die Verbindung ist unterbrochen. Ich glaube, dies ist die neue: github.com/mbriggs/.emacs.d/blob/master/config/keybinds.el
Sean Leather
1
@ SeanLeather Aktualisierte Antwort auf einen funktionierenden Link.
Christopher Bottoms
34

Als jemand, der von Emacs kam, Vim ausprobierte und erkannte, dass es eine große Anzahl von Dingen zu gewinnen gab, experimentierte ich viel, als ich anfing, das Böse zu benutzen. Während das Folgende umstritten ist, wollte ich die Emacs-Schlüssel behalten, die universeller in Terminal, Firefox, Kakao usw. verwendet werden, wollte aber die Vim-Bearbeitungsfunktionen nicht verlieren. Am Ende habe ich mich entschlossen, die folgenden Schlüssel in meinen .emacs neu 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 überschneiden sich diese mit den vim-Vorgängen zum Verschieben eines Bildschirms nach oben oder unten. Ich habe es mir jedoch bequem gemacht, stattdessen Folgendes zu verwenden:

(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 mit "jk" (oder einer anderen 2-Strich-Kombination) einen schnellen Weg vom Einfügen in den normalen Modus suchen, ist es am besten, den Text von http://www.emacswiki.org/ zu kopieren. emacs / download / key-chord.el und füge es in deine ~ / .emacs.d / key-chord.el ein. Fügen Sie dann Folgendes zu Ihren .emacs 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 gut ist, haben Sie wahrscheinlich Recht. Nach dem Ausführen von sudo apt-get install xsel kann Folgendes jedoch hilfreich sein:

(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 kontroversen Änderungen lohnt, aber vielleicht werden Sie diese grundlegenden Änderungen inspirieren.

Für einige andere wirklich coole Funktionsimplementierungen, wie Löschen und Einfügen, Löschen ohne Kopieren in die Zwischenablage, effiziente 4x / 16x-Bewegung, Verwendung von Zählwerten für die Einfügungsregisterspezifikation, Registerkarteneinstellungen, die tatsächlich für c / c ++ funktionieren, und vieles mehr, können Sie überprüfen Die vollständigen Versionen von .emacs, init.el, my-keymaps.el und my-functions.el finden Sie auf meinem Git unter https://github.com/Russell91/emacs

RussellStewart
quelle
2
Das alles ist großartig, ich habe einige in Wikemacs hinzugefügt: wikemacs.org/index.php/Evil#Configuration
Ehvince
Ich verstehe Ihren Willen, Ihre Gewohnheiten von Emacs wiederzuverwenden. Für die Arbeit in Firefox empfehle ich dringend, das Vimperator-Addon zu verwenden, das viele vim-ähnliche Funktionen für Ihr Surfen bietet. Standardmäßig werden jedoch vim-Bewegungsbefehle verwendet (wie dies bei Befehlen lessund anderen der Fall ist ).
Jan Vlcinsky
Genau wie Sie mag ich die böse Bindung im Insert-State-Modus nicht, also binde ich "i" in der Normal-State-Map einfach wieder an "Evil-Emacs-State".
user49117
Anstatt die Tastatur von zu überschreiben evil, entferne ich sie, damit sie auf die Tastatureinstellung normaler Emacs zurückgreift, zum Beispiel(dolist (m (list evil-normal-state-map evil-motion-state-map evil-insert-state-map)) (define-key m "\C-e" 'nil))
Bach Lien
30

Ich war auch ein Viper / Vimpulse-Benutzer mit einer enormen Konfiguration. Dann habe ich den Evil-Modus gefunden.

Was sind Ihre teilungswürdigen Erfahrungen / Tipps zu diesem Thema?

Dies ist meine gesamte Konfiguration im bösen Modus, und sie 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.

Kenny Meyer
quelle
Ich erhalte folgende Fehlermeldung: prognost: Der Wert des Symbols als Variable ist ungültig: state Wo ist state definiert?
Justingordon
Sie können versuchenevil-emacs-state
Kenny Meyer
2
Können Sie klarstellen, wo Sie das hinstellen?
Justingordon
1
Das ist fantastisch, genau das habe ich gesucht. Upvotes in Hülle und Fülle!
Jplindstrom
1
Werfen
17

Ich habe vor einem Monat angefangen, Evil zu benutzen. davor habe ich versucht, viper / vimpulse ohne großen erfolg zu verwenden. Um ehrlich zu sein, ist vimpulse ganz nett, aber die Verwendung mit verschiedenen Modi war etwas mühsam (z. B. Kompilierungsmodus, in dem vimpulse immer verrückt wurde), wobei Emacs in einem Modus zwischen vi-emacs-etwas zurückgelassen wurden.

Als ich zu Evil wechselte, begann ich endlich, die volle Emacs-Kraft zu erforschen, und glaube mir, ich habe es nicht bereut. Das Böse funktioniert gut in allen Modi, die ich verwendet habe (hauptsächlich Bearbeiten, Kompilieren, Scratchen und Schälen), und selbst das Lesen von Informationen / Mann / Hilfe funktioniert ohne Probleme.

Abgesehen davon fand ich die Pufferumschaltung nur ungerade, wie ich es früher getan habe: b <0-9> statt: b-TAB-dann-vollständiger-Name oder: bn. Beachten Sie jedoch, dass Evil-Entwickler (in einigen Fällen) versuchen, doppelte Funktionen zu reduzieren. Stattdessen :! (um den Shell-Befehl auszuführen), sollten Sie native M-! verwenden.

Wenn Sie den Drang haben, einige benutzerdefinierte Ex-Befehle hinzuzufügen / neu zu definieren, öffnen Sie einfach evil-maps.el und bearbeiten Sie sie (versuchen Sie das in vim!).

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

Dennis
quelle
4
Soll dies bedeuten, dass es nicht möglich ist, Befehle in vim hinzuzufügen / neu zu definieren?
John Tyree
1
@JohnTyree Benutzerdefinierte Befehle sind erforderlich, um in Vim mit einem Großbuchstaben zu beginnen, während alle integrierten Befehle mit einem Kleinbuchstaben beginnen.
Austin Taylor
10

Ich möchte den Puffer speichern, wenn ich insert-modeFolgendes beende: (bearbeitet: Bitten Sie nicht um Speicherung, wenn für diesen Puffer keine zugeordnete Datei vorhanden ist, z. B. 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 finden Sie unter http://wikemacs.org/index.php/Evil

Kommentare willkommen für Verbesserungen!

Ehvince
quelle
Vielen Dank. Übrigens ist Ihre Verbindung unterbrochen.
Amos
Danke auch. Wikemacs werden wiederkommen. Die Seite wird gewartet, hoffentlich nicht mehr zu lange.
Ehvince
9
  1. Ich benutze den bösen Anführer und benutze ", xm", um "Mx" zu ersetzen, also drücke ich selten die Alt-Taste. Es gibt auch general.el, das mehrere Führungsschlüssel unterstützt.

  2. böses Matchit , drücke "%", um zwischen den Tag-Paaren zu springen.

  3. böser-Nerd-Kommentator , drücke "9, ci", um 9 Zeilen zu kommentieren / zu kommentieren

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

  5. Vertrauen Sie auf freie Software! Mit dem Bösen, das die Kraft von Vim und Emacs kombiniert, ist nichts unmöglich. Beispielsweise gehen viele Leute davon aus, dass Evil Keybindings mit vorhandenen Emacs-Plugins in Konflikt stehen, ohne dass eine erneute Bindung erforderlich ist. Das ist eigentlich falsch

Chen Bin
quelle
0

Ich komme von der Emacs-Seite und bevorzuge M-. zur Definition gehen, aber die Funktion, die ausgeführt wird, M-.unterscheidet sich zwischen den Modi. Ich könnte es auf normale Weise überschreiben, (define-key evil-normal-state-map (kbd "M-.") 'foo)indem ich fooden aktuellen Hauptmodus überprüfe und die entsprechende Funktion ausführe, aber das klingt so, als würde es viel Hardcodierung erfordern. Eine allgemeinere Lösung ist folgende:

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

Abgesehen davon mag ich die Plugins Evil -Surround (obwohl ich Smartparens für eine vollständigere Lösung halte) und Evil -Leader .

Früher habe ich Key-Chord verwendet, um jk dem ESC zuzuordnen, wie ich es in vim gelernt habe, aber es bestand darauf, kj genauso zu behandeln wie jk, 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 anscheinend auch Ihren vimrc dazu bringen können, dies zu tun), habe ich mich einfach nie daran gewöhnt, dass sich der Cursor nach dem Beenden des Einfügens zurückbewegt.

Praktischer Tipp: Verwenden Sie es evil-local-mode-hookfür Dinge wie das verzögerte Laden des Evil-Surround-Modus. Es hilft nicht, es einfach zu machen evil-mode-hook. Wenn Sie also Evil und Evil-Surround mit Package-Install installieren, können Sie es starten, wenn Sie dies M-x evil-modetun

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

(Wenn Sie immer den bösen Modus ausführen und immer das Böse installiert haben, ist dieses Autoload-Zeug nicht erforderlich, aber ich möchte, dass meine .emacs so allgemein sind, dass ich sie auf Maschinen mit altem Emacsen oder ohne Emacsen verwenden kann elpa-Pakete installiert.)

Unhammer
quelle