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
17 , LSP.fromNormalizedUri
20 , toNormalizedFilePath
21 , fromNormalizedFilePath
27import Language.Haskell.LSP.Types (Location(..), Range(..), Position(..))
29import Data.Maybe as Maybe
33import System.Info.Extra
34import qualified Language.Haskell.LSP.Types as LSP
35import Language.Haskell.LSP.Types as LSP (
44-- | Newtype wrapper around FilePath that always has normalized slashes.
45newtype NormalizedFilePath = NormalizedFilePath FilePath
46 deriving (Eq, Ord, Show, Hashable, NFData)
48instance IsString NormalizedFilePath where
49 fromString = toNormalizedFilePath
51toNormalizedFilePath :: FilePath -> NormalizedFilePath
52toNormalizedFilePath "" = NormalizedFilePath ""
53toNormalizedFilePath fp = NormalizedFilePath $ normalise' fp
55 -- We do not use System.FilePath’s normalise here since that
56 -- also normalises things like the case of the drive letter
57 -- which NormalizedUri does not normalise so we get VFS lookup failures.
58 normalise' :: FilePath -> FilePath
59 normalise' = oneSlash . map (\c -> if isPathSeparator c then pathSeparator else c)
61 -- Allow double slashes as the very first element of the path for UNC drives on Windows
62 -- otherwise turn adjacent slashes into one. These slashes often arise from dodgy CPP
63 oneSlash :: FilePath -> FilePath
64 oneSlash (x:xs) | isWindows = x : f xs
67 f (x:y:xs) | isPathSeparator x, isPathSeparator y = f (x:xs)
72fromNormalizedFilePath :: NormalizedFilePath -> FilePath
73fromNormalizedFilePath (NormalizedFilePath fp) = fp
75-- | We use an empty string as a filepath when we don’t have a file.
76-- However, haskell-lsp doesn’t support that in uriToFilePath and given
77-- that it is not a valid filepath it does not make sense to upstream a fix.
78-- So we have our own wrapper here that supports empty filepaths.
79uriToFilePath' :: Uri -> Maybe FilePath
81 | uri == filePathToUri "" = Just ""
82 | otherwise = LSP.uriToFilePath uri
84filePathToUri' :: NormalizedFilePath -> NormalizedUri
85filePathToUri' = toNormalizedUri . filePathToUri . fromNormalizedFilePath
88fromUri :: LSP.NormalizedUri -> NormalizedFilePath
89fromUri = toNormalizedFilePath . fromMaybe noFilePath . uriToFilePath' . fromNormalizedUri
93noFilePath = "<unknown>"
95-- A dummy range to use when range is unknown
97noRange = Range (Position 0 0) (Position 100000 0)
100showPosition :: Position -> String
101showPosition Position{..} = show (_line + 1) ++ ":" ++ show (_character + 1)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list