Kötü Mod en iyi uygulama? [kapalı]


104

Vim'i yıllardır ana editörüm olarak kullanıyorum ve bu süre zarfında Emacs'ı birkaç kez denedim. Sonra Evil'i keşfettim ve hızlı hareket talebimi yeterince iyi karşıladığına karar verdim ve sonunda Emacs'a geçebilirim.

Öyleyse, siz Evil kullanıcıları için, onu normal Emacs işlevlerine nasıl entegre edersiniz? Bu mod ile diğerleri arasında herhangi bir çelişki ile karşılaştınız mı? Bu konudaki paylaşmaya değer deneyimleriniz / ipuçlarınız nelerdir?

Yanıtlar:


71

Oldukça özelleştirilmiş bir vim kullandım ve şimdi daha da özelleştirilmiş emac'ler kullanıyorum. Anahtar eşleme yapılandırma dosyamda her anahtar eşleme örneğini bulacağınızı düşünüyorum https://github.com/mbriggs/.emacs.d-oldv2/blob/master/init/init-keymaps.el

Unutmayın, ben gerçek emacs kullanıcılarının sapkınlık olarak kabul edeceği şeyleri yeniden söylüyorum, bu yüzden YMMV eğer "gerçek" emacs öğrenmek istiyorsanız (gerçekten istemiyorum).

Eski bir vimmer'a tavsiye edeceğim bir şey şudur:

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

böylece esc aslında hemen hemen her şeyi kapatır (mini arabellekte bekleyen istemler gibi)


7
Minibuffer-keyboard- quit'in
Adam Bell

1
@Adam bunun için üzgünüm>.> Çok fazla şey yükledim, bazen yerleşik olduğunu düşündüğüm, ancak aslında başka bir yerden gelen bir işlevi kullanıyorum
Matt Briggs 13

3
Bunun benim için çalışmadığını anladım. En son Emacs 24.4'ü kullanıyorum, aynı deneyimi yaşayan var mı?
Dzung Nguyen

1
Bağlantı koptu. Bunun yeni olduğuna inanıyorum: github.com/mbriggs/.emacs.d/blob/master/config/keybinds.el
Sean Leather

1
@SeanLeather Çalışan bir bağlantıya verilen yanıt güncellendi.
Christopher Bottoms

34

Emacs'tan gelen, vim'i deneyen ve kazanacak çok şey olduğunu fark eden biri olarak, kötülüğü ilk kullanmaya başladığımda çok fazla deney yaptım. Aşağıdakiler tartışmalı olsa da, terminal, firefox, kakao vb.'de daha evrensel olarak kullanılan emacs anahtarlarını saklamak istedim, ancak vim düzenleme yeteneklerini kaybetmek istemedim. Emac'lerimde aşağıdaki anahtarları yeniden oluşturmaya karar verdim:

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

Ne yazık ki, bunlar vim "bir ekranı yukarı veya aşağı taşıma" işlemleriyle örtüşüyor. Ancak, bunun yerine aşağıdakileri kullanmak konusunda rahat oldum:

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

Ayrıca, vim'den geliyorsanız ve "jk" (veya başka herhangi bir 2 vuruşlu kombinasyon) kullanarak eklemeden normal moda hızlı bir yol istiyorsanız, en iyi yol metni http://www.emacswiki.org/ adresinden kopyalamaktır. emacs / download / key-chord.el ve ~ / .emacs.d / key-chord.el dosyanıza yapıştırın. Ardından .emac'lerinize şunları ekleyin:

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

Ayrıca, vim'den geliyorsanız ve emacs'deki panoya kopyalamanın iyi olmadığını düşünüyorsanız, muhtemelen haklısınız. Ancak, sudo apt-get install xsel'i çalıştırdıktan sonra aşağıdakileri yararlı bulabilirsiniz:

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

Açıkçası, bu tartışmalı değişikliklerden herhangi birinin buna değip değmeyeceğine kendiniz karar vermeniz gerekecek, ancak belki de bu temel değişiklikler size ilham verecektir.

