Skip to content

Commit 160fb6a

Browse files
committed
Change tracking of file types to language kinds
The plugin descriptor now tracks the language kinds it is responsible for instead of the file endings. We get the language kinds of any file from the VFS. Currently we are using a source repository to be able to use the lsp changes needed, but once lsp is released this can be removed.
1 parent b1966ff commit 160fb6a

File tree

5 files changed

+57
-42
lines changed

5 files changed

+57
-42
lines changed

cabal.project

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

10+
source-repository-package
11+
type: git
12+
location: https://github.com/VeryMilkyJoe/lsp.git
13+
subdir: lsp
14+
tag: 39d780bbe9ebb4a21bd6d132a3c1abe4edf2b5a4
15+
16+
source-repository-package
17+
type: git
18+
location: https://github.com/VeryMilkyJoe/lsp.git
19+
subdir: lsp-test
20+
tag: 39d780bbe9ebb4a21bd6d132a3c1abe4edf2b5a4
1021

1122
index-state: 2025-05-12T13:26:29Z
1223

ghcide/src/Development/IDE/Core/FileStore.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ getVersionedTextDoc doc = do
226226
maybe (pure Nothing) getVirtualFile $
227227
uriToNormalizedFilePath $ toNormalizedUri uri
228228
let ver = case mvf of
229-
Just (VirtualFile lspver _ _) -> lspver
229+
Just (VirtualFile lspver _ _ _) -> lspver
230230
Nothing -> 0
231231
return (VersionedTextDocumentIdentifier uri ver)
232232

ghcide/src/Development/IDE/Plugin/Completions/Logic.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ mergeListsBy cmp all_lists = merge_lists all_lists
854854

855855
-- |From the given cursor position, gets the prefix module or record for autocompletion
856856
getCompletionPrefix :: Position -> VFS.VirtualFile -> PosPrefixInfo
857-
getCompletionPrefix pos (VFS.VirtualFile _ _ ropetext) = getCompletionPrefixFromRope pos ropetext
857+
getCompletionPrefix pos (VFS.VirtualFile _ _ ropetext _) = getCompletionPrefixFromRope pos ropetext
858858

859859
getCompletionPrefixFromRope :: Position -> Rope.Rope -> PosPrefixInfo
860860
getCompletionPrefixFromRope pos@(Position l c) ropetext =

