和message相关的东西全部是写死在C里的,(比如Message buffer的名字)。
我自己写了一个蹩脚的方法,但是十分不完美。
(let ((standard-output (current-buffer)))
(letf (((symbol-function #'message)
#'(lambda (s &rest r) (princ (concat (apply #'format s r) "\n")))))
(package-refresh-contents)
nil))
执行的时候会等待整个块执行结束才显示出来,有没有办法实时显示?
后面的结果是一瞬间打印出来的。但是单单eval (package-refresh-contents)
就是一句句出来
Importing package-keyring.gpg...
Importing package-keyring.gpg...done
Contacting host: elpa.emacs-china.org:80
Contacting host: elpa.emacs-china.org:80
Package refresh done
你想解决的问题是什么?即「XY Problem」中的「X」。
X:现在有一个函数,用于自动获取更新并更新所有的旧的包。
(defun package-upgrade-all ()
"Upgrade all packages automatically without showing *Packages* buffer."
(interactive)
(package-refresh-contents)
(let (upgrades)
(cl-flet ((get-version (name where)
(let ((pkg (cadr (assq name where))))
(when pkg (package-desc-version pkg)))))
(dolist (package (mapcar #'car package-alist))
(let ((in-archive (get-version package package-archive-contents)))
(when (and in-archive
(version-list-< (get-version package package-alist) in-archive))
(push (cadr (assq package package-archive-contents)) upgrades)))))
(write-to-package-upgrade-history "")
(if upgrades
(save-window-excursion
(dolist (package-desc upgrades)
(let ((old-package (cadr (assq (package-desc-name package-desc) package-alist))))
(package-install package-desc)
(package-delete old-package)
(save-update-history old-package package-desc)
(write-to-package-upgrade-history (package-desc-full-name package-desc) (package-desc-full-name old-package))))
(write-update-history-to-cache)
(message "{%s} Update done... [%s]" (length upgrades) (mapconcat #'package-desc-full-name upgrades ", ")))
(write-to-package-upgrade-history "All packages are up to date"))))
(其中的 save-update-history
write-to-package-upgrade-history
write-update-history-to-cache
是我自定义的其他函数。)
这个函数在执行的时候会向Message中写入一堆安装的信息:
[20:14:35] Importing package-keyring.gpg...
[20:14:36] Importing package-keyring.gpg...done
[20:14:36] Contacting host: elpa.emacs-china.org:80
[20:14:40] Contacting host: elpa.emacs-china.org:80
[20:14:40] Package refresh done
[20:14:40] [18-08-23_20:14:40]
[20:14:41] Contacting host: elpa.emacs-china.org:80
[20:14:41] Generating autoloads for counsel-projectile.el...done
[20:14:42] Done (Total of 1 file compiled, 2 skipped)
[20:14:42] Package `counsel-projectile-20180822.4' deleted.
[20:14:42] [18-08-23_20:14:42] counsel-projectile-20180822.4 -> counsel-projectile-20180822.1458
[20:14:42] Contacting host: elpa.emacs-china.org:80
[20:14:43] Contacting host: elpa.emacs-china.org:80
...
需求就是把这些信息打印在 *eshell* 里或者 *terminal* 里(当前执行命令的那个buffer),不想污染整个全局的 *Messages* buffer。
因为这些buffer可以随时杀掉,*Messages* 不想随便杀。编译产生的信息动辄几千行,完全不记录很可惜,全部记在 *Messages* 里就会导致它很卡,同时,看其他的信息也不方便。事实上在哪里操作的,就该打印在哪里,也很符合直觉。
因為 Emacs 是单任务的,在函數调用完成之前是不会 redraw display 的。
sleep-for
的 doc 也提到了
(sleep-for SECONDS &optional MILLISECONDS)
Pause, without updating display, for SECONDS seconds.
1 个赞
是有这个问题,而且也不需要 sleep-for ,这样也可以复现
(let ((standard-output (current-buffer)))
(letf (((symbol-function #'message)
#'(lambda (s &rest r) (princ (concat (apply #'format s r) "\n")))))
(package-refresh-contents)
nil))
后面的结果是一瞬间打印出来的。但是单单eval (package-refresh-contents)
就是一句句出来
Importing package-keyring.gpg...
Importing package-keyring.gpg...done
Contacting host: elpa.emacs-china.org:80
Contacting host: elpa.emacs-china.org:80
Package refresh done
我最近换上了 lsp-java ,非常好用,补全等方面完全不弱于 eclipse 。但是,它会不断地向 message 里写日志,导致我有些会开 minibuffer 的功能体验极差,比方说 ivy-yasnippet
。求解解决方案。
歪个楼,java language server用的啥?
emacs-lsp 底下的 lsp-java ? 修改 ls 启动参数就可以了:
1 个赞
Eclipse JDT Language Server
你的需求不是很好理解,似乎是在定制的路上走了太远。就你的问题,如果你不喜欢 message
的效果,自然就不要使用它(使用 insert
),至于内置函数使用了它,就只能接受这个事实。此外,应该避免修改 message
的定义,否则 Emacs 性能变差应该不奇怪。
1 个赞