Thomas Nelson
Thomas Nelson

Reputation: 683

How can I make GHCI recognize working directory changes?

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

Answers (1)

Alpaca
Alpaca

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

Related Questions