ghcide/src/Development/IDE/Plugin/HLS.hs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,11 +251,12 @@ extensiblePlugins recorder plugins = mempty { P.pluginHandlers = handlers }
251251
handlers = mconcat $ do
252252
(IdeMethod m :=> IdeHandler fs') <- DMap.assocs handlers'
253253
pure $ requestHandler m $ \ide params -> do
254+
vfs <- LSP.getVirtualFiles
254255
config <- Ide.PluginUtils.getClientConfig
255256
-- Only run plugins that are allowed to run on this request, save the
256257
-- list of disabled plugins incase that's all we have
257-
let (fs, dfs) = List.partition (\(_, desc, _) -> handlesRequest m params desc config == HandlesRequest) fs'
258-
let disabledPluginsReason = (\(x, desc, _) -> (x, handlesRequest m params desc config)) <$> dfs
258+
let (fs, dfs) = List.partition (\(_, desc, _) -> handlesRequest vfs m params desc config == HandlesRequest) fs'
259+
let disabledPluginsReason = (\(x, desc, _) -> (x, handlesRequest vfs m params desc config)) <$> dfs
259260
-- Clients generally don't display ResponseErrors so instead we log any that we come across
260261
-- However, some clients do display ResponseErrors! See for example the issues:
261262
-- https://github.com/haskell/haskell-language-server/issues/4467
@@ -370,7 +371,7 @@ extensibleNotificationPlugins recorder xs = mempty { P.pluginHandlers = handlers
370371
pure $ notificationHandler m $ \ide vfs params -> do
371372
config <- Ide.PluginUtils.getClientConfig
372373
-- Only run plugins that are enabled for this request
373-
let fs = filter (\(_, desc, _) -> handlesRequest m params desc config == HandlesRequest) fs'
374+
let fs = filter (\(_, desc, _) -> handlesRequest vfs m params desc config == HandlesRequest) fs'
374375
case nonEmpty fs of
375376
Nothing -> do
376377
logWith recorder Warning (LogNoPluginForMethod $ Some m)

hls-plugin-api/src/Ide/Types.hs

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ import Ide.Plugin.Properties
9494
import qualified Language.LSP.Protocol.Lens as L
9595
import Language.LSP.Protocol.Message
9696
import Language.LSP.Protocol.Types
97+
import qualified Language.LSP.Protocol.Types as J
9798
import Language.LSP.Server
9899
import Language.LSP.VFS
99100
import Numeric.Natural
@@ -323,7 +324,7 @@ data PluginDescriptor (ideState :: Type) =
323324
, pluginNotificationHandlers :: PluginNotificationHandlers ideState
324325
, pluginModifyDynflags :: DynFlagsModifications
325326
, pluginCli :: Maybe (ParserInfo (IdeCommand ideState))
326-
, pluginFileType :: [T.Text]
327+
, pluginLanguageIds :: [J.LanguageKind]
327328
-- ^ File extension of the files the plugin is responsible for.
328329
-- The plugin is only allowed to handle files with these extensions.
329330
-- When writing handlers, etc. for this plugin it can be assumed that all handled files are of this type.
@@ -416,14 +417,14 @@ pluginResolverResponsible _ _ = DoesNotHandleRequest $ NotResolveOwner "(unable
416417
-- We are passing the msgParams here even though we only need the URI URI here.
417418
-- If in the future we need to be able to provide only an URI it can be
418419
-- separated again.
419-
pluginSupportsFileType :: (L.HasTextDocument m doc, L.HasUri doc Uri) => m -> PluginDescriptor c -> HandleRequestResult
420-
pluginSupportsFileType msgParams pluginDesc =
421-
case mfp of
422-
Just fp | T.pack (takeExtension fp) `elem` pluginFileType pluginDesc -> HandlesRequest
423-
_ -> DoesNotHandleRequest $ DoesNotSupportFileType (maybe "(unable to determine file type)" (T.pack . takeExtension) mfp)
420+
pluginSupportsFileType :: (L.HasTextDocument m doc, L.HasUri doc Uri) => VFS -> m -> PluginDescriptor c -> HandleRequestResult
421+
pluginSupportsFileType (VFS vfs) msgParams pluginDesc =
422+
case _language_id =<< mVFS of
423+
Just languageKind | languageKind `elem` pluginLanguageIds pluginDesc -> HandlesRequest
424+
_ -> DoesNotHandleRequest $ DoesNotSupportFileType (maybe "(unable to determine file type)" (T.pack . show) $ _language_id =<< mVFS)
424425
where
425-
mfp = uriToFilePath uri
426-
uri = msgParams ^. L.textDocument . L.uri
426+
mVFS = Map.lookup uri vfs
427+
uri = toNormalizedUri $ msgParams ^. L.textDocument . L.uri
427428

428429
-- | Methods that can be handled by plugins.
429430
-- 'ExtraParams' captures any extra data the IDE passes to the handlers for this method
@@ -452,7 +453,9 @@ class HasTracing (MessageParams m) => PluginMethod (k :: MessageKind) (m :: Meth
452453
--
453454
-- But there is no use to split it up into two different methods for now.
454455
handlesRequest
455-
:: SMethod m
456+
:: VFS
457+
-- ^ The virtual file system, contains the language kind of the file.
458+
-> SMethod m
456459
-- ^ Method type.
457460
-> MessageParams m
458461
-- ^ Whether a plugin is enabled might depend on the message parameters
@@ -468,24 +471,24 @@ class HasTracing (MessageParams m) => PluginMethod (k :: MessageKind) (m :: Meth
468471
-- with the given parameters?
469472

470473
default handlesRequest :: (L.HasTextDocument (MessageParams m) doc, L.HasUri doc Uri)
471-
=> SMethod m -> MessageParams m -> PluginDescriptor c -> Config -> HandleRequestResult
472-
handlesRequest _ params desc conf =
473-
pluginEnabledGlobally desc conf <> pluginSupportsFileType params desc
474+
=> VFS -> SMethod m -> MessageParams m -> PluginDescriptor c -> Config -> HandleRequestResult
475+
handlesRequest vfs _ params desc conf =
476+
pluginEnabledGlobally desc conf <> pluginSupportsFileType vfs params desc
474477

475478
-- | Check if a plugin is enabled, if one of it's specific config's is enabled,
476479
-- and if it supports the file
477480
pluginEnabledWithFeature :: (L.HasTextDocument (MessageParams m) doc, L.HasUri doc Uri)
478-
=> (PluginConfig -> Bool) -> SMethod m -> MessageParams m
481+
=> (PluginConfig -> Bool) -> VFS -> SMethod m -> MessageParams m
479482
-> PluginDescriptor c -> Config -> HandleRequestResult
480-
pluginEnabledWithFeature feature _ msgParams pluginDesc config =
483+
pluginEnabledWithFeature feature vfs _ msgParams pluginDesc config =
481484
pluginEnabledGlobally pluginDesc config
482485
<> pluginFeatureEnabled feature pluginDesc config
483-
<> pluginSupportsFileType msgParams pluginDesc
486+
<> pluginSupportsFileType vfs msgParams pluginDesc
484487

485488
-- | Check if a plugin is enabled, if one of it's specific configs is enabled,
486489
-- and if it's the plugin responsible for a resolve request.
487-
pluginEnabledResolve :: L.HasData_ s (Maybe Value) => (PluginConfig -> Bool) -> p -> s -> PluginDescriptor c -> Config -> HandleRequestResult
488-
pluginEnabledResolve feature _ msgParams pluginDesc config =
490+
pluginEnabledResolve :: L.HasData_ s (Maybe Value) => (PluginConfig -> Bool) -> VFS -> p -> s -> PluginDescriptor c -> Config -> HandleRequestResult
491+
pluginEnabledResolve feature _ _ msgParams pluginDesc config =
489492
pluginEnabledGlobally pluginDesc config
490493
<> pluginFeatureEnabled feature pluginDesc config
491494
<> pluginResolverResponsible msgParams pluginDesc
@@ -498,23 +501,23 @@ instance PluginMethod Request Method_CodeActionResolve where
498501
handlesRequest = pluginEnabledResolve plcCodeActionsOn
499502

500503
instance PluginMethod Request Method_TextDocumentDefinition where
501-
handlesRequest _ msgParams pluginDesc _ = pluginSupportsFileType msgParams pluginDesc
504+
handlesRequest vfs _ msgParams pluginDesc _ = pluginSupportsFileType vfs msgParams pluginDesc
502505

503506
instance PluginMethod Request Method_TextDocumentTypeDefinition where
504-
handlesRequest _ msgParams pluginDesc _ = pluginSupportsFileType msgParams pluginDesc
507+
handlesRequest vfs _ msgParams pluginDesc _ = pluginSupportsFileType vfs msgParams pluginDesc
505508

506509
instance PluginMethod Request Method_TextDocumentImplementation where
507-
handlesRequest _ msgParams pluginDesc _ = pluginSupportsFileType msgParams pluginDesc
510+
handlesRequest vfs _ msgParams pluginDesc _ = pluginSupportsFileType vfs msgParams pluginDesc
508511

509512
instance PluginMethod Request Method_TextDocumentDocumentHighlight where
510-
handlesRequest _ msgParams pluginDesc _ = pluginSupportsFileType msgParams pluginDesc
513+
handlesRequest vfs _ msgParams pluginDesc _ = pluginSupportsFileType vfs msgParams pluginDesc
511514

512515
instance PluginMethod Request Method_TextDocumentReferences where
513-
handlesRequest _ msgParams pluginDesc _ = pluginSupportsFileType msgParams pluginDesc
516+
handlesRequest vfs _ msgParams pluginDesc _ = pluginSupportsFileType vfs msgParams pluginDesc
514517

515518
instance PluginMethod Request Method_WorkspaceSymbol where
516519
-- Unconditionally enabled, but should it really be?
517-
handlesRequest _ _ _ _ = HandlesRequest
520+
handlesRequest _ _ _ _ _ = HandlesRequest
518521

519522
instance PluginMethod Request Method_TextDocumentInlayHint where
520523
handlesRequest = pluginEnabledWithFeature plcInlayHintsOn
@@ -549,22 +552,22 @@ instance PluginMethod Request Method_TextDocumentCompletion where
549552
handlesRequest = pluginEnabledWithFeature plcCompletionOn
550553

551554
instance PluginMethod Request Method_TextDocumentFormatting where
552-
handlesRequest _ msgParams pluginDesc conf =
555+
handlesRequest vfs _ msgParams pluginDesc conf =
553556
(if PluginId (formattingProvider conf) == pid
554557
|| PluginId (cabalFormattingProvider conf) == pid
555558
then HandlesRequest
556559
else DoesNotHandleRequest (NotFormattingProvider (formattingProvider conf)) )
557-
<> pluginSupportsFileType msgParams pluginDesc
560+
<> pluginSupportsFileType vfs msgParams pluginDesc
558561
where
559562
pid = pluginId pluginDesc
560563

561564
instance PluginMethod Request Method_TextDocumentRangeFormatting where
562-
handlesRequest _ msgParams pluginDesc conf =
565+
handlesRequest vfs _ msgParams pluginDesc conf =
563566
(if PluginId (formattingProvider conf) == pid
564567
|| PluginId (cabalFormattingProvider conf) == pid
565568
then HandlesRequest
566569
else DoesNotHandleRequest (NotFormattingProvider (formattingProvider conf)))
567-
<> pluginSupportsFileType msgParams pluginDesc
570+
<> pluginSupportsFileType vfs msgParams pluginDesc
568571
where
569572
pid = pluginId pluginDesc
570573

@@ -585,21 +588,21 @@ instance PluginMethod Request Method_TextDocumentFoldingRange where
585588

586589
instance PluginMethod Request Method_CallHierarchyIncomingCalls where
587590
-- This method has no URI parameter, thus no call to 'pluginResponsible'
588-
handlesRequest _ _ pluginDesc conf =
591+
handlesRequest _ _ _ pluginDesc conf =
589592
pluginEnabledGlobally pluginDesc conf
590593
<> pluginFeatureEnabled plcCallHierarchyOn pluginDesc conf
591594

592595
instance PluginMethod Request Method_CallHierarchyOutgoingCalls where
593596
-- This method has no URI parameter, thus no call to 'pluginResponsible'
594-
handlesRequest _ _ pluginDesc conf =
597+
handlesRequest _ _ _ pluginDesc conf =
595598
pluginEnabledGlobally pluginDesc conf
596599
<> pluginFeatureEnabled plcCallHierarchyOn pluginDesc conf
597600

598601
instance PluginMethod Request Method_WorkspaceExecuteCommand where
599-
handlesRequest _ _ _ _= HandlesRequest
602+
handlesRequest _ _ _ _ _ = HandlesRequest
600603

601604
instance PluginMethod Request (Method_CustomMethod m) where
602-
handlesRequest _ _ _ _ = HandlesRequest
605+
handlesRequest _ _ _ _ _ = HandlesRequest
603606

604607
-- Plugin Notifications
605608

@@ -613,19 +616,19 @@ instance PluginMethod Notification Method_TextDocumentDidClose where
613616

614617
instance PluginMethod Notification Method_WorkspaceDidChangeWatchedFiles where
615618
-- This method has no URI parameter, thus no call to 'pluginResponsible'.
616-
handlesRequest _ _ desc conf = pluginEnabledGlobally desc conf
619+
handlesRequest _ _ _ desc conf = pluginEnabledGlobally desc conf
617620

618621
instance PluginMethod Notification Method_WorkspaceDidChangeWorkspaceFolders where
619622
-- This method has no URI parameter, thus no call to 'pluginResponsible'.
620-
handlesRequest _ _ desc conf = pluginEnabledGlobally desc conf
623+
handlesRequest _ _ _ desc conf = pluginEnabledGlobally desc conf
621624

622625
instance PluginMethod Notification Method_WorkspaceDidChangeConfiguration where
623626
-- This method has no URI parameter, thus no call to 'pluginResponsible'.
624-
handlesRequest _ _ desc conf = pluginEnabledGlobally desc conf
627+
handlesRequest _ _ _ desc conf = pluginEnabledGlobally desc conf
625628

626629
instance PluginMethod Notification Method_Initialized where
627630
-- This method has no URI parameter, thus no call to 'pluginResponsible'.
628-
handlesRequest _ _ desc conf = pluginEnabledGlobally desc conf
631+
handlesRequest _ _ _ desc conf = pluginEnabledGlobally desc conf
629632

630633

631634
-- ---------------------------------------------------------------------
@@ -1054,7 +1057,7 @@ defaultPluginDescriptor plId desc =
10541057
mempty
10551058
mempty
10561059
Nothing
1057-
[".hs", ".lhs", ".hs-boot"]
1060+
[J.LanguageKind_Haskell, J.LanguageKind_Custom "literate haskell"]
10581061

10591062
-- | Set up a plugin descriptor, initialized with default values.
10601063
-- This plugin descriptor is prepared for @.cabal@ files and as such,
@@ -1075,7 +1078,7 @@ defaultCabalPluginDescriptor plId desc =
10751078
mempty
10761079
mempty
10771080
Nothing
1078-
[".cabal"]
1081+
[J.LanguageKind_Custom "cabal"]
10791082

10801083
newtype CommandId = CommandId T.Text
10811084
deriving (Show, Read, Eq, Ord)

0 commit comments

Comments
 (0)