Skip to content

Commit cd9e6b6

Browse files
trangdoan982claude
andauthored
ENG-1610: Pre-fill create node dialog with highlighted text (#969)
When the "Create/Insert discourse node" command is triggered with text selected in a block, the dialog title field is now pre-filled with that text. On success, the selected text is also replaced by the inserted page reference instead of inserting at cursor position. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 4717625 commit cd9e6b6

1 file changed

Lines changed: 38 additions & 7 deletions

File tree

apps/roam/src/utils/registerCommandPaletteCommands.ts

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,19 +166,48 @@ export const registerCommandPaletteCommands = (onloadArgs: OnloadArgs) => {
166166
renderSettings({ onloadArgs });
167167
};
168168

169-
const getSelectionStartForBlock = (uid: string): number => {
169+
type BlockSelection = {
170+
selectionStart: number;
171+
selectionEnd: number;
172+
selectedText: string;
173+
};
174+
175+
const getBlockSelection = (uid: string): BlockSelection => {
170176
const activeElement = document.activeElement;
171177
const isFocusedTextarea =
172178
activeElement instanceof HTMLTextAreaElement &&
173179
activeElement.classList.contains("rm-block-input") &&
174180
getUids(activeElement).blockUid === uid;
175-
if (isFocusedTextarea) return activeElement.selectionStart;
181+
if (isFocusedTextarea) {
182+
return {
183+
selectionStart: activeElement.selectionStart,
184+
selectionEnd: activeElement.selectionEnd,
185+
selectedText: activeElement.value.substring(
186+
activeElement.selectionStart,
187+
activeElement.selectionEnd,
188+
),
189+
};
190+
}
176191
const textareas = document.querySelectorAll("textarea.rm-block-input");
177192
for (const el of textareas) {
178193
const textarea = el as HTMLTextAreaElement;
179-
if (getUids(textarea).blockUid === uid) return textarea.selectionStart;
194+
if (getUids(textarea).blockUid === uid) {
195+
return {
196+
selectionStart: textarea.selectionStart,
197+
selectionEnd: textarea.selectionEnd,
198+
selectedText: textarea.value.substring(
199+
textarea.selectionStart,
200+
textarea.selectionEnd,
201+
),
202+
};
203+
}
180204
}
181-
return (getTextByBlockUid(uid) || "").length;
205+
const textLength = (getTextByBlockUid(uid) || "").length;
206+
return {
207+
selectionStart: textLength,
208+
selectionEnd: textLength,
209+
selectedText: "",
210+
};
182211
};
183212

184213
const createDiscourseNodeFromCommand = () => {
@@ -187,12 +216,14 @@ export const registerCommandPaletteCommands = (onloadArgs: OnloadArgs) => {
187216
const uid = focusedBlock?.["block-uid"];
188217
const windowId = focusedBlock?.["window-id"] || "main-window";
189218

190-
const selectionStart = uid ? getSelectionStartForBlock(uid) : 0;
219+
const { selectionStart, selectionEnd, selectedText } = uid
220+
? getBlockSelection(uid)
221+
: { selectionStart: 0, selectionEnd: 0, selectedText: "" };
191222

192223
renderModifyNodeDialog({
193224
mode: "create",
194225
nodeType: "",
195-
initialValue: { text: "", uid: "" },
226+
initialValue: { text: selectedText, uid: "" },
196227
extensionAPI,
197228
onSuccess: async (result) => {
198229
if (!uid) {
@@ -204,7 +235,7 @@ export const registerCommandPaletteCommands = (onloadArgs: OnloadArgs) => {
204235
}
205236
const originalText = getTextByBlockUid(uid) || "";
206237
const pageRef = `[[${result.text}]]`;
207-
const newText = `${originalText.substring(0, selectionStart)}${pageRef}${originalText.substring(selectionStart)}`;
238+
const newText = `${originalText.substring(0, selectionStart)}${pageRef}${originalText.substring(selectionEnd)}`;
208239
const newCursorPosition = selectionStart + pageRef.length;
209240

210241
await updateBlock({ uid, text: newText });

0 commit comments

Comments
 (0)