Silme ve yapıştırma, panoya kopyalamadan silme, verimli 4x / 16x hareket, yapıştırma kaydı belirtimi için sayım kullanımı, c / c ++ için gerçekten çalışan sekme ayarları ve daha fazlası gibi diğer gerçekten harika işlev uygulamaları için kontrol edebilirsiniz. tam .emacs, init.el, my-keymaps.el ve my-functions.el versons'ı https://github.com/Russell91/emacs adresinde


2
tüm bunlar harika, wikemac'lara bazılarını ekledim: wikemacs.org/index.php/Evil#Configuration
Ehvince

Emacs'tan alışkanlıklarınızı yeniden kullanma isteğinizi anlıyorum. Firefox'ta çalışmak için, gezintinize pek çok vim benzeri işlevsellik getiren Vimperator eklentisini denemenizi şiddetle tavsiye ederim. Ancak, varsayılan olarak vim hareket komutlarını kullanıyor ( lesskomut ve diğerleri için olduğu gibi ).
Jan Vlcinsky

Sizinle aynı şekilde, durum ekleme modundaki kötü bağlamayı sevmiyorum, bu yüzden normal durum haritasındaki "i" yi "kötü-emacs-durumuna yeniden bağlarım.
user49117

Klavyesini geçersiz kılmak yerine evilkaldırıyorum, böylece normal emac'lerin klavye ayarına geri dönüyor, örneğin(dolist (m (list evil-normal-state-map evil-motion-state-map evil-insert-state-map)) (define-key m "\C-e" 'nil))
Bach Lien

30

Ayrıca büyük miktarda konfigürasyona sahip bir Viper / Vimpulse kullanıcısıydım . Sonra Kötü modu buldum.

Bu konudaki paylaşmaya değer deneyimleriniz / ipuçlarınız nelerdir?

Bu benim tüm kötü mod konfigürasyonum ve benim için harika çalışıyor:

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

Bu mod ile diğerleri arasında herhangi bir çelişki yaşadınız mı?

Hayır, çeşitli modlarda sorun yaratan Viper / Vimpulse'un aksine.


Şu hatayı alıyorum: progn: Sembolün değişken olarak değeri void: durum Durum nerede tanımlanır?
justingordon

Deneyebilirsinevil-emacs-state
Kenny Meyer

2
Bunu nereye koyduğunuzu açıklayabilir misiniz?
justingordon

1
Bu harika, tam olarak bunu aradım. Bolca olumlu oylar!
jplindstrom


17

