Source code for esbonio.server.features.directives
from__future__importannotationsimportinspectimporttypingfromlsprotocolimporttypesaslspfromesbonioimportserverfromesbonio.sphinx_agentimporttypesfrom.importprovidersfrom.providersimportDirectiveArgumentProvideriftyping.TYPE_CHECKING:fromcollections.abcimportCoroutinefromtypingimportAnyfromesbonio.serverimportUriclassDirectiveProvider:"""Base class for directive providers"""defget_directive(self,uri:Uri,name:str)->types.Directive|None|Coroutine[Any,Any,types.Directive|None]:"""Return the definition of the given directive, if known Parameters ---------- uri The uri of the document in which the directive name appears name The name of the directive, as the user would type in a document """returnNonedefsuggest_directives(self,context:server.CompletionContext)->(list[types.Directive]|None|Coroutine[Any,Any,list[types.Directive]|None]):"""Given a completion context, suggest directives that may be used."""returnNone
[docs]classDirectiveFeature(server.LanguageFeature):"""'Backend' support for directives. It's this language feature's responsibility to provide an API that exposes the information a "frontend" language feature may want. """def__init__(self,*args,**kwargs):super().__init__(*args,**kwargs)self._directive_providers:dict[int,DirectiveProvider]={}self._argument_providers:dict[str,DirectiveArgumentProvider]={}
[docs]defadd_directive_provider(self,provider:DirectiveProvider):"""Register a directive provider. Parameters ---------- provider The directive provider """self._directive_providers[id(provider)]=provider
[docs]defadd_directive_argument_provider(self,name:str,provider:DirectiveArgumentProvider):"""Register a directive argument provider. Parameters ---------- provider The directive argument provider """if(existing:=self._argument_providers.get(name))isnotNone:raiseValueError(f"DirectiveArgumentProvider {provider!r} conflicts with existing "f"provider: {existing!r}")self._argument_providers[name]=provider
[docs]asyncdefsuggest_directives(self,context:server.CompletionContext)->list[types.Directive]:"""Suggest directives that may be used, given a completion context. Parameters ---------- context The completion context. """items:list[types.Directive]=[]forproviderinself._directive_providers.values():try:result:list[types.Directive]|None=Nonearesult=provider.suggest_directives(context)ifinspect.isawaitable(aresult):result=awaitaresultifresult:items.extend(result)exceptException:name=type(provider).__name__self.logger.error("Error in '%s.suggest_directives'",name,exc_info=True)returnitems
[docs]asyncdefget_directive(self,uri:Uri,name:str)->types.Directive|None:"""Return the definition of the given directive name. Parameters ---------- uri The uri of the document in which the directive name appears name The name of the directive, as the user would type into a document. Returns ------- types.Directive | None The directive's definition, if known """forproviderinself._directive_providers.values():try:result:types.Directive|None=Nonearesult=provider.get_directive(uri,name)ifinspect.isawaitable(aresult):result=awaitaresultifresultisnotNone:returnresultexceptException:name=type(provider).__name__self.logger.error("Error in '%s.get_directive'",name,exc_info=True)returnNone
[docs]asyncdefsuggest_arguments(self,context:server.CompletionContext,directive_name:str)->list[lsp.CompletionItem]:"""Suggest directive arguments that may be used, given a completion context. Parameters ---------- context The completion context directive_name The directive to suggest arguments for """if(directive:=awaitself.get_directive(context.uri,directive_name))isNone:self.logger.debug("Unknown directive '%s'",directive_name)return[]arguments=[]self.logger.debug("Suggesting arguments for directive: '%s' (%s)",directive.name,directive.implementation,)forspecindirective.argument_providers:if(provider:=self._argument_providers.get(spec.name))isNone:self.logger.error("Unknown argument provider: '%s'",spec.name)continuetry:result:list[lsp.CompletionItem]|None=Nonearesult=provider.suggest_arguments(context,**spec.kwargs)ifinspect.isawaitable(aresult):result=awaitaresultelse:result=aresultifresultisnotNone:arguments.extend(result)exceptException:name=type(provider).__name__self.logger.error("Error in '%s.suggest_arguments'",name,exc_info=True)returnarguments