Reputation: 683
I am experimenting with using ghci+Turtle as my interactive shell instead of bash. So far it's working pretty well!
But I'd really like Turtle's cd
function to change ghci's working directory, the way ghci command :cd
does.
Let's say I load ghci and turtle in /home
λ> 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:
.
λ>
So far so good: changing the directory with ghci's :cd
also changes Turtle's working directory.
But the other way is not true:
λ> cd "/home"
λ> pwd
FilePath "/home"
λ> :show paths
current working directory:
/tmp
module import search paths:
.
λ>
This means that if I change directories with Turtle, I can't use :load
or :script
or take advantage of ghci's tab completion.
I can just always use :cd
instead of cd
, but because :cd
is a ghci command, it can't be called from a function or composed in any way.
What would it take to make a cd
function that talks to ghci? I think I need to do something like
write my own wrapper cd
that that somehow changes the environment.
I'm not sure what that looks like, since I can't invoke :cd
in my cd
wrapper.
I'm guessing I need to use the ghc API? I can't find anything obvious.
EDIT: I found a similar problem exists when I try changing the ghci prompt with :set prompt-function. If you put the following in your ghci.conf:
:module + Turtle
:set prompt-function \libs n -> (\wd -> encodeString wd ++ "> ") <$> pwd
The prompt won't change working directories with cd
, but will with :cd
. Using something like :set prompt "%w > "
works the same way.
My best guess is that ghci keeps a completely separate filesystem module from the user-space module somehow. I may have to dig into ghci source to figure out what's going on.
It's not limited to Turtle, Filesystem.setWorkingDirectory
shows the same behavior as Turtle.cd
.
Upvotes: 2
Views: 338
Reputation: 707
I had a similar issue while developing shh. I've worked around this by providing a cd
function that sets PWD
as well as changing the directory, and using a prompt-function
which reads that variable.
Minimal example..
:set prompt-function \_ _ -> getEnv "PWD"
cd :: FilePath -> IO ()
cd p = do
setCurrentDirectory p
a <- getCurrentDirectory
setEnv "PWD" a
Upvotes: 1