在 Windows 10 上的 Emacs, 通过w32-shell-execute 打开文件夹冻结 Emacs,测试过 Emacs 29 和 Emacs 30,都有问题。
重现步骤:
- 通过
emacs -Q
启动 Emacs
- 按
M-:
执行下面的代码(用什么文件夹没关系),Emacs 就会卡死,无法进行任何操作,C-g也没法恢复:
(w32-shell-execute "open" "~/.emacs.d/")
其实受这个问题困扰很久了,最近给 Emacs 报Bug后,才发现可能和 PowerToys 有关。
因为 Eli Zaretskii 也没法重现我的问题,于是我到另外一台Windows 机器尝试重现,结果也没法重现了。然后想起来这机器没安装过 PowerToys,通过 winget install Microsoft.PowerToys
安装上PowerToys以后,再试就能重现问题了。
气人的是卸载 PowerToys 后也还是能重现。
想问问大家是不能重现这个问题? 还有如何把 PowerToys 卸载干净,恢复原来的设置,让 w32-shell-execute 可以正常使用?
目前的临时解决方法是第一个参数用 nil:
(w32-shell-execute nil "~/.emacs.d/")
参考 bug#67006: 30.0.50; w32-shell-execute will freeze Emacs on Windows 10
1 个赞
这个问题我也忍了很久了,每次尝试从 Emacs 内打开 explorer.exe 的时候都会卡死或者需要等很长一段时间
你安装了 PowerToys 吗?我不确定是否 100% 和它有关。
我之前好像是有时好用,有时不好用。最近是直接完全不能用了。
没有安装,确实是有时能用有时也不行
之前我使用下面的代码让 org-mode 在打开本地目录的 link 时启动资源管理器:
(require 'org)
(setq org-file-apps
(cl-substitute-if '(directory . default) (lambda (x) (eq (car x) 'directory)) org-file-apps))
执行上面的代码,然后在 Emacs 的 org-mode buffer 内找一个本地目录链接并 C-c C-o,然后我的 Emacs 就卡住了,且无法通过 C-g 恢复。
我使用的是 Windows 10 22H2 19045.3570,Emacs 版本是官方提供的 GNU Emacs 29.1 (build 2, x86_64-w64-mingw32) of 2023-07-31
(注,以上操作均在 emacs -Q 下执行)
用的win10+emacs29.1,用以下函数打开文件夹很正常,而且试了 (w32-shell-execute nil "~/.emacs.d/")
和 (w32-shell-execute "open" "~/.emacs.d/")
打开也是正常的。
(defun eye/open-explorer ()
"Open explorer of current buffer directory."
(interactive)
(when (and default-directory (file-directory-p default-directory)
(eq system-type 'windows-nt))
(let ((dir default-directory)
(explorer (replace-regexp-in-string "/" "\\\\" (executable-find "C:/Windows/SysWOW64/explorer")))
(command))
(setq dir (encode-coding-string
(replace-regexp-in-string "/" "\\\\" dir) 'gbk-dos))
(setq command (concat explorer " " dir))
(shell-command command nil nil)
(message command))
))
1 个赞
我用你的 eye/open-explorer
函数确实可以用。
很奇怪,试了一次 eye/open-explorer
后,(w32-shell-execute "open" "~/.emacs.d/")
也正常了。
我这个安装过 PowerToys 的机器又没法重现问题了。
新发现:
执行一次 下面的代码后
(executable-find "C:/Windows/SysWOW64/explorer")
再执行下面的代码就能正常打开文件夹了:
(w32-shell-execute "open" "C:/Windows/SysWOW64/")
然后就都正常了。
不过重启机器后,问题依旧。
msys2 下装的 emacs 也遇到类似的情况。las-bridge 怎么也调用不了 epc
也是这个函数 w32-shell-execute 问题?lsp-bridge 调用不了 epc 应该和 w32-shell-execute 不相关吧。
可以问问在 Windows 上用 lsp-bridge的大佬。
不是 w32-shell-execute 的问题,不过症状相似
在 early-init.el 中加入下面的配置可以临时解决问题:
(add-to-list 'exec-path "C:/Windows/SysWOW64")
学到了,还有 w32-shell-execute 这样一个方法。之前都是通过 call-process-shell-command 直接开explorer 的。
不过主楼的这个问题在 win11 上不存在,powertoys 也是装了的。
多谢提供信息,可惜我的老机器都升级不了 Windows 11.
我主要是想用 embark 的一个打开外部文件的函数 embark-open-externally。按完 embark-act (我邦定到C-.) 后,接 x 就可以打开外部文件了。
1 个赞
SPQR
14
我是win10 emacs 30 也安装了powertoy,但是没这个问题(emacs -Q和加载自己的配置时都没有),不过我对于exec-path也做了特殊处理,每次启动emacs的时候手动把exec-path用PATH的值覆盖。
我还没注意过这方面,Emacs 的exec-path 在Windows上不是直接继承了系统的 Path 和 当前用户的 Path吗?
SPQR
16
msys2默认不继承windows的PATH变量,当从msys2的任意终端环境下启动emacs的时候,exec-path只会包含PATH的一部分,而且是只有一小部分。可以把msys2改成继承windows的PATH,但是每次大更新都会恢复默认,所以我干脆把几个关键路径用setenv硬编码然后覆盖exec-path
用 msys2的终端启动确实是你说的这样的。
我用在 Windows下只是用 msys2编译 Emacs ,然后安装Emacs到其他位置。启动时是直接通过 runemacs.exe 启动,所以是默认继承了系统环境变量和用户环境变量。和你的情况正好相反,我需要手动加 msys2的环境路径(“C:/msys64/mingw64/bin” 和"C:/msys64/usr/bin")到 exec-path中,或者加到用户环境变量中。
目前曲线一点的办法是使用 Treemacs
打开文件夹。