From adf3b44f50721755c0b27c85cbe8823e36cc3118 Mon Sep 17 00:00:00 2001 From: Ali Date: Wed, 11 Dec 2024 15:10:31 +0300 Subject: [PATCH] fix string stream not reflecting real changes in tab completion --- .../autocomplete/SingleCommandCompleter.java | 10 +-- .../revxrsal/commands/node/ParameterNode.java | 4 +- .../node/parser/ParameterNodeImpl.java | 2 +- .../commands/stream/MutableStringStream.java | 12 +++ .../stream/MutableStringStreamImpl.java | 80 +++++++++++++++++++ 5 files changed, 99 insertions(+), 9 deletions(-) diff --git a/common/src/main/java/revxrsal/commands/autocomplete/SingleCommandCompleter.java b/common/src/main/java/revxrsal/commands/autocomplete/SingleCommandCompleter.java index e58dfabc..517658e9 100644 --- a/common/src/main/java/revxrsal/commands/autocomplete/SingleCommandCompleter.java +++ b/common/src/main/java/revxrsal/commands/autocomplete/SingleCommandCompleter.java @@ -31,7 +31,7 @@ final class SingleCommandCompleter { public SingleCommandCompleter(A actor, ExecutableCommand command, MutableStringStream input) { this.command = command; this.input = input; - this.context = ExecutionContext.createMutable(command, actor, input.toImmutableCopy()); + this.context = ExecutionContext.createMutable(command, actor, input.toImmutableView()); } private void rememberPosition() { @@ -84,7 +84,7 @@ private CompletionResult completeParameter(@NotNull ParameterNode par context.addResolvedArgument(parameter.name(), value); int positionAfterParsing = input.position(); String consumed = restorePosition(); - Collection parameterSuggestions = parameter.complete(context.actor(), input, context); + Collection parameterSuggestions = parameter.complete(context); input.setPosition(positionAfterParsing); // restore so that we can move forward if (input.hasFinished()) { @@ -96,7 +96,7 @@ private CompletionResult completeParameter(@NotNull ParameterNode par return CompletionResult.CONTINUE; } catch (Throwable t) { String consumed = restorePosition(); - filterSuggestions(consumed, parameter.complete(context.actor(), input, context)); + filterSuggestions(consumed, parameter.complete(context)); return CompletionResult.HALT; } } @@ -123,7 +123,7 @@ private void completeFlags(@NotNull Map> remain if (input.hasFinished()) return; if (input.remaining() == 1 && input.peek() == ' ') { - Collection parameterSuggestions = targetFlag.complete(context.actor(), input, context); + Collection parameterSuggestions = targetFlag.complete(context); suggestions.addAll(parameterSuggestions); return; } @@ -161,7 +161,7 @@ private void completeFlags(@NotNull Map> remain if (targetFlag.isSwitch()) continue; if (input.remaining() == 1 && input.peek() == ' ') { - Collection parameterSuggestions = targetFlag.complete(context.actor(), input, context); + Collection parameterSuggestions = targetFlag.complete(context); suggestions.addAll(parameterSuggestions); return; } diff --git a/common/src/main/java/revxrsal/commands/node/ParameterNode.java b/common/src/main/java/revxrsal/commands/node/ParameterNode.java index 31514089..3e56679e 100644 --- a/common/src/main/java/revxrsal/commands/node/ParameterNode.java +++ b/common/src/main/java/revxrsal/commands/node/ParameterNode.java @@ -140,13 +140,11 @@ default boolean isRequired() { /** * Provides suggestions for the given user input. * - * @param actor The actor to generate for - * @param input The command input * @param context The execution context. * @return The */ @Contract(pure = true) - @NotNull Collection complete(A actor, @NotNull StringStream input, @NotNull ExecutionContext context); + @NotNull Collection complete(@NotNull ExecutionContext context); /** * Returns the parameter Java type diff --git a/common/src/main/java/revxrsal/commands/node/parser/ParameterNodeImpl.java b/common/src/main/java/revxrsal/commands/node/parser/ParameterNodeImpl.java index d4cee1df..36d878ea 100644 --- a/common/src/main/java/revxrsal/commands/node/parser/ParameterNodeImpl.java +++ b/common/src/main/java/revxrsal/commands/node/parser/ParameterNodeImpl.java @@ -182,7 +182,7 @@ public boolean isOptional() { } @Override - public @NotNull Collection complete(@NotNull A actor, @NotNull StringStream input, @NotNull ExecutionContext context) { + public @NotNull Collection complete(@NotNull ExecutionContext context) { return suggestions.getSuggestions(context); } diff --git a/common/src/main/java/revxrsal/commands/stream/MutableStringStream.java b/common/src/main/java/revxrsal/commands/stream/MutableStringStream.java index b82e012e..2fcb9fb5 100644 --- a/common/src/main/java/revxrsal/commands/stream/MutableStringStream.java +++ b/common/src/main/java/revxrsal/commands/stream/MutableStringStream.java @@ -204,4 +204,16 @@ public interface MutableStringStream extends StringStream { @Contract(pure = true, value = "-> new") MutableStringStream toMutableCopy(); + /** + * Returns an immutable view of this {@link MutableStringStream}. A view is different + * from a copy, as it will reflect changes to the original string stream, but cannot + * be used to it. + * + * @return An immutable string stream view + */ + @NotNull + @Contract(pure = true) + @Unmodifiable + StringStream toImmutableView(); + } diff --git a/common/src/main/java/revxrsal/commands/stream/MutableStringStreamImpl.java b/common/src/main/java/revxrsal/commands/stream/MutableStringStreamImpl.java index 4fc8bd46..e4642d35 100644 --- a/common/src/main/java/revxrsal/commands/stream/MutableStringStreamImpl.java +++ b/common/src/main/java/revxrsal/commands/stream/MutableStringStreamImpl.java @@ -25,6 +25,7 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Unmodifiable; import revxrsal.commands.exception.InputParseException; import revxrsal.commands.exception.InvalidBooleanException; import revxrsal.commands.exception.InvalidDecimalException; @@ -34,6 +35,8 @@ public final class MutableStringStreamImpl extends BaseStringStream implements MutableStringStream { + private StringStreamView immutableView = null; + /** * Creates a new {@link MutableStringStream} with its position at zero. * @@ -217,4 +220,81 @@ public boolean isMutable() { return true; } + @Override public @NotNull @Unmodifiable StringStream toImmutableView() { + if (immutableView == null) + immutableView = new StringStreamView(); + return immutableView; + } + + private class StringStreamView implements StringStream { + + @Override public @NotNull String source() { + return MutableStringStreamImpl.this.source(); + } + + @Override public int totalSize() { + return MutableStringStreamImpl.this.totalSize(); + } + + @Override public int remaining() { + return MutableStringStreamImpl.this.remaining(); + } + + @Override public char peek() { + return MutableStringStreamImpl.this.peek(); + } + + @Override public String peek(int characters) { + return MutableStringStreamImpl.this.peek(characters); + } + + @Override public char peekOffset(int offset) { + return MutableStringStreamImpl.this.peekOffset(offset); + } + + @Override public boolean hasRemaining() { + return MutableStringStreamImpl.this.hasRemaining(); + } + + @Override public boolean hasFinished() { + return MutableStringStreamImpl.this.hasFinished(); + } + + @Override public boolean canRead(int characters) { + return MutableStringStreamImpl.this.canRead(characters); + } + + @Override public int position() { + return MutableStringStreamImpl.this.position(); + } + + @Override public @NotNull String peekUnquotedString() { + return MutableStringStreamImpl.this.peekUnquotedString(); + } + + @Override public @NotNull String peekString() { + return MutableStringStreamImpl.this.peekString(); + } + + @Override public @NotNull String peekRemaining() { + return MutableStringStreamImpl.this.peekRemaining(); + } + + @Override public @NotNull @Unmodifiable StringStream toImmutableCopy() { + return MutableStringStreamImpl.this.toImmutableCopy(); + } + + @Override public @NotNull MutableStringStream toMutableCopy() { + return MutableStringStreamImpl.this.toMutableCopy(); + } + + @Override public boolean isMutable() { + return false; + } + + @Override public boolean isEmpty() { + return MutableStringStreamImpl.this.isEmpty(); + } + } + }