Skip to content

Support PackageImports in hiddenPackageSuggestion #4537

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 2 commits into from
Apr 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/CabalAdd.hs
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also notice that the "not found" error remains even after the dependency is added by the code action (with and without PackageImports). That may be a bug of my lsp client (eglot on Emacs) or HLS. Needs further investigation.

Oh, it is indeed a known HLS bug. With HLS 2.10.0.0 and vscode 2.5.3, I need to manually restart HLS or saving hie.yaml after adding dependencies to .cabal file to let HLS find the newly added dependencies.

In addition, there seems to be a bug in my preferred setting: Emacs with eglot as a LSP client. In that setting, only manual restart works and saving hie.yaml has no effect.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that sounds correct!

Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ addDependencySuggestCodeAction plId verTxtDocId suggestions haskellFilePath caba
-- > It is a member of the hidden package ‘split-0.2.5’.
-- > Perhaps you need to add ‘split’ to the build-depends in your .cabal file."
--
-- or this if PackageImports extension is used:
--
-- > "Could not find module ‘Data.List.Split’
-- > Perhaps you meant
-- > Data.List.Split (needs flag -package-id split-0.2.5)"
--
-- It extracts mentioned package names and version numbers.
-- In this example, it will be @[("split", "0.2.5")]@
--
Expand All @@ -204,13 +210,18 @@ hiddenPackageSuggestion diag = getMatch (msg =~ regex)
msg :: T.Text
msg = _message diag
regex :: T.Text -- TODO: Support multiple packages suggestion
regex = "It is a member of the hidden package [\8216']([a-zA-Z0-9-]*[a-zA-Z0-9])(-([0-9\\.]*))?[\8217']"
regex =
let regex' = "([a-zA-Z0-9-]*[a-zA-Z0-9])(-([0-9\\.]*))?"
in "It is a member of the hidden package [\8216']" <> regex' <> "[\8217']"
<> "|"
<> "needs flag -package-id " <> regex'
-- Have to do this matching because `Regex.TDFA` doesn't(?) support
-- not-capturing groups like (?:message)
getMatch :: (T.Text, T.Text, T.Text, [T.Text]) -> [(T.Text, T.Text)]
getMatch (_, _, _, []) = []
getMatch (_, _, _, [dependency, _, cleanVersion]) = [(dependency, cleanVersion)]
getMatch (_, _, _, _) = error "Impossible pattern matching case"
getMatch (_, _, _, [dependency, _, cleanVersion, "", "", ""]) = [(dependency, cleanVersion)]
getMatch (_, _, _, ["", "", "", dependency, _, cleanVersion]) = [(dependency, cleanVersion)]
getMatch (_, _, _, _) = []

command :: Recorder (WithPriority Log) -> CommandFunction IdeState CabalAddCommandParams
command recorder state _ params@(CabalAddCommandParams {cabalPath = path, verTxtDocId = verTxtDocId, buildTarget = target, dependency = dep, version = mbVer}) = do
Expand Down
19 changes: 19 additions & 0 deletions plugins/hls-cabal-plugin/test/CabalAdd.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ cabalAddTests =
(generateAddDependencyTestSession "cabal-add-lib.cabal" ("src" </> "MyLib.hs") "split" [348])
, runHaskellTestCaseSession "Code Actions - Can add hidden package to a test" ("cabal-add-testdata" </> "cabal-add-tests")
(generateAddDependencyTestSession "cabal-add-tests.cabal" ("test" </> "Main.hs") "split" [478])
, runHaskellTestCaseSession "Code Actions - Can add hidden package to a test with PackageImports" ("cabal-add-testdata" </> "cabal-add-tests")
(generateAddDependencyTestSession "cabal-add-tests.cabal" ("test" </> "MainPackageImports.hs") "split" [731])
, runHaskellTestCaseSession "Code Actions - Can add hidden package to a benchmark" ("cabal-add-testdata" </> "cabal-add-bench")
(generateAddDependencyTestSession "cabal-add-bench.cabal" ("bench" </> "Main.hs") "split" [403])

Expand Down Expand Up @@ -122,6 +124,23 @@ cabalAddTests =
[ ("3d-graphics-examples", T.empty)
, ("3d-graphics-examples", "1.1.6")
]
, testHiddenPackageSuggestions "Check CabalAdd's parser, with version, with PackageImports"
[ "(needs flag -package-id base-0.1.0.0)"
, "(needs flag -package-id Blammo-wai-0.11.0)"
, "(needs flag -package-id BlastHTTP-2.6.4.3)"
, "(needs flag -package-id CC-delcont-ref-tf-0.0.0.2)"
, "(needs flag -package-id 3d-graphics-examples-1.1.6)"
, "(needs flag -package-id AAI-0.1)"
, "(needs flag -package-id AWin32Console-1.19.1)"
]
[ ("base","0.1.0.0")
, ("Blammo-wai", "0.11.0")
, ("BlastHTTP", "2.6.4.3")
, ("CC-delcont-ref-tf", "0.0.0.2")
, ("3d-graphics-examples", "1.1.6")
, ("AAI", "0.1")
, ("AWin32Console", "1.19.1")
]
]
where
generateAddDependencyTestSession :: FilePath -> FilePath -> T.Text -> [Int] -> Session ()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,11 @@ test-suite cabal-add-tests-test
hs-source-dirs: test
main-is: Main.hs
build-depends: base

test-suite cabal-add-tests-test-package-imports
import: warnings
default-language: Haskell2010
type: exitcode-stdio-1.0
hs-source-dirs: test
main-is: MainPackageImports.hs
build-depends: base
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{-# LANGUAGE PackageImports #-}

module Main (main) where

import "split" Data.List.Split

main :: IO ()
main = putStrLn "Test suite not yet implemented."
Loading