Chế độ ác thực hành tốt nhất? [đóng cửa]


104

Tôi đã sử dụng Vim làm trình soạn thảo chính của mình trong nhiều năm và đã thử Emacs vài lần trong thời gian đó. Sau đó, tôi phát hiện ra Ác ma và quyết định rằng nó đáp ứng nhu cầu di chuyển nhanh của tôi đủ tốt để cuối cùng tôi có thể chuyển sang Emacs.

Vì vậy, với tất cả những người dùng Ác ma, bạn làm cách nào để tích hợp nó với các chức năng Emacs bình thường? Bạn có gặp bất kỳ xung đột nào giữa chế độ này và các chế độ khác không? Kinh nghiệm / mẹo đáng được chia sẻ của bạn về chủ đề này là gì?

Câu trả lời:


71

Tôi đã sử dụng một vim được tùy chỉnh cao và bây giờ sử dụng một emac được tùy chỉnh nhiều hơn. Tôi nghĩ rằng bạn sẽ tìm thấy mọi trường hợp của keymapping trong tệp cấu hình keymapping của tôi https://github.com/mbriggs/.emacs.d-oldv2/blob/master/init/init-keymaps.el

Xin lưu ý rằng tôi đang liên kết những thứ mà người dùng emacs thực sẽ coi là dị giáo, vì vậy hãy YMMV nếu bạn muốn tìm hiểu emacs "thực sự" (tôi thực sự không).

Một điều tôi muốn giới thiệu cho bất kỳ người yêu cũ nào là

;;; 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 thực sự thoát khỏi khá nhiều thứ (như lời nhắc đang chờ xử lý trong bộ đệm nhỏ)


7
Định nghĩa cho minibuffer-bàn phím-quit có thể được tìm thấy ở đây: github.com/davvil/.emacs.d/blob/master/init.el
Adam Chuông

1
@ Adam xin lỗi về điều đó>> Tôi có rất nhiều thứ được cài đặt, đôi khi tôi sử dụng một chức năng mà tôi nghĩ rằng được xây dựng trong, nhưng thực sự là đến từ nơi khác.
Matt Briggs

3
Tôi thấy rằng điều này không hiệu quả với tôi. Tôi sử dụng Emacs 24.4 mới nhất, có ai bị như vậy không?
Dzung Nguyen

1
Liên kết bị hỏng. Tôi tin rằng đây là cái mới: github.com/mbriggs/.emacs.d/blob/master/config/keybinds.el
Sean Leather

1
@SeanLeather Đã cập nhật câu trả lời cho một liên kết đang hoạt động.
Christopher Bottoms

34

Là một người đến từ Emacs, đã thử vim và nhận ra rằng có rất nhiều thứ cần đạt được, tôi đã thực hiện rất nhiều thử nghiệm khi lần đầu tiên bắt đầu sử dụng cái ác. Trong khi những điều sau còn gây tranh cãi, tôi muốn giữ lại các phím emacs được sử dụng phổ biến hơn trong terminal, firefox, ca cao, v.v., nhưng không muốn mất khả năng chỉnh sửa vim. Cuối cùng, tôi đã quyết định gắn lại các khóa sau trong .emac của mình:

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

Thật không may, những điều này trùng lặp với vim "di chuyển một màn hình lên hoặc xuống". Tuy nhiên, tôi đã cảm thấy thoải mái khi sử dụng những thứ sau để thay thế:

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

Ngoài ra, nếu bạn đến từ vim và muốn một đường dẫn nhanh từ chèn sang chế độ bình thường bằng cách sử dụng "jk" (hoặc bất kỳ kết hợp 2 nét nào khác), cách tốt nhất là sao chép văn bản từ http://www.emacswiki.org/ emacs / download / key-chord.el và dán nó vào ~ / .emacs.d / key-chord.el của bạn. Sau đó, thêm phần sau vào .emac của bạn:

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

Ngoài ra, nếu bạn đến từ vim và bạn nghĩ rằng copy-to-clipboard trong emacs là không tốt, có lẽ bạn đã đúng. Tuy nhiên, bạn có thể thấy hữu ích sau khi chạy 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)

Rõ ràng, bạn sẽ phải tự mình quyết định xem liệu bất kỳ thay đổi gây tranh cãi này có đáng giá hay không, nhưng có lẽ những thay đổi cơ bản này sẽ truyền cảm hứng cho bạn.