Evil'i bir ay önce kullanmaya başladım; ondan önce, engerek / vimpulse'u pek başarı olmadan kullanmaya çalıştım. Dürüst olmak gerekirse, vimpulse oldukça güzel, ancak onu çeşitli modlarla kullanmak biraz zahmetliydi (örneğin, vimpulse'un her zaman çıldırdığı derleme modu), vi-emacs-something arasında bir modda emac'leri bırakmak.

Kötülüğe geçtiğimde, nihayet Emacs'in tüm gücünü keşfetmeye başladım ve inan bana pişman olmadım. Kötülük, kullandığım tüm modlarda (çoğunlukla düzenleme, derleme, çizme ve eshell) güzel çalışıyor ve hatta bilgi / adam / yardım okumak bile sorunsuz çalışıyor.

Bunun dışında, önceden yaptığım gibi arabellek anahtarlamasını tek buldum: b <0-9> yerine: b-TAB-then-complete-name veya: bn. Bununla birlikte, Evil geliştiricilerinin (bazı durumlarda) yinelenen işlevleri azaltmaya çalıştığını unutmayın, bunun yerine:! (kabuk komutunu çalıştırmak için), yerel M-! kullanmalısınız.

Bazı özel ex komutları ekleme / yeniden tanımlama dürtüsü bulursanız, sadece evil-maps.el dosyasını açın ve düzenleyin (bunu vim'de deneyin!).

Evil hala genç ama umut verici bir proje ve resmi Emacs dağıtımında engerek yerine geçeceği günü bekliyorum.


4
Bu, vim'de komutların eklenmesinin / yeniden tanımlanmasının mümkün olmadığı anlamına mı geliyor?
John Tyree

1
@JohnTyree Kullanıcı tanımlı komutların Vim'de büyük harfle başlaması gerekirken, tüm yerleşik komutlar küçük harfle başlar.
Austin Taylor

10

insert-modeŞuradan çıktığımda arabelleği kaydetmeyi seviyorum : (düzenlendi: bu arabellek için ilişkilendirilmiş dosya olmadığında, örneğin bir çizikte veya bir magit arabelleğindeyken kaydetmeyi sorma)

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

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

daha fazla olasılık için: bkz. http://wikemacs.org/index.php/Evil

İyileştirmeler için yorumlar kabul edilir!


Teşekkürler. BTW, bağlantınız koptu.
Amos

Çok teşekkürler. Wikemacs geri gelecek. Site bakımda, umarım tekrar çok uzun sürmez.
Ehvince

9
  1. Kullandığım kötülük-lideri , 'Mx' yerine bu yüzden nadiren Alt tuşuna basın ve kullanımını "XM". Birden fazla lider anahtarını destekleyen general.el de vardır .

  2. evil-matchit , etiket çifti arasında geçiş yapmak için "%" tuşuna basın.

  3. kötü-nerd-yorumcu , 9 satıra yorum yapmak / açıklamayı kaldırmak için "9, ci" ye basın

  4. ESC tuşunu kullanmaktan kaçının, bunun yerine "kj" tuşuna basabilirsiniz .

  5. Özgür yazılıma güvenin! Vim ve Emacs'ın gücünü birleştiren Evil ile hiçbir şey imkansız değildir. Örneğin, birçok kişi Evil keybindings'in mevcut eklentiler Emacs ile yoğun bir yeniden bağlama olmaksızın çakıştığını varsayar. Bu aslında yanlış


0

Emacs tarafından gelince, M-'yi çok tercih ederim. tanımlanabilir, ancak üzerinde çalışan işlev M-.modlar arasında farklılık gösterir. Ben düzenli bir şekilde geçersiz olabilir (define-key evil-normal-state-map (kbd "M-.") 'foo)nerede fooçekleri geçerli majör modu ve uygun fonksiyonunu çalışır, ancak bunun gibi sesler gömmek çok ihtiyaç olacağını unutmayın. Daha genel bir çözüm şudur:

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

Bunun dışında, kötü çevreleyen eklentileri (smartparens'ın daha eksiksiz bir çözüm olduğunu düşünmeme rağmen) ve kötü lideri seviyorum .

Eskiden vim'de öğrendiğim gibi jk'yi ESC ile eşlemek için key-chord kullanırdım, ancak kj'yi jk ile aynı muamelesi yapmakta ısrar etti, bunun yerine aşağıdakileri kullanıyorum:

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

kullanırım (setq evil-move-cursor-back nil) çok vimmy olmayan kullanıyorum (görünüşe göre vimrc'nizin de bunu yapmasını sağlayabilirsiniz), imlecin insert'ten çıktıktan sonra geri hareket etmesine hiç alışamadım.

Pratik ipucu: evil-local-mode-hooktembel yükleme kötü surround modu gibi şeyler için kullanın , onu açıklığa kavuşturmanın faydası olmaz evil-mode-hook. Yani eğer kötü ve kötü çevreyi paket-yükleme ile kurarsanız, bunu M-x evil-modeyaptığınız zaman başlayabilirsiniz.

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

(Elbette, her zaman kötü modu çalıştırırsanız ve her zaman kötülük yüklüyseniz, bu otomatik yükleme öğelerine gerek yoktur, ancak .emac'lerimin eski emacsen'lı veya emacsen'lı makinelerde kullanabilmem için yeterince genel olmasını tercih ederim. elpa paketleri yüklendi.)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.