Skip to content

Commit 49b4587

Browse files
committed
Merge branch 'master' into cabal-hover-documentation
2 parents d725541 + 9cc8c62 commit 49b4587

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1308
-27
lines changed

.github/actions/setup-build/action.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ runs:
3131
sudo chown -R $USER /usr/local/.ghcup
3232
shell: bash
3333

34-
- uses: haskell-actions/[email protected].5
34+
- uses: haskell-actions/[email protected].6
3535
id: HaskEnvSetup
3636
with:
3737
ghc-version : ${{ inputs.ghc }}
@@ -116,3 +116,18 @@ runs:
116116
- name: "Remove freeze file"
117117
run: rm -f cabal.project.freeze
118118
shell: bash
119+
120+
# Make sure to clear all unneeded `ghcup`` caches.
121+
# At some point, we were running out of disk space, see issue
122+
# https://github.com/haskell/haskell-language-server/issues/4386 for details.
123+
#
124+
# Using "printf" debugging (`du -sh *` and `df -h /`) and binary searching,
125+
# we figured out that `ghcup` caches are taking up a sizable portion of the
126+
# disk space.
127+
# Thus, we remove anything we don't need, especially caches and temporary files.
128+
# For got measure, we also make sure no other tooling versions are
129+
# installed besides the ones we explicitly want.
130+
- name: "Remove ghcup caches"
131+
if: runner.os == 'Linux'
132+
run: ghcup gc --ghc-old --share-dir --hls-no-ghc --cache --tmpdirs --unset
133+
shell: bash

.github/workflows/bench.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ jobs:
127127
example: ['cabal', 'lsp-types']
128128

129129
steps:
130-
- uses: haskell-actions/[email protected].3
130+
- uses: haskell-actions/[email protected].6
131131
with:
132132
ghc-version : ${{ matrix.ghc }}
133133
cabal-version: ${{ matrix.cabal }}

cabal.project

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ packages:
77
./hls-plugin-api
88
./hls-test-utils
99

10+
-- Only keep this until https://github.com/Bodigrim/cabal-add/issues/7
11+
-- is resolved
12+
source-repository-package
13+
type: git
14+
location: https://github.com/Bodigrim/cabal-add.git
15+
tag: 8c004e2a4329232f9824425f5472b2d6d7958bbd
16+
1017
index-state: 2024-06-29T00:00:00Z
1118

1219
tests: True

exe/Wrapper.hs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ module Main where
99