Đối với một số triển khai chức năng thực sự thú vị khác, chẳng hạn như xóa và dán, xóa mà không cần sao chép vào khay nhớ tạm, di chuyển 4x / 16x hiệu quả, sử dụng số lượng để dán đặc tả thanh ghi, cài đặt tab thực sự hoạt động cho c / c ++ và hơn thế nữa, bạn có thể kiểm tra tìm ra toàn bộ so sánh .emacs, init.el, my-keymaps.el và my-functions.el trên git của tôi tại https://github.com/Russell91/emacs


2
tất cả điều này thật tuyệt, tôi đã thêm một số vào wikemacs: wikemacs.org/index.php/Evil#Configuration
Ehvince

Tôi hiểu ý muốn của bạn để sử dụng lại thói quen của bạn từ emacs. Để làm việc trên Firefox, tôi thực sự khuyên bạn nên thử addon Vimperator, nó mang lại nhiều chức năng vim like cho trình duyệt của bạn. Tuy nhiên, nó đang sử dụng các lệnh di chuyển vim theo mặc định (như trường hợp của lesslệnh và các lệnh khác).
Jan Vlcinsky

Giống như bạn, tôi không thích sự ràng buộc ác trong chế độ chèn-trạng thái, vì vậy tôi chỉ gắn lại "i" trong bản đồ trạng thái bình thường thành 'ác-emacs-trạng thái.
user49117 21/04

