你做错了什么
您应该知道这*pathname-encoding*
是一个SYMBOL-MACRO,而不是一个变量。正如CLISP手册中的注释所说,
提醒:您必须对SYMBOL-MACRO使用EXT:LEETF/EXT:LETF*;
LET/LET*将不起作用!
所以,你需要做的是
(ext:letf ((*pathname-encoding* charset:utf-8)) ...)
(无论如何都会忽略line-terminator
模式*pathname-encoding*
)。
例子
$ touch 'идиотский файл'
$ ls
идиотский файл
$ LANG=C ls
?????????????????? ????????
$ LANG=C clisp -q -norc
> *pathname-encoding*
#<ENCODING CHARSET:ASCII :UNIX>
> *default-file-encoding*
#<ENCODING CHARSET:ASCII :UNIX>
> *terminal-encoding*
#<ENCODING CHARSET:ASCII :UNIX>
> (letf ((*pathname-encoding* charset:utf-8))
(with-open-file (o "foo" :direction :output :external-format charset:utf-8)
(format o "~A~%" (directory "*"))))
NIL
> (quit)
$ cat foo
(/home/sds/tmp/z/идиотский файл /home/sds/tmp/z/foo)
调试您的特定问题
在任何情况下,CLISP 都不会打印或返回?
它无法处理的字符 - 它会发出错误信号(尝试省略其中一个编码规范,您将得到一个错误Invalid byte #xD0 in CHARSET:ASCII conversion
- fromwrite
或 from directory
)。
因此问题出在边界上:
- 要么操作系统给出 CLISP 问号而不是 unicode(因为它认为 CLISP 无法处理 i18n)
- 或者 CLISP 生成的文件被低级 OS 层错误地保存
- 或者您用于查看文件的工具无法显示 unicode 字符
(只有最后一个选项似乎是合理的)。
你可以做的是:
- 从删除编码规范开始 - 你得到转换错误吗?检查默认的编码位置
*pathname-encoding*
(对于像&c这样的符号宏来说,这是花哨的 Lisp 词)
- 确保
*pathname-encoding*
是utf-8
并尝试类似的东西(coerce (pathname-name (car (directory "*"))) 'list)
- 在我上面的例子中我看到了(#\CYRILLIC_SMALL_LETTER_I ...)
;您是否像我一样看到 unicode 字符,或者您看到了#\?
吗?
- 试试
cygwin
( ls
, ls | od
, ls > foo; cat foo | od
) 看看它是否可以捕获非 ASCII 字符。