diff --git a/djlsp/parser.py b/djlsp/parser.py index 53b2d99..fb057e1 100644 --- a/djlsp/parser.py +++ b/djlsp/parser.py @@ -42,21 +42,23 @@ def loaded_libraries(self): def completions(self, line, character): line_fragment = self.document.lines[line][:character] - - if match := self.re_load.match(line_fragment): - return self.get_load_completions(match) - if match := self.re_url.match(line_fragment): - return self.get_url_completions(match) - elif match := self.re_static.match(line_fragment): - return self.get_static_completions(match) - elif match := self.re_template.match(line_fragment): - return self.get_template_completions(match) - elif match := self.re_tag.match(line_fragment): - return self.get_tag_completions(match) - elif match := self.re_filter.match(line_fragment): - return self.get_filter_completions(match) - elif match := self.re_context.match(line_fragment): - return self.get_context_completions(match) + try: + if match := self.re_load.match(line_fragment): + return self.get_load_completions(match) + if match := self.re_url.match(line_fragment): + return self.get_url_completions(match) + elif match := self.re_static.match(line_fragment): + return self.get_static_completions(match) + elif match := self.re_template.match(line_fragment): + return self.get_template_completions(match) + elif match := self.re_tag.match(line_fragment): + return self.get_tag_completions(match) + elif match := self.re_filter.match(line_fragment): + return self.get_filter_completions(match) + elif match := self.re_context.match(line_fragment): + return self.get_context_completions(match) + except Exception as e: + logger.debug(e) return [] @@ -129,8 +131,12 @@ def get_filter_completions(self, match: Match): def get_context_completions(self, match: Match): prefix = match.group(2) - logger.debug(f"Finde context matches for: {prefix}") + logger.debug(f"Find context matches for: {prefix}") context = self.workspace_index.global_template_context.copy() + if "/templates/" in self.document.path: + template_name = self.document.path.split("/templates/", 1)[1] + if template := self.workspace_index.templates.get(template_name): + context.update(template.context) prefix, lookup_context = self._recursive_context_lookup( prefix.strip().split("."), context diff --git a/djlsp/scripts/django-collector.py b/djlsp/scripts/django-collector.py index 3defd66..5565570 100644 --- a/djlsp/scripts/django-collector.py +++ b/djlsp/scripts/django-collector.py @@ -129,6 +129,8 @@ }, } +WAGTAIL_PAGE_TEMPLATE_LOOKUP = None + def get_file_watcher_globs(): """ @@ -158,7 +160,34 @@ def get_file_watcher_globs(): return patterns -def get_object_types(): +def _build_wagtail_page_template_lookup(): + try: + from wagtail.models import Page + except ImportError: + return {} + wagtail_page_template_lookup = {} + models = apps.get_models() + for model in models: + if issubclass(model, Page): + wagtail_page_template_lookup[model.template] = { + "page": model.__module__ + "." + model.__name__, + "self": model.__module__ + "." + model.__name__, + } + if model.context_object_name: + wagtail_page_template_lookup[model.template][ + model.context_object_name + ] = (model.__module__ + "." + model.__name__) + return wagtail_page_template_lookup + + +def get_wagtail_page_context(template_name: str) -> dict: + global WAGTAIL_PAGE_TEMPLATE_LOOKUP + if WAGTAIL_PAGE_TEMPLATE_LOOKUP is None: + WAGTAIL_PAGE_TEMPLATE_LOOKUP = _build_wagtail_page_template_lookup() + return WAGTAIL_PAGE_TEMPLATE_LOOKUP.get(template_name, {}) + + +def get_object_types() -> dict: models = apps.get_models() object_types = {} for model in models: @@ -295,12 +324,12 @@ def get_templates(): # Get used template (other apps can override templates) template_files[template_name] = _parse_template( - _get_template_content(default_engine, template_name) + _get_template_content(default_engine, template_name), template_name ) return template_files -def _get_template_content(engine: Engine, template_name): +def _get_template_content(engine: Engine, template_name: str): for loader in engine.template_loaders: for origin in loader.get_template_sources(template_name): try: @@ -331,7 +360,7 @@ def get_global_template_context(): return global_context -def _parse_template(content): +def _parse_template(content, template_name: str) -> dict: extends = None blocks = set() for line in content.splitlines(): @@ -343,7 +372,9 @@ def _parse_template(content): return { "extends": extends, "blocks": list(blocks), - "context": {}, # TODO: Find view/model/contectprocessors + "context": get_wagtail_page_context( + template_name + ), # TODO: Find view/model/contectprocessors } diff --git a/djlsp/server.py b/djlsp/server.py index 4a4a466..9c92686 100644 --- a/djlsp/server.py +++ b/djlsp/server.py @@ -227,7 +227,7 @@ def initialized(ls: DjangoTemplateLanguageServer, params: InitializeParams): @server.feature( - TEXT_DOCUMENT_COMPLETION, CompletionOptions(trigger_characters=[" ", "|", "'"]) + TEXT_DOCUMENT_COMPLETION, CompletionOptions(trigger_characters=[" ", "|", "'", "."]) ) def completions(ls: DjangoTemplateLanguageServer, params: CompletionParams): logger.info(f"COMMAND: {TEXT_DOCUMENT_COMPLETION}")