1
0
silverbullet/plugs/editor/text.ts

143 lines
3.9 KiB
TypeScript
Raw Normal View History

2023-08-28 15:12:15 +00:00
import { editor } from "$sb/syscalls.ts";
export async function quoteSelection() {
2022-10-14 13:11:33 +00:00
let text = await editor.getText();
const selection = await editor.getSelection();
let from = selection.from;
while (from >= 0 && text[from] !== "\n") {
from--;
}
from++;
if (text[from] === ">" && text[from + 1] === " ") {
// Already quoted, we have to unquote
text = text.slice(from + 2, selection.to);
text = text.replaceAll("\n> ", "\n");
} else {
text = text.slice(from, selection.to);
text = `> ${text.replaceAll("\n", "\n> ")}`;
}
2022-10-14 13:11:33 +00:00
await editor.replaceRange(from, selection.to, text);
}
2022-06-23 15:59:18 +00:00
export async function listifySelection() {
2022-10-14 13:11:33 +00:00
let text = await editor.getText();
const selection = await editor.getSelection();
//if very first of doc, just add a bullet and end
if (selection.to == 0 && selection.from == 0) {
2023-01-22 17:53:14 +00:00
await editor.insertAtCursor("* ");
return;
}
2022-06-23 15:59:18 +00:00
let from = selection.from;
if (text[from] == "\n") {
//end of line, need to find previous line break
2023-01-22 17:53:14 +00:00
from--;
}
2022-06-23 15:59:18 +00:00
while (from >= 0 && text[from] !== "\n") {
from--;
}
from++;
text = text.slice(from, selection.to);
text = `* ${text.replaceAll(/\n(?!\n)/g, "\n* ")}`;
2022-10-14 13:11:33 +00:00
await editor.replaceRange(from, selection.to, text);
2022-06-23 15:59:18 +00:00
}
export async function numberListifySelection() {
2022-10-14 13:11:33 +00:00
let text = await editor.getText();
const selection = await editor.getSelection();
2022-06-23 15:59:18 +00:00
let from = selection.from;
while (from >= 0 && text[from] !== "\n") {
from--;
}
from++;
text = text.slice(from, selection.to);
let counter = 1;
2023-01-22 17:53:14 +00:00
text = `1. ${
text.replaceAll(/\n(?!\n)/g, () => {
counter++;
return `\n${counter}. `;
})
}`;
2022-10-14 13:11:33 +00:00
await editor.replaceRange(from, selection.to, text);
2022-06-23 15:59:18 +00:00
}
2022-07-10 15:51:34 +00:00
export async function linkSelection() {
2022-10-14 13:11:33 +00:00
const text = await editor.getText();
const selection = await editor.getSelection();
2022-07-10 15:51:34 +00:00
const textSelection = text.slice(selection.from, selection.to);
let linkedText = `[]()`;
2022-07-10 21:30:38 +00:00
let pos = 1;
2022-07-10 15:51:34 +00:00
if (textSelection.length > 0) {
try {
new URL(textSelection);
linkedText = `[](${textSelection})`;
} catch {
linkedText = `[${textSelection}]()`;
2022-07-10 21:30:38 +00:00
pos = linkedText.length - 1;
2022-07-10 15:51:34 +00:00
}
}
2022-10-14 13:11:33 +00:00
await editor.replaceRange(selection.from, selection.to, linkedText);
await editor.moveCursor(selection.from + pos);
2022-07-10 15:51:34 +00:00
}
export function wrapSelection(cmdDef: any) {
return insertMarker(cmdDef.wrapper);
}
async function insertMarker(marker: string) {
2022-10-14 13:11:33 +00:00
const text = await editor.getText();
const selection = await editor.getSelection();
if (selection.from === selection.to) {
// empty selection
if (markerAt(selection.from)) {
// Already there, skipping ahead
2022-10-14 13:11:33 +00:00
await editor.moveCursor(selection.from + marker.length);
} else {
// Not there, inserting
2022-10-14 13:11:33 +00:00
await editor.insertAtCursor(marker + marker);
await editor.moveCursor(selection.from + marker.length);
}
} else {
let from = selection.from;
let to = selection.to;
let hasMarker = markerAt(from);
if (!markerAt(from)) {
// Maybe just before the cursor? We'll accept that
from = selection.from - marker.length;
to = selection.to + marker.length;
hasMarker = markerAt(from);
}
if (!hasMarker) {
// Adding
2022-10-14 13:11:33 +00:00
await editor.replaceRange(
selection.from,
selection.to,
marker + text.slice(selection.from, selection.to) + marker,
);
2022-10-14 13:11:33 +00:00
await editor.setSelection(
selection.from + marker.length,
selection.to + marker.length,
);
} else {
// Removing
2022-10-14 13:11:33 +00:00
await editor.replaceRange(
from,
to,
text.substring(from + marker.length, to - marker.length),
);
2022-10-14 13:11:33 +00:00
await editor.setSelection(from, to - marker.length * 2);
}
}
function markerAt(pos: number) {
2022-10-14 13:11:33 +00:00
for (let i = 0; i < marker.length; i++) {
if (text[pos + i] !== marker[i]) {
return false;
}
}
return true;
}
}