teach codevier to highlight tokens

This commit is contained in:
Nikita Galaiko 2023-03-22 15:54:10 +01:00
parent 258ed370f7
commit 1ffb00b106
No known key found for this signature in database
GPG Key ID: EBAB54E845BA519D
5 changed files with 38 additions and 57 deletions

View File

@ -53,8 +53,8 @@ export const highlightStyle: HighlightStyle = HighlightStyle.define([
{ tag: t.emphasis, class: 'token-emphasis' }
]);
export function create(code: string, mimeType: string): CodeHighlighter {
const language = languageFromFilename(mimeType);
export function create(code: string, filepath: string): CodeHighlighter {
const language = languageFromFilename(filepath);
let tree: Tree;
if (language) {
tree = language.language.parser.parse(code);

View File

@ -10,6 +10,7 @@
export let doc: string;
export let deltas: Delta[];
export let filepath: string;
export let highlight: string[] = [];
export let paddingLines = 10000;
const applyDeltas = (text: string, deltas: Delta[]) => {
@ -40,7 +41,7 @@
$: right = deltas.length > 0 ? applyDeltas(left, deltas.slice(deltas.length - 1)) : left;
$: diff = lineDiff(left.split('\n'), right.split('\n'));
$: diffRows = buildDiffRows(diff, { paddingLines: paddingLines });
$: diffRows = buildDiffRows(diff, { paddingLines });
$: originalHighlighter = create(diffRows.originalLines.join('\n'), filepath);
$: originalMap = documentMap(diffRows.originalLines);
$: currentHighlighter = create(diffRows.currentLines.join('\n'), filepath);
@ -62,8 +63,19 @@
for (const token of row.tokens) {
let tokenContent = '';
doc.highlightRange(pos, pos + token.text.length, (text, style) => {
tokenContent += style ? `<span class=${style}>${sanitize(text)}</span>` : sanitize(text);
doc.highlightRange(pos, pos + token.text.length, (text, classNames) => {
const shouldHighlight =
(row.type === RowType.Deletion || row.type === RowType.Addition) &&
highlight.find((h) => text.includes(h));
if (classNames && shouldHighlight) {
tokenContent += `<span class=${classNames}><mark>${sanitize(text)}</mark></span>`;
} else if (shouldHighlight) {
tokenContent += `<mark>${sanitize(text)}</mark>`;
} else if (classNames) {
tokenContent += `<span class=${classNames}>${sanitize(text)}</span>`;
} else {
tokenContent += sanitize(text);
}
});
content.push(

View File

@ -152,7 +152,7 @@
}
</script>
<div class="flex flex-row h-full">
<div class="flex h-full flex-row">
<div class="flex w-[500px] min-w-[500px] flex-shrink-0 flex-col p-2">
<div
class="button group mb-2 flex max-w-[500px] rounded border border-zinc-600 bg-zinc-700 py-2 px-4 text-zinc-300 shadow"
@ -188,7 +188,7 @@
<div class="changed-files-list-container mt-2 mb-4">
<div
class="changed-files-list rounded border font-mono text-zinc-900 border-t-[0.5px] border-r-[0.5px] border-b-[0.5px] border-l-[0.5px] border-gb-700 bg-gb-900"
class="changed-files-list rounded border border-t-[0.5px] border-r-[0.5px] border-b-[0.5px] border-l-[0.5px] border-gb-700 bg-gb-900 font-mono text-zinc-900"
>
<div
class="mb-2 flex flex-row space-x-2 rounded-t border-b border-b-gb-750 bg-gb-800 p-2 text-zinc-200"
@ -229,14 +229,14 @@
name="subject"
bind:value={commitSubject}
placeholder={placeholderSubject}
class="mb-2 block w-full rounded-md p-4 bg-zinc-700 border-zinc-600 text-zinc-200 ring-1 ring-inset ring-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:py-1.5 sm:text-sm sm:leading-6"
class="mb-2 block w-full rounded-md border-zinc-600 bg-zinc-700 p-4 text-zinc-200 ring-1 ring-inset ring-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:py-1.5 sm:text-sm sm:leading-6"
/>
<textarea
rows={messageRows}
name="message"
placeholder={placeholderMessage}
bind:value={commitMessage}
class="mb-2 block w-full rounded-md p-4 bg-zinc-700 border-zinc-600 text-zinc-200 ring-1 ring-inset ring-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:py-1.5 sm:text-sm sm:leading-6"
class="mb-2 block w-full rounded-md border-zinc-600 bg-zinc-700 p-4 text-zinc-200 ring-1 ring-inset ring-gray-600 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-blue-600 sm:py-1.5 sm:text-sm sm:leading-6"
/>
</div>
@ -258,7 +258,7 @@
{/if}
{#if !generatedMessage}
<a
class="cursor-pointer rounded bg-green-800 p-2 text-zinc-50 bg-gradient-to-b from-[#623871] to-[#502E5C] shadow"
class="cursor-pointer rounded bg-green-800 bg-gradient-to-b from-[#623871] to-[#502E5C] p-2 text-zinc-50 shadow"
on:click={fetchCommitMessage}>✨ Generate commit message</a
>
{:else if generatedMessage == 'loading'}
@ -275,13 +275,13 @@
{/if}
</div>
</div>
<div class="h-full max-h-screen flex-grow overflow-auto p-2 h-100">
<div class="h-100 h-full max-h-screen flex-grow overflow-auto p-2">
{#if currentDiff}
<DiffViewer diff={currentDiff} path={currentPath} />
{:else if addedContents}
<pre class="bg-green-900">{addedContents}</pre>
{:else}
<div class="text-zinc-400 text-center text-lg p-20">Select a file to view changes.</div>
<div class="p-20 text-center text-lg text-zinc-400">Select a file to view changes.</div>
{/if}
</div>
<!-- commit message -->

View File

@ -4,8 +4,9 @@
import { getContext } from 'svelte';
import type { Writable } from 'svelte/store';
import { listFiles } from '$lib/sessions';
import { formatDistanceToNow } from 'date-fns';
import { list as listDeltas, type Delta } from '$lib/deltas';
import ResultSnippet from './ResultSnippet.svelte';
import { CodeViewer } from '$lib/components';
export let data: PageData;
const { project } = data;
@ -70,8 +71,19 @@
<ul class="flex-auto overflow-auto">
{#each processedResults as { doc, deltas, filepath, highlight }}
{@const timestamp = deltas[deltas.length - 1].timestampMs}
<li class="mt-6">
<ResultSnippet {doc} {deltas} {filepath} mark={highlight} />
<div class="flex flex-col gap-2">
<p class="flex justify-between text-lg">
<span>{filepath}</span>
<span>{formatDistanceToNow(timestamp)} ago</span>
</p>
<div
class="flex-auto overflow-auto rounded-lg border border-zinc-700 bg-[#2F2F33] text-[#EBDBB2] drop-shadow-lg"
>
<CodeViewer {doc} {deltas} {filepath} paddingLines={4} {highlight} />
</div>
</div>
</li>
{/each}
</ul>

View File

@ -1,43 +0,0 @@
<script lang="ts">
import { CodeViewer } from '$lib/components';
import type { Delta } from '$lib/deltas';
import { formatDistanceToNow } from 'date-fns';
import { onMount } from 'svelte';
export let doc: string;
export let deltas: Delta[];
export let filepath: string;
export let mark: string[];
const timestamp = deltas[deltas.length - 1].timestampMs;
let viewer: HTMLDivElement;
const markElement = (node: Element) => {
if (node.textContent === null) return;
node.innerHTML = node.innerHTML.replaceAll(
new RegExp(mark.join('|'), 'g'),
(match) => `<span style="background: #AC8F2F;">${match}</span>`
);
};
onMount(() => {
if (mark.length === 0) return;
for (const elem of viewer.getElementsByClassName('line-changed')) {
markElement(elem);
}
});
</script>
<div class="flex flex-col gap-2">
<p class="flex justify-between text-lg">
<span>{filepath}</span>
<span>{formatDistanceToNow(timestamp)} ago</span>
</p>
<div
bind:this={viewer}
class="flex-auto overflow-auto rounded-lg border border-zinc-700 bg-[#2F2F33] text-[#EBDBB2] drop-shadow-lg"
>
<CodeViewer {doc} {deltas} {filepath} paddingLines={4} />
</div>
</div>