bytebeat-composer/src/code-editor/textarea.ts

58 lines
1.6 KiB
TypeScript
Raw Permalink Normal View History

export function initTextarea(editCallback: () => void, textarea: HTMLTextAreaElement) {
2024-03-13 21:20:53 +01:00
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
2024-08-09 20:43:51 +02:00
const lines = textarea.value.split("\n");
2024-03-13 21:20:53 +01:00
2024-08-09 20:43:51 +02:00
function getLine(char: number) {
2024-03-13 21:20:53 +01:00
let line = 0;
for (let c = 0; ; line++) {
c += lines[line].length;
2024-08-09 20:43:51 +02:00
if (c > char) {
2024-04-23 23:16:19 +02:00
break;
2024-08-09 20:43:51 +02:00
}
2024-03-13 21:20:53 +01:00
}
return line;
};
2024-08-09 20:43:51 +02:00
const startLine = getLine(selectionStart);
const endLine = getLine(selectionEnd);
2024-03-13 21:20:53 +01:00
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;
}
}
});
}