bytebeat-composer/src/code-editor/textarea.ts
2024-08-09 15:07:45 -04:00

57 lines
1.6 KiB
TypeScript

export function initTextarea(editCallback: () => void, textarea: HTMLTextAreaElement) {
textarea.addEventListener("input", () => editCallback());
let keyTrap = true;
textarea.addEventListener("keydown", e => {
if (!e.altKey && !e.ctrlKey) {
if (e.key === "Escape") {
if (keyTrap) {
e.preventDefault();
keyTrap = false;
}
} else if (e.key === "Tab" && keyTrap) {
e.preventDefault();
const { selectionStart, selectionEnd } = textarea;
if (e.shiftKey) {
// remove indentation on all selected lines
const lines = textarea.value.split("\n");
function getLine(char: number) {
let line = 0;
for (let c = 0; ; line++) {
c += lines[line].length;
if (c > char) {
break;
}
}
return line;
};
const startLine = getLine(selectionStart);
const endLine = getLine(selectionEnd);
let newSelectionStart = selectionStart;
let newSelectionEnd = selectionEnd;
for (let i = startLine; i <= endLine; i++) {
if (lines[i][0] === "\t") {
lines[i] = lines[i].slice(1);
if (i === startLine) {
newSelectionStart--;
}
newSelectionEnd--;
}
}
textarea.value = lines.join("\n");
textarea.setSelectionRange(newSelectionStart, newSelectionEnd);
} else {
// add tab character
textarea.value = `${textarea.value.slice(0, selectionStart)}\t${textarea.value.slice(
selectionEnd,
)}`;
textarea.setSelectionRange(selectionStart + 1, selectionStart + 1);
}
editCallback();
} else {
keyTrap = false;
}
}
});
}