From c9a93f1d0a7faa9f9fa3518558ea75e39e462455 Mon Sep 17 00:00:00 2001 From: Christoph Brandau Date: Wed, 8 Jul 2026 14:20:51 +0200 Subject: [PATCH] feat(blame): add search functionality to blame dialog This update introduces a search bar to the blame dialog, allowing users to filter blame lines based on their input. The search highlights matching text segments, improving the usability of the blame feature for navigating large files. - Implemented a search bar for filtering blame lines - Added visual feedback for matched search terms - Enhanced overall user experience in the blame dialog --- src/app.css | 45 ++++++++ src/lib/components/BlameDialog.svelte | 141 +++++++++++++++++++++----- 2 files changed, 163 insertions(+), 23 deletions(-) diff --git a/src/app.css b/src/app.css index b0448e9..e9b0c7e 100644 --- a/src/app.css +++ b/src/app.css @@ -3120,6 +3120,45 @@ font-weight: 800; } + .blame-search-bar { + position: relative; + display: flex; + align-items: center; + min-height: 38px; + padding: 6px 10px; + border-bottom: 1px solid var(--color-border-subtle); + background: #111321; + } + .blame-search-bar svg { + position: absolute; + left: 20px; + color: var(--color-ink-faint); + pointer-events: none; + } + .blame-search-bar input { + width: 100%; + height: 26px; + padding: 0 34px; + border: 1px solid var(--color-border-subtle); + border-radius: 6px; + background: #0b0e18; + color: var(--color-ink); + font-size: 12px; + } + .blame-search-clear { + position: absolute; + right: 14px; + width: 24px; + height: 24px; + padding: 0; + border: 0; + background: transparent; + color: var(--color-ink-faint); + } + .blame-search-clear svg { + position: static; + } + .blame-column-headers { grid-template-columns: minmax(300px, 340px) minmax(0, 1fr); } @@ -3233,6 +3272,12 @@ .blame-group:hover .blame-line-code { background: #151a2b; } + .blame-search-hit { + padding: 0 1px; + border-radius: 3px; + background: rgba(240,182,72,0.28); + color: #f3d487; + } .global-search-body { display: grid; diff --git a/src/lib/components/BlameDialog.svelte b/src/lib/components/BlameDialog.svelte index b9a7884..0738f02 100644 --- a/src/lib/components/BlameDialog.svelte +++ b/src/lib/components/BlameDialog.svelte @@ -1,5 +1,5 @@ {:else if error}
{error}
- {:else if groups.length === 0} + {:else if lines.length === 0}
No blame information available for this file.
{:else}
+
Commit
@@ -107,26 +178,50 @@
-
- {#each groups as group (group.id)} -
-
- {group.isUncommitted ? "Uncommitted" : group.shortHash} - {group.isUncommitted ? "Not committed yet" : group.authorName} - {group.summary || "No commit message"} - {#if !group.isUncommitted} - {formatBlameDate(group.authorTime)} - {/if} + {#if groups.length === 0} +
No matches found.
+ {:else} +
+ {#each groups as group (group.id)} +
+
+ + {#each textSegments(group.isUncommitted ? "Uncommitted" : group.shortHash) as segment, index (`hash-${group.id}-${index}`)} + {#if segment.matched}{segment.text}{:else}{segment.text}{/if} + {/each} + + + {#each textSegments(group.isUncommitted ? "Not committed yet" : group.authorName) as segment, index (`author-${group.id}-${index}`)} + {#if segment.matched}{segment.text}{:else}{segment.text}{/if} + {/each} + + + {#each textSegments(group.summary || "No commit message") as segment, index (`summary-${group.id}-${index}`)} + {#if segment.matched}{segment.text}{:else}{segment.text}{/if} + {/each} + + {#if !group.isUncommitted} + + {#each textSegments(formatBlameDate(group.authorTime)) as segment, index (`date-${group.id}-${index}`)} + {#if segment.matched}{segment.text}{:else}{segment.text}{/if} + {/each} + + {/if} +
+
+ {#each group.lines as line (line.line_number)} + {line.line_number} + + {#each textSegments(line.content) as segment, index (`line-${line.line_number}-${index}`)} + {#if segment.matched}{segment.text}{:else}{segment.text}{/if} + {/each} + + {/each} +
-
- {#each group.lines as line (line.line_number)} - {line.line_number} - {line.content} - {/each} -
-
- {/each} -
+ {/each} +
+ {/if}
{/if}