fixes in styles
This commit is contained in:
@@ -109,3 +109,76 @@ export function bindFormatShortcuts(editor) {
|
||||
applyFormat(editor, format);
|
||||
});
|
||||
}
|
||||
|
||||
function selectedLineRange(value, start, end) {
|
||||
const blockStart = value.lastIndexOf("\n", Math.max(0, start - 1)) + 1;
|
||||
let blockEnd = value.indexOf("\n", end);
|
||||
if (blockEnd < 0) blockEnd = value.length;
|
||||
if (end > start && value[end - 1] === "\n") blockEnd = end - 1;
|
||||
return { blockStart, blockEnd };
|
||||
}
|
||||
|
||||
function mapOffsetThroughEdits(offset, edits) {
|
||||
let delta = 0;
|
||||
for (const edit of edits) {
|
||||
if (offset < edit.start) break;
|
||||
const editEnd = edit.start + edit.remove;
|
||||
if (offset <= editEnd) return edit.start + delta + edit.insert.length;
|
||||
delta += edit.insert.length - edit.remove;
|
||||
}
|
||||
return offset + delta;
|
||||
}
|
||||
|
||||
export function applyIndentation(editor, { outdent = false, size = 2 } = {}) {
|
||||
if (!editor || editor.readOnly) return false;
|
||||
const indent = " ".repeat(Math.max(1, Number(size) || 2));
|
||||
const start = editor.selectionStart;
|
||||
const end = editor.selectionEnd;
|
||||
const direction = editor.selectionDirection || "none";
|
||||
|
||||
if (!outdent && start === end) {
|
||||
editor.setRangeText(indent, start, end, "end");
|
||||
editor.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
return true;
|
||||
}
|
||||
|
||||
const value = editor.value;
|
||||
const { blockStart, blockEnd } = selectedLineRange(value, start, end);
|
||||
const block = value.slice(blockStart, blockEnd);
|
||||
const lineStarts = [0];
|
||||
for (let index = 0; index < block.length; index++) {
|
||||
if (block[index] === "\n") lineStarts.push(index + 1);
|
||||
}
|
||||
|
||||
const edits = lineStarts.map(relativeStart => {
|
||||
const absoluteStart = blockStart + relativeStart;
|
||||
if (!outdent) return { start: absoluteStart, remove: 0, insert: indent };
|
||||
const line = value.slice(absoluteStart, value.indexOf("\n", absoluteStart) < 0 ? value.length : value.indexOf("\n", absoluteStart));
|
||||
const removable = line.startsWith("\t") ? 1 : Math.min(indent.length, (line.match(/^ +/) || [""])[0].length);
|
||||
return { start: absoluteStart, remove: removable, insert: "" };
|
||||
}).filter(edit => edit.remove || edit.insert);
|
||||
|
||||
if (!edits.length) return false;
|
||||
let replacement = block;
|
||||
for (let index = edits.length - 1; index >= 0; index--) {
|
||||
const edit = edits[index];
|
||||
const relativeStart = edit.start - blockStart;
|
||||
replacement = `${replacement.slice(0, relativeStart)}${edit.insert}${replacement.slice(relativeStart + edit.remove)}`;
|
||||
}
|
||||
|
||||
const nextStart = mapOffsetThroughEdits(start, edits);
|
||||
const nextEnd = mapOffsetThroughEdits(end, edits);
|
||||
editor.setRangeText(replacement, blockStart, blockEnd, "start");
|
||||
editor.setSelectionRange(nextStart, nextEnd, direction);
|
||||
editor.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
return true;
|
||||
}
|
||||
|
||||
export function bindIndentationShortcuts(editor, { size = 2 } = {}) {
|
||||
editor.addEventListener("keydown", event => {
|
||||
if (event.key !== "Tab" || event.ctrlKey || event.metaKey || event.altKey) return;
|
||||
if (editor.readOnly) return;
|
||||
event.preventDefault();
|
||||
applyIndentation(editor, { outdent: event.shiftKey, size });
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user