Skip to content
Open
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
Add Open in Editor support for template paths
  • Loading branch information
federicobond committed Dec 4, 2025
commit 75c29becf97dba04cdac385257b9e811d1cf17eb
3 changes: 3 additions & 0 deletions debug_toolbar/panels/templates/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from debug_toolbar.panels.sql.tracking import SQLQueryTriggered, allow_sql
from debug_toolbar.panels.templates import views
from debug_toolbar.sanitize import force_str
from debug_toolbar.utils import get_editor_url

if find_spec("jinja2"):
from debug_toolbar.panels.templates.jinja2 import patch_jinja_render
Expand Down Expand Up @@ -195,13 +196,15 @@ def generate_stats(self, request, response):
if hasattr(template, "origin") and template.origin and template.origin.name:
template.origin_name = template.origin.name
template.origin_hash = signing.dumps(template.origin.name)
template.editor_url = get_editor_url(template.origin.name)
else:
template.origin_name = _("No origin")
template.origin_hash = ""
info["template"] = {
"name": template.name,
"origin_name": template.origin_name,
"origin_hash": template.origin_hash,
"editor_url": getattr(template, "editor_url", None),
Comment thread
tim-schilling marked this conversation as resolved.
Outdated
}
# Clean up context for better readability
if self.toolbar.config["SHOW_TEMPLATE_CONTEXT"]:
Expand Down
1 change: 1 addition & 0 deletions debug_toolbar/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def _is_running_tests():
"debug_toolbar.panels.profiling.ProfilingPanel",
"debug_toolbar.panels.redirects.RedirectsPanel",
},
"EDITOR": "vscode",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there should be a default. I'd rather have the feature disabled by default.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think defaulting to enabled with vscode is reasonable.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't JetBrains a big sponsor? If we're giving special treatment, let's make it community-friendly.

However, I was going for default OFF. I don't have VSCode installed, so I would get an error.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm for the off by default, no spécial traitment. And if a special traitment there is it should be the most used ide in the django community. Dunno how to find this info.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codingjoe as far as I can tell, it doesn't error. It's a no-op in the browser. If we want, we're safe picking something as the default. However, we should consider how to make this setting a bit more obvious. I'll push a commit that adds the note and a link to the setting in the docs.

Image

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be resolved in 1d6349f

"INSERT_BEFORE": "</body>",
"IS_RUNNING_TESTS": _is_running_tests(),
"OBSERVE_REQUEST_CALLBACK": "debug_toolbar.toolbar.observe_request",
Expand Down
10 changes: 9 additions & 1 deletion debug_toolbar/templates/debug_toolbar/panels/templates.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@ <h4>{% blocktranslate count template_count=templates|length %}Template{% plural
<dl>
{% for template in templates %}
<dt><strong><a class="remoteCall toggleTemplate" href="{% url 'djdt:template_source' %}?template={{ template.template.name }}&amp;template_origin={{ template.template.origin_hash }}">{{ template.template.name|addslashes }}</a></strong></dt>
<dd><samp>{{ template.template.origin_name|addslashes }}</samp></dd>
<dd>
<samp>
{% if template.template.editor_url %}
<a href="{{ template.template.editor_url }}" title="{% translate "Open in editor" %}">{{ template.template.origin_name|addslashes }}</a>
{% else %}
{{ template.template.origin_name|addslashes }}
{% endif %}
</samp>
</dd>
{% if template.context %}
<dd>
<details>
Expand Down
25 changes: 25 additions & 0 deletions debug_toolbar/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,3 +415,28 @@ def get_csp_nonce(request) -> str | None:
return csp_nonce
# Django's built-in CSP support uses get_nonce(request)
return compat.get_nonce(request)


def get_editor_url(file: str, line: int = 1) -> str | None:
formats = {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be a great application for the all new template strings.

"cursor": "cursor://file/{file}:{line}",
"emacs": "emacs://open?url=file://{file}&line={line}",
"espresso": "x-espresso://open?filepath={file}&lines={line}",
"idea": "idea://open?file={file}&line={line}",
"idea-remote": "javascript:(()=>{let r=new XMLHttpRequest; r.open('get','http://localhost:63342/api/file/?file={file}&line={line}');r.send();})()",
"macvim": "mvim://open/?url=file://{file}&line={line}",
"nova": "nova://open?path={file}&line={line}",
"pycharm": "pycharm://open?file={file}&line={line}",
Comment thread
tim-schilling marked this conversation as resolved.
"pycharm-remote": "javascript:(()=>{let r=new XMLHttpRequest; r.open('get','http://localhost:63342/api/file/{file}:{line}');r.send();})()",
"sublime": "subl://open?url=file://{file}&line={line}",
"vscode": "vscode://file/{file}:{line}",
"vscode-insiders": "vscode-insiders://file/{file}:{line}",
"vscode-remote": "vscode://vscode-remote/{file}:{line}",
"vscode-insiders-remote": "vscode-insiders://vscode-remote/{file}:{line}",
"vscodium": "vscodium://file/{file}:{line}",
"windsurf": "windsurf://file/{file}:{line}",
}
template = formats.get(dt_settings.get_config()["EDITOR"])
if template is None:
return None
return template.format(file=file, line=line)
Comment thread
tim-schilling marked this conversation as resolved.
Outdated
10 changes: 10 additions & 0 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ Toolbar options
This setting is a set of the full Python paths to each panel that you
want disabled (but still displayed) by default.

* ``EDITOR``

Default: ``'vscode'``

The editor to use to open file paths from the toolbar.

Available editors: ``'vscode'``, ``'cursor'``, ``'emacs'``, ``'idea'``,
``'pycharm'``, ``'sublime'``, ``'vscode-insiders'``, ``'vscode-remote'``,
``'vscodium'``, ``'windsurf'``
Comment thread
federicobond marked this conversation as resolved.
Outdated

* ``INSERT_BEFORE``

Default: ``'</body>'``
Expand Down