2022-10-14 13:11:33 +00:00
|
|
|
import { editor } from "$sb/silverbullet-syscall/mod.ts";
|
2022-06-23 15:08:42 +00:00
|
|
|
|
|
|
|
export async function quoteSelection() {
|
2022-10-14 13:11:33 +00:00
|
|
|
let text = await editor.getText();
|
|
|
|
const selection = await editor.getSelection();
|
2022-06-23 15:08:42 +00:00
|
|
|
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:08:42 +00:00
|
|
|
}
|
|
|
|
|
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();
|
2023-01-06 17:47:08 +00:00
|
|
|
|
|
|
|
//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;
|
2023-01-06 17:47:08 +00:00
|
|
|
}
|
|
|
|
|
2022-06-23 15:59:18 +00:00
|
|
|
let from = selection.from;
|
2023-01-06 17:47:08 +00:00
|
|
|
if (text[from] == "\n") {
|
|
|
|
//end of line, need to find previous line break
|
2023-01-22 17:53:14 +00:00
|
|
|
from--;
|
2023-01-06 17:47:08 +00:00
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
2022-07-04 13:07:27 +00:00
|
|
|
export function wrapSelection(cmdDef: any) {
|
|
|
|
return insertMarker(cmdDef.wrapper);
|
2022-06-23 15:08:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async function insertMarker(marker: string) {
|
2022-10-14 13:11:33 +00:00
|
|
|
const text = await editor.getText();
|
|
|
|
const selection = await editor.getSelection();
|
2022-06-23 15:08:42 +00:00
|
|
|
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);
|
2022-06-23 15:08:42 +00:00
|
|
|
} else {
|
|
|
|
// Not there, inserting
|
2022-10-14 13:11:33 +00:00
|
|
|
await editor.insertAtCursor(marker + marker);
|
|
|
|
await editor.moveCursor(selection.from + marker.length);
|
2022-06-23 15:08:42 +00:00
|
|
|
}
|
|
|
|
} 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(
|
2022-06-23 15:08:42 +00:00
|
|
|
selection.from,
|
|
|
|
selection.to,
|
2022-10-10 12:50:21 +00:00
|
|
|
marker + text.slice(selection.from, selection.to) + marker,
|
2022-06-23 15:08:42 +00:00
|
|
|
);
|
2022-10-14 13:11:33 +00:00
|
|
|
await editor.setSelection(
|
2022-06-23 15:08:42 +00:00
|
|
|
selection.from + marker.length,
|
2022-10-10 12:50:21 +00:00
|
|
|
selection.to + marker.length,
|
2022-06-23 15:08:42 +00:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
// Removing
|
2022-10-14 13:11:33 +00:00
|
|
|
await editor.replaceRange(
|
2022-06-23 15:08:42 +00:00
|
|
|
from,
|
|
|
|
to,
|
2022-10-10 12:50:21 +00:00
|
|
|
text.substring(from + marker.length, to - marker.length),
|
2022-06-23 15:08:42 +00:00
|
|
|
);
|
2022-10-14 13:11:33 +00:00
|
|
|
await editor.setSelection(from, to - marker.length * 2);
|
2022-06-23 15:08:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function markerAt(pos: number) {
|
2022-10-14 13:11:33 +00:00
|
|
|
for (let i = 0; i < marker.length; i++) {
|
2022-06-23 15:08:42 +00:00
|
|
|
if (text[pos + i] !== marker[i]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|