-
-
Notifications
You must be signed in to change notification settings - Fork 396
Cabal plugin outline view #4323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
d49a000
working test message cabal file
VenInf 632f5a0
trivial outline with rule invocation
VenInf 3574165
outline with field lines
VenInf 965d61b
complete outline prototype
VenInf fd0b2ea
small improvements
VenInf a5e7e53
remove fieldLines, one line Section display
VenInf d616c54
stylish haskell
VenInf a953ecb
tests
VenInf d201493
imports changes
VenInf f4d57a5
outline tests changes
VenInf 526fac3
duplicate defDocumentSymbol
VenInf 9860ea3
cabal outline test imports change
VenInf a79be35
schema 96 94 update
VenInf a0642ef
schema 94 update
VenInf c867a29
94 schema update
VenInf aeca984
94 schema update
VenInf ae772a2
Merge branch 'master' into cabal-plugin-outline-view
VenInf f77dea5
+ cabal-add
VenInf 6f9fbcd
Revert "+ cabal-add"
VenInf 4735e7d
+ docs, refactoring
VenInf 000dcbe
Update plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Cabal…
fendor 851daef
Merge branch 'master' into cabal-plugin-outline-view
VenInf cb2fbf7
formatting
VenInf 050af38
newline
VenInf af4d8c8
Merge branch 'master' into cabal-plugin-outline-view
fendor File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
119 changes: 119 additions & 0 deletions
119
plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Outline.hs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
{-# LANGUAGE CPP #-} | ||
{-# LANGUAGE DataKinds #-} | ||
{-# LANGUAGE DuplicateRecordFields #-} | ||
{-# LANGUAGE GADTs #-} | ||
{-# LANGUAGE OverloadedStrings #-} | ||
{-# LANGUAGE ViewPatterns #-} | ||
|
||
module Ide.Plugin.Cabal.Outline where | ||
|
||
import Control.Monad.IO.Class | ||
import Data.Maybe | ||
import qualified Data.Text as T | ||
import Data.Text.Encoding (decodeUtf8) | ||
import Development.IDE.Core.Rules | ||
import Development.IDE.Core.Shake (IdeState (shakeExtras), | ||
runIdeAction, | ||
useWithStaleFast) | ||
import Development.IDE.Types.Location (toNormalizedFilePath') | ||
import Distribution.Fields.Field (Field (Field, Section), | ||
Name (Name)) | ||
import Distribution.Parsec.Position (Position) | ||
import Ide.Plugin.Cabal.Completion.CabalFields (onelineSectionArgs) | ||
import Ide.Plugin.Cabal.Completion.Types (ParseCabalFields (..), | ||
cabalPositionToLSPPosition) | ||
import Ide.Plugin.Cabal.Orphans () | ||
import Ide.Types (PluginMethodHandler) | ||
import Language.LSP.Protocol.Message (Method (..)) | ||
import Language.LSP.Protocol.Types (DocumentSymbol (..)) | ||
import qualified Language.LSP.Protocol.Types as LSP | ||
|
||
|
||
moduleOutline :: PluginMethodHandler IdeState Method_TextDocumentDocumentSymbol | ||
moduleOutline ideState _ LSP.DocumentSymbolParams {_textDocument = LSP.TextDocumentIdentifier uri} = | ||
case LSP.uriToFilePath uri of | ||
Just (toNormalizedFilePath' -> fp) -> do | ||
mFields <- liftIO $ runIdeAction "cabal-plugin.fields" (shakeExtras ideState) (useWithStaleFast ParseCabalFields fp) | ||
case fmap fst mFields of | ||
Just fieldPositions -> pure $ LSP.InR (LSP.InL allSymbols) | ||
where | ||
allSymbols = mapMaybe documentSymbolForField fieldPositions | ||
Nothing -> pure $ LSP.InL [] | ||
Nothing -> pure $ LSP.InL [] | ||
|
||
-- | Creates a @DocumentSymbol@ object for the | ||
-- cabal AST, without displaying @fieldLines@ and | ||
-- displaying @Section Name@ and @SectionArgs@ in one line. | ||
-- | ||
-- @fieldLines@ are leaves of a cabal AST, so they are omitted | ||
-- in the outline. Sections have to be displayed in one line, because | ||
-- the AST representation looks unnatural. See examples: | ||
-- | ||
-- * part of a cabal file: | ||
-- | ||
-- > if impl(ghc >= 9.8) | ||
-- > ghc-options: -Wall | ||
-- | ||
-- * AST representation: | ||
-- | ||
-- > if | ||
-- > impl | ||
-- > ( | ||
-- > ghc >= 9.8 | ||
-- > ) | ||
-- > | ||
-- > ghc-options: | ||
-- > -Wall | ||
-- | ||
-- * resulting @DocumentSymbol@: | ||
-- | ||
-- > if impl(ghc >= 9.8) | ||
-- > ghc-options: | ||
-- > | ||
documentSymbolForField :: Field Position -> Maybe DocumentSymbol | ||
documentSymbolForField (Field (Name pos fieldName) _) = | ||
Just | ||
(defDocumentSymbol range) | ||
{ _name = decodeUtf8 fieldName, | ||
_kind = LSP.SymbolKind_Field, | ||
_children = Nothing | ||
} | ||
where | ||
range = cabalPositionToLSPRange pos `addNameLengthToLSPRange` decodeUtf8 fieldName | ||
documentSymbolForField (Section (Name pos fieldName) sectionArgs fields) = | ||
Just | ||
(defDocumentSymbol range) | ||
{ _name = joinedName, | ||
_kind = LSP.SymbolKind_Object, | ||
_children = | ||
Just | ||
(mapMaybe documentSymbolForField fields) | ||
} | ||
where | ||
joinedName = decodeUtf8 fieldName <> " " <> onelineSectionArgs sectionArgs | ||
range = cabalPositionToLSPRange pos `addNameLengthToLSPRange` joinedName | ||
|
||
-- | Creates a single point LSP range | ||
-- using cabal position | ||
cabalPositionToLSPRange :: Position -> LSP.Range | ||
cabalPositionToLSPRange pos = LSP.Range lspPos lspPos | ||
where | ||
lspPos = cabalPositionToLSPPosition pos | ||
|
||
addNameLengthToLSPRange :: LSP.Range -> T.Text -> LSP.Range | ||
addNameLengthToLSPRange (LSP.Range pos1 (LSP.Position line char)) name = | ||
LSP.Range | ||
pos1 | ||
(LSP.Position line (char + fromIntegral (T.length name))) | ||
|
||
defDocumentSymbol :: LSP.Range -> DocumentSymbol | ||
defDocumentSymbol range = DocumentSymbol | ||
{ _detail = Nothing | ||
, _deprecated = Nothing | ||
, _name = "" | ||
, _kind = LSP.SymbolKind_File | ||
, _range = range | ||
, _selectionRange = range | ||
, _children = Nothing | ||
, _tags = Nothing | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
{-# LANGUAGE OverloadedStrings #-} | ||
|
||
module Outline ( | ||
outlineTests, | ||
) where | ||
|
||
import Language.LSP.Protocol.Types (DocumentSymbol (..), | ||
Position (..), Range (..)) | ||
import qualified Test.Hls as T | ||
import Utils | ||
|
||
testSymbols :: (T.HasCallStack) => T.TestName -> FilePath -> [DocumentSymbol] -> T.TestTree | ||
testSymbols testName path expectedSymbols = | ||
runCabalTestCaseSession testName "outline-cabal" $ do | ||
docId <- T.openDoc path "cabal" | ||
symbols <- T.getDocumentSymbols docId | ||
T.liftIO $ symbols T.@?= Right expectedSymbols | ||
|
||
outlineTests :: T.TestTree | ||
outlineTests = | ||
T.testGroup | ||
"Cabal Outline Tests" | ||
[ testSymbols | ||
"cabal Field outline test" | ||
"field.cabal" | ||
[fieldDocumentSymbol] | ||
, testSymbols | ||
"cabal FieldLine outline test" | ||
"fieldline.cabal" | ||
[fieldLineDocumentSymbol] | ||
, testSymbols | ||
"cabal Section outline test" | ||
"section.cabal" | ||
[sectionDocumentSymbol] | ||
, testSymbols | ||
"cabal SectionArg outline test" | ||
"sectionarg.cabal" | ||
[sectionArgDocumentSymbol] | ||
] | ||
where | ||
fieldDocumentSymbol :: DocumentSymbol | ||
fieldDocumentSymbol = | ||
( defDocumentSymbol | ||
( Range { _start = Position{_line = 0, _character = 0} | ||
, _end = Position{_line = 0, _character = 8} }) | ||
) | ||
{ _name = "homepage" | ||
, _kind = T.SymbolKind_Field | ||
, _children = Nothing | ||
} | ||
fieldLineDocumentSymbol :: DocumentSymbol | ||
fieldLineDocumentSymbol = | ||
( defDocumentSymbol | ||
( Range { _start = Position{_line = 0, _character = 0} | ||
, _end = Position{_line = 0, _character = 13} }) | ||
) | ||
{ _name = "cabal-version" | ||
, _kind = T.SymbolKind_Field | ||
, _children = Nothing -- the values of fieldLine are removed from the outline | ||
} | ||
sectionDocumentSymbol :: DocumentSymbol | ||
sectionDocumentSymbol = | ||
( defDocumentSymbol | ||
( Range { _start = Position{_line = 0, _character = 2} | ||
, _end = Position{_line = 0, _character = 15} }) | ||
) | ||
{ _name = "build-depends" | ||
, _kind = T.SymbolKind_Field | ||
, _children = Nothing -- the values of fieldLine are removed from the outline | ||
} | ||
sectionArgDocumentSymbol :: DocumentSymbol | ||
sectionArgDocumentSymbol = | ||
( defDocumentSymbol | ||
( Range { _start = Position{_line = 0, _character = 2} | ||
, _end = Position{_line = 0, _character = 19} }) | ||
) | ||
{ _name = "if os ( windows )" | ||
, _kind = T.SymbolKind_Object | ||
, _children = Just $ [sectionArgChildrenDocumentSymbol] | ||
} | ||
sectionArgChildrenDocumentSymbol :: DocumentSymbol | ||
sectionArgChildrenDocumentSymbol = | ||
( defDocumentSymbol | ||
( Range { _start = Position{_line = 1, _character = 4} | ||
, _end = Position{_line = 1, _character = 17} }) | ||
) | ||
{ _name = "build-depends" | ||
, _kind = T.SymbolKind_Field | ||
, _children = Nothing | ||
} | ||
|
||
defDocumentSymbol :: Range -> DocumentSymbol | ||
defDocumentSymbol range = | ||
DocumentSymbol | ||
{ _detail = Nothing | ||
, _deprecated = Nothing | ||
, _name = "" | ||
, _kind = T.SymbolKind_File | ||
, _range = range | ||
, _selectionRange = range | ||
, _children = Nothing | ||
, _tags = Nothing | ||
} |
1 change: 1 addition & 0 deletions
1
plugins/hls-cabal-plugin/test/testdata/outline-cabal/field.cabal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
homepage: |
1 change: 1 addition & 0 deletions
1
plugins/hls-cabal-plugin/test/testdata/outline-cabal/fieldline.cabal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
cabal-version: 3.0 |
2 changes: 2 additions & 0 deletions
2
plugins/hls-cabal-plugin/test/testdata/outline-cabal/section.cabal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
build-depends: | ||
base >=4.16 && <5 |
2 changes: 2 additions & 0 deletions
2
plugins/hls-cabal-plugin/test/testdata/outline-cabal/sectionarg.cabal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
if os(windows) | ||
build-depends: Win32 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.