Đây là những gì tôi tạo ra cho chính mình, đối mặt với cùng một vấn đề. Nó là từ trang Wiki Emacs của chế độ công ty , nhưng được mở rộng rất nhiều:
(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)
Về cơ bản, điều này làm cho <tab>điều đúng đắn hầu hết thời gian. Nhấn tab sẽ
- Thụt dòng
- Nếu có một yasnippet để mở rộng, hãy mở rộng nó, ngay cả khi điều này có nghĩa là hủy bỏ hoàn thành công ty (tôi không sử dụng viết tắt nhiều, vì vậy chưa có hỗ trợ viết tắt),
- Nếu việc hoàn thành công ty đang diễn ra, hãy hoàn thành với mục đã chọn,
- Nếu không, hãy thử sử dụng công ty để bắt đầu tự động hoàn thành,
- Nếu không có gì để tự động hoàn tất và chúng tôi đang ở trong một trình giữ chỗ yasnippet, hãy bỏ qua trình giữ chỗ tiếp theo.
Lưu ý rằng nếu có cơ hội tự động hoàn thành và bạn hiện đang chỉnh sửa trong một trình giữ chỗ đoạn trích, tình huống này rất mơ hồ. Như một sự thỏa hiệp, tôi nhất C-<tab>định bỏ qua trực tiếp cho trình giữ chỗ tiếp theo.
Thực tế là tên của đoạn trích không xuất hiện trong menu công ty và sự tồn tại của đoạn mã âm thầm sửa đổi hành vi của phím tab không đặc biệt tốt, thật không may ... Mặc dù ít nhất có thể gõ <return>thay vào đó để hoàn thành của đoạn trích.
tab
chocompany
vàC-o
choyasnippet
. Tôi có thể mô tả thêm nếu bạn quan tâm.