go import add 和 go impl 执行后都需要很长一段时间才有反应

@seagle0128 我学习了一下你的 init-go.el, 里面有用 go-impl,但是我每次用的时候都会需要很长一段时间,应该能有 10 秒左右,才会有反应

然后我也试了一下,在 Go mode 里,有一个 go-import-add,也是同样需要等很久才有反应

我在 emacs -Q 里也试过,也是要等很久,不知道你用的时候也是这样的吗?还是我哪里配置的有问题呢?

如果是我的环境问题,我应该怎么去排查一下呢?我现在只会看 *Message* 里的日志,但是日志里并没有什么输出。

我的环境是

macOS 10.14.4
homebrew 安装的 Emacs 26.2

回车之后一直没内容,而且这个时候 Emacs 是卡住的

35

10 多秒以后才会出来这个画面

image

我也是很慢,然后我用rg写了个新的。但是不支持go mod。等个好用的。

rg 写的这个能分享出来,我学习一下吗?go mod 用得还不算多

;; go-mod 的 go package add 太慢了,使用fd重现实现
(defun my-go-packages-native ()
  "Return a list of all installed Go packages.
It looks for archive files in /pkg/."
  (sort
   (delete-dups
    (cl-mapcan
     (lambda (topdir)
       (let ((pkgdir (concat topdir "/pkg/")))
	 (go-gackages pkgdir)
         	 ))
     (go-root-and-paths)))
   #'string<))

(defun go-gackages (topdir)
  "Rewrite go-mod my-go-packages-native.

   topdir is pkgdir"
  (--> (shell-command-to-string (concat "fd -e a . " topdir))
     (split-string it "\n")
     (-map (lambda (str)
	     (--> (string-remove-prefix topdir str)
		  (string-trim-left it ".*?/")
		  (string-remove-suffix ".a" it)
		  )
	     ) it)))

(fset 'go-packages-native 'my-go-packages-native)

说错了不是rg 是fd实现的

1 个赞

这个是go package本身慢的缘故。你用命令行试试就知道了。这个只能问问go package作者怎么改进,Emacs本身没有关系。

貌似不是这样的,

Eshell:

56

M-x:

21

gifox 有 10 秒的限制,但是可以看到,10 秒过去了,Receiver 的提示还是没有出现。

go-impl会执行·go-packages找出所有的package,这个比较耗时,跟你本地安装的包多少也有关。我这里大概6秒左右。你profile下就知道了。如果你知道明确的receiver和interface,不如直接eval。

(defun go-impl (receiver interface)
  (interactive
   (let* ((packages (go-packages))
          (comp-fn (lambda (input predicate code)
                     (when (bound-and-true-p helm-mode)
                       (setq input (or (bound-and-true-p helm-input) input)))
                     (go-impl--completing-function packages input predicate code))))
     (setq go-impl--receiver-cache nil)
     (list
      (read-from-minibuffer "Receiver: " nil go-impl--local-command-map nil
                            'go-impl--receiver-history nil t)
      (completing-read "Interface: " comp-fn nil nil nil 'go-impl--interface-history))))
  (when go-impl-aliases-alist
    (setq interface (or (assoc-default interface go-impl-aliases-alist)
                        interface)))
  (let ((stubs (go-impl--execute receiver interface)))
    (save-excursion
      (insert stubs))
    (when go-impl-enter-function
      (forward-line)
      (back-to-indentation))))
1 个赞

老兄使用fd确实快很多,不过这么实现有点奇怪,直接增加一个函数,设置给go-packages-function就好了。

可以用gopkgs, 第一次go-import-add会慢一些,后面就快了

(defun maple/go-packages-function()
  "Return a list of all Go packages, using `gopkgs'."
  (sort (process-lines "gopkgs") #'string<))

(setq go-packages-function 'maple/go-packages-function)
2 个赞

:rofl: 哈哈,确实是直接设置go-packages-function就可以,我是之前直接调试到这个函数比较慢,就直接改了。没考虑太多。

这个好用。:+1:

我已经放弃了, 体验太差劲了。 用回了 goland, 毫秒级的反应从来不卡。等 emacs 生态下的体验什么时候好了, 再用回来试试

何必呢,如果觉得还是慢,可以有多种方式解决

  • 可以缓存一下
  (defvar maple/go-packages-list nil)

  (defun maple/go-packages()
    (or maple/go-packages-list
        (setq maple/go-packages-list (go-packages-native))))

  (add-hook 'go-mode-hook
            (lambda() (run-with-idle-timer 0.1 nil 'maple/go-packages)))

  (setq go-packages-function 'maple/go-packages)
  • 可以先异步调用一下
  (defun maple/go-packages-function()
    "Return a list of all Go packages, using `gopkgs'."
    (sort (process-lines "gopkgs") #'string<))

  (with-eval-after-load 'async
    (add-hook 'go-mode-hook
              (lambda() (async-start (lambda() (process-lines "gopkgs")) 'ignore))))

  (setq go-packages-function 'maple/go-packages-function)
  • 还可以异步调用后再缓存一下
  (defun maple/go-packages-function()
    "Return a list of all Go packages, using `gopkgs'."
    (or maple/go-packages-list
        (sort (process-lines "gopkgs") #'string<)))

  (defvar maple/go-packages-list nil)

  (with-eval-after-load 'async
    (add-hook 'go-mode-hook
              (lambda()
                (async-start
                 (lambda()
                   (process-lines "gopkgs"))
                 (lambda(results)
                   (setq maple/go-packages-list (sort results#'string<)))))))

  (setq go-packages-function 'maple/go-packages-function)

总会有方式来解决的

1 个赞

测试后 直接把 company-lsp 卸载了, 不要了, 一切都清净了

gopls 删除了, 换回了 bingo ,没有卡死的问题了, 看来还是 lsp 服务不行啊

最近卡死的问题特别严重。。。gopls 真得背这锅,太难受了

意外发现 saibing 还有一个 fork,我准备试一下

最新的 go-mode 似乎解决这个问题了,直接用的 go list