mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-18 09:35:20 +02:00
67 lines
1.9 KiB
TypeScript
67 lines
1.9 KiB
TypeScript
|
import { Text as DocumentText, EditorSelection, SelectionRange } from '@codemirror/state';
|
||
|
import { RegionSpec } from './RegionSpec';
|
||
|
import findInlineMatch, { MatchSide } from './findInlineMatch';
|
||
|
import { SelectionUpdate } from './types';
|
||
|
|
||
|
// Toggles whether the given selection matches the inline region specified by [spec].
|
||
|
//
|
||
|
// For example, something similar to toggleSurrounded('**', '**') would surround
|
||
|
// every selection range with asterisks (including the caret).
|
||
|
// If the selection is already surrounded by these characters, they are
|
||
|
// removed.
|
||
|
const toggleInlineRegionSurrounded = (
|
||
|
doc: DocumentText, sel: SelectionRange, spec: RegionSpec,
|
||
|
): SelectionUpdate => {
|
||
|
let content = doc.sliceString(sel.from, sel.to);
|
||
|
const startMatchLen = findInlineMatch(doc, spec, sel, MatchSide.Start);
|
||
|
const endMatchLen = findInlineMatch(doc, spec, sel, MatchSide.End);
|
||
|
|
||
|
const startsWithBefore = startMatchLen >= 0;
|
||
|
const endsWithAfter = endMatchLen >= 0;
|
||
|
|
||
|
const changes = [];
|
||
|
let finalSelStart = sel.from;
|
||
|
let finalSelEnd = sel.to;
|
||
|
|
||
|
if (startsWithBefore && endsWithAfter) {
|
||
|
// Remove the before and after.
|
||
|
content = content.substring(startMatchLen);
|
||
|
content = content.substring(0, content.length - endMatchLen);
|
||
|
|
||
|
finalSelEnd -= startMatchLen + endMatchLen;
|
||
|
|
||
|
changes.push({
|
||
|
from: sel.from,
|
||
|
to: sel.to,
|
||
|
insert: content,
|
||
|
});
|
||
|
} else {
|
||
|
changes.push({
|
||
|
from: sel.from,
|
||
|
insert: spec.template.start,
|
||
|
});
|
||
|
|
||
|
changes.push({
|
||
|
from: sel.to,
|
||
|
insert: spec.template.end,
|
||
|
});
|
||
|
|
||
|
// If not a caret,
|
||
|
if (!sel.empty) {
|
||
|
// Select the surrounding chars.
|
||
|
finalSelEnd += spec.template.start.length + spec.template.end.length;
|
||
|
} else {
|
||
|
// Position the caret within the added content.
|
||
|
finalSelStart = sel.from + spec.template.start.length;
|
||
|
finalSelEnd = finalSelStart;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
changes,
|
||
|
range: EditorSelection.range(finalSelStart, finalSelEnd),
|
||
|
};
|
||
|
};
|
||
|
|
||
|
export default toggleInlineRegionSurrounded;
|