From 8a4fb30d13db15523b0f27228a80b1fe0dccf43b Mon Sep 17 00:00:00 2001 From: Ethan Graf Date: Sat, 18 Jul 2026 23:48:59 -0400 Subject: [PATCH] Include backticks in inline-code highlight MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cm-inline-code was applied only to the text between the backticks, so when the markers were visible (cursor near) the highlight box stopped short of them. Style the whole InlineCode node instead — backticks included — matching the bold/italic content-mark pattern. When the backticks are hidden they collapse to zero width inside the same box, so the far-cursor appearance is unchanged. Co-Authored-By: Claude Opus 4.8 --- .../automerge/livePreview/codeDecoration.ts | 15 ++++++--------- .../automerge/livePreview/livePreview.test.ts | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/editors/automerge/livePreview/codeDecoration.ts b/src/editors/automerge/livePreview/codeDecoration.ts index 45c42cb..d415bda 100644 --- a/src/editors/automerge/livePreview/codeDecoration.ts +++ b/src/editors/automerge/livePreview/codeDecoration.ts @@ -47,16 +47,13 @@ export function buildCodeDecorations( node.to, PROXIMITY_CHARS, ); - const first = node.node.firstChild; - const last = node.node.lastChild; - // Content class spans between the backticks (or the whole node if - // markers are missing on malformed input). - const contentFrom = first?.name === 'CodeMark' ? first.to : node.from; - const contentTo = last?.name === 'CodeMark' ? last.from : node.to; - if (contentTo > contentFrom) { - out.push(contentFrom, contentTo, inlineCodeMark); - } + // Highlight the whole span, backticks included, so the code + // styling wraps the markers when they are visible (and when they + // are hidden they collapse to zero width inside the same box). + out.push(node.from, node.to, inlineCodeMark); if (!near) { + const first = node.node.firstChild; + const last = node.node.lastChild; if (first?.name === 'CodeMark') { out.push(first.from, first.to, inlineFormattingHiddenMark, true); } diff --git a/src/editors/automerge/livePreview/livePreview.test.ts b/src/editors/automerge/livePreview/livePreview.test.ts index 961a2d7..83639e7 100644 --- a/src/editors/automerge/livePreview/livePreview.test.ts +++ b/src/editors/automerge/livePreview/livePreview.test.ts @@ -144,17 +144,28 @@ describe('inlineFormatDecoration', () => { }); describe('codeDecoration', () => { - it('styles inline code and hides backticks when far', () => { + it('styles the whole inline-code span and hides backticks when far', () => { const state = makeState('hello world `code` end', 0); const list = decos(state, buildCodeDecorations(state)); const code = withClass(list, 'cm-inline-code'); expect(code).toHaveLength(1); - expect(code[0].text).toBe('code'); + // Highlight covers the backticks too, not just the content. + expect(code[0].text).toBe('`code`'); expect( withClass(list, 'cm-inline-formatting-hidden').map((h) => h.text), ).toEqual(['`', '`']); }); + it('keeps the backticks highlighted (and visible) when cursor is near', () => { + const state = makeState('hello world `code` end', 18); // just past closing ` + const list = decos(state, buildCodeDecorations(state)); + const code = withClass(list, 'cm-inline-code'); + expect(code).toHaveLength(1); + expect(code[0].text).toBe('`code`'); + // Backticks are visible (not hidden) while the cursor touches the span. + expect(withClass(list, 'cm-inline-formatting-hidden')).toHaveLength(0); + }); + it('paints codeblock lines and hides fences when cursor is outside', () => { const state = makeState('```js\ncode\n```\n\nafter', 18); // in "after" const list = decos(state, buildCodeDecorations(state)); -- 2.51.2