Emacs'ta anahtar bağlamayı genel olarak geçersiz kılma


101

Global olarak geçersiz kılan ve bu anahtar için diğer tüm bağlamalardan öncelikli olan bir anahtar bağlamayı nasıl ayarlayabilirim? Tüm büyük / küçük mod haritalarını geçersiz kılmak ve bağlamamın her zaman etkin olduğundan emin olmak istiyorum.

Bu elbette çalışmıyor:

(global-set-key "\C-i" 'some-function)

O çalışır text-mode, ama kullanırken lisp-mode, C-ikarşı tepme olduğunu lisp-indent-line.

Bu bağlamayı lisp-modediğer tüm modlarda ayrı ayrı geçebilir ve geçersiz kılabilirim , ancak daha kolay bir yol olmalı. Yeni bir dosya türü için her yeni mod yüklediğimde, geri dönüp tüm anahtar bağlamalarımın yeni mod tarafından geçersiz kılınmadığından emin olmak için kontrol etmem gerekir.

Bunu yapmak istiyorum çünkü zaten diğer editörlerden öğrendiğim ve kökleşmiş bağları taklit etmek istiyorum.

Yanıtlar:


151

Tüm "geçersiz kılma" tuş bağlamalarım için küçük bir mod kullanıyorum:

(defvar my-keys-minor-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "C-i") 'some-function)
    map)
  "my-keys-minor-mode keymap.")

(define-minor-mode my-keys-minor-mode
  "A minor mode so that my key settings override annoying major modes."
  :init-value t
  :lighter " my-keys")

(my-keys-minor-mode 1)

Bu, klavyeyi başka birinin kullanması durumunda veya varsayılan bir tuş bağlantısının ne yaptığını görmem gerekirse, tüm değişikliklerimi tek bir hamlede kapatabilme (sadece küçük modu devre dışı bırakma) gibi ek bir faydaya sahiptir.

Mini arabellekte bunu kapatmanız gerekebileceğini unutmayın:

(defun my-minibuffer-setup-hook ()
  (my-keys-minor-mode 0))

(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)

1
Bu iyi bir fikir gibi görünüyor. Küçük modunuzun diğer küçük modlarla savaşmamasını sağlamanın bir yolu var mı?
Brian Carper

3
Minör modunuzun küçük mod haritası listesinde ilk sırada olduğundan emin olun.
Trey Jackson

2
Trey haklı. Genellikle bunu .emac'lerinizin sonuna yakın bir yere koymak yeterlidir. Ayrıca, geçersiz kılacağınız çoğu bağlama, ana modların ayarladığı bağlantılardır ... küçük modlar genellikle yoldan uzak durur.
scottfrazer

Bu yaklaşımı izledim, ancak sonra Ci'ye bağladığım her şeyin TAB tuşuna da bağlı olduğunu fark ettim. Baska öneri?
Steve

3
Brian Carper: Daha sonra yüklenen küçük modlarla başa çıkmak için bir iyileştirme: stackoverflow.com/questions/683425/…
phils

30

Scottfrazer'in cevabına bir ek olarak , aşağıdakileri yazdım, böylece daha sonra yüklenen kitaplıklar kendilerine ait yeni tuş eşlemeleri getirseler bile, benim tuş bağlarımın önceliği korumasını sağladım .

Tuş eşlemeleri derleme zamanında oluşturulabildiğinden, loadbunu yapmak için en iyi yer gibi görünüyordu.

(add-hook 'after-load-functions 'my-keys-have-priority)