Thay vì ghi đè bàn phím của evil, tôi gỡ bỏ nó, vì vậy nó sẽ trở lại cài đặt bàn phím của emac thông thường, ví dụ(dolist (m (list evil-normal-state-map evil-motion-state-map evil-insert-state-map)) (define-key m "\C-e" 'nil))
Bach Lien

30

Tôi cũng từng là một Viper / vimpulse người dùng, với một lớn lượng cấu hình. Sau đó, tôi tìm thấy Evil-mode.

Kinh nghiệm / mẹo đáng được chia sẻ của bạn về chủ đề này là gì?

Đây là toàn bộ cấu hình chế độ ác của tôi và nó hoạt động tuyệt vời đối với tôi:

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

Bạn có gặp bất kỳ xung đột nào giữa chế độ này và chế độ khác không?

Không, trái ngược với Viper / Vimpulse gây ra sự cố ở một số chế độ.


Tôi gặp lỗi này: progn: Giá trị của biểu tượng khi biến là void: state Trạng thái được xác định ở đâu?
justingordon

Bạn có thể thửevil-emacs-state
Kenny Meyer

2
Bạn có thể làm rõ nơi bạn đặt nó?
justingordon

1
Điều này thật tuyệt vời, tôi đã tìm kiếm chính xác điều này. Ủng hộ rất nhiều!
jplindstrom

1
Có một cái nhìn tại này github.com/edwtjo/evil-org-mode
avendael

17

Tôi bắt đầu sử dụng Evil một tháng trước; trước đó, tôi đã thử sử dụng viper / vimpulse mà không mấy thành công. Thành thật mà nói, vimpulse khá đẹp, nhưng sử dụng nó với nhiều chế độ khác nhau hơi rắc rối (ví dụ như chế độ biên dịch nơi vimpulse luôn phát điên) để lại emac ở một số chế độ giữa vi-emacs-something.

Khi tôi chuyển sang Ác ma, cuối cùng tôi cũng bắt đầu khám phá toàn bộ sức mạnh của Emacs, và tin tôi đi, tôi không hối hận. Evil hoạt động tốt ở tất cả các chế độ tôi đã sử dụng (chủ yếu là chỉnh sửa, biên dịch, cào và eshell) và thậm chí đọc thông tin / man / help vẫn hoạt động mà không gặp bất kỳ sự cố nào.

Ngoại trừ điều đó, tôi chỉ thấy chuyển đổi bộ đệm kỳ lạ như tôi đã từng làm: b <0-9> thay vì: b-TAB-then-complete-name hoặc: bn. Tuy nhiên, lưu ý rằng các nhà phát triển Evil cố gắng (trong một số trường hợp) để giảm các chức năng trùng lặp, vì vậy thay vào đó:! (để thực thi lệnh shell), bạn nên sử dụng M- !.

Nếu bạn thấy muốn thêm / xác định lại một số lệnh cũ tùy chỉnh, chỉ cần mở evil-maps.el và chỉnh sửa nó (hãy thử điều đó trong vim!).

Evil vẫn là dự án trẻ nhưng đầy hứa hẹn và tôi đang chờ ngày sẽ thay thế viper trong bản phân phối chính thức của Emacs.


4
Điều này có ngụ ý rằng không thể thêm / xác định lại các lệnh trong vim không?
John Tyree

1
@JohnTyree Các lệnh do người dùng định nghĩa bắt buộc phải bắt đầu bằng chữ hoa trong Vim, trong khi tất cả các lệnh tích hợp đều bắt đầu bằng chữ thường.
Austin Taylor

10

Tôi muốn lưu bộ đệm khi thoát khỏi insert-mode: (đã chỉnh sửa: không yêu cầu lưu khi không có tệp được liên kết cho bộ đệm này, như khi ở trong một đầu hoặc bộ đệm magit)

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

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

để biết thêm khả năng: xem http://wikemacs.org/index.php/Evil

Nhận xét được hoan nghênh cho các cải tiến!


Cảm ơn. BTW, liên kết của bạn bị hỏng.
Amos

Cảm ơn quá. Wikemacs sẽ trở lại. Trang web đang được bảo trì, hy vọng sẽ không quá lâu nữa.
Ehvince

9
  1. Tôi sử dụng Evil-leader và sử dụng ", xm" để thay thế "Mx", vì vậy tôi hiếm khi nhấn phím Alt. Ngoài ra còn có general.el hỗ trợ nhiều khóa lãnh đạo.

  2. ác-matchit , nhấn "%" để chuyển giữa các cặp thẻ.

  3. ác-nerd-commenter , nhấn "9, ci" để nhận xét / bỏ ghi chú 9 dòng

  4. tránh sử dụng phím ESC, bạn có thể nhấn "kj" để thay thế.

  5. Có niềm tin vào phần mềm miễn phí! Không gì là không thể với Ác ma kết hợp sức mạnh của Vim và Emacs. Ví dụ: nhiều người cho rằng liên kết chính Evil xung đột với các plugin hiện có Emacs mà không có liên kết lại nặng. Điều đó thực sự sai


0

Đến từ phe emacs, tôi rất thích M-. để đi đến định nghĩa, nhưng chức năng chạy trên M-.các chế độ khác nhau. Tôi có thể ghi đè nó theo cách thông thường với (define-key evil-normal-state-map (kbd "M-.") 'foo)nơi fookiểm tra chế độ chính hiện tại và chạy chức năng thích hợp, nhưng điều đó có vẻ như nó sẽ yêu cầu nhiều mã cứng. Một giải pháp chung hơn là:

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

Ngoài ra, tôi thích các plugin ác-xung-quanh (mặc dù tôi cảm thấy smartparens là một giải pháp hoàn thiện hơn) và lãnh đạo độc ác .

Tôi đã từng sử dụng hợp âm phím để ánh xạ jk sang ESC giống như tôi đã học trong vim, nhưng nó khăng khăng coi kj giống như jk, vì vậy thay vào đó tôi sử dụng như sau:

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

Tôi sử dụng (setq evil-move-cursor-back nil)mà không phải là rất vimmy (mặc dù chắc chắn bạn cũng có thể làm cho vimrc của mình làm điều đó), tôi chỉ chưa bao giờ quen với việc con trỏ di chuyển trở lại sau khi thoát khỏi chèn.

Mẹo thực tế: sử dụng evil-local-mode-hook cho những thứ như lười biếng tải chế độ âm thanh vòm ác, nó sẽ không giúp ích gì khi đặt nó một cách đơn giản evil-mode-hook. Vì vậy, nếu bạn cài đặt ác và bao quanh ác với gói cài đặt, bạn có thể bắt đầu nó khi bạn thực hiện M-x evil-modebằng cách

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

(Tất nhiên, nếu bạn luôn chạy chế độ ác và luôn cài đặt chế độ ác nhân, thì không cần phải có nội dung tự động tải đó, nhưng tôi thích có .emac của mình đủ chung để tôi có thể sử dụng nó trên các máy có emacsen cũ hoặc không có bất kỳ gói elpa đã được cài đặt.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.