mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-08-29 08:31:18 +02:00
4dee52f82d
* ui: split the markdown rendering setting per surface User content and thinking get their own toggle again, so turning off markdown for a message leaves reasoning blocks formatted. Both default to markdown. A stored renderContentAsRawText unfolds onto the user key and is dropped from the config. File mentions render as badges in the raw text path too, through a narrow pass over [name](file://path) that leaves everything else untouched. * ui: let the rich chat input scroll past its max height The contenteditable renderer caps its height with max-height but had no overflow rule, so a long buffer overflowed into the input area wrapper and got clipped by its overflow-hidden, leaving no way to reach the bottom of the message. The textarea renderer scrolls natively and was never affected. * ui: apply the new lint and format config * ui: move the render keys unfolding into the migration service Address review from @allozaur: the settings store no longer rewrites persisted config on load, the raw text toggle now unfolds onto the per-surface render keys in migration.service.ts, next to the other config migrations. The mention scanner flag and the directory path suffix become named constants.
49 lines
1.6 KiB
TypeScript
49 lines
1.6 KiB
TypeScript
import { splitMentionSegments } from '$lib/utils/mention-badge';
|
|
import { describe, expect, it } from 'vitest';
|
|
|
|
describe('splitMentionSegments', () => {
|
|
it('returns a single plain run when there is no mention', () => {
|
|
const segments = splitMentionSegments('# not a heading here');
|
|
|
|
expect(segments).toEqual([{ mention: null, text: '# not a heading here' }]);
|
|
});
|
|
|
|
it('splits text around a mention', () => {
|
|
const segments = splitMentionSegments('look at [main.c](file:///src/main.c) please');
|
|
|
|
expect(segments.map((segment) => segment.text)).toEqual([
|
|
'look at ',
|
|
'[main.c](file:///src/main.c)',
|
|
' please'
|
|
]);
|
|
expect(segments[1].mention).toEqual({ name: 'main.c', path: '/src/main.c' });
|
|
});
|
|
|
|
it('decodes percent-encoded paths', () => {
|
|
const segments = splitMentionSegments('[a b.txt](file:///tmp/a%20b.txt)');
|
|
|
|
expect(segments[0].mention?.path).toBe('/tmp/a b.txt');
|
|
});
|
|
|
|
it('keeps the directory marker so the folder icon is picked', () => {
|
|
const segments = splitMentionSegments('[src](file:///repo/src/)');
|
|
|
|
expect(segments[0].mention?.path).toBe('/repo/src/');
|
|
});
|
|
|
|
it('handles adjacent mentions with no text between them', () => {
|
|
const segments = splitMentionSegments('[a](file:///a)[b](file:///b)');
|
|
|
|
expect(segments).toHaveLength(2);
|
|
expect(segments.every((segment) => segment.mention !== null)).toBe(true);
|
|
});
|
|
|
|
it('preserves the exact source when segments are joined back', () => {
|
|
const source = 'see [a](file:///a) and [b](file:///b/) done';
|
|
|
|
expect(splitMentionSegments(source).reduce((acc, segment) => acc + segment.text, '')).toBe(
|
|
source
|
|
);
|
|
});
|
|
});
|