Yasnippet और कंपनी के काम को अच्छा बनाने के लिए कैसे?


22

अपने "elisp"एमएसीएस में , आइए बताते हैं, मैं ऑर्ग-मोड में एक लिस्प ब्लॉक का विस्तार करने के लिए यास्नीपेट का उपयोग करता हूं। लेकिन इससे पहले कि मैं इसे बढ़ाता हूं, पहले कंपनी को ट्रिगर किया जाता है, जो मुझे एक "1. elisp1, 2. elisp2"विकल्प के बिना एक मेनू देता है "elisp"। अब अगर मैं tabyasnippet को विस्तारित करने के लिए उपयोग करता हूं, तो यह हमेशा कष्टप्रद होता है कि "elisp1"हमेशा पहली बार स्क्रीन पर जाता है। इसलिए मुझे "1"सबसे पहले हटाने की ज़रूरत है , और यस्नीपेट स्निपेट का विस्तार करना है।

इसलिए एक समाधान के रूप में, मैं हमेशा कंपनी के पूरा होने वाले मेनू को बंद करने के लिए बाएं तीर कुंजी का उपयोग करता हूं, लेकिन कर्सर अब जाएगा "elis|p", इसलिए कर्सर को समाप्त "elisp|"करने के लिए और स्निपेट का विस्तार करने के लिए मैं सही तीर कुंजी का उपयोग करता हूं।

यहाँ मेरा सवाल आता है: मैं tabपहली बार यासनीपेट ट्रिगर कुंजी कैसे बाँध सकता हूं लेकिन मुझे जीवन बचाने के लिए कंपनी नहीं?


1
मैं उपयोग कर रहा हूँ tabके लिए companyऔर C-oके लिए yasnippet। यदि आप रुचि रखते हैं तो मैं आगे वर्णन कर सकता हूं।
abo-abo

@ abo-abo, धन्यवाद उत्तर। मुझे पता है कि जैसा आप कर सकते हैं मैं कर सकता हूं, लेकिन मैं सह को अन्य कमांड से बांधता हूं, और बुरी तरह से मैंने अपने हाथ की मांसपेशियों को अनुकूलित करने के लिए प्रशिक्षित किया है tab। इसलिए मैं बंधन को बदलना नहीं चाहूंगा।
लेउ_ग्राडी

इसीलिए मैंने पूछा :) C-oयदि आप रुचि रखते हैं तो एब्स और स्निपेट्स और ओपन लाइन्स आदि का विस्तार कैसे किया जा सकता है , इसके बारे में बताने का कोई मतलब नहीं है।
abo-abo

दिलचस्प लगता है, क्या आप और अधिक वर्णन कर सकते हैं? :)
Leu_Grady

जवाबों:


22

यह वही है जो मैंने अपने लिए बनाया था, उसी मुद्दे का सामना कर रहा हूं। यह कंपनी-मोड के Emacs Wiki पेज से है , लेकिन इसे बहुत अधिक बढ़ाया गया है:

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

मूल रूप से, यह ज्यादातर समय <tab>सही काम करता है। दबाने वाला टैब होगा

  • वर्तमान लाइन को इंगित करें,
  • अगर कोई विस्तार करने के लिए यास्नीपेट है, तो इसका मतलब है, भले ही इसका मतलब है कि कंपनी को पूरा करने से रोकना (मैं संक्षिप्त रूप का उपयोग नहीं करता हूं, इसलिए कोई संक्षिप्त समर्थन अभी तक नहीं)
  • यदि कोई कंपनी पूर्ण हो रही है, तो चयनित आइटम के साथ पूर्ण,
  • अन्यथा स्वत: पूर्ण शुरू करने के लिए कंपनी का उपयोग करने का प्रयास करें,
  • अगर वहाँ स्वत: पूर्ण करने के लिए कुछ भी नहीं है और हम एक yasnippet प्लेसहोल्डर में हैं, तो अगले प्लेसहोल्डर पर जाएं।

ध्यान दें कि यदि स्वत: पूर्ण होने का अवसर है और आप वर्तमान में स्निपेट प्लेसहोल्डर में संपादन कर रहे हैं, तो स्थिति अस्पष्ट है। एक समझौते के रूप में, मैं C-<tab>सीधे अगले प्लेसहोल्डर को छोड़ना चाहता हूं ।

तथ्य यह है कि स्निपेट का नाम कंपनी मेनू में नहीं दिखता है और एक स्निपेट का अस्तित्व चुपचाप संशोधित करता है टैब कुंजी का व्यवहार विशेष रूप से अच्छा नहीं है, दुर्भाग्य से ... हालांकि कम से कम इसके <return>बजाय टाइप करना संभव है ताकि पूरा होने के बजाय स्निपेट का।


यह मैजिट के साथ हस्तक्षेप करने के लिए लगता है। मजिट में टैब को बढ़ाता है Buffer is read-only: #<buffer *magit: ~/.emacs.d/*>। किसी भी विचार मैं कैसे तय कर सकते हैं?
zsquare

@zsquare मैं मैगिट का उपयोग नहीं करता (मुझे पता है, मैं पागल हूं) इसलिए मैं यह सुनिश्चित करने के लिए परीक्षण नहीं कर सकता, लेकिन यह टीएबी के लिए मैगिट के कीमैप की तरह लगता है, जो इसे बांधता हैmagit-section-toggle , (global-set-key [tab] 'tab-indent-or-complete)ऊपर की रेखा के साथ विरोध कर रहा है। एक त्वरित और गंदे फिक्स को tab-indent-or-completeऊपर फ़ंक्शन की शुरुआत में एक चेक जोड़ना होगा, यह देखने के लिए कि क्या हम मैगिट मोड में हैं, उदाहरण के लिए एक वैश्विक चर के लिए जो सेट हो जाता है magit-mode-hook
dodgethesteamroller 21

यह बहुत बढ़िया है, धन्यवाद! :) छोटी शैली बिंदु, whenबहुत ज्यादा एक if+progn
मैट ब्रिग्स

@zsquare मैगिट मोड में टैब को सपोर्ट करने के लिए इसे tab-indent-or-completecond ('(व्युत्पन्न-मोड-पी' मैगिट-मोड) (मैगिट-सेक्शन-टॉगल (मैजिट-करंट-सेक्शन)) में जोड़ें ''
Bae

डिफ़ॉल्ट minibuffer पूरा होने के बजाय समर्थन Ido करने के लिए, साथ cond की जगह `((minibufferp) (Ido-पूर्ण))`
बे

10

यहां वह कोड है जो मैं उपयोग कर रहा हूं:

(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-lineसे ऑटो yasnippet एक सादे की तुलना में अधिक होता है open-line:

  • यह abbrevs का विस्तार करने की कोशिश करता है
  • यह यास्निपेट के अगले क्षेत्र में जाने की कोशिश करता है
  • यह यास्निपेट का विस्तार करने की कोशिश करता है
  • अंत में, यह कॉल करता है open-lineयदि अन्य सभी विफल रहता है

आपके स्निपेट के लिए धन्यवाद। काफी अच्छा। लेकिन समस्या अभी भी मौजूद है। जब मैं पहली बार उपयोग करता हूं C-o, तो यह सिर्फ कंपनी मेनू बंद करता है, इसलिए मुझे यास्निपेट का विस्तार करने के लिए दो बार प्रेस की आवश्यकता है।
Leu_Grady

मेरे पास ऐसा कोई मुद्दा नहीं है: C-oकंपनी मेनू के साथ सक्रिय मेनू को बंद कर देगा और स्निपेट का विस्तार करेगा ।
abo-abo
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.