Yasnippet ve şirketin daha iyi çalışmasını sağlamak


22

Emacs, diyelim ki, "elisp"org modunda bir lisp bloğunu uzatmak için bir yasnipet kullanıyorum . Bunu uzatmak önce şirketin bana böyle bir menü veren ilk olarak tetiklenen "1. elisp1, 2. elisp2"bir seçenek olmadan "elisp". Şimdi eğer tabyasnipeti uzatmak için kullanırsam, her "elisp1"zaman ilk önce ekranda görünmesi can sıkıcıdır . Bu yüzden "1"öncelikle silmem ve yasnippet snippet'ini uzatmam gerekiyor.

Bu yüzden bir çözüm olarak, önce şirket tamamlama menüsünü kapatmak için her zaman sol ok tuşunu kullandım, ancak imleç şimdi gidecek "elis|p", bu yüzden tekrar imleci sonuna kadar hareket ettirmek "elisp|"ve snippet'i uzatmak için sağ ok tuşunu kullanıyorum .

İşte benim sorum şu: Nasıl bir tabanahtarla bağlanırım yasnippet'i ilk önce tetikler ama şirket beni kurtarmaz?


1
Ben kullanıyorum tabiçin companyve C-oiçin yasnippet. İlgileniyorsan daha fazla tarif edebilirim.
abo-abo

@ abo-abo, teşekkürler cevap. Bildiğin gibi yapabileceğimi biliyorum, ama Co'yu diğer komuta ben bağlarım ve elimde kasları adapte etmek için eğittim tab. Bu yüzden bağlamayı değiştirmek istemem.
Leu_Grady

Bu yüzden sordum :) C-oEğer ilgilenmiyorsanız, kısaltmaları ve parçacıkları genişletip satırları açmayı vs.
abo-abo,

ilginç görünüyor, daha fazla tarif edebilir misiniz? :)
Leu_Grady

Yanıtlar:


22

Aynı mesele ile kendim için yarattığım şey bu. Bu dan şirket modun Emacs Wiki sayfasında , ancak yoğun genişletilmiş:

(defun check-expansion ()
  (save-excursion
    (if (looking-at "\\_>") t
      (backward-char 1)
      (if (looking-at "\\.") t
    (backward-char 1)
    (if (looking-at "->") t nil)))))

