Skip to content

Commit

Permalink
fix(ui): fix suggestions when quoting a suggestion with no spaces
Browse files Browse the repository at this point in the history
  • Loading branch information
paradoxuum committed Sep 29, 2024
1 parent 6f1e040 commit 24dc2ab
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 22 deletions.
44 changes: 26 additions & 18 deletions packages/ui/src/components/terminal/suggestion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import {
import { ReadonlyDeep } from "@rbxts/centurion/out/shared/util/data";
import { Players } from "@rbxts/services";
import { ArgumentSuggestion, CommandSuggestion } from "../../types";

const MAX_OTHER_SUGGESTIONS = 3;
import { containsSpace, getQuoteChar } from "../../utils/string";

export interface SingleArgument {
kind: "single";
Expand All @@ -28,41 +27,50 @@ export interface ListArgument {

export type Argument = SingleArgument | ListArgument;

function formatText(text: string) {
return text.match("%s").isEmpty() ? text : `"${text}"`;
}

function getMatches(
strings: string[],
text?: string,
): [number, string, number][] {
if (text === undefined) {
return strings.sort().map((str, i) => [i, str, str.size()]);
return strings.sort().map((str, i) => {
const formatted = containsSpace(str) ? `"${str}"` : str;
return [i, formatted, formatted.size()];
});
}

const textLower = text.lower();
const textEndIndex = text.size();
return strings
.mapFiltered<[number, string, number] | undefined>((str, i) => {
const part = str.lower().sub(0, textEndIndex);
if (part === textLower) return [i, str, str.size()];
})
.sort((a, b) => a[1] < b[1]);
const quoteChar = getQuoteChar(text);
const quoted = quoteChar !== undefined;

const results: [number, string, number][] = [];
for (const i of $range(0, strings.size() - 1)) {
let str = strings[i];
if (quoted) {
str = `${quoteChar}${str}${quoteChar}`;
} else if (containsSpace(str)) {
str = `"${str}"`;
}

const part = str.lower().sub(0, textEndIndex);
if (part === textLower) {
results.push([i, str, str.size()]);
}
}
return results.sort((a, b) => a[1] < b[1]);
}

export function getArgumentSuggestion(arg: Argument, textPart?: string) {
const suggestions =
arg.options.suggestions !== undefined
? arg.options.suggestions.map(formatText)
: [];
arg.options.suggestions !== undefined ? [...arg.options.suggestions] : [];
const singleArg = arg.kind === "single";

const typeSuggestions = singleArg
? arg.type.suggestions?.(arg.input ?? "", Players.LocalPlayer)
: arg.type.suggestions?.(arg.input, Players.LocalPlayer);
if (typeSuggestions !== undefined) {
for (const text of typeSuggestions) {
suggestions.push(formatText(text));
suggestions.push(text);
}
}

Expand Down Expand Up @@ -118,7 +126,7 @@ export function getCommandSuggestion(
return {
type: "command",
title: firstPath.tail(),
others: sortedPaths.map(([, str]) => formatText(str)),
others: sortedPaths.map(([, str]) => str),
description: mainData.description,
shortcuts: (mainData as CommandOptions).shortcuts,
};
Expand Down
1 change: 0 additions & 1 deletion packages/ui/src/components/terminal/terminal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import { TerminalTextField } from "./terminal-text-field";

const MAX_HEIGHT = HISTORY_TEXT_SIZE * 10;
const TEXT_FIELD_HEIGHT = 40;
const START_QUOTE_PATTERN = `^(['"])`;
const TRAILING_SPACE_PATTERN = "(%s+)$";

export function Terminal() {
Expand Down
8 changes: 5 additions & 3 deletions packages/ui/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { splitString } from "@rbxts/centurion/out/shared/util/string";
import { atom, computed } from "@rbxts/charm";
import { DEFAULT_INTERFACE_OPTIONS } from "./constants/options";
import { Suggestion } from "./types";
import { isQuoteEnded, isQuoteStarted } from "./utils/string";

export const interfaceVisible = atom(false);
export const interfaceOptions = atom(DEFAULT_INTERFACE_OPTIONS);
Expand All @@ -23,9 +24,10 @@ export const atNextPart = computed(() => {
const parts = terminalTextParts();
const textPart = parts[parts.size() - 1] as string | undefined;

const startQuote = textPart?.match(`^(['"])`);
const endQuote = textPart?.match(`(['"])%s*$`);
const quoted = startQuote !== undefined && endQuote === undefined;
let quoted = false;
if (textPart !== undefined) {
quoted = isQuoteStarted(textPart) && !isQuoteEnded(textPart);
}
return terminalText().sub(-1) === " " && !quoted;
});
export const terminalTextValid = atom(false);
Expand Down
22 changes: 22 additions & 0 deletions packages/ui/src/utils/string.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const START_QUOTE_PATTERN = `^(['"])`;
const END_QUOTE_PATTERN = `(['"])%s*$`;

export function containsSpace(text: string) {
return !text.match("%s").isEmpty();
}

export function stripQuotes(text: string) {
return text.gsub(START_QUOTE_PATTERN, "")[0].gsub(END_QUOTE_PATTERN, "")[0];
}

export function getQuoteChar(text: string) {
return text.match(START_QUOTE_PATTERN)[0] as string;
}

export function isQuoteStarted(text: string) {
return text.match(START_QUOTE_PATTERN)[0] !== undefined;
}

export function isQuoteEnded(text: string) {
return text.match(END_QUOTE_PATTERN)[0] !== undefined;
}

0 comments on commit 24dc2ab

Please sign in to comment.