From 0a3c1255202c7657b8a39ce0232648d6289dca6d Mon Sep 17 00:00:00 2001 From: Luka Hietala Date: Thu, 20 Nov 2025 22:31:01 +0200 Subject: [PATCH] cursed blame view --- app.py | 4 ++-- git/blame.py | 9 ++++++--- highlight.py | 27 +++++++++++++++++++++++++-- static/styles.css | 8 +++++++- templates/blame.html | 36 ++++++++---------------------------- 5 files changed, 48 insertions(+), 36 deletions(-) diff --git a/app.py b/app.py index d483772..2564732 100644 --- a/app.py +++ b/app.py @@ -122,8 +122,8 @@ def repo_blob_path(repo_name, path): def repo_blame_path(repo_name, path): ref = request.args.get('ref', 'HEAD') refs = get_refs(f"{repo_path}/{repo_name}") - blame = get_blame(f"{repo_path}/{repo_name}", ref, path) - return render_template("blame.html", repo_name=repo_name, ref=ref, path=path, blame=blame, refs=refs) + blame, style = get_blame(f"{repo_path}/{repo_name}", ref, path) + return render_template("blame.html", repo_name=repo_name, ref=ref, path=path, blame=blame, refs=refs, style=style) @app.route("//diff") def repo_diff(repo_name): diff --git a/git/blame.py b/git/blame.py index 8ec663d..6d391de 100644 --- a/git/blame.py +++ b/git/blame.py @@ -1,4 +1,5 @@ import pygit2 as git +from highlight import get_highlight_blame_style, highlight_line # discourage using blame because its very expensive, especially on repos with long commits history # retrieves blame information for a file at given ref and path @@ -61,7 +62,9 @@ def get_blame(repo_path, ref="HEAD", file_path=""): result.append({ 'line_num': i + 1, 'content': line, - 'blame': blame_lines[i] + 'blame': blame_lines[i], + # highlight every line individually + 'highlighted': highlight_line(line, file_path) }) - - return result \ No newline at end of file + + return result, get_highlight_blame_style() \ No newline at end of file diff --git a/highlight.py b/highlight.py index 626c617..afd7796 100644 --- a/highlight.py +++ b/highlight.py @@ -8,8 +8,7 @@ from pygments.formatters import HtmlFormatter # server-side syntax highlighting -# https://git.kernel.org/pub/scm/infra/cgit.git/tree/filters/syntax-highlighting.py?id=dbaee2672be14374acb17266477c19294c6155f3 - +# reference: https://git.kernel.org/pub/scm/infra/cgit.git/tree/filters/syntax-highlighting.py?id=dbaee2672be14374acb17266477c19294c6155f3 def highlight_code(data, filename): formatter = HtmlFormatter(style='sas', nobackground=True, linenos=True) try: @@ -25,6 +24,30 @@ def highlight_code(data, filename): highlighted = highlight(data, lexer, formatter) return f'{highlighted}' +def get_highlight_blame_style(): + formatter = HtmlFormatter(style='sas', nobackground=True, cssclass='blame-code') + return formatter.get_style_defs('.blame-code') + +# highlight a single line (for blame) +def highlight_line(line, filename): + formatter = HtmlFormatter(style='sas', nobackground=True, cssclass='blame-code') + try: + lexer = guess_lexer_for_filename(filename, line) + except ClassNotFound: + if line.startswith('#!'): + lexer = guess_lexer(line) + else: + lexer = TextLexer() + except TypeError: + lexer = TextLexer() + highlighted = highlight(line, lexer, formatter) + # remove the outer div and pre + # highlighted is
mirri
+ # extract inner + start = highlighted.find('
') + 5 # length of 
, very hacky i know
+    end = highlighted.find('
') + return highlighted[start:end] + # bare diff highlighting def highlight_diff(data): formatter = HtmlFormatter(style='sas', nobackground=True) diff --git a/static/styles.css b/static/styles.css index 19d285c..90526f3 100644 --- a/static/styles.css +++ b/static/styles.css @@ -117,7 +117,13 @@ table.commits-table .message-col { } .deletions { - color: red; + color: red; +} + +.blame-code { + background-color: #f9f9f9; + border: 1px solid lightgray; + overflow-x: auto; } diff --git a/templates/blame.html b/templates/blame.html index 26cc641..ba4b8e7 100644 --- a/templates/blame.html +++ b/templates/blame.html @@ -1,36 +1,16 @@ {% extends "base.html" %} {% block content %} + +

Blame: {{ path }}

{% if blame %} - - - - - - - - - - - - {% for line in blame %} - - - {% if line.blame %} - - - - {% else %} - - - - {% endif %} - - - {% endfor %} - -
LineCommitAuthorDateContent
{{ line.line_num }}{{ line.blame.commit_id[:8] }}{{ line.blame.author.name }}{{ line.blame.author.time | datetime }}
{{ line.content }}
+
+
+
+
+{% for line in blame %}{{ "%4s" % line.line_num }} {% if line.blame %}{{ line.blame.commit_id[:8] }} {{ "%-15s" % line.blame.author.name[:15] }} {{ line.blame.author.time | datetime }}{% endif %} | {{ line.highlighted | safe }}
+{% endfor %}
{% else %}

No blame info

{% endif %} -- 2.47.3