Skip to content

Commit 75c29be

Browse files
committed
Add Open in Editor support for template paths
1 parent 2542c06 commit 75c29be

File tree

5 files changed

+48
-1
lines changed

5 files changed

+48
-1
lines changed

debug_toolbar/panels/templates/panel.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from debug_toolbar.panels.sql.tracking import SQLQueryTriggered, allow_sql
1717
from debug_toolbar.panels.templates import views
1818
from debug_toolbar.sanitize import force_str
19+
from debug_toolbar.utils import get_editor_url
1920

2021
if find_spec("jinja2"):
2122
from debug_toolbar.panels.templates.jinja2 import patch_jinja_render
@@ -195,13 +196,15 @@ def generate_stats(self, request, response):
195196
if hasattr(template, "origin") and template.origin and template.origin.name:
196197
template.origin_name = template.origin.name
197198
template.origin_hash = signing.dumps(template.origin.name)
199+
template.editor_url = get_editor_url(template.origin.name)
198200
else:
199201
template.origin_name = _("No origin")
200202
template.origin_hash = ""
201203
info["template"] = {
202204
"name": template.name,
203205
"origin_name": template.origin_name,
204206
"origin_hash": template.origin_hash,
207+
"editor_url": getattr(template, "editor_url", None),
205208
}
206209
# Clean up context for better readability
207210
if self.toolbar.config["SHOW_TEMPLATE_CONTEXT"]:

debug_toolbar/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def _is_running_tests():
2222
"debug_toolbar.panels.profiling.ProfilingPanel",
2323
"debug_toolbar.panels.redirects.RedirectsPanel",
2424
},
25+
"EDITOR": "vscode",
2526
"INSERT_BEFORE": "</body>",
2627
"IS_RUNNING_TESTS": _is_running_tests(),
2728
"OBSERVE_REQUEST_CALLBACK": "debug_toolbar.toolbar.observe_request",

debug_toolbar/templates/debug_toolbar/panels/templates.html

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,15 @@ <h4>{% blocktranslate count template_count=templates|length %}Template{% plural
1515
<dl>
1616
{% for template in templates %}
1717
<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>
18-
<dd><samp>{{ template.template.origin_name|addslashes }}</samp></dd>
18+
<dd>
19+
<samp>
20+
{% if template.template.editor_url %}
21+
<a href="{{ template.template.editor_url }}" title="{% translate "Open in editor" %}">{{ template.template.origin_name|addslashes }}</a>
22+
{% else %}
23+
{{ template.template.origin_name|addslashes }}
24+
{% endif %}
25+
</samp>
26+
</dd>
1927
{% if template.context %}
2028
<dd>
2129
<details>

debug_toolbar/utils.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,3 +415,28 @@ def get_csp_nonce(request) -> str | None:
415415
return csp_nonce
416416
# Django's built-in CSP support uses get_nonce(request)
417417
return compat.get_nonce(request)
418+
419+
420+
def get_editor_url(file: str, line: int = 1) -> str | None:
421+
formats = {
422+
"cursor": "cursor://file/{file}:{line}",
423+
"emacs": "emacs://open?url=file://{file}&line={line}",
424+
"espresso": "x-espresso://open?filepath={file}&lines={line}",
425+
"idea": "idea://open?file={file}&line={line}",
426+
"idea-remote": "javascript:(()=>{let r=new XMLHttpRequest; r.open('get','http://localhost:63342/api/file/?file={file}&line={line}');r.send();})()",
427+
"macvim": "mvim://open/?url=file://{file}&line={line}",
428+
"nova": "nova://open?path={file}&line={line}",
429+
"pycharm": "pycharm://open?file={file}&line={line}",
430+
"pycharm-remote": "javascript:(()=>{let r=new XMLHttpRequest; r.open('get','http://localhost:63342/api/file/{file}:{line}');r.send();})()",
431+
"sublime": "subl://open?url=file://{file}&line={line}",
432+
"vscode": "vscode://file/{file}:{line}",
433+
"vscode-insiders": "vscode-insiders://file/{file}:{line}",
434+
"vscode-remote": "vscode://vscode-remote/{file}:{line}",
435+
"vscode-insiders-remote": "vscode-insiders://vscode-remote/{file}:{line}",
436+
"vscodium": "vscodium://file/{file}:{line}",
437+
"windsurf": "windsurf://file/{file}:{line}",
438+
}
439+
template = formats.get(dt_settings.get_config()["EDITOR"])
440+
if template is None:
441+
return None
442+
return template.format(file=file, line=line)

docs/configuration.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ Toolbar options
6767
This setting is a set of the full Python paths to each panel that you
6868
want disabled (but still displayed) by default.
6969

70+
* ``EDITOR``
71+
72+
Default: ``'vscode'``
73+
74+
The editor to use to open file paths from the toolbar.
75+
76+
Available editors: ``'vscode'``, ``'cursor'``, ``'emacs'``, ``'idea'``,
77+
``'pycharm'``, ``'sublime'``, ``'vscode-insiders'``, ``'vscode-remote'``,
78+
``'vscodium'``, ``'windsurf'``
79+
7080
* ``INSERT_BEFORE``
7181

7282
Default: ``'</body>'``

0 commit comments

Comments
 (0)