From 0d78ee4096df893de1b6caff684dca4aaed5d2ef Mon Sep 17 00:00:00 2001 From: Nikolay Yakimov Date: Mon, 17 Aug 2015 08:43:34 +0300 Subject: [PATCH] getCanonicalFileNameSafe is now best-effort canonicalizatoin Canonicalizes longest init of path possible, and appends rest verbatim --- Language/Haskell/GhcMod/Utils.hs | 14 ++++++++------ src/GHCMod.hs | 6 +++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Language/Haskell/GhcMod/Utils.hs b/Language/Haskell/GhcMod/Utils.hs index b675c06..377a7e7 100644 --- a/Language/Haskell/GhcMod/Utils.hs +++ b/Language/Haskell/GhcMod/Utils.hs @@ -27,6 +27,9 @@ import Control.Applicative import Data.Char import qualified Data.Map as M import Data.Maybe (fromMaybe) +import Data.Either (rights) +import Data.List (inits) +import System.FilePath (joinPath, splitPath) import Exception import Language.Haskell.GhcMod.Error import Language.Haskell.GhcMod.Types @@ -170,12 +173,11 @@ withMappedFile file action = getCanonicalFileNameSafe file >>= lookupMMappedFile getCanonicalFileNameSafe :: (IOish m, GmEnv m) => FilePath -> m FilePath getCanonicalFileNameSafe fn = do - crdl <- cradle - let ccfn = cradleRootDir crdl fn - fex <- liftIO $ doesFileExist ccfn - if fex - then liftIO $ canonicalizePath ccfn - else return ccfn + pl <- liftIO $ rights <$> (mapM ((try :: IO FilePath -> IO (Either SomeException FilePath)) . canonicalizePath . joinPath) $ reverse $ inits $ splitPath fn) + return $ + if (length pl > 0) + then joinPath $ (head pl):(drop (length pl - 1) (splitPath fn)) + else error "Current dir doesn't seem to exist?" mkRevRedirMapFunc :: (Functor m, GmState m, GmEnv m) => m (FilePath -> FilePath) mkRevRedirMapFunc = do diff --git a/src/GHCMod.hs b/src/GHCMod.hs index 44a6e30..eb57ed1 100644 --- a/src/GHCMod.hs +++ b/src/GHCMod.hs @@ -277,20 +277,20 @@ File map docs: CLI options: * `--map-file "file1.hs=file2.hs"` can be used to tell ghc-mod that it should take source code for `file1.hs` from `file2.hs`. - `file1.hs` can be either full path, or path relative to project root. + `file1.hs` can be either full path, or path relative to current directory. `file2.hs` has to be either relative to current directory, or full path (preferred). * `--map-file "file.hs"` can be used to tell ghc-mod that it should take source code for `file.hs` from stdin. File end marker is `\EOT\n`, i.e. `\x04\x0A`. `file.hs` may or may not exist, and should be - either full path, or relative to project root. + either full path, or relative to current directory. Interactive commands: * `map-file file.hs` -- tells ghc-modi to read `file.hs` source from stdin. Works the same as second form of `--map-file` CLI option. * `unmap-file file.hs` -- unloads previously mapped file, so that it's no longer mapped. `file.hs` can be full path or relative to - project root, either will work. + current directory, either will work. Exposed functions: * `loadMappedFile :: FilePath -> FilePath -> GhcModT m ()` -- maps `FilePath`,