Skip to content

Commit

Permalink
Add templates support for new index
Browse files Browse the repository at this point in the history
  • Loading branch information
krukas committed Jun 12, 2024
1 parent b3946a4 commit 3b2c69f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 42 deletions.
32 changes: 6 additions & 26 deletions djlsp/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,11 @@

@dataclass
class Template:
file_path: str = ""
workspace_file_path: str = ""
context: dict = field(default_factory=dict)
# Attributes filled by parser
name: str = ""
extends: str | None = None
loaded_libraries: list[str] | None = None
blocks: list[str] | None = None

def clear(self):
self.extends = None
self.blocks = None
context: dict = field(default_factory=dict)


@dataclass
Expand Down Expand Up @@ -63,21 +57,7 @@ def update(self, django_data: dict):
# for library in libraries
# }

# TODO: Add Support in django collector
# Update templates
# if templates := django_data.get("templates"):
# found_templates = []
# for template in templates:
# # TODO: how to handle template override
# file_path = template.get("file_path")
# found_templates.append(file_path)
# if file_path in self.templates:
# self.templates[file_path].context = template.get("context", dict)
# else:
# self.templates[file_path] = Template(
# file_path=file_path,
# workspace_file_path=template.get("workspace_file_path", ""),
# context=template.get("context", dict),
# )

# self.templates = [t for t in self.templates if t in found_templates]
self.templates = {
name: Template(name=name, **options)
for name, options in django_data.get("templates", {}).items()
}
21 changes: 11 additions & 10 deletions djlsp/parser.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import os
import re
from functools import cached_property
from re import Match
Expand Down Expand Up @@ -31,15 +32,15 @@ def __init__(
@cached_property
def loaded_libraries(self):
loaded = {BUILTIN}
for line in self.document.lines:
if match := self.re_loaded.match(line):
loaded.update(
[
lib
for lib in match.group(1).strip().split(" ")
if lib in self.django_data["libraries"]
]
)
# TODO: split on all aviable template dirs
if "templates" in self.document.path:
template_name = self.document.path.split(
os.path.sep + "templates" + os.path.sep, 1
)[1]

if template := self.workspace_index.templates.get(template_name):
loaded.update(template.loaded_libraries)

logger.debug(f"Loaded libraries: {loaded}")
return loaded

Expand Down Expand Up @@ -96,7 +97,7 @@ def get_template_completions(self, match: Match):
return sorted(
[
template
for template in self.django_data["templates"]
for template in self.workspace_index.templates
if template.startswith(prefix)
]
)
Expand Down
46 changes: 40 additions & 6 deletions djlsp/scripts/django-collector.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
import inspect
import json
import os
import re
import sys

import django
from django.apps import apps
from django.conf import settings
from django.contrib.staticfiles.finders import get_finders
from django.template.backends.django import get_installed_libraries
from django.template.engine import Engine
from django.template.engine import Engine, Template
from django.template.library import InvalidTemplateLibrary
from django.template.utils import get_app_template_dirs
from django.urls import URLPattern, URLResolver
Expand Down Expand Up @@ -194,19 +195,52 @@ def get_libraries():


def get_templates():
template_files = []
template_files = {}
default_engine = Engine.get_default()
for templates_dir in [
*Engine.get_default().dirs,
*default_engine.dirs,
*get_app_template_dirs("templates"),
]:
for root, dirs, files in os.walk(templates_dir):
for file in files:
template_files.append(
os.path.relpath(os.path.join(root, file), templates_dir)
)
template_name = os.path.relpath(os.path.join(root, file), templates_dir)

if template_name in template_files:
# Skip already procecesed template
# (template have duplicates because other apps can override)
continue

# Get used template (other apps can override templates)
django_template = default_engine.get_template(template_name)
template_files[template_name] = _parse_template(django_template)
return template_files


re_extends = re.compile(r""".*{% ?extends ['"](.*)['"] ?%}.*""")
re_loaded = re.compile(r".*{% ?load ([\w ]*) ?%}$")
re_block = re.compile(r".*{% ?block (\w*) ?%}.*")


def _parse_template(django_template: Template):
extends = None
loaded_libraries = set()
blocks = set()
for line in django_template.source.splitlines():
if match := re_extends.match(line):
extends = match.group(1)
if match := re_loaded.match(line):
loaded_libraries.update(match.group(1).strip().split(" "))
if match := re_block.match(line):
blocks.add(match.group(1))

return {
"extends": extends,
"loaded_libraries": list(loaded_libraries),
"blocks": list(blocks),
"context": {}, # TODO: Find view/model/contectprocessors
}


def collect_project_data():
return {
"file_watcher_globs": get_file_watcher_globs(),
Expand Down

0 comments on commit 3b2c69f

Please sign in to comment.