我正在尝试使用ghci + Turtle作为我的交互式shell而不是bash。到目前为止它工作得很好!但我真的很喜欢Turtle的cd
函数来改变ghci的工作目录,就像ghci命令:cd
那样。
假设我在/home
中加载ghci和turtle
λ> pwd
FilePath "/home"
λ> :show paths
current working directory:
/home
module import search paths:
.
λ> :cd /tmp/
λ> pwd
FilePath "/tmp"
λ> :show paths
current working directory:
/tmp
module import search paths:
.
λ>
到目前为止一切顺利:使用ghci的:cd
更改目录也会改变Turtle的工作目录。但另一种方式并非如此:
λ> cd "/home"
λ> pwd
FilePath "/home"
λ> :show paths
current working directory:
/tmp
module import search paths:
.
λ>
这意味着如果我用Turtle更改目录,我不能使用:load
或:script
或利用ghci的选项卡完成。我总是可以使用:cd
而不是cd
,但因为:cd
是一个ghci命令,所以它不能从函数调用或以任何方式编写。
如何制作与ghci对话的cd
功能呢?我想我需要做一些像写我自己的包装器cd
那样以某种方式改变环境。我不确定那是什么样的,因为我无法在我的:cd
包装中调用cd
。我猜我需要使用ghc API?我找不到任何明显的东西。
编辑:当我尝试用:set prompt-function更改ghci提示时,我发现存在类似的问题。如果你把以下内容放在你的ghci.conf中:
:module + Turtle
:set prompt-function \libs n -> (\wd -> encodeString wd ++ "> ") <$> pwd
提示不会改变使用cd
的工作目录,但会使用:cd
。使用像:set prompt "%w > "
这样的东西也是一样的。我最好的猜测是ghci以某种方式与用户空间模块保持完全独立的文件系统模块。我可能不得不深入研究ghci来源以找出正在发生的事情。
它不仅限于Turtle,Filesystem.setWorkingDirectory
表现出与Turtle.cd
相同的行为。
在开发时我有类似的问题。我通过提供cd
函数设置PWD
以及更改目录,并使用读取该变量的prompt-function
来解决这个问题。
最小的例子..
:set prompt-function \_ _ -> getEnv "PWD"
cd :: FilePath -> IO ()
cd p = do
setCurrentDirectory p
a <- getCurrentDirectory
setEnv "PWD" a