(defun my-keys-have-priority (_file)
  "Try to ensure that my keybindings retain priority over other minor modes.

Called via the `after-load-functions' special hook."
  (unless (eq (caar minor-mode-map-alist) 'my-keys-minor-mode)
    (let ((mykeys (assq 'my-keys-minor-mode minor-mode-map-alist)))
      (assq-delete-all 'my-keys-minor-mode minor-mode-map-alist)
      (add-to-list 'minor-mode-map-alist mykeys))))

Komut dosyanızı yapıştırdım ama herhangi bir etkisi olmadı :(
alper

@alper Gerçekte kullandığınız kod ve sorunu yeniden oluşturmak için belirli bir örnek / tarif dahil olmak üzere tüm ilgili ayrıntıları içeren bir soru göndermenizi öneririm.
phils

21

Kurun use-package, değerlendirin ve bitirdiniz:

(require 'bind-key)
(bind-key* "C-i" 'some-function)

5
Kullanım paketi bağlama anahtarına bağlı olsa da, yalnızca bağlama anahtarı yükleme kullanım durumu için yeterlidir.
xuchunyang

2
Bu ('bind-key' paketi) en uygun çözüm gibi görünüyor; paylaşım için teşekkürler.
oligilo

use-packageInstall package: use-package [No Match]
alper

15

Bu soruyu "emacs undefine org mode keybindings" i ararken buldum, çünkü global haritamın gömme tamponunun bir org arabelleğinde çalışmasına izin vermek için mevcut Cc Cb davranışını çözmek istedim.

Bu benim için en basit çözüm oldu:

(add-hook 'org-mode-hook
      (lambda ()
        (local-unset-key (kbd "C-c C-b"))))

1
Bu moda özgüdür ve tek kullanımlık durumunuzda işe yarasa da büyük resmi ele almaz.
RichieHH

12

Scottfrazer'in cevabı tam olarak istediğiniz şey olsa da, gelecek nesil için başka bir çözümden bahsedeceğim.

Gönderen Manuel Emacs :

"Lisp programlarında Cc harfini anahtar olarak tanımlamayın. Cc ve bir harften (büyük veya küçük harf) oluşan diziler kullanıcılar için ayrılmıştır; kullanıcılar için ayrılmış tek dizilerdir, bu yüzden onları engellemeyin."

Kişisel genel bağlantılarınızı Cc artı bir harfe bağlarsanız, o zaman güvende "olmalısınız". Ancak, bu yalnızca bir kuraldır ve herhangi bir mod, bağlamalarınızı yine de geçersiz kılabilir.


3
Tüm modlardan org modunun bu kuralı ihlal etmesini beklemiyordum. 'Cc Ch' bana Cc a, b, c ve l'nin sırasıyla org-agenda, org-iswitchb, org-capture ve org-store-link'e bağlı olduğunu söylüyor.
Nate Parsons

7
Afaik, bunları bağlamak, org-modunun onu kullanmak için önerdiği ilk adımdır, ancak kullanıcının bunları kendisi tanımlaması gerekir (yani varsayılan olarak yapılmaz) ve bunu yaparken başka herhangi birini seçebilir. (ayrıca, bu bağlamaların kuruluş ana moduna bağlı değil, küresel olması gerektiği için)
Nikana Reklawyks

3

"Belirli bir mod haritası için onları açıkça geçersiz kılmadığım sürece, her zaman haritada tuş bağlarını kullanmak" istiyorsanız ve scottfrazier'in yaklaşımını kullandığınızı varsayarsak , şunları istiyorsunuz:

(defun locally-override (key cmd)
  (unless (local-variable-p 'my-keys-minor-mode-map)
    (set (make-variable-buffer-local 'my-keys-minor-mode-map)
         (make-sparse-keymap))
    (set-keymap-parent my-keys-minor-mode-map 
                       (default-value 'my-keys-minor-mode-map)))
  (define-key my-keys-minor-mode-map key cmd))

Yani

(locally-override "\C-i" nil)

"\ Ci" bağlamasını yalnızca geçerli arabellekteki ikincil moddan kaldırmalıdır. Uyarı: Bu tamamen test edilmemiş, ancak doğru yaklaşım gibi görünüyor. Anahtarlarım-küçük-mod-haritasının genel değerini başa çıkmaktan ziyade üst öğeyi ayarlamanın amacı, global değerde daha sonra yapılacak herhangi bir değişiklik otomatik olarak yerel değere yansıtılır.


2

Yapabileceğini sanmıyorum. Bu kabaca, işlevlerdeki yerel değişken bildirimleriyle gizlenemeyen global bir değişken tanımlamak istediğinizi söylemeye eşdeğerdir. Kapsam bu şekilde çalışmıyor.

Bununla birlikte, mod listesinden geçmek ve sizin için her birine yeniden atamak için bir elisp işlevi yazmanın bir yolu olabilir.


Bu kapsam belirleme fikri teknik olarak doğrudur, ancak overriding-local-mapdiğer tüm haritaları geçersiz kılmak için özel olarak tasarlanmıştır. Ancak kullanmak tehlikelidir.
event_jr

2

Bunu gerçekten kendiniz yapmak istemiyorsanız, etrafı kontrol etmeli ve daha önce başka birinin yapıp yapmadığını görmelisiniz.

Windows benzeri tuş atamalarınızı sağlayan bir Emacs paketi var. Bunu google aracılığıyla bulabilmelisin.


4
Düşündüğünüz paket muhtemelen cua-mode.
Drew

1
Evet, paket bu.
JesperE
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.