Use Unicode delimiter character

This commit is contained in:
Henrik Giesel 2021-07-08 21:25:01 +02:00
parent 6ccf75a077
commit 3de1d6e604
3 changed files with 48 additions and 38 deletions

View file

@ -16,18 +16,28 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import ButtonToolbar from "components/ButtonToolbar.svelte";
import { controlPressed } from "lib/keys";
import type { Tag as TagType } from "./tags";
import { attachId, getName } from "./tags";
import {
attachId,
getName,
delimChar,
replaceWithDelimChar,
replaceWithColon,
} from "./tags";
export let size = isApplePlatform() ? 1.6 : 2.0;
export let tags: TagType[] = [];
export function resetTags(names: string[]): void {
tags = names.map(attachId);
tags = names.map(replaceWithDelimChar).map(attachId);
}
function saveTags(): void {
bridgeCommand(`saveTags:${JSON.stringify(tags.map((tag) => tag.name))}`);
bridgeCommand(
`saveTags:${JSON.stringify(
tags.map((tag) => tag.name).map(replaceWithColon)
)}`
);
}
let active: number | null = null;
@ -43,7 +53,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
"en::vocabulary",
"en::idioms",
Math.random().toString(36).substring(2),
]);
]).then((names: string[]): string[] => names.map(replaceWithDelimChar));
}
function onAutocomplete(selected: string): void {
@ -369,17 +379,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
$: shortenTags = shortenTags || assumedRows > 2;
function processTagName(name: string): string {
const parts = name.split("::");
const parts = name.split(delimChar);
if (parts.length === 1) {
return name;
}
return "…::" + parts[parts.length - 1];
return `…${delimChar}` + parts[parts.length - 1];
}
function hasMultipleParts(name: string): boolean {
return name.split("::").length > 1;
return name.split(delimChar).length > 1;
}
</script>

View file

@ -4,7 +4,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="typescript">
import { onMount, createEventDispatcher, tick } from "svelte";
import { normalizeTagname } from "./tags";
import { normalizeTagname, delimChar } from "./tags";
export let id: string | undefined = undefined;
let className: string = "";
@ -55,11 +55,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const nameUptoCaret = name.slice(0, position);
if (nameUptoCaret.endsWith("::")) {
name = name.slice(0, position - 2) + name.slice(position, name.length);
if (nameUptoCaret.endsWith(delimChar)) {
name = name.slice(0, position - 1) + name.slice(position, name.length);
await tick();
setPosition(position - 2);
setPosition(position - 1);
event.preventDefault();
}
}
@ -106,36 +106,30 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
async function onDelimiter(event: Event, single: boolean = false): Promise<void> {
event.preventDefault();
const positionStart = input.selectionStart!;
const positionEnd = input.selectionEnd!;
const before = name.slice(0, positionStart);
if (before.endsWith("::")) {
if (before.endsWith(delimChar)) {
event.preventDefault();
event.stopPropagation();
return;
} else if (before.endsWith(":")) {
event.preventDefault();
name = `${before.slice(0, -1)}${delimChar}${name.slice(
positionEnd,
name.length
)}`;
} else if (single) {
return;
} else {
event.preventDefault();
name = `${before}${delimChar}${name.slice(positionEnd, name.length)}`;
}
name = `${before}${single ? ":" : "::"}${name.slice(positionEnd, name.length)}`;
await tick();
setPosition(positionStart + (single ? 1 : 2));
}
function maybeMovePastDelimiter(event: Event, forwards: boolean): void {
const position = input.selectionStart!;
const before = name.slice(0, position);
const after = name.slice(position, name.length);
if (!forwards && before.endsWith("::")) {
setPosition(position - 2);
event.preventDefault();
} else if (forwards && after.startsWith("::")) {
setPosition(position + 2);
event.preventDefault();
}
setPosition(positionStart + 1);
}
function onKeydown(event: KeyboardEvent): void {
@ -166,8 +160,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
} else if (caretAtStart()) {
dispatch("tagmoveprevious");
event.preventDefault();
} else if (isCollapsed()) {
maybeMovePastDelimiter(event, false);
}
break;
@ -177,8 +169,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
} else if (caretAtEnd()) {
dispatch("tagmovenext");
event.preventDefault();
} else if (isCollapsed()) {
maybeMovePastDelimiter(event, true);
}
break;
}

View file

@ -1,13 +1,23 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export const delimChar = "\u2237";
export function replaceWithDelimChar(name: string): string {
return name.replace(/::/g, delimChar);
}
export function replaceWithColon(name: string): string {
return name.replace(/\u2237/gu, "::");
}
export function normalizeTagname(tagname: string): string {
let trimmed = tagname.trim();
while (true) {
if (trimmed.startsWith(":")) {
if (trimmed.startsWith(":") || trimmed.startsWith(delimChar)) {
trimmed = trimmed.slice(1).trimStart();
} else if (trimmed.endsWith(":")) {
} else if (trimmed.endsWith(":") || trimmed.endsWith(delimChar)) {
trimmed = trimmed.slice(0, -1).trimEnd();
} else {
return trimmed;