Skip to content

Break down ghcide functionality in HLS plugins #1257

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 8 commits into from
Jan 25, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Clean up no longer needed handlers
  • Loading branch information
pepeiborra committed Jan 24, 2021
commit 774cc277c69841f46e9a0f210e3141d0c4700159
9 changes: 3 additions & 6 deletions ghcide/src/Development/IDE/LSP/HoverDefinition.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

-- | Display information on hover.
module Development.IDE.LSP.HoverDefinition
( setHandlersHover
, setHandlersDefinition
( setHandlersDefinition
, setHandlersTypeDefinition
, setHandlersDocHighlight
-- * For haskell-language-server
Expand Down Expand Up @@ -38,13 +37,11 @@ foundHover :: (Maybe Range, [T.Text]) -> Maybe Hover
foundHover (mbRange, contents) =
Just $ Hover (HoverContents $ MarkupContent MkMarkdown $ T.intercalate sectionSeparator contents) mbRange

setHandlersDefinition, setHandlersHover, setHandlersTypeDefinition, setHandlersDocHighlight :: PartialHandlers c
setHandlersDefinition, setHandlersTypeDefinition, setHandlersDocHighlight :: PartialHandlers c
setHandlersDefinition = PartialHandlers $ \WithMessage{..} x ->
return x{LSP.definitionHandler = withResponse RspDefinition $ const gotoDefinition}
setHandlersTypeDefinition = PartialHandlers $ \WithMessage{..} x ->
return x{LSP.typeDefinitionHandler = withResponse RspDefinition $ const gotoTypeDefinition}
setHandlersHover = PartialHandlers $ \WithMessage{..} x ->
return x{LSP.hoverHandler = withResponse RspHover $ const hover}
return x {LSP.typeDefinitionHandler = withResponse RspDefinition $ const gotoTypeDefinition}
setHandlersDocHighlight = PartialHandlers $ \WithMessage{..} x ->
return x{LSP.documentHighlightHandler = withResponse RspDocumentHighlights $ const documentHighlight}

Expand Down
2 changes: 1 addition & 1 deletion ghcide/src/Development/IDE/LSP/LanguageServer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ runLanguageServer options userHandlers onInitialConfig onConfigChange getIdeStat
let PartialHandlers parts =
initializeRequestHandler <>
setHandlersIgnore <> -- least important
setHandlersDefinition <> setHandlersHover <> setHandlersTypeDefinition <>
setHandlersDefinition <> setHandlersTypeDefinition <>
setHandlersDocHighlight <>
setHandlersOutline <>
userHandlers <>
Expand Down
35 changes: 0 additions & 35 deletions ghcide/src/Development/IDE/Plugin.hs
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
module Development.IDE.Plugin
( Plugin(..)
, codeActionPlugin
, codeActionPluginWithRules
, makeLspCommandId
) where

import Data.Default
import qualified Data.Text as T
import Development.Shake
import Development.IDE.LSP.Server
import Development.IDE.Core.Rules
import Ide.PluginUtils
import Language.Haskell.LSP.Types
import qualified Language.Haskell.LSP.Core as LSP
import Language.Haskell.LSP.Messages


data Plugin c = Plugin
Expand All @@ -29,29 +20,3 @@ instance Semigroup (Plugin c) where

instance Monoid (Plugin c) where
mempty = def


codeActionPlugin :: (LSP.LspFuncs c -> IdeState -> TextDocumentIdentifier -> Range -> CodeActionContext -> IO (Either ResponseError [CAResult])) -> Plugin c
codeActionPlugin = codeActionPluginWithRules mempty

codeActionPluginWithRules :: Rules () -> (LSP.LspFuncs c -> IdeState -> TextDocumentIdentifier -> Range -> CodeActionContext -> IO (Either ResponseError [CAResult])) -> Plugin c
codeActionPluginWithRules rr f = Plugin rr $ PartialHandlers $ \WithMessage{..} x -> return x{
LSP.codeActionHandler = withResponse RspCodeAction g
}
where
g lsp state (CodeActionParams a b c _) = fmap List <$> f lsp state a b c

-- | Prefix to uniquely identify commands sent to the client. This
-- has two parts
--
-- - A representation of the process id to make sure that a client has
-- unique commands if it is running multiple servers, since some
-- clients have a global command table and get confused otherwise.
--
-- - A string to identify ghcide, to ease integration into
-- haskell-language-server, which routes commands to plugins based
-- on that.
makeLspCommandId :: T.Text -> IO T.Text
makeLspCommandId command = do
pid <- getProcessID
return $ T.pack (show pid) <> ":ghcide:" <> command
26 changes: 2 additions & 24 deletions ghcide/src/Development/IDE/Plugin/CodeAction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@
-- | Go to the definition of a variable.
module Development.IDE.Plugin.CodeAction
(
plugin

-- * For haskell-language-server
, codeAction
codeAction
, codeLens
, rulePackageExports
, commandHandler
Expand All @@ -23,7 +21,6 @@ module Development.IDE.Plugin.CodeAction
) where

import Control.Monad (join, guard)
import Development.IDE.Plugin
import Development.IDE.GHC.Compat
import Development.IDE.Core.Rules
import Development.IDE.Core.RuleTypes
Expand All @@ -39,7 +36,6 @@ import Development.IDE.Plugin.CodeAction.Rules
import Development.IDE.Types.Exports
import Development.IDE.Types.Location
import Development.IDE.Types.Options
import Development.Shake (Rules)
import qualified Data.HashMap.Strict as Map
import qualified Language.Haskell.LSP.Core as LSP
import Language.Haskell.LSP.VFS
Expand All @@ -66,13 +62,6 @@ import Control.Concurrent.Extra (threadDelay, readVar)
import Development.IDE.GHC.Util (printRdrName)
import Ide.PluginUtils (subRange)

plugin :: Plugin c
plugin = codeActionPluginWithRules rules codeAction <> Plugin mempty setHandlersCodeLens

rules :: Rules ()
rules = do
rulePackageExports

-- | a command that blocks forever. Used for testing
blockCommandId :: T.Text
blockCommandId = "ghcide.command.block"
Expand Down Expand Up @@ -135,7 +124,7 @@ codeLens
-> CodeLensParams
-> IO (Either ResponseError (List CodeLens))
codeLens _lsp ideState CodeLensParams{_textDocument=TextDocumentIdentifier uri} = do
commandId <- makeLspCommandId "typesignature.add"
let commandId = "typesignature.add"
fmap (Right . List) $ case uriToFilePath' uri of
Just (toNormalizedFilePath' -> filePath) -> do
_ <- runAction "codeLens" ideState (use TypeCheck filePath)
Expand Down Expand Up @@ -1202,17 +1191,6 @@ matchRegex message regex = case message =~~ regex of
Just (_ :: T.Text, _ :: T.Text, _ :: T.Text, bindings) -> Just bindings
Nothing -> Nothing

setHandlersCodeLens :: PartialHandlers c
setHandlersCodeLens = PartialHandlers $ \WithMessage{..} x -> return x{
LSP.codeLensHandler =
withResponse RspCodeLens codeLens,
LSP.executeCommandHandler =
withResponseAndRequest
RspExecuteCommand
ReqApplyWorkspaceEdit
commandHandler
}

filterNewlines :: T.Text -> T.Text
filterNewlines = T.concat . T.lines

Expand Down
15 changes: 1 addition & 14 deletions ghcide/src/Development/IDE/Plugin/Completions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,16 @@

module Development.IDE.Plugin.Completions
(
plugin
produceCompletions
, getCompletionsLSP
) where

import Language.Haskell.LSP.Messages
import Language.Haskell.LSP.Types
import qualified Language.Haskell.LSP.Core as LSP
import qualified Language.Haskell.LSP.VFS as VFS

import Development.Shake.Classes
import Development.Shake
import GHC.Generics

import Development.IDE.Plugin
import Development.IDE.Core.Service
import Development.IDE.Core.PositionMapping
import Development.IDE.Plugin.Completions.Logic
Expand All @@ -27,7 +23,6 @@ import Development.IDE.Core.Shake
import Development.IDE.GHC.Compat

import Development.IDE.GHC.Util
import Development.IDE.LSP.Server
import TcRnDriver (tcRnImportDecls)
import Data.Maybe
import Ide.Plugin.Config (Config (completionSnippetsOn))
Expand All @@ -36,10 +31,6 @@ import Ide.PluginUtils (getClientConfig)
#if defined(GHC_LIB)
import Development.IDE.Import.DependencyInformation
#endif

plugin :: Plugin Config
plugin = Plugin produceCompletions setHandlersCompletion

produceCompletions :: Rules ()
produceCompletions = do
define $ \ProduceCompletions file -> do
Expand Down Expand Up @@ -150,7 +141,3 @@ getCompletionsLSP lsp ide
_ -> return (Completions $ List [])
_ -> return (Completions $ List [])
_ -> return (Completions $ List [])
setHandlersCompletion :: PartialHandlers Config
setHandlersCompletion = PartialHandlers $ \WithMessage{..} x -> return x{
LSP.completionHandler = withResponse RspCompletion getCompletionsLSP
}
3 changes: 1 addition & 2 deletions ghcide/src/Development/IDE/Plugin/HLS/GhcIde.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ module Development.IDE.Plugin.HLS.GhcIde

import Data.Aeson
import Development.IDE
import Development.IDE.Plugin as Ghcide
import Development.IDE.Plugin.Completions as Completions
import Development.IDE.Plugin.CodeAction as CodeAction
import Development.IDE.LSP.HoverDefinition
Expand All @@ -29,7 +28,7 @@ descriptor plId = (defaultPluginDescriptor plId)
, pluginHoverProvider = Just hover'
, pluginSymbolsProvider = Just symbolsProvider
, pluginCompletionProvider = Just getCompletionsLSP
, pluginRules = Ghcide.pluginRules Completions.plugin <> Ghcide.pluginRules CodeAction.plugin
, pluginRules = produceCompletions <> rulePackageExports
}

-- ---------------------------------------------------------------------
Expand Down