1010
import Control.Monad.Extra
1111
import Data.Default
12-
import Data.Either.Extra (eitherToMaybe)
1312
import Data.Foldable
1413
import Data.List
1514
import Data.List.Extra (trimEnd)
@@ -76,8 +75,11 @@ main = do
7675
putStrLn $ showProgramVersionOfInterest programsOfInterest
7776
putStrLn "Tool versions in your project"
7877
cradle <- findProjectCradle' recorder False
79-
ghcVersion <- runExceptT $ getRuntimeGhcVersion' cradle
80-
putStrLn $ showProgramVersion "ghc" $ mkVersion =<< eitherToMaybe ghcVersion
78+
runExceptT (getRuntimeGhcVersion' cradle) >>= \case
79+
Left err ->
80+
T.hPutStrLn stderr (prettyError err NoShorten)
81+
Right ghcVersion ->
82+
putStrLn $ showProgramVersion "ghc" $ mkVersion ghcVersion
8183

8284
VersionMode PrintVersion ->
8385
putStrLn hlsVer

haskell-language-server.cabal

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,10 @@ library hls-cabal-plugin
242242
Ide.Plugin.Cabal.Completion.Completions
243243
Ide.Plugin.Cabal.Completion.Data
244244
Ide.Plugin.Cabal.Completion.Types
245+
Ide.Plugin.Cabal.Definition
245246
Ide.Plugin.Cabal.FieldSuggest
246247
Ide.Plugin.Cabal.LicenseSuggest
248+
Ide.Plugin.Cabal.CabalAdd
247249
Ide.Plugin.Cabal.Orphans
248250
Ide.Plugin.Cabal.Outline
249251
Ide.Plugin.Cabal.Parse
@@ -270,6 +272,12 @@ library hls-cabal-plugin
270272
, transformers
271273
, unordered-containers >=0.2.10.0
272274
, containers
275+
, cabal-add
276+
, process
277+
, aeson
278+
, Cabal
279+
, pretty
280+
273281
hs-source-dirs: plugins/hls-cabal-plugin/src
274282

275283
test-suite hls-cabal-plugin-tests
@@ -280,10 +288,12 @@ test-suite hls-cabal-plugin-tests
280288
hs-source-dirs: plugins/hls-cabal-plugin/test
281289
main-is: Main.hs
282290
other-modules:
291+
CabalAdd
283292
Completer
284293
Context
285-
Utils
294+
Definition
286295
Outline
296+
Utils
287297
build-depends:
288298
, base
289299
, bytestring
@@ -296,6 +306,7 @@ test-suite hls-cabal-plugin-tests
296306
, lens
297307
, lsp-types
298308
, text
309+
, hls-plugin-api
299310

300311
-----------------------------
301312
-- class plugin

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

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
{-# LANGUAGE OverloadedStrings #-}
55
{-# LANGUAGE TypeFamilies #-}
66

7-
module Ide.Plugin.Cabal (descriptor, Log (..)) where
7+
module Ide.Plugin.Cabal (descriptor, haskellInteractionDescriptor, Log (..)) where
88

99
import Control.Concurrent.Strict
1010
import Control.DeepSeq
@@ -54,6 +54,35 @@ import Ide.Plugin.Cabal.Orphans ()
5454
import Ide.Plugin.Cabal.Outline
5555
import qualified Ide.Plugin.Cabal.Parse as Parse
5656
import Ide.Plugin.Error
57+
import Data.HashMap.Strict (HashMap)
58+
import qualified Data.HashMap.Strict as HashMap
59+
import qualified Data.List.NonEmpty as NE
60+
import qualified Data.Maybe as Maybe
61+
import qualified Data.Text as T
62+
import qualified Data.Text.Encoding as Encoding
63+
import Data.Typeable
64+
import Development.IDE as D
65+
import Development.IDE.Core.Shake (restartShakeSession)
66+
import qualified Development.IDE.Core.Shake as Shake
67+
import Development.IDE.Graph (Key, alwaysRerun)
68+
import qualified Development.IDE.Plugin.Completions.Logic as Ghcide
69+
import Development.IDE.Types.Shake (toKey)
70+
import qualified Distribution.Fields as Syntax
71+
import qualified Distribution.Parsec.Position as Syntax
72+
import GHC.Generics
73+
import qualified Ide.Plugin.Cabal.Completion.Completer.Types as CompleterTypes
74+
import qualified Ide.Plugin.Cabal.Completion.Completions as Completions
75+
import Ide.Plugin.Cabal.Completion.Types (ParseCabalCommonSections (ParseCabalCommonSections),
76+
ParseCabalFields (..),
77+
ParseCabalFile (..))
78+
import qualified Ide.Plugin.Cabal.Completion.Types as Types
79+
import Ide.Plugin.Cabal.Definition (gotoDefinition)
80+
import qualified Ide.Plugin.Cabal.Diagnostics as Diagnostics
81+
import qualified Ide.Plugin.Cabal.FieldSuggest as FieldSuggest
82+
import qualified Ide.Plugin.Cabal.LicenseSuggest as LicenseSuggest
83+
import Ide.Plugin.Cabal.Orphans ()
84+
import Ide.Plugin.Cabal.Outline
85+
import qualified Ide.Plugin.Cabal.Parse as Parse
5786
import Ide.Types
5887
import qualified Language.LSP.Protocol.Lens as JL
5988
import qualified Language.LSP.Protocol.Message as LSP
@@ -62,6 +91,9 @@ import qualified Language.LSP.VFS as VFS
6291
import Text.Regex.TDFA
6392

6493

94+
import qualified Data.Text ()
95+
import qualified Ide.Plugin.Cabal.CabalAdd as CabalAdd
96+
6597
data Log
6698
= LogModificationTime NormalizedFilePath FileVersion
6799
| LogShake Shake.Log
@@ -72,6 +104,7 @@ data Log
72104
| LogFOI (HashMap NormalizedFilePath FileOfInterestStatus)
73105
| LogCompletionContext Types.Context Position
74106
| LogCompletions Types.Log
107+
| LogCabalAdd CabalAdd.Log
75108
deriving (Show)
76109

77110
instance Pretty Log where
@@ -95,6 +128,25 @@ instance Pretty Log where
95128
<+> "for cursor position:"
96129
<+> pretty position
97130
LogCompletions logs -> pretty logs
131+
LogCabalAdd logs -> pretty logs
132+
133+
-- | Some actions with cabal files originate from haskell files.
134+
-- This descriptor allows to hook into the diagnostics of haskell source files, and
135+
-- allows us to provide code actions and commands that interact with `.cabal` files.
136+
haskellInteractionDescriptor :: Recorder (WithPriority Log) -> PluginId -> PluginDescriptor IdeState
137+
haskellInteractionDescriptor recorder plId =
138+
(defaultPluginDescriptor plId "Provides the cabal-add code action in haskell files")
139+
{ pluginHandlers =
140+
mconcat
141+
[ mkPluginHandler LSP.SMethod_TextDocumentCodeAction cabalAddCodeAction
142+
]
143+
, pluginCommands = [PluginCommand CabalAdd.cabalAddCommand "add a dependency to a cabal file" (CabalAdd.command cabalAddRecorder)]
144+
, pluginRules = pure ()
145+
, pluginNotificationHandlers = mempty
146+
}
147+
where
148+
cabalAddRecorder = cmapWithPrio LogCabalAdd recorder
149+
98150

99151
descriptor :: Recorder (WithPriority Log) -> PluginId -> PluginDescriptor IdeState
100152
descriptor recorder plId =
@@ -319,6 +371,32 @@ gotoDefinition ideState _ msgParam = do
319371
isSectionArgName name (Syntax.Section _ sectionArgName _) = name == CabalFields.onelineSectionArgs sectionArgName
320372
isSectionArgName _ _ = False
321373

374+
375+
cabalAddCodeAction :: PluginMethodHandler IdeState 'LSP.Method_TextDocumentCodeAction
376+
cabalAddCodeAction state plId (CodeActionParams _ _ (TextDocumentIdentifier uri) _ CodeActionContext{_diagnostics=diags}) = do
377+
maxCompls <- fmap maxCompletions . liftIO $ runAction "cabal.cabal-add" state getClientConfigAction
378+
let suggestions = take maxCompls $ concatMap CabalAdd.hiddenPackageSuggestion diags
379+
case suggestions of
380+
[] -> pure $ InL []
381+
_ ->
382+
case uriToFilePath uri of
383+
Nothing -> pure $ InL []
384+
Just haskellFilePath -> do
385+
mbCabalFile <- liftIO $ CabalAdd.findResponsibleCabalFile haskellFilePath
386+
case mbCabalFile of
387+
Nothing -> pure $ InL []
388+
Just cabalFilePath -> do
389+
verTxtDocId <- lift $ pluginGetVersionedTextDoc $ TextDocumentIdentifier (filePathToUri cabalFilePath)
390+
mbGPD <- liftIO $ runAction "cabal.cabal-add" state $ useWithStale ParseCabalFile $ toNormalizedFilePath cabalFilePath
391+
case mbGPD of
392+
Nothing -> pure $ InL []
393+
Just (gpd, _) -> do
394+
actions <- liftIO $ CabalAdd.addDependencySuggestCodeAction plId verTxtDocId
395+
suggestions
396+
haskellFilePath cabalFilePath
397+
gpd
398+
pure $ InL $ fmap InR actions
399+
322400
-- | Handler for hover messages.
323401
--
324402
-- Provides a Handler for displaying message on hover.
@@ -361,6 +439,7 @@ hover ide _ msgParam = do
361439
documentationText :: T.Text -> T.Text
362440
documentationText package = "[Documentation](https://hackage.haskell.org/package/" <> package <> ")"
363441

442+
364443
-- ----------------------------------------------------------------
365444
-- Cabal file of Interest rules and global variable
366445
-- ----------------------------------------------------------------

0 commit comments

Comments
 (0)