web-dev-qa-db-ja.com

悪モードのベストプラクティスは?

私はVimを主なエディターとして何年も使用しており、その間にEmacsを何度か試しました。それから、私は Evil を発見し、それが私が最終的にEmacsに移ることができるほど十分に迅速な動きに対する私の要求を満たすことを決定しました。

それで、あなたのすべての邪悪なユーザーにとって、どのようにそれを通常のEmacs機能と統合しますか?このモードと他のモードとの間に競合が発生しましたか?このトピックに関する共有に値する経験/ヒントは何ですか?

104
Daniel Duan

高度にカスタマイズされたvimを使用し、さらにカスタマイズされたemacsを使用します。キーマッピング設定ファイルでキーマッピングのすべてのインスタンスが見つかると思います https://github.com/mbriggs/.emacs.d-oldv2/blob/master/init/init-keymaps.el

覚えておいてください、私は本当のemacsユーザーが異端と考えるものを再バインドしているので、「本当の」emacsを学びたいならYMMV(私は本当にしません)。

元ビマーにお勧めしたいことはこれです

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

そのため、escは実際にはほとんどすべてを終了します(ミニバッファの保留中のプロンプトなど)

71
Matt Briggs

Emacsから来て、vimを試して、得るべきものが非常に多いことに気付いた誰かとして、私は最初に悪を使い始めたときに多くの実験をしました。以下は議論の余地がありますが、ターミナル、Firefox、ココアなどでより普遍的に使用されるemacsキーを保持したいのですが、vim編集機能を失いたくありませんでした。 .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)))))

残念ながら、これらはvimの「1画面上または下に移動」操作と重複しています。ただし、代わりに以下を使用することに慣れました。

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

また、vimから来て、「jk」(または他の2ストロークの組み合わせ)を使用して挿入から通常モードへのクイックパスが必要な場合、最良の方法は http:// www。 emacswiki.org/emacs/download/key-chord.el を〜/ .emacs.d/key-chord.elに貼り付けます。次に、以下を.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)

また、vimから来て、emacsのクリップボードへのコピーが良くないと思う場合は、おそらく正しいでしょう。ただし、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)

明らかに、これらの物議をかもすような変更が価値があるかどうかを自分で決める必要がありますが、おそらくこれらの基本的な変更はあなたに刺激を与えるでしょう。

削除と貼り付け、クリップボードにコピーせずに削除、効率的な4倍/ 16倍の移動、貼り付けレジスタ仕様のカウントの使用、c/c ++で実際に動作するタブ設定など、他の本当にクールな機能の実装については、チェックできます https://github.com/Russell91/emacs のgitで、.emacs、init.el、my-keymaps.el、およびmy-functions.elの全バージョンを出力します。

34
RussellStewart

私はかつてhuge量の設定を持つViper/Vimpulseユーザーでもありました。それから私は邪悪なモードを見つけました。

このトピックに関する共有に値する経験/ヒントは何ですか?

これは私の全体の邪悪なモードの構成であり、私にとってはうまく機能します:

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

このモードと他のモードとの間に競合が発生しましたか?

いいえ、いくつかのモードで問題を引き起こしていたViper/Vimpulseとは対照的です

30
Kenny Meyer

1か月前にEvilを使い始めました。その前に、私はほとんど成功せずにviper/vimpulseを使用しようとしました。正直に言うと、vimpulseは非常に素晴らしいですが、さまざまなモードで使用するのは少し面倒でした(たとえば、vimpulseが常に狂っていたコンパイルモード)。

Evilに切り替えたとき、私はついにEmacsのフルパワーを探求し始めました。 Evilは、私が使用したすべてのモード(ほとんどが編集、コンパイル、スクラッチ、およびeshell)でうまく機能し、info/man/helpを読むことでも問題なく機能します。

それ以外は、:b-TAB-then-complete-nameまたは:bnの代わりに:b <0-9>を使用していたため、バッファスイッチングが奇数であることがわかりました。ただし、Evil開発者は(場合によっては)重複する機能を削減しようとするため、代わりに:! (シェルコマンドを実行するには)、ネイティブM-!を使用する必要があります。

いくつかのカスタムexコマンドを追加/再定義する必要がある場合は、evil-maps.elを開いて編集します(vimで試してください!)。

Evilはまだ若いが、有望なプロジェクトであり、公式のEmacsディストリビューションでviperを置き換える日を待っています。

17
dennis

insert-modeを終了するときにバッファーを保存するのが好きです:(編集:スクラッチバッファーやmagitバッファーの場合など、このバッファーに関連付けられたファイルがない場合は保存を要求しないでください)

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

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

その他の可能性については、 http://wikemacs.org/index.php/Evil を参照してください

改善のためのコメントを歓迎します!

10
Ehvince
  1. evil-leader を使用し、 "、xm"を使用して "M-x"を置き換えるため、Altキーを押すことはめったにありません。また、複数のリーダーキーをサポートする general.el もあります。

  2. evil-matchit 、「%」を押してタグペア間をジャンプします。

  3. evil-nerd-commenter 、9行をコメント/コメント解除するには「9、ci」を押します

  4. eSCキーの使用を避け、代わりに "kj" を使用できます。

  5. フリーソフトウェアを信頼してください! VimとEmacsのパワーを組み合わせたEvilで不可能なことはありません。たとえば、多くの人々は、Evilキーバインドが既存のプラグインEmacsと競合することを強く再バインドせずに想定しています。 実際は間違っています

9
chen bin

Emacs側から来ると、私はM-をとても好みます。定義になりますが、M-.で実行される関数はモードによって異なります。 (define-key evil-normal-state-map (kbd "M-.") 'foo)で通常の方法でオーバーライドできます。ここでfooは現在のメジャーモードをチェックし、適切な機能を実行しますが、多くのハードコーディングが必要になるようです。より一般的な解決策は次のとおりです。

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

それ以外は、プラグイン evil-surround (smartparensはより完全なソリューションだと感じていますが)と evil-leader が好きです。

私はvimでやることを学んだようにキーコードを使ってjkをESCにマッピングしていましたが、kjをjkと同じように扱うことを主張していたので、代わりに次のものを使用しています:

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

私は(setq evil-move-cursor-back nil)を使用しますが、これはあまりビミーではありません(ただし、vimrcでも同様に実行できます)が、挿入を終了した後にカーソルが戻ることに慣れていません。

実用的なヒント:怠loadingなロードの邪悪なサラウンドモードのようなものにはevil-local-mode-hookを使用しますが、それを平易なevil-mode-hookに入れても役に立ちません。したがって、package-installを使用してevilとevil-surroundをインストールすると、M-x evil-modeを実行したときに開始することができます。

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

(もちろん、常にevilモードを実行し、常にevilをインストールしている場合、その自動ロードのものは必要ありませんが、古いemacsenを搭載したマシンや何も持たないマシンで使用できるように、.emacsを十分に一般的にすることを好みますelpaパッケージがインストールされています。)

0
unhammer