Skip to content

Commit 6cceeb5

Browse files
authored
fix: keep formatting out of unselected lines (#1412)
* fix: keep formatting out of unselected lines * fix: handle selected first-line newline in markdown formatting
1 parent 0717e72 commit 6cceeb5

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

‎resources/js/lib/markdown-format.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,10 @@ export function formatMarkdown(
7272
}
7373

7474
const prefix = PREFIXES[format] ?? (() => '');
75-
const from = value.lastIndexOf('\n', start - 1) + 1;
76-
const lineEnd = value.indexOf('\n', end);
75+
const from = start === 0 ? 0 : value.lastIndexOf('\n', start - 1) + 1;
76+
// A selection ending just after a newline does not include the next line.
77+
const lastSelected = end > start && value[end - 1] === '\n' ? end - 1 : end;
78+
const lineEnd = value.indexOf('\n', lastSelected);
7779
const to = lineEnd === -1 ? value.length : lineEnd;
7880
const insert = value
7981
.slice(from, to)

‎tests/Unit/MarkdownFormat.test.ts‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,21 @@ await test('prefixes every line the selection touches', () => {
3535
assert.deepEqual(apply('What shipped', 3, 3, 'heading'), ['## What shipped', '']);
3636
assert.deepEqual(apply('a\nquote', 2, 2, 'quote'), ['a\n> quote', '']);
3737
});
38+
39+
await test('does not prefix the next line when selection ends after a newline', () => {
40+
assert.deepEqual(apply('first\nsecond', 0, 6, 'bulleted'), [
41+
'- first\nsecond',
42+
'',
43+
]);
44+
assert.deepEqual(apply('first\nsecond\nthird', 0, 13, 'numbered'), [
45+
'1. first\n2. second\nthird',
46+
'',
47+
]);
48+
});
49+
50+
void test('formats a selected first-line newline without an invalid range', () => {
51+
assert.deepEqual(apply('\nsecond', 0, 1, 'bulleted'), [
52+
'- \nsecond',
53+
'',
54+
]);
55+
});

0 commit comments

Comments
 (0)