Skip to content

Commit 4568c52

Browse files
committed
Implement correct behaviour for keyword and value in different lines inside stanza in cabal files
Add tests documenting the behaviour
1 parent d877dcd commit 4568c52

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completions.hs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,21 @@ getContext pos ls =
5858
kwContext <- getKeyWordContext pos ls m
5959
pure (Stanza s, kwContext)
6060
where
61-
lvlContext = findCurrentLevel (getPreviousLines pos ls)
61+
lvlContext = if pos ^. JL.character == 0 then TopLevel else findCurrentLevel (getPreviousLines pos ls)
6262

6363
-- | Takes a position, a list of lines (representing a file) and a map of keywords as keys
6464
-- and returns a keyword context if there is a keyword from the map before the current position
6565
-- in the given line list
6666
getKeyWordContext :: Position -> [T.Text] -> Map T.Text a -> Maybe KeyWordContext
6767
getKeyWordContext pos ls keywords = do
68-
case fmap T.stripStart lastNonEmptyLineM of
68+
case lastNonEmptyLineM of
6969
Nothing -> Just None
70-
Just lastLine -> do
71-
if not isCursorAtLineStart then
70+
Just lastLine' -> do
71+
let (whitespaces, lastLine) = T.span (== ' ') lastLine'
72+
let keywordIndentation = T.length whitespaces
73+
let cursorIndentation = fromIntegral (pos ^. JL.character)
74+
-- in order to be in a keyword context the cursor needs to be indented more than the keyword
75+
if cursorIndentation > keywordIndentation then
7276
-- if the last thing written was a keyword without a value
7377
case List.find (`T.isPrefixOf` lastLine) (Map.keys keywords) of
7478
Nothing -> Just None
@@ -80,7 +84,6 @@ getKeyWordContext pos ls keywords = do
8084
cur <- currentLineM
8185
List.find (not . T.null . T.stripEnd) $ cur : getPreviousLines pos ls
8286
currentLineM = ls Extra.!? (fromIntegral $ pos ^. JL.line)
83-
isCursorAtLineStart = 0 == pos ^. JL.character
8487

8588
-- | Takes info about the current cursor position and a set of possible keywords
8689
-- and creates completion suggestions that fit the current input from the given list

plugins/hls-cabal-plugin/test/Main.hs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ completionUnitTests = testGroup "Context Tests"
9797
testCase "Inside Stanza - no keyword" $ do
9898
-- on a file, where the library stanza has been defined
9999
-- but no keyword is defined afterwards, the stanza context should be recognized
100-
getContext (Position 3 0) libraryStanzaData @?= Just (Stanza "library", None),
100+
getContext (Position 3 2) libraryStanzaData @?= Just (Stanza "library", None),
101101
testCase "Inside Stanza - keyword, no value" $ do
102102
-- on a file, where the library stanza and a keyword
103103
-- has been defined, the keyword and stanza should be recognized
@@ -123,7 +123,21 @@ completionUnitTests = testGroup "Context Tests"
123123
-- if a keyword, other than the cabal version keyword has been written
124124
-- with no value, even with multiple lines in between we can still write the
125125
-- value corresponding to the keyword
126-
getContext (Position 5 4) topLevelData @?= Just (TopLevel, KeyWord "name:")
126+
getContext (Position 5 4) topLevelData @?= Just (TopLevel, KeyWord "name:"),
127+
testCase "Keyword inside stanza - cursor indented more than keyword in next line" $ do
128+
-- if a keyword, other than the cabal version keyword has been written
129+
-- in a stanza context with no value, then the value may be written in the next line,
130+
-- when the cursor is indented more than the keyword
131+
getContext (Position 5 8) libraryStanzaData @?= Just (Stanza "library", KeyWord "build-depends:"),
132+
testCase "Keyword inside stanza - cursor indented less than keyword in next line" $ do
133+
-- if a keyword, other than the cabal version keyword has been written
134+
-- in a stanza context with no value, then the value may not be written in the next line,
135+
-- when the cursor is indented less than the keyword
136+
getContext (Position 5 2) libraryStanzaData @?= Just (Stanza "library", None),
137+
testCase "Keyword inside stanza - cursor at start of next line" $ do
138+
-- in a stanza context with no value the value may not be written in the next line,
139+
-- when the cursor is not indented and we are in the toplevel context
140+
getContext (Position 5 0) libraryStanzaData @?= Just (TopLevel, None)
127141
]
128142

129143
-- ------------------------------------------------------------------------
@@ -251,7 +265,8 @@ libraryStanzaData =
251265
"name: simple-cabal",
252266
"library ",
253267
"",
254-
" build-depends: "
268+
" build-depends: ",
269+
" "
255270
]
256271

257272
topLevelData :: [Text.Text]

0 commit comments

Comments
 (0)