@@ -88,9 +88,7 @@ getFoldingRanges :: NormalizedFilePath -> ExceptT String IdeAction [FoldingRange
88
88
getFoldingRanges file = do
89
89
(codeRange, _) <- maybeToExceptT " fail to get code range" $ useE GetCodeRange file
90
90
91
- let foldingRanges = findFoldingRanges codeRange
92
-
93
- maybeToExceptT " Fail to generate folding range" (MaybeT . pure $ Just foldingRanges)
91
+ pure $ findFoldingRanges codeRange
94
92
95
93
selectionRangeHandler :: IdeState -> PluginId -> SelectionRangeParams -> LspM c (Either ResponseError (List SelectionRange ))
96
94
selectionRangeHandler ide _ SelectionRangeParams {.. } = do
@@ -150,32 +148,59 @@ findPosition pos root = go Nothing root
150
148
startOfRight <- _start . _codeRange_range <$> V. headM right
151
149
if pos < startOfRight then binarySearchPos left else binarySearchPos right
152
150
153
- -- | Traverses through the code range and children to a folding ranges
151
+ -- | Traverses through the code range and it children to a folding ranges.
152
+ --
153
+ -- It starts with the root node, converts that into a folding range then moves towards the children.
154
+ -- It converts each child of each root node and parses it to folding range and moves to its children.
154
155
findFoldingRanges :: CodeRange -> [FoldingRange ]
155
156
findFoldingRanges r@ (CodeRange _ children _) =
156
- let frRoot :: [FoldingRange ] = case createFoldingRange r of
157
- Just x -> [x]
157
+ let frChildren :: [FoldingRange ] = concat $ V. toList $ fmap findFoldingRanges children
158
+ in case createFoldingRange r of
159
+ Just x -> x: frChildren
158
160
Nothing -> []
159
161
160
- frChildren :: [FoldingRange ] = concat $ V. toList $ fmap findFoldingRanges children
161
- in frRoot ++ frChildren
162
-
163
162
-- | Parses code range to folding range
164
163
createFoldingRange :: CodeRange -> Maybe FoldingRange
165
164
createFoldingRange (CodeRange (Range (Position lineStart charStart) (Position lineEnd charEnd)) _ ck) = do
165
+ -- Type conversion of codeRangeKind to FoldingRangeKind
166
166
let frk = crkToFrk ck
167
+
168
+ -- Filtering code ranges that start and end on the same line as need/can not be folded.
169
+ --
170
+ -- Eg. A single line function will also generate a Folding Range but it cannot be folded
171
+ -- because it is already single line, so omiting it.
167
172
if lineStart == lineEnd
168
173
then Nothing
169
174
else case frk of
170
175
Just _ -> Just (FoldingRange lineStart (Just charStart) lineEnd (Just charEnd) frk)
171
176
Nothing -> Nothing
172
177
173
- -- Removes all small foldings that start from the same line
178
+ -- | Removes all small foldings that start from the same line.
179
+ --
180
+ -- As we are converting nodes of the ast into folding ranges, there are multiple nodes starting from a single line.
181
+ -- A single line of code doesn't mean a single node in AST, so this function removes all the nodes that have a duplicate
182
+ -- start line, ie. they start from the same line.
183
+ --
184
+ -- This function preserves the largest folding range from the ranges that start from the same line.
185
+ --
186
+ -- Eg. A multi-line function that also has a multi-line if statement starting from the same line should have the folding
187
+ -- according to the function.
188
+ --
189
+ -- This is done by breaking the [FoldingRange] into parts -->
190
+ -- frx: Head
191
+ -- xs: rest of the array
192
+ -- fry(not shown as it is not used): head of xs
193
+ -- xs2: rest of the array other than the first two elements
194
+ -- slx and sly: start line of frx and fry
195
+ --
196
+ -- We compare the start line of the first two elements in the array and if the start line is the same we remove the
197
+ -- second one as it is the smaller one amoung the two.
198
+ -- otherwise frx is returned and the function runs recursively on xs.
174
199
removeDupStartLineFoldings :: [FoldingRange ] -> [FoldingRange ]
175
200
removeDupStartLineFoldings [] = []
176
201
removeDupStartLineFoldings [x] = [x]
177
- removeDupStartLineFoldings (frx@ (FoldingRange x _ _ _ _): xs@ ((FoldingRange y _ _ _ _): xs2))
178
- | x == y = removeDupStartLineFoldings (frx: xs2)
202
+ removeDupStartLineFoldings (frx@ (FoldingRange slx _ _ _ _): xs@ ((FoldingRange sly _ _ _ _): xs2))
203
+ | slx == sly = removeDupStartLineFoldings (frx: xs2)
179
204
| otherwise = frx : removeDupStartLineFoldings xs
180
205
181
206
-- | Likes 'toCurrentPosition', but works on 'SelectionRange'
0 commit comments