(defun do-yas-expand ()
  (let ((yas/fallback-behavior 'return-nil))
    (yas/expand)))

(defun tab-indent-or-complete ()
  (interactive)
  (cond
   ((minibufferp)
    (minibuffer-complete))
   (t
    (indent-for-tab-command)
    (if (or (not yas/minor-mode)
        (null (do-yas-expand)))
    (if (check-expansion)
        (progn
          (company-manual-begin)
          (if (null company-candidates)
          (progn
            (company-abort)
            (indent-for-tab-command)))))))))

(defun tab-complete-or-next-field ()
  (interactive)
  (if (or (not yas/minor-mode)
      (null (do-yas-expand)))
      (if company-candidates
      (company-complete-selection)
    (if (check-expansion)
      (progn
        (company-manual-begin)
        (if (null company-candidates)
        (progn
          (company-abort)
          (yas-next-field))))
      (yas-next-field)))))

(defun expand-snippet-or-complete-selection ()
  (interactive)
  (if (or (not yas/minor-mode)
      (null (do-yas-expand))
      (company-abort))
      (company-complete-selection)))

(defun abort-company-or-yas ()
  (interactive)
  (if (null company-candidates)
      (yas-abort-snippet)
    (company-abort)))

(global-set-key [tab] 'tab-indent-or-complete)
(global-set-key (kbd "TAB") 'tab-indent-or-complete)
(global-set-key [(control return)] 'company-complete-common)

(define-key company-active-map [tab] 'expand-snippet-or-complete-selection)
(define-key company-active-map (kbd "TAB") 'expand-snippet-or-complete-selection)

(define-key yas-minor-mode-map [tab] nil)
(define-key yas-minor-mode-map (kbd "TAB") nil)

(define-key yas-keymap [tab] 'tab-complete-or-next-field)
(define-key yas-keymap (kbd "TAB") 'tab-complete-or-next-field)
(define-key yas-keymap [(control tab)] 'yas-next-field)
(define-key yas-keymap (kbd "C-g") 'abort-company-or-yas)

Temel olarak, bu çoğu zaman <tab>doğru olanı yapar . Sekmeye basmak

  • Geçerli çizgiyi girinti,
  • Eğer genişletmek için bir yaylı püskürtü varsa, genişletmek, bu şirketin tamamlanmadığı anlamına gelse bile (kısaltmaları fazla kullanmıyorum, bu nedenle henüz kısaltma desteği yok),
  • Bir şirketin tamamlanması sürüyorsa, seçilen öğeyle tamamlayın,
  • Aksi takdirde, otomatik tamamlama işlemini başlatmak için şirketi kullanmayı deneyin
  • Otomatik tamamlayacak bir şey yoksa ve bir yaylacı yer tutucusuysak, bir sonraki yer tutucusuna atlayın.

Otomatik tamamlama fırsatı varsa ve şu anda bir snippet yer tutucusunda düzenleme yapıyorsanız, durumun belirsiz olduğunu unutmayın. Bir uzlaşma olarak, C-<tab>doğrudan bir sonraki yer tutucuya atlamak zorunda kaldım.

Snippet'in adının şirket menüsünde görünmemesi ve bir snippet'in varlığı sekme tuşunun davranışını sessizce değiştirmesi aslında hoş değil, ne yazık ki ... En azından <return>tamamlanmak yerine yazmak mümkün olsa da snippet'in


Bu magit ile etkileşime giriyor gibi görünüyor. Magit'te sekmenin yükselmesine neden olur Buffer is read-only: #<buffer *magit: ~/.emacs.d/*>. Bunu nasıl düzeltebileceğime dair bir fikrin var mı?
zsquare

@zsquare magit kullanmıyorum (biliyorum, ben deliyim) bu yüzden emin olmak için test edemiyorum, ama magit'in TAB için anahtar haritası gibi olmasımagit-section-toggle , (global-set-key [tab] 'tab-indent-or-complete)yukarıdaki çizgiyle çelişiyor gibi gözüküyor . Hızlı ve kirli bir düzeltme tab-indent-or-complete, magit modunda olup olmadığımızı görmek için yukarıdaki fonksiyonun başlangıcına bir kontrol eklemek olacaktır , örn magit-mode-hook.
dodgethesteamroller 8:15

bu harika, teşekkürler! :) küçük stil noktası, whenhemen hemen bir if+progn
Matt Briggs

@zsquare Magit modundaki sekmeyi desteklemek için bunu con'a ekleyiniz tab-indent-or-complete`((türetilmiş-mod-p 'magit-mod)) (magit-bölüm-toggle (magit-akım-bölüm))`
Bae

Varsayılan minibuffer yerine ido'yu desteklemek için condi `((minibufferp) (ido-complete))` ile değiştirin
Bae

10

İşte kullanıyorum kodu:

(global-set-key "\C-o" 'aya-open-line)

(defun aya-open-line ()
  "Call `open-line', unless there are abbrevs or snippets at point.
In that case expand them.  If there's a snippet expansion in progress,
move to the next field. Call `open-line' if nothing else applies."
  (interactive)
  (cond ((expand-abbrev))

        ((yas--snippets-at-point)
         (yas-next-field-or-maybe-expand))

        ((ignore-errors
           (yas-expand)))

        (t
         (open-line 1))))

aya-open-linedan otomatik yasnippet düz daha fazlasını yapıyor open-line:

  • kısaltmaları genişletmeye çalışır
  • bir sonraki yasnippet alanına taşınmaya çalışıyor
  • yasnippet'i genişletmeye çalışıyor
  • Sonunda, open-linediğerleri başarısız olursa çağırır.

pasajın için teşekkürler. Oldukça iyi. Ancak sorun hala var. İlk kullandığımda C-o, sadece şirket menüsünü kapattığım için yasnipeti uzatmak için iki kez basmaya ihtiyacım var.
Leu_Grady

Böyle bir sorunum yok: C-oşirket menüsü etkinken menüyü kapatacak ve pasajı genişletecek.
abo-abo
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.