on 0336e41 help sign in
89 lines 2.9 kB history raw
1-- Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2-- SPDX-License-Identifier: Apache-2.0
4{-# LANGUAGE OverloadedStrings #-}
6-- | Types and functions for working with source code locations.
7module Development.IDE.Types.Location
8 ( Location(..)
9 , noFilePath
10 , noRange
11 , Position(..)
12 , showPosition
13 , Range(..)
14 , Uri(..)
15 , NormalizedUri
16 , LSP.toNormalizedUri
17 , LSP.fromNormalizedUri
18 , NormalizedFilePath
19 , fromUri
20 , toNormalizedFilePath
21 , fromNormalizedFilePath
22 , filePathToUri
23 , filePathToUri'
24 , uriToFilePath'
25 ) where
27import Language.Haskell.LSP.Types (Location(..), Range(..), Position(..))
28import Control.DeepSeq
29import Data.Maybe as Maybe
30import Data.Hashable
31import Data.String
32import System.FilePath
33import qualified Language.Haskell.LSP.Types as LSP
34import Language.Haskell.LSP.Types as LSP (
35 filePathToUri
36 , NormalizedUri(..)
37 , Uri(..)
38 , toNormalizedUri
39 , fromNormalizedUri
40 )
43-- | Newtype wrapper around FilePath that always has normalized slashes.
44newtype NormalizedFilePath = NormalizedFilePath FilePath
45 deriving (Eq, Ord, Show, Hashable, NFData)
47instance IsString NormalizedFilePath where
48 fromString = toNormalizedFilePath
50toNormalizedFilePath :: FilePath -> NormalizedFilePath
51toNormalizedFilePath "" = NormalizedFilePath ""
52toNormalizedFilePath fp = NormalizedFilePath $ normalise' fp
53 where
54 -- We do not use System.FilePath’s normalise here since that
55 -- also normalises things like the case of the drive letter
56 -- which NormalizedUri does not normalise so we get VFS lookup failures.
57 normalise' :: FilePath -> FilePath
58 normalise' = map (\c -> if isPathSeparator c then pathSeparator else c)
60fromNormalizedFilePath :: NormalizedFilePath -> FilePath
61fromNormalizedFilePath (NormalizedFilePath fp) = fp
63-- | We use an empty string as a filepath when we don’t have a file.
64-- However, haskell-lsp doesn’t support that in uriToFilePath and given
65-- that it is not a valid filepath it does not make sense to upstream a fix.
66-- So we have our own wrapper here that supports empty filepaths.
67uriToFilePath' :: Uri -> Maybe FilePath
68uriToFilePath' uri
69 | uri == filePathToUri "" = Just ""
70 | otherwise = LSP.uriToFilePath uri
72filePathToUri' :: NormalizedFilePath -> NormalizedUri
73filePathToUri' = toNormalizedUri . filePathToUri . fromNormalizedFilePath
76fromUri :: LSP.NormalizedUri -> NormalizedFilePath
77fromUri = toNormalizedFilePath . fromMaybe noFilePath . uriToFilePath' . fromNormalizedUri
80noFilePath :: FilePath
81noFilePath = "<unknown>"
83-- A dummy range to use when range is unknown
84noRange :: Range
85noRange = Range (Position 0 0) (Position 100000 0)
88showPosition :: Position -> String
89showPosition Position{..} = show (_line + 1) ++ ":" ++ show (_character + 1)