[提问] 怎么在不关闭 emacs 的情况下,重装 magit

有时,在 list-packages 页面,更新 packages 后,用 magit 会出现问题。

大概是说 upstream 的 symbol 不对还是啥,总之 magit-status 的功能不 work 了。就算关闭 emacs,再重新打开依然不行。

可行的办法,就是将 magit 移除 (package-delete),然后重启 emacs,它会重新装 magit,这个时候就恢复正常了。

但是我需要每次都用 package-delete 去删除magit,以及相关依赖,再重启 emacs,相当麻烦。

于是想,既然重装 magit 就行,那是否可以写一个函数,完成 magit 的卸载和重装?

然后就写了下面的函数,逻辑是把我知道的依赖包列出来,然后一个一个的调用 package-delete 删除,删除后再调用 package-install 去重新安装。

(defun spike-leung/reinstall-magit ()
  "Remove magit dependences and reinstall magit."
  (interactive)
  (let ((remove-packages '(magit-todos github-clone forge magit)))
    (progn
      (while remove-packages
        (let ((package (car remove-packages)))
          (if (assq package package-alist)
              (package-delete (package-get-descriptor package))))
        (setq remove-packages (cdr remove-packages)))
      )))

;; (let ((install-packages) '(magit github-clone forge))
;;   (while install-packages
;;     (package-install (car install-packages))
;;     (setq install-packages (cdr install-packages));
;;     ))

但是,这样也是不行。删除是能够删除,在文件目录中,maigt 的文件已经删除了,但 magit 注册在 emacs 里的函数依然可以用。

我想请问,有什么办法可以删除 magit,并且把 magit 注册的函数一并删除吗?是否有相关的 elisp 函数?

或者,有没有什么办法,在不重启 emacs 的前提下, 把一个 package 以及它注册的函数全部删除?

我对 elisp 还不是很熟,也许有什么内置函数?(不太清楚怎么找到有什么函数可用= =)

unload-feature

https://www.gnu.org/software/emacs/manual/html_node/elisp/Unloading.html

2 个赞

感谢 :grinning:,看起来可以了。不过像 magit-todos, github-clone 这些,似乎不被认为是 feature,我看看 feature里具体怎么描述的。

最后改好的函数,看起来是能用了。

;;; Package --- Summary
;; init-custom-function
;;; Commentary:
;;; Code:
(defun spike-leung/reinstall-magit ()
  "Remove magit dependences and reinstall magit."
  (interactive)
  (let ((remove-packages '(magit-todos github-clone forge magit)))
    (progn
      (while remove-packages
        (let ((package (car remove-packages)))
          (if (assq package package-alist)
              (progn
                (package-delete (package-get-descriptor package))
                )))
        (setq remove-packages (cdr remove-packages)))
      (if (featurep 'magit) (unload-feature 'magit t))
      (let ((install-packages '(magit magit-todos github-clone forge)))
        (while install-packages
          (package-install (car install-packages))
          (setq install-packages (cdr install-packages)) ;
          ))
      )))

(provide 'init-custom-function)
;;; init-custom-function.el ends here

1 个赞

这个看起并不是root cause,解决方案有点本末倒置啊。从描述来看,根本原因是更新包之后为什么magit出问题了。猜测是正好更新了magit或者其依赖包,这时才调用magit相关功能肯定就找不到了。除非是安装magit并不完整,重启emacs功能一切正常,不必删除再重启。

如果是这种情况,可以按照两个方面来考虑。

  1. 既然是更新包,重启emacs是正常的,也是可接受的。
  2. 如果更新完不想重启,需要重新读取load-path,再重新load libaray即可。前提是对使用的emacs加载机制有一定理解,否则重启是最干净,也是最省事的。

是的,估计是在更新包的时候,把 magit 或者 magit 相关依赖更新了吧,尝试去看 magit 代码以及 google 报的错误,似乎也没有人碰到过,暂时还没搞明白是什么问题。

而且,更新包后,如果不卸载 magit ,即使重启 emacs,magit 依然是不正常的。唯有重装 magit 才行。

你说的读取 load-path 在 load-library 也许可行,之后我了解机制后试试。

Thanks :slight_smile: