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
21import Control.DeepSeq (NFData (..))
22import Data.Aeson.Types (FromJSON, FromJSONKey, ToJSON, ToJSONKey)
23import Data.Binary (Binary)
25import Data.Text.Prettyprint.Doc.Syntax
28------------------------------------------------------------------------------
30------------------------------------------------------------------------------
32-- | Position in a text document expressed as zero-based line and
34data Position = Position
35 { positionLine :: {-# UNPACK #-} !Int
36 -- ^ Zero-based line position in the document.
37 , positionCharacter :: {-# UNPACK #-} !Int
38 -- ^ Zero-based character offset on the line.
39 } deriving (Eq, Ord, Read, Show, Generic, Data)
41instance NFData Position
43instance Pretty Position where
45 pretty (positionLine pos + 1) <> colon <> pretty (positionCharacter pos + 1)
48-- | A range in a text document expressed as inclusive start-position and an
49-- exclusive end-position.
51 { rangeStart :: {-# UNPACK #-} !Position
52 -- ^ The start position of the range, which is considered to be part of
54 , rangeEnd :: {-# UNPACK #-} !Position
55 -- ^ The end position of the range, which is not considered to be part
57 } deriving (Eq, Ord, Read, Show, Generic, Data)
61instance Pretty Range where
63 pretty (rangeStart range) <> "-" <> pretty (rangeEnd range)
66-- | Represents a location inside a resource, such as a line inside a text file.
67data Location = Location
68 { lFilePath :: !FilePath
69 -- ^ The uri of the document.
71 -- ^ The range within the document.
72 } deriving (Eq, Ord, Read, Show, Generic, Data)
74instance NFData Location
77-- | A dummy location to use when location information is missing.
80 { lFilePath = "<unknown>"
84-- A dummy range to use when range is unknown
86noRange = Range (Position 0 0) (Position 100000 0)
89-- | A dummy location to use when location information is not present because
90-- the code was generated.
91genLocation :: Location
93 { lFilePath = "<generated>"
94 , lRange = Range (Position 0 0) (Position 0 0)
98-- | Is a location generated.
99isGenLocation :: Location -> Bool
100isGenLocation x = lFilePath x == "<generated>"
103-- | Check if a position is inside a range.
104-- Our definition states that the start of the range is included, but not the end.
105inRange :: Position -> Range -> Bool
106inRange pos (Range start end) = start <= pos && pos < end
109-- | Check if a position is inside a range, including the end.
110-- Both start and end of the range are included.
111inRangeClosed :: Position -> Range -> Bool
112inRangeClosed pos (Range start end) = start <= pos && pos <= end
115-- | Produce a new range where the minimum position is the min of both,
116-- and the maximum position is the max of both.
117appendRange :: Range -> Range -> Range
119 = Range { rangeStart = min (rangeStart r1) (rangeStart r2)
120 , rangeEnd = max (rangeEnd r1) (rangeEnd r2) }
123-- | Produce a new location where the ranges are the appended and we choose
124-- the file path of the second.
125appendLocation :: Location -> Location -> Location
127 = Location { lFilePath = lFilePath l2
128 , lRange = appendRange (lRange l1) (lRange l2) }
130instance ToJSON Position
131instance FromJSON Position
132instance ToJSONKey Position
133instance FromJSONKey Position
134instance Binary Position
137instance FromJSON Range
140instance ToJSON Location
141instance FromJSON Location
142instance Binary Location
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