如何仅在 term-line-mode 中启用制表符完成

如何仅在 term-line-mode 中启用制表符完成

我安装了 company-mode。当我在 term-mode 中按 tab 时,它总是调用 company-complete。我尝试使用以下方法禁用 company-mode

(global-company-mode '(not (equal major-mode 'term-mode)))

以下也不起作用

(add-hook 'term-mode-hook (lambda()
(company-mode 0)
(global-unset-key (kbd "<tab>"))))

我尝试了另一种方法

(defun term-send-tab()
(interactive)
(term-send-raw-string "\t"))

(define-key term-raw-map (kbd "TAB") 'term-send-tab)
(define-key term-raw-map (kbd "<tab>") 'term-send-tab)

全部失败。任何帮助都将不胜感激!

答案1

我使用自定义函数 my-tab 解决了这个问题,该函数使用了 phil 编写的一些代码。我将 tab 键绑定到 my-tab,这样当处于 term-char-mode 时,它​​将发送一个原始制表符,而在其他情况下则完成,另外两个快速制表符将执行 yas-expand,通过将 yas-next-field 绑定到“Mn”,制表符补全甚至可以在代码片段扩展中工作。

问题是,当 company 和 yasnnipet 具有相同的前缀时,tab 只会完成补全。是否可以在按下 tab 键后设置 company 补全的延迟时间,使其大于 my-double-key-timeout,这样双击 tab 就会执行 yas-expand,如果用户想要 company 补全,他只需键入一个 tab 并等待即可。(使用 sit for 解决)

我不知道为什么我不能只绑定标签来在 term-raw-map 中发送原始标签。

(defvar my-double-key-timeout 0.25
  "The number of seconds to wait for a second key press.")

 (defun my-tab ()
  "Move to the beginning of the current line on the first key stroke,
and to the beginning of the buffer if there is a second key stroke
within `my-double-key-timeout' seconds."
  (interactive)
  (let ((last-called (get this-command 'my-last-call-time)) )
        (is-term (string= "term-mode" major-mode)))
    (if (and is-term (term-in-char-mode))
    (term-send-raw-string "\t")
      (if (and (eq last-command this-command)
           last-called
           (<= (time-to-seconds (time-since last-called))
           my-double-key-timeout))
      (yas-expand) 

            (if (sit-for my-double-key-timeout)
             (complete-indent-fold)))

    (put this-command 'my-last-call-time (current-time))))

(defun complete-indent-fold()
  (interactive)
  (if (looking-at outline-regexp)
      (if (equal major-mode 'org-mode) (org-cycle) (my-outline-cycle))
    (if (looking-at "\\_>") (company-complete) (indent-for-tab-command))))

请帮助我改善这一点。谢谢!

答案2

它仍然有一点 bug,但对我来说很好用。欢迎提出任何建议!

(defun my-tab ()
  (interactive)
  (let ((str (thing-at-point 'line t))
    (ep nil))
    (setq str (replace-regexp-in-string "^.*\\$ " "" str))
    (setq ep (- (length str) 1))
    (goto-char (line-beginning-position))
    (delete-region (point) (line-end-position))
    (term-send-raw-string
     (format "\r%s\t\t" (substring str 0 ep)))))

(define-key term-mode-map (kbd "TAB") 'my-tab)

相关内容