char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Aleksander Grygierui: Constants refactor (#26908)e21152dc9

char/aliceai-t5-moe
3.9 KiB130 linesraw
1import { abbreviateHome, lastPathSegment } from './path-display';
2import {
3	DIRECTORY_PATH_SUFFIX,
4	FILE_URI_PREFIX,
5	MENTION_BADGE_FILE_ICON_PATHS,
6	MENTION_BADGE_FOLDER_ICON_PATHS,
7	MENTION_LINK_SCAN_FLAGS
8} from '$lib/constants';
9import { FileMentionEntryType } from '$lib/enums';
10import type { FileMentionEntry } from '$lib/types';
11
12export {
13	MENTION_BADGE_CLASSNAME,
14	MENTION_BADGE_ICON_CLASSNAME,
15	MENTION_BADGE_SVG_ATTRIBUTES,
16	MENTION_BADGE_FILE_ICON_PATHS,
17	MENTION_BADGE_FOLDER_ICON_PATHS
18} from '$lib/constants';
19
20// `)` is allowed in a path only when not followed by whitespace or `[`,
21// so macOS paths parse while adjacent badges still terminate the match.
22const FILE_MENTION_LINK_SOURCE = String.raw`\[([^\]\n]+?)\]\(file:\/\/((?:[^)\n]|\)(?![\s[]))+)\)`;
23
24export function fileMentionLinkRe(flags = ''): RegExp {
25	return new RegExp(FILE_MENTION_LINK_SOURCE, flags);
26}
27
28export function containsFileMentionLink(value: string): boolean {
29	return fileMentionLinkRe().test(value);
30}
31
32// Escape each path segment for a markdown link destination (spaces/parens
33// break CommonMark); keeps the trailing slash that marks a directory.
34export function encodeFileLinkPath(path: string): string {
35	return path
36		.split('/')
37		.map((segment) => encodeURIComponent(segment))
38		.join('/');
39}
40
41// Malformed escape sequences fall back to the input unchanged.
42export function decodeFileLinkPath(path: string): string {
43	try {
44		return path
45			.split('/')
46			.map((segment) => decodeURIComponent(segment))
47			.join('/');
48	} catch {
49		return path;
50	}
51}
52
53export interface MentionTextSegment {
54	text: string;
55	mention: { name: string; path: string } | null;
56}
57
58/**
59 * Split raw text into plain runs and `[name](file://path)` mentions.
60 * The raw-text renderers walk these segments to draw badges without
61 * handing the message to the markdown parser, so a `#` stays a `#`.
62 */
63export function splitMentionSegments(value: string): MentionTextSegment[] {
64	const linkRe = fileMentionLinkRe(MENTION_LINK_SCAN_FLAGS);
65	const segments: MentionTextSegment[] = [];
66
67	let cursor = 0;
68	let match: RegExpExecArray | null;
69
70	while ((match = linkRe.exec(value)) !== null) {
71		if (match.index > cursor) {
72			segments.push({ mention: null, text: value.slice(cursor, match.index) });
73		}
74
75		segments.push({
76			mention: { name: match[1], path: decodeFileLinkPath(match[2]) },
77			text: match[0]
78		});
79
80		cursor = match.index + match[0].length;
81	}
82
83	if (cursor < value.length) segments.push({ mention: null, text: value.slice(cursor) });
84
85	return segments;
86}
87
88export function getMentionBadgeIconPaths(path: string): readonly string[] {
89	return path.endsWith(DIRECTORY_PATH_SUFFIX)
90		? MENTION_BADGE_FOLDER_ICON_PATHS
91		: MENTION_BADGE_FILE_ICON_PATHS;
92}
93
94export function getMentionBadgeLabel(
95	name: string,
96	path: string,
97	showFullPath: boolean,
98	home?: string | null
99): string {
100	if (!showFullPath) return name;
101
102	const decoded = decodeFileLinkPath(path.replace(/\/+$/, ''));
103
104	if (!decoded) return name;
105
106	return abbreviateHome(decoded, home);
107}
108
109/**
110 * Build the markdown link that replaces a mention token. Entry `path` is
111 * already rooted, so `file://` + `/abs` yields the canonical `file:///`.
112 * Null when the token is invalid.
113 */
114export function buildMentionInsertion(
115	entry: FileMentionEntry,
116	value: string,
117	token: { start: number; end: number }
118): { newValue: string; caretOffset: number } | null {
119	if (token.start < 0 || token.end > value.length || token.start > token.end) return null;
120
121	// Strip the entry's directory marker so it is not doubled below.
122	const cleanedPath = entry.path.replace(/\/+$/, '');
123	const pathWithSeparator =
124		entry.type === FileMentionEntryType.DIRECTORY ? `${cleanedPath}/` : cleanedPath;
125	const basename = lastPathSegment(cleanedPath) || entry.name;
126	const insertion = `[${basename}](${FILE_URI_PREFIX}${encodeFileLinkPath(pathWithSeparator)}) `;
127	const newValue = value.slice(0, token.start) + insertion + value.slice(token.end);
128
129	return { caretOffset: token.start + insertion.length, newValue };
130}