code block: copy and language selection#2871
code block: copy and language selection#2871Soxasora wants to merge 7 commits intostackernews:masterfrom
Conversation
| /> | ||
| ) | ||
| : <span className={codeStyles.codeActionLanguage}>{getLanguageFriendlyName(lang)}</span>} | ||
| <CopyButton icon value={getCodeContent()} /> |
There was a problem hiding this comment.
Copy button captures stale code content at render
Low Severity
getCodeContent() is eagerly evaluated at render time and passed as a static value prop to CopyButton. The CodeActionMenuContainer only re-renders when isShown, lang, or position state changes — not when the code block's text content changes. If the user edits the code block content while the action menu is visible (e.g., via keyboard while mouse hovers over the copy button area), clicking copy will capture stale content from the last render rather than current content.
Additional Locations (1)
There was a problem hiding this comment.
Lexical selection is not lost by clicking quote reply and getCodeContent() creates a live read transaction in the editor (the reader in this case):
const getCodeContent = useCallback(() => {
const domNode = codeDOMNodeRef.current
if (!domNode) return ''
let content = ''
editor.read(() => {
const codeNode = getCodeNodeFromDOMNode(domNode)
if (codeNode) content = codeNode.getTextContent()
})
return content
}, [editor])| right: `${editorRight - right + CODE_PADDING}px`, | ||
| top: `${y - editorY}px` | ||
| }) | ||
| } |
There was a problem hiding this comment.
Menu not hidden when code node belongs to different editor
Low Severity
When handleMouseMove finds a codeDOMNode via DOM query but getCodeNodeFromDOMNode returns null (the node isn't in this editor's Lexical tree), the handler falls through without hiding the menu. Additionally, codeDOMNodeRef.current is updated on line 169 before validating the node belongs to this editor. In multi-reader pages (e.g., a feed with multiple posts containing code blocks), hovering from one reader's code block to another's leaves a stale menu visible and points codeDOMNodeRef at the wrong code block, causing getCodeContent() to return an empty string on copy.
|
This looks good to me and works well. My bot found issues, but I don't think they're worth blocking for as they seem to be issues beyond the scope of the PR (generic to linebreaks) or assume many simultaneous code editors: I found 3 concrete risks against
lmk |
…e mousemove on language selector close
|
I still need to verify the other claims but the 2nd is actually a problem I didn't foresee. If you open the code language selector on confused.codeblocks.mov |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 3 total unresolved issues (including 2 from previous reviews).
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| setFilter('') | ||
| onClose() | ||
| } | ||
| }, [open, isEditingRef, onClose]) |
There was a problem hiding this comment.
Language close handler can trigger render loop
High Severity
LanguageSelector effect depends on onClose, but parent passes a new inline onClose each render. When closed, effect calls onClose, which can call handleMouseMove and update position state, causing another render and another new onClose, repeatedly.


Post #2865
Description
Closes #2857
Adds code actions on code block hover:
Screenshots
Additional Context
tbd
Checklist
Are your changes backward compatible? Please answer below:
Yes
On a scale of 1-10 how well and how have you QA'd this change and any features it might affect? Please answer below:
6, in QA
For frontend changes: Tested on mobile, light and dark mode? Please answer below:
Yes, tested on mobile Safari and Chrome, in both light and dark mode.
Did you introduce any new environment variables? If so, call them out explicitly here:
n/a
Did you use AI for this? If so, how much did it assist you?
Porting and refactor of the dom injection logic from the original PR
Note
Medium Risk
Introduces new global mouse event handling and Lexical mutation listeners to show a hover UI over code blocks; risk is mainly UI/interaction regressions and performance in documents with many code blocks.
Overview
Adds a new
CodeActionMenuPluginthat appears when hovering code blocks, showing a copy button and a language selector (disabled in read-only/reader mode).Wires this plugin into both the rich editor (
editor.js) and the reader (reader.js), adds new CSS for the hover UI, and factors the dropdown portal helper into a sharedMenuAlternateDimensionutility used by both the toolbar and the new code actions menu.Written by Cursor Bugbot for commit a6ef0a1. This will update automatically on new commits. Configure here.