Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,33 @@ export class AttachmentAction extends TextEditorAction {

/**
* Executes the action in the current editor with the given arguments (url and text).
* @param args The text and url of the attachment to insert. If one or both are not provided, the default text will be inserted.
* @param args The text and url of the attachment to insert. If one or both are not provided, checks for selected text to wrap.
*/
executeInCurrentEditor(args?: AttachmentArguments): void {
super.executeInCurrentEditor(args);
}

/**
* Inserts, at the current selection, the attachment markdown with the given text and url if they were provided, or the default text otherwise.
* Inserts, at the current selection, the attachment markdown with the given text and url if they were provided.
* If no arguments are provided and there is selected text, wraps the selected text with ![selectedText](https://).
* Otherwise, inserts the default text.
* @param editor The editor in which to insert the attachment.
* @param args The text and url of the attachment to insert. If one or both are not provided, the default text will be inserted.
* @param args The text and url of the attachment to insert. If one or both are not provided, checks for selected text to wrap.
*/
run(editor: TextEditor, args?: AttachmentArguments): void {
if (!args?.text || !args?.url) {
this.replaceTextAtCurrentSelection(editor, AttachmentAction.DEFAULT_INSERT_TEXT);
// Check if there's selected text
const selectedText = this.getSelectedText(editor);
if (selectedText && selectedText.trim()) {
// Wrap selected text with attachment syntax
const selection = editor.getSelection();
if (selection) {
this.replaceTextAtRange(editor, selection, `![${sanitizeStringForMarkdownEditor(selectedText)}](https://)`);
}
} else {
// No selection, insert default text
this.replaceTextAtCurrentSelection(editor, AttachmentAction.DEFAULT_INSERT_TEXT);
}
} else {
this.replaceTextAtCurrentSelection(editor, `![${sanitizeStringForMarkdownEditor(args.text)}](${args.url})`);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,33 @@ export class UrlAction extends TextEditorAction {

/**
* Executes the action in the current editor with the given arguments (url and text).
* @param args The text and url of the URL to insert. If one or both are not provided, the default text will be inserted.
* @param args The text and url of the URL to insert. If one or both are not provided, checks for selected text to wrap.
*/
executeInCurrentEditor(args?: UrlArguments): void {
super.executeInCurrentEditor(args);
}

/**
* Inserts, at the current selection, the markdown URL with the given text and url if they were provided, or the default text otherwise.
* Inserts, at the current selection, the markdown URL with the given text and url if they were provided.
* If no arguments are provided and there is selected text, wraps the selected text with [selectedText](https://).
* Otherwise, inserts the default text.
* @param editor The editor in which to insert the URL.
* @param args The text and url of the URL to insert. If one or both are not provided, the default text will be inserted.
* @param args The text and url of the URL to insert. If one or both are not provided, checks for selected text to wrap.
*/
run(editor: TextEditor, args?: UrlArguments): void {
if (!args?.text || !args?.url) {
this.replaceTextAtCurrentSelection(editor, UrlAction.DEFAULT_INSERT_TEXT);
// Check if there's selected text
const selectedText = this.getSelectedText(editor);
if (selectedText && selectedText.trim()) {
// Wrap selected text with link syntax
const selection = editor.getSelection();
if (selection) {
this.replaceTextAtRange(editor, selection, `[${sanitizeStringForMarkdownEditor(selectedText)}](https://)`);
}
} else {
// No selection, insert default text
this.replaceTextAtCurrentSelection(editor, UrlAction.DEFAULT_INSERT_TEXT);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Extract duplicated wrapping logic to parent class.

The text-wrapping logic in lines 39-51 is nearly identical to lines 81-93 in attachment.action.ts. The only difference is the markdown syntax format ([text](url) vs ![text](url)).

Consider extracting this shared logic to the parent TextEditorAction class with a method like:

protected wrapSelectionOrInsertDefault(
    editor: TextEditor,
    wrapFormat: (text: string) => string,
    defaultText: string
): void {
    const selectedText = this.getSelectedText(editor)?.trim();
    if (selectedText) {
        const selection = editor.getSelection();
        if (selection) {
            this.replaceTextAtRange(editor, selection, wrapFormat(sanitizeStringForMarkdownEditor(selectedText)));
        }
    } else {
        this.replaceTextAtCurrentSelection(editor, defaultText);
    }
}

Then both classes can call:

// In UrlAction:
this.wrapSelectionOrInsertDefault(editor, (text) => `[${text}](https://)`, UrlAction.DEFAULT_INSERT_TEXT);

// In AttachmentAction:
this.wrapSelectionOrInsertDefault(editor, (text) => `![${text}](https://)`, AttachmentAction.DEFAULT_INSERT_TEXT);
🤖 Prompt for AI Agents
src/main/webapp/app/shared/monaco-editor/model/actions/url.action.ts lines
39-51: the selection-wrapping logic here duplicates logic in
attachment.action.ts (lines ~81-93) differing only by the wrapper syntax; move
that shared behavior into the parent TextEditorAction by adding a protected
helper (e.g., wrapSelectionOrInsertDefault) that accepts the editor, a function
to produce the wrapped string from sanitized text, and the default insert text,
and then replace the duplicated blocks in UrlAction and AttachmentAction with
calls to that helper using the appropriate wrapper-producing function for
`[text](https://)` and `![text](https://)` respectively.

} else {
this.replaceTextAtCurrentSelection(editor, `[${sanitizeStringForMarkdownEditor(args.text)}](${args.url})`);
}
Expand Down
Loading