Skip to content

Commit aa929f8

Browse files
committed
feat: implement text wrapping commands and enhance image preview dimensions in MarkdownEditor
1 parent 444a56b commit aa929f8

File tree

1 file changed

+88
-7
lines changed

1 file changed

+88
-7
lines changed

custom/MarkdownEditor.vue

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,60 @@ function getTurndownService(): TurndownService {
229229
return `![${altFinal}](${src} "${escapedTitle}")`;
230230
},
231231
});
232-
232+
turndownService.escape = (s: string) => s;
233233
return turndownService;
234234
}
235235
236+
function toggleWrap(ed: monaco.editor.IStandaloneCodeEditor, left: string, right = left) {
237+
const m = ed.getModel();
238+
if (!m) return;
239+
240+
const selections = ed.getSelections() || [];
241+
if (!selections.length) return;
242+
243+
const edits: monaco.editor.IIdentifiedSingleEditOperation[] = [];
244+
const nextSelections: monaco.Selection[] = [];
245+
246+
for (const sel of selections) {
247+
const text = m.getValueInRange(sel);
248+
249+
if (sel.isEmpty()) {
250+
edits.push({ range: sel, text: `${left}${right}` });
251+
const pos = sel.getStartPosition();
252+
const col = pos.column + left.length;
253+
nextSelections.push(new monaco.Selection(pos.lineNumber, col, pos.lineNumber, col));
254+
continue;
255+
}
256+
257+
const isWrapped = text.startsWith(left) && text.endsWith(right) && text.length >= left.length + right.length;
258+
259+
if (isWrapped) {
260+
const unwrapped = text.slice(left.length, text.length - right.length);
261+
edits.push({ range: sel, text: unwrapped });
262+
263+
const start = sel.getStartPosition();
264+
nextSelections.push(new monaco.Selection(start.lineNumber, start.column, start.lineNumber, start.column + unwrapped.length));
265+
} else {
266+
edits.push({ range: sel, text: `${left}${text}${right}` });
267+
268+
const start = sel.getStartPosition();
269+
nextSelections.push(
270+
new monaco.Selection(
271+
start.lineNumber,
272+
start.column + left.length,
273+
start.lineNumber,
274+
start.column + left.length + text.length,
275+
),
276+
);
277+
}
278+
}
279+
280+
ed.pushUndoStop();
281+
ed.executeEdits('md-format', edits);
282+
ed.pushUndoStop();
283+
ed.setSelections(nextSelections);
284+
}
285+
236286
let editor: monaco.editor.IStandaloneCodeEditor | null = null;
237287
let model: monaco.editor.ITextModel | null = null;
238288
const disposables: monaco.IDisposable[] = [];
@@ -310,13 +360,14 @@ function updateImagePreviews() {
310360
preview.style.display = 'inline-block';
311361
preview.style.borderRadius = '6px';
312362
preview.style.overflow = 'hidden';
313-
preview.style.maxWidth = '220px';
314-
preview.style.maxHeight = '140px';
363+
preview.style.maxWidth = '440px';
364+
preview.style.maxHeight = '280px';
365+
315366
316367
const imageEl = document.createElement('img');
317368
imageEl.src = img.src;
318-
imageEl.style.maxWidth = '220px';
319-
imageEl.style.maxHeight = '140px';
369+
imageEl.style.maxWidth = '440px';
370+
imageEl.style.maxHeight = '280px';
320371
imageEl.style.display = 'block';
321372
imageEl.style.opacity = '0.95';
322373
@@ -325,7 +376,7 @@ function updateImagePreviews() {
325376
326377
const zone: monaco.editor.IViewZone = {
327378
afterLineNumber: img.lineNumber,
328-
heightInPx: 160,
379+
heightInPx: 320,
329380
domNode: wrapper,
330381
};
331382
@@ -336,7 +387,7 @@ function updateImagePreviews() {
336387
imageEl.onload = () => {
337388
if (!editor) return;
338389
const measured = wrapper.offsetHeight;
339-
const nextHeight = Math.max(40, Math.min(200, measured || 160));
390+
const nextHeight = Math.max(60, Math.min(520, measured || 320));
340391
if (zone.heightInPx !== nextHeight) {
341392
zone.heightInPx = nextHeight;
342393
editor.changeViewZones((a) => a.layoutZone(zoneId));
@@ -455,8 +506,38 @@ onMounted(async () => {
455506
model,
456507
language: 'markdown',
457508
automaticLayout: true,
509+
wordWrap: 'on',
510+
wrappingStrategy: 'advanced',
511+
wrappingIndent: 'same',
512+
scrollbar: {
513+
horizontal: 'hidden',
514+
},
515+
scrollBeyondLastColumn: 0,
516+
});
517+
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyI, () => {
518+
toggleWrap(editor!, '*');
458519
});
459520
521+
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyB, () => {
522+
toggleWrap(editor!, '**');
523+
});
524+
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyU, () => {
525+
toggleWrap(editor!, '<u>', '</u>');
526+
});
527+
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyE, () => {
528+
toggleWrap(editor!, '`');
529+
});
530+
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Shift | monaco.KeyCode.KeyX, () => {
531+
toggleWrap(editor!, '~~');
532+
});
533+
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyK, () => {
534+
const selection = editor!.getSelection();
535+
if (!selection) return;
536+
const text = model?.getValueInRange(selection) || '';
537+
const escaped = escapeMarkdownLinkText(text);
538+
const markdownLink = `[${escaped}](url)`;
539+
editor!.executeEdits('insert-link', [{ range: selection, text: markdownLink, forceMoveMarkers: true }]);
540+
});
460541
debug('Monaco editor created', {
461542
hasUploadPluginInstanceId: Boolean(props.meta?.uploadPluginInstanceId),
462543
});

0 commit comments

Comments
 (0)