Windows下使用外部ls导致dired打不开中文目录

这个问题不知道是不是我个人电脑独有的 在这里描述一下问题 我使用的外部ls是msys2自带的ls.exe

(prefer-coding-system 'utf-8-unix)
(set-default-coding-systems 'utf-8-unix)
(setq ls-lisp-use-insert-directory-program t)

emacs -Q以后执行上面代码用dired导航到一个带有中文目录的目录 按回车进入这个中文目录 我这边的报错信息是

find-file-noselect: ~/.emacs.d/测试 is a directory

这是调用栈

Debugger entered--Lisp error: (error "~/.emacs.d/测试 is a directory")
  error("%s is a directory" "~/.emacs.d/测试")
  find-file-noselect("c:/Users/you/.emacs.d/测试" nil nil nil)
  find-file("c:/Users/you/.emacs.d/测试")
  dired--find-file(find-file "c:/Users/you/.emacs.d/测试")
  dired--find-possibly-alternative-file("c:/Users/you/.emacs.d/测试")
  dired-find-file()
  funcall-interactively(dired-find-file)
  command-execute(dired-find-file)

Emcas版本: GNU Emacs 31.1 (build 2, x86_64-w64-mingw32) of 2026-08-24

OS版本: Microsoft Windows [Version 10.0.19045.3803]

我目前的修复办法是

(when (and ls-lisp-use-insert-directory-program
           (eq system-type 'windows-nt))
  (define-advice insert-directory (:around (orig &rest args) my-w32-msys-ls)
    "Pass ANSI-codepage argv to `insert-directory-program', decode its UTF-8 output."
    (let ((file-name-coding-system (intern (format "cp%d" w32-ansi-code-page)))
          (coding-system-for-read 'utf-8))
      (apply orig args)))

  (define-advice write-region
      (:around (orig start end filename &optional append visit &rest args)
       my-w32-write-region)
    "Use the Windows ANSI filename encoding for empty-file creation."
    (let ((filename
           (if (and (eq visit 0)
                    (stringp filename)
                    (multibyte-string-p filename))
               (string-make-unibyte
                (encode-coding-string
                 filename
                 (intern (format "cp%d" w32-ansi-code-page))))
             filename)))
      (apply orig start end filename append visit args))))

有遇到过同样情况的朋友吗 不确定是不是bug 是编码问题还是什么的 这个修复方案是通过AI扫描源码 vibe出来的解决方案

用 Windows 这个就不该设成 t

真要用 lsw32-unicode-filenames 也得是 nil

或许吧 不过我意外发现在中文目录下调用dired-create-empty-file 不管是内置的ls还是外置的ls 都会报错

报错信息 dired-create-empty-file: Opening output file: No such file or directory, c:/Users/you/.emacs.d/测试/a.js Mark set

调用栈

Debugger entered--Lisp error: (file-missing "Opening output file" "No such file or directory" "c:/Users/you/.emacs.d/测试/a.js")
  make-empty-file("~/.emacs.d/测试/a.js" parents)
  dired-create-empty-file("~/.emacs.d/测试/a.js")
  funcall-interactively(dired-create-empty-file "~/.emacs.d/测试/a.js")
  command-execute(dired-create-empty-file record)
  execute-extended-command(nil "dired-create-empty-file" nil)
  funcall-interactively(execute-extended-command nil "dired-create-empty-file" nil)
  command-execute(execute-extended-command)

只在macos上遇见过,通过安装gnu ls解决:

(when (eq system-type 'darwin)
    (setq insert-directory-program "/opt/homebrew/bin/gls"))