Add limited support for completions, add .editorconfig and reformat.
This commit is contained in:
parent
10aba61110
commit
762bdb7ff4
22 changed files with 676 additions and 203 deletions
248
.editorconfig
Normal file
248
.editorconfig
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
max_line_length = 120
|
||||
tab_width = 4
|
||||
ij_continuation_indent_size = 8
|
||||
ij_formatter_off_tag = @formatter:off
|
||||
ij_formatter_on_tag = @formatter:on
|
||||
ij_formatter_tags_enabled = true
|
||||
ij_smart_tabs = false
|
||||
ij_visual_guides = 130
|
||||
ij_wrap_on_typing = false
|
||||
|
||||
[*.java]
|
||||
max_line_length = 130
|
||||
ij_java_align_consecutive_assignments = false
|
||||
ij_java_align_consecutive_variable_declarations = false
|
||||
ij_java_align_group_field_declarations = false
|
||||
ij_java_align_multiline_annotation_parameters = true
|
||||
ij_java_align_multiline_array_initializer_expression = true
|
||||
ij_java_align_multiline_assignment = false
|
||||
ij_java_align_multiline_binary_operation = false
|
||||
ij_java_align_multiline_chained_methods = true
|
||||
ij_java_align_multiline_extends_list = false
|
||||
ij_java_align_multiline_for = true
|
||||
ij_java_align_multiline_method_parentheses = false
|
||||
ij_java_align_multiline_parameters = true
|
||||
ij_java_align_multiline_parameters_in_calls = true
|
||||
ij_java_align_multiline_parenthesized_expression = false
|
||||
ij_java_align_multiline_records = true
|
||||
ij_java_align_multiline_resources = true
|
||||
ij_java_align_multiline_ternary_operation = true
|
||||
ij_java_align_multiline_text_blocks = false
|
||||
ij_java_align_multiline_throws_list = false
|
||||
ij_java_align_subsequent_simple_methods = false
|
||||
ij_java_align_throws_keyword = false
|
||||
ij_java_annotation_parameter_wrap = off
|
||||
ij_java_array_initializer_new_line_after_left_brace = true
|
||||
ij_java_array_initializer_right_brace_on_new_line = true
|
||||
ij_java_array_initializer_wrap = on_every_item
|
||||
ij_java_assert_statement_colon_on_next_line = false
|
||||
ij_java_assert_statement_wrap = off
|
||||
ij_java_assignment_wrap = off
|
||||
ij_java_binary_operation_sign_on_next_line = false
|
||||
ij_java_binary_operation_wrap = off
|
||||
ij_java_blank_lines_after_anonymous_class_header = 0
|
||||
ij_java_blank_lines_after_class_header = 0
|
||||
ij_java_blank_lines_after_imports = 1
|
||||
ij_java_blank_lines_after_package = 1
|
||||
ij_java_blank_lines_around_class = 1
|
||||
ij_java_blank_lines_around_field = 0
|
||||
ij_java_blank_lines_around_field_in_interface = 0
|
||||
ij_java_blank_lines_around_initializer = 1
|
||||
ij_java_blank_lines_around_method = 1
|
||||
ij_java_blank_lines_around_method_in_interface = 1
|
||||
ij_java_blank_lines_before_class_end = 0
|
||||
ij_java_blank_lines_before_imports = 1
|
||||
ij_java_blank_lines_before_method_body = 0
|
||||
ij_java_blank_lines_before_package = 0
|
||||
ij_java_block_brace_style = end_of_line
|
||||
ij_java_block_comment_at_first_column = true
|
||||
ij_java_call_parameters_new_line_after_left_paren = false
|
||||
ij_java_call_parameters_right_paren_on_new_line = false
|
||||
ij_java_call_parameters_wrap = normal
|
||||
ij_java_case_statement_on_separate_line = true
|
||||
ij_java_catch_on_new_line = false
|
||||
ij_java_class_annotation_wrap = split_into_lines
|
||||
ij_java_class_brace_style = end_of_line
|
||||
ij_java_class_count_to_use_import_on_demand = 9999999
|
||||
ij_java_class_names_in_javadoc = 1
|
||||
ij_java_do_not_indent_top_level_class_members = false
|
||||
ij_java_do_not_wrap_after_single_annotation = true
|
||||
ij_java_do_while_brace_force = always
|
||||
ij_java_doc_add_blank_line_after_description = true
|
||||
ij_java_doc_add_blank_line_after_param_comments = false
|
||||
ij_java_doc_add_blank_line_after_return = false
|
||||
ij_java_doc_add_p_tag_on_empty_lines = true
|
||||
ij_java_doc_align_exception_comments = true
|
||||
ij_java_doc_align_param_comments = true
|
||||
ij_java_doc_do_not_wrap_if_one_line = false
|
||||
ij_java_doc_enable_formatting = true
|
||||
ij_java_doc_enable_leading_asterisks = true
|
||||
ij_java_doc_indent_on_continuation = false
|
||||
ij_java_doc_keep_empty_lines = true
|
||||
ij_java_doc_keep_empty_parameter_tag = true
|
||||
ij_java_doc_keep_empty_return_tag = true
|
||||
ij_java_doc_keep_empty_throws_tag = true
|
||||
ij_java_doc_keep_invalid_tags = true
|
||||
ij_java_doc_param_description_on_new_line = false
|
||||
ij_java_doc_preserve_line_breaks = false
|
||||
ij_java_doc_use_throws_not_exception_tag = true
|
||||
ij_java_else_on_new_line = false
|
||||
ij_java_enum_constants_wrap = split_into_lines
|
||||
ij_java_extends_keyword_wrap = off
|
||||
ij_java_extends_list_wrap = normal
|
||||
ij_java_field_annotation_wrap = split_into_lines
|
||||
ij_java_finally_on_new_line = false
|
||||
ij_java_for_brace_force = always
|
||||
ij_java_for_statement_new_line_after_left_paren = false
|
||||
ij_java_for_statement_right_paren_on_new_line = false
|
||||
ij_java_for_statement_wrap = off
|
||||
ij_java_generate_final_locals = true
|
||||
ij_java_generate_final_parameters = true
|
||||
ij_java_if_brace_force = always
|
||||
ij_java_imports_layout = *, |, javax.**, java.**, |, $*
|
||||
ij_java_indent_case_from_switch = true
|
||||
ij_java_insert_inner_class_imports = false
|
||||
ij_java_insert_override_annotation = true
|
||||
ij_java_keep_blank_lines_before_right_brace = 2
|
||||
ij_java_keep_blank_lines_between_package_declaration_and_header = 2
|
||||
ij_java_keep_blank_lines_in_code = 2
|
||||
ij_java_keep_blank_lines_in_declarations = 2
|
||||
ij_java_keep_control_statement_in_one_line = true
|
||||
ij_java_keep_first_column_comment = true
|
||||
ij_java_keep_indents_on_empty_lines = false
|
||||
ij_java_keep_line_breaks = true
|
||||
ij_java_keep_multiple_expressions_in_one_line = false
|
||||
ij_java_keep_simple_blocks_in_one_line = false
|
||||
ij_java_keep_simple_classes_in_one_line = false
|
||||
ij_java_keep_simple_lambdas_in_one_line = false
|
||||
ij_java_keep_simple_methods_in_one_line = false
|
||||
ij_java_label_indent_absolute = false
|
||||
ij_java_label_indent_size = 0
|
||||
ij_java_lambda_brace_style = end_of_line
|
||||
ij_java_layout_static_imports_separately = true
|
||||
ij_java_line_comment_add_space = false
|
||||
ij_java_line_comment_at_first_column = true
|
||||
ij_java_method_annotation_wrap = split_into_lines
|
||||
ij_java_method_brace_style = end_of_line
|
||||
ij_java_method_call_chain_wrap = on_every_item
|
||||
ij_java_method_parameters_new_line_after_left_paren = false
|
||||
ij_java_method_parameters_right_paren_on_new_line = false
|
||||
ij_java_method_parameters_wrap = on_every_item
|
||||
ij_java_modifier_list_wrap = false
|
||||
ij_java_names_count_to_use_import_on_demand = 9999999
|
||||
ij_java_new_line_after_lparen_in_record_header = false
|
||||
ij_java_parameter_annotation_wrap = on_every_item
|
||||
ij_java_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_java_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_java_place_assignment_sign_on_next_line = false
|
||||
ij_java_prefer_longer_names = true
|
||||
ij_java_prefer_parameters_wrap = false
|
||||
ij_java_record_components_wrap = normal
|
||||
ij_java_repeat_synchronized = true
|
||||
ij_java_replace_instanceof_and_cast = false
|
||||
ij_java_replace_null_check = true
|
||||
ij_java_replace_sum_lambda_with_method_ref = true
|
||||
ij_java_resource_list_new_line_after_left_paren = false
|
||||
ij_java_resource_list_right_paren_on_new_line = false
|
||||
ij_java_resource_list_wrap = off
|
||||
ij_java_rparen_on_new_line_in_record_header = false
|
||||
ij_java_space_after_closing_angle_bracket_in_type_argument = false
|
||||
ij_java_space_after_colon = true
|
||||
ij_java_space_after_comma = true
|
||||
ij_java_space_after_comma_in_type_arguments = true
|
||||
ij_java_space_after_for_semicolon = true
|
||||
ij_java_space_after_quest = true
|
||||
ij_java_space_after_type_cast = true
|
||||
ij_java_space_before_annotation_array_initializer_left_brace = false
|
||||
ij_java_space_before_annotation_parameter_list = false
|
||||
ij_java_space_before_array_initializer_left_brace = false
|
||||
ij_java_space_before_catch_keyword = true
|
||||
ij_java_space_before_catch_left_brace = true
|
||||
ij_java_space_before_catch_parentheses = true
|
||||
ij_java_space_before_class_left_brace = true
|
||||
ij_java_space_before_colon = true
|
||||
ij_java_space_before_colon_in_foreach = true
|
||||
ij_java_space_before_comma = false
|
||||
ij_java_space_before_do_left_brace = true
|
||||
ij_java_space_before_else_keyword = true
|
||||
ij_java_space_before_else_left_brace = true
|
||||
ij_java_space_before_finally_keyword = true
|
||||
ij_java_space_before_finally_left_brace = true
|
||||
ij_java_space_before_for_left_brace = true
|
||||
ij_java_space_before_for_parentheses = true
|
||||
ij_java_space_before_for_semicolon = false
|
||||
ij_java_space_before_if_left_brace = true
|
||||
ij_java_space_before_if_parentheses = true
|
||||
ij_java_space_before_method_call_parentheses = false
|
||||
ij_java_space_before_method_left_brace = true
|
||||
ij_java_space_before_method_parentheses = false
|
||||
ij_java_space_before_opening_angle_bracket_in_type_parameter = false
|
||||
ij_java_space_before_quest = true
|
||||
ij_java_space_before_switch_left_brace = true
|
||||
ij_java_space_before_switch_parentheses = true
|
||||
ij_java_space_before_synchronized_left_brace = true
|
||||
ij_java_space_before_synchronized_parentheses = true
|
||||
ij_java_space_before_try_left_brace = true
|
||||
ij_java_space_before_try_parentheses = true
|
||||
ij_java_space_before_type_parameter_list = false
|
||||
ij_java_space_before_while_keyword = true
|
||||
ij_java_space_before_while_left_brace = true
|
||||
ij_java_space_before_while_parentheses = true
|
||||
ij_java_space_inside_one_line_enum_braces = false
|
||||
ij_java_space_within_empty_array_initializer_braces = false
|
||||
ij_java_space_within_empty_method_call_parentheses = false
|
||||
ij_java_space_within_empty_method_parentheses = false
|
||||
ij_java_spaces_around_additive_operators = true
|
||||
ij_java_spaces_around_assignment_operators = true
|
||||
ij_java_spaces_around_bitwise_operators = true
|
||||
ij_java_spaces_around_equality_operators = true
|
||||
ij_java_spaces_around_lambda_arrow = true
|
||||
ij_java_spaces_around_logical_operators = true
|
||||
ij_java_spaces_around_method_ref_dbl_colon = false
|
||||
ij_java_spaces_around_multiplicative_operators = true
|
||||
ij_java_spaces_around_relational_operators = true
|
||||
ij_java_spaces_around_shift_operators = true
|
||||
ij_java_spaces_around_type_bounds_in_type_parameters = true
|
||||
ij_java_spaces_around_unary_operator = false
|
||||
ij_java_spaces_within_angle_brackets = false
|
||||
ij_java_spaces_within_annotation_parentheses = false
|
||||
ij_java_spaces_within_array_initializer_braces = false
|
||||
ij_java_spaces_within_braces = false
|
||||
ij_java_spaces_within_brackets = false
|
||||
ij_java_spaces_within_cast_parentheses = false
|
||||
ij_java_spaces_within_catch_parentheses = false
|
||||
ij_java_spaces_within_for_parentheses = false
|
||||
ij_java_spaces_within_if_parentheses = false
|
||||
ij_java_spaces_within_method_call_parentheses = false
|
||||
ij_java_spaces_within_method_parentheses = false
|
||||
ij_java_spaces_within_parentheses = false
|
||||
ij_java_spaces_within_switch_parentheses = false
|
||||
ij_java_spaces_within_synchronized_parentheses = false
|
||||
ij_java_spaces_within_try_parentheses = false
|
||||
ij_java_spaces_within_while_parentheses = false
|
||||
ij_java_special_else_if_treatment = true
|
||||
ij_java_subclass_name_suffix = Impl
|
||||
ij_java_ternary_operation_signs_on_next_line = false
|
||||
ij_java_ternary_operation_wrap = on_every_item
|
||||
ij_java_test_name_suffix = Test
|
||||
ij_java_throws_keyword_wrap = off
|
||||
ij_java_throws_list_wrap = normal
|
||||
ij_java_use_external_annotations = false
|
||||
ij_java_use_fq_class_names = false
|
||||
ij_java_use_relative_indents = false
|
||||
ij_java_use_single_class_imports = true
|
||||
ij_java_variable_annotation_wrap = on_every_item
|
||||
ij_java_visibility = public
|
||||
ij_java_while_brace_force = always
|
||||
ij_java_while_on_new_line = false
|
||||
ij_java_wrap_comments = false
|
||||
ij_java_wrap_first_method_in_call_chain = false
|
||||
ij_java_wrap_long_lines = false
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>Commands</artifactId>
|
||||
|
|
|
|||
|
|
@ -27,12 +27,17 @@ import com.intellectualsites.commands.Command;
|
|||
import com.intellectualsites.commands.CommandManager;
|
||||
import com.intellectualsites.commands.CommandTree;
|
||||
import com.intellectualsites.commands.components.CommandComponent;
|
||||
import com.intellectualsites.commands.components.StaticComponent;
|
||||
import com.intellectualsites.commands.exceptions.InvalidSyntaxException;
|
||||
import com.intellectualsites.commands.exceptions.NoSuchCommandException;
|
||||
import com.intellectualsites.commands.execution.CommandExecutionCoordinator;
|
||||
import com.intellectualsites.commands.internal.CommandRegistrationHandler;
|
||||
import com.intellectualsites.commands.parser.ComponentParseResult;
|
||||
import org.jline.reader.*;
|
||||
import org.jline.reader.Candidate;
|
||||
import org.jline.reader.Completer;
|
||||
import org.jline.reader.LineReader;
|
||||
import org.jline.reader.LineReaderBuilder;
|
||||
import org.jline.reader.ParsedLine;
|
||||
import org.jline.terminal.Terminal;
|
||||
import org.jline.terminal.TerminalBuilder;
|
||||
|
||||
|
|
@ -45,16 +50,27 @@ import java.util.function.Function;
|
|||
*/
|
||||
public class JLineCommandManager extends CommandManager<JLineCommandSender> implements Completer {
|
||||
|
||||
public JLineCommandManager(@Nonnull
|
||||
final Function<CommandTree<JLineCommandSender>, CommandExecutionCoordinator<JLineCommandSender>> executionCoordinatorFunction) {
|
||||
super(executionCoordinatorFunction, CommandRegistrationHandler.NULL_COMMAND_REGISTRATION_HANDLER);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// TODO: REMOVE THIS!!!!
|
||||
final JLineCommandManager jLineCommandManager = new JLineCommandManager(CommandExecutionCoordinator.simpleCoordinator());
|
||||
final Terminal terminal = TerminalBuilder.builder().dumb(true).build();
|
||||
final Terminal terminal = TerminalBuilder.builder().build();
|
||||
LineReader lineReader = LineReaderBuilder.builder()
|
||||
.completer(jLineCommandManager).terminal(terminal).appName("Test").build();
|
||||
.completer(jLineCommandManager)
|
||||
.option(LineReader.Option.INSERT_TAB, false)
|
||||
.terminal(terminal)
|
||||
.appName("Test")
|
||||
.build();
|
||||
boolean[] shouldStop = new boolean[]{false};
|
||||
jLineCommandManager.registerCommand(Command.newBuilder("stop").withHandler(commandContext ->
|
||||
shouldStop[0] = true).build()).registerCommand(Command.newBuilder("echo")
|
||||
.withComponent(CommandComponent.ofType(String.class).named("string").asRequired()
|
||||
shouldStop[0] = true).build())
|
||||
.registerCommand(Command.newBuilder("echo")
|
||||
.withComponent(
|
||||
CommandComponent.ofType(String.class).named("string").asRequired()
|
||||
.withParser(((commandContext, inputQueue) -> {
|
||||
final StringBuilder stringBuilder = new StringBuilder();
|
||||
while (!inputQueue.isEmpty()) {
|
||||
|
|
@ -63,16 +79,34 @@ public class JLineCommandManager extends CommandManager<JLineCommandSender> impl
|
|||
stringBuilder.append(" ");
|
||||
}
|
||||
}
|
||||
return ComponentParseResult.success(stringBuilder.toString());
|
||||
return ComponentParseResult.success(
|
||||
stringBuilder.toString());
|
||||
})).build())
|
||||
.withHandler(commandContext -> commandContext.get("string").ifPresent(System.out::println)).build());
|
||||
.withHandler(commandContext -> commandContext.get("string")
|
||||
.ifPresent(System.out::println))
|
||||
.build())
|
||||
.registerCommand(Command.newBuilder("test")
|
||||
.withComponent(StaticComponent.required("one"))
|
||||
.withHandler(commandContext -> System.out.println("Test (1)"))
|
||||
.build())
|
||||
.registerCommand(Command.newBuilder("test")
|
||||
.withComponent(StaticComponent.required("two"))
|
||||
.withHandler(commandContext -> System.out.println("Test (2)"))
|
||||
.build());
|
||||
System.out.println("Ready...");
|
||||
while (!shouldStop[0]) {
|
||||
final String line = lineReader.readLine();
|
||||
if (line == null || line.isEmpty() || !line.startsWith("/")) {
|
||||
System.out.println("Empty line");
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
jLineCommandManager.executeCommand(new JLineCommandSender(), line.substring(1)).join();
|
||||
final List<String> suggestions = jLineCommandManager.suggest(new JLineCommandSender(), line.substring(1));
|
||||
for (final String suggestion : suggestions) {
|
||||
System.out.printf("> %s\n", suggestion);
|
||||
}
|
||||
// jLineCommandManager.executeCommand(new JLineCommandSender(), line.substring(1)).join();
|
||||
// System.out.println("Successfully executed " + line);
|
||||
} catch (RuntimeException runtimeException) {
|
||||
if (runtimeException.getCause() instanceof NoSuchCommandException) {
|
||||
System.out.println("No such command");
|
||||
|
|
@ -89,13 +123,16 @@ public class JLineCommandManager extends CommandManager<JLineCommandSender> impl
|
|||
}
|
||||
}
|
||||
|
||||
public JLineCommandManager(@Nonnull final Function<CommandTree<JLineCommandSender>, CommandExecutionCoordinator<JLineCommandSender>> executionCoordinatorFunction) {
|
||||
super(executionCoordinatorFunction, CommandRegistrationHandler.NULL_COMMAND_REGISTRATION_HANDLER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete(@Nonnull final LineReader lineReader, @Nonnull final ParsedLine parsedLine, @Nonnull final List<Candidate> list) {
|
||||
// TODO: Implement
|
||||
public void complete(@Nonnull final LineReader lineReader,
|
||||
@Nonnull final ParsedLine parsedLine,
|
||||
@Nonnull final List<Candidate> list) {
|
||||
final String line = parsedLine.line();
|
||||
if (line == null || line.isEmpty() || !line.startsWith("/")) {
|
||||
System.out.println("Cannot suggest: empty line");
|
||||
return;
|
||||
}
|
||||
System.out.printf("Trying to complete '%s'\n", line);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
4
pom.xml
4
pom.xml
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,13 @@ import com.intellectualsites.commands.execution.CommandExecutionHandler;
|
|||
import com.intellectualsites.commands.sender.CommandSender;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.*;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* A command consists out of a chain of {@link com.intellectualsites.commands.components.CommandComponent command components}.
|
||||
|
|
@ -38,10 +44,13 @@ import java.util.*;
|
|||
*/
|
||||
public class Command<C extends CommandSender> {
|
||||
|
||||
private final CommandComponent<C, ?>[] components;
|
||||
private final CommandExecutionHandler<C> commandExecutionHandler;
|
||||
@Nonnull private final CommandComponent<C, ?>[] components;
|
||||
@Nonnull private final CommandExecutionHandler<C> commandExecutionHandler;
|
||||
@Nullable private final Class<? extends C> senderType;
|
||||
|
||||
protected Command(@Nonnull final CommandComponent<C, ?>[] commandComponents, @Nonnull final CommandExecutionHandler<C> commandExecutionHandler) {
|
||||
protected Command(@Nonnull final CommandComponent<C, ?>[] commandComponents,
|
||||
@Nonnull final CommandExecutionHandler<C> commandExecutionHandler,
|
||||
@Nullable final Class<? extends C> senderType) {
|
||||
this.components = Objects.requireNonNull(commandComponents, "Command components may not be null");
|
||||
if (this.components.length == 0) {
|
||||
throw new IllegalArgumentException("At least one command component is required");
|
||||
|
|
@ -50,12 +59,15 @@ public class Command<C extends CommandSender> {
|
|||
boolean foundOptional = false;
|
||||
for (final CommandComponent<C, ?> component : this.components) {
|
||||
if (foundOptional && component.isRequired()) {
|
||||
throw new IllegalArgumentException(String.format("Command component '%s' cannot be placed after an optional component", component.getName()));
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Command component '%s' cannot be placed after an optional component",
|
||||
component.getName()));
|
||||
} else if (!component.isRequired()) {
|
||||
foundOptional = true;
|
||||
}
|
||||
}
|
||||
this.commandExecutionHandler = commandExecutionHandler;
|
||||
this.senderType = senderType;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -66,7 +78,7 @@ public class Command<C extends CommandSender> {
|
|||
*/
|
||||
@Nonnull
|
||||
public static <C extends CommandSender> Builder<C> newBuilder(@Nonnull final String commandName) {
|
||||
return new Builder<>(Collections.singletonList(StaticComponent.required(commandName)),
|
||||
return new Builder<>(null, Collections.singletonList(StaticComponent.required(commandName)),
|
||||
new CommandExecutionHandler.NullCommandExecutionHandler<>());
|
||||
}
|
||||
|
||||
|
|
@ -75,7 +87,8 @@ public class Command<C extends CommandSender> {
|
|||
*
|
||||
* @return Copy of the command component array
|
||||
*/
|
||||
@Nonnull @SuppressWarnings("ALL")
|
||||
@Nonnull
|
||||
@SuppressWarnings("ALL")
|
||||
public CommandComponent<C, ?>[] getComponents() {
|
||||
return (CommandComponent<C, ?>[]) Arrays.asList(this.components).toArray();
|
||||
}
|
||||
|
|
@ -85,10 +98,21 @@ public class Command<C extends CommandSender> {
|
|||
*
|
||||
* @return Command execution handler
|
||||
*/
|
||||
@Nonnull public CommandExecutionHandler<C> getCommandExecutionHandler() {
|
||||
@Nonnull
|
||||
public CommandExecutionHandler<C> getCommandExecutionHandler() {
|
||||
return this.commandExecutionHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required sender type, if one has been specified
|
||||
*
|
||||
* @return Required sender type
|
||||
*/
|
||||
@Nonnull
|
||||
public Optional<Class<? extends C>> getSenderType() {
|
||||
return Optional.ofNullable(this.senderType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the longest chain of similar components for
|
||||
* two commands
|
||||
|
|
@ -110,12 +134,16 @@ public class Command<C extends CommandSender> {
|
|||
|
||||
public static class Builder<C extends CommandSender> {
|
||||
|
||||
private final List<CommandComponent<C, ?>> commandComponents;
|
||||
private final CommandExecutionHandler<C> commandExecutionHandler;
|
||||
@Nonnull private final List<CommandComponent<C, ?>> commandComponents;
|
||||
@Nonnull private final CommandExecutionHandler<C> commandExecutionHandler;
|
||||
@Nullable private final Class<? extends C> senderType;
|
||||
|
||||
private Builder(@Nonnull final List<CommandComponent<C, ?>> commandComponents, @Nonnull final CommandExecutionHandler<C> commandExecutionHandler) {
|
||||
private Builder(@Nullable final Class<? extends C> senderType,
|
||||
@Nonnull final List<CommandComponent<C, ?>> commandComponents,
|
||||
@Nonnull final CommandExecutionHandler<C> commandExecutionHandler) {
|
||||
this.commandComponents = commandComponents;
|
||||
this.commandExecutionHandler = commandExecutionHandler;
|
||||
this.senderType = senderType;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -129,7 +157,7 @@ public class Command<C extends CommandSender> {
|
|||
public <T> Builder<C> withComponent(@Nonnull final CommandComponent<C, T> component) {
|
||||
final List<CommandComponent<C, ?>> commandComponents = new LinkedList<>(this.commandComponents);
|
||||
commandComponents.add(component);
|
||||
return new Builder<>(commandComponents, this.commandExecutionHandler);
|
||||
return new Builder<>(this.senderType, commandComponents, this.commandExecutionHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -140,7 +168,18 @@ public class Command<C extends CommandSender> {
|
|||
*/
|
||||
@Nonnull
|
||||
public Builder<C> withHandler(@Nonnull final CommandExecutionHandler<C> commandExecutionHandler) {
|
||||
return new Builder<>(this.commandComponents, commandExecutionHandler);
|
||||
return new Builder<>(this.senderType, this.commandComponents, commandExecutionHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify a required sender type
|
||||
*
|
||||
* @param senderType Required sender type
|
||||
* @return New builder instance using the command execution handler
|
||||
*/
|
||||
@Nonnull
|
||||
public Builder<C> withSenderType(@Nonnull final Class<? extends C> senderType) {
|
||||
return new Builder<>(senderType, this.commandComponents, this.commandExecutionHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -150,7 +189,8 @@ public class Command<C extends CommandSender> {
|
|||
*/
|
||||
@Nonnull
|
||||
public Command<C> build() {
|
||||
return new Command<>(this.commandComponents.toArray(new CommandComponent[0]), this.commandExecutionHandler);
|
||||
return new Command<>(this.commandComponents.toArray(new CommandComponent[0]), this.commandExecutionHandler,
|
||||
this.senderType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import com.intellectualsites.commands.sender.CommandSender;
|
|||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
|
@ -56,13 +57,23 @@ public abstract class CommandManager<C extends CommandSender> {
|
|||
}
|
||||
|
||||
public CompletableFuture<CommandResult> executeCommand(@Nonnull final C commandSender, @Nonnull final String input) {
|
||||
final CommandContext<C> context = new CommandContext<>(commandSender);
|
||||
return this.commandExecutionCoordinator.coordinateExecution(context, tokenize(input));
|
||||
}
|
||||
|
||||
public List<String> suggest(@Nonnull final C commandSender, @Nonnull final String input) {
|
||||
final CommandContext<C> context = new CommandContext<>(commandSender);
|
||||
return this.commandTree.getSuggestions(context, tokenize(input));
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private Queue<String> tokenize(@Nonnull final String input) {
|
||||
final StringTokenizer stringTokenizer = new StringTokenizer(input, " ");
|
||||
final Queue<String> tokens = new LinkedList<>();
|
||||
while (stringTokenizer.hasMoreElements()) {
|
||||
tokens.add(stringTokenizer.nextToken());
|
||||
}
|
||||
final CommandContext<C> context = new CommandContext<>(commandSender);
|
||||
return this.commandExecutionCoordinator.coordinateExecution(context, tokens);
|
||||
return tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -81,7 +92,8 @@ public abstract class CommandManager<C extends CommandSender> {
|
|||
*
|
||||
* @return Command syntax formatter
|
||||
*/
|
||||
@Nonnull public CommandSyntaxFormatter getCommandSyntaxFormatter() {
|
||||
@Nonnull
|
||||
public CommandSyntaxFormatter getCommandSyntaxFormatter() {
|
||||
return this.commandSyntaxFormatter;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,14 @@ import com.intellectualsites.commands.sender.CommandSender;
|
|||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Queue;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
|
@ -50,7 +57,8 @@ public class CommandTree<C extends CommandSender> {
|
|||
private final CommandManager<C> commandManager;
|
||||
private final CommandRegistrationHandler commandRegistrationHandler;
|
||||
|
||||
private CommandTree(@Nonnull final CommandManager<C> commandManager, @Nonnull final CommandRegistrationHandler commandRegistrationHandler) {
|
||||
private CommandTree(@Nonnull final CommandManager<C> commandManager,
|
||||
@Nonnull final CommandRegistrationHandler commandRegistrationHandler) {
|
||||
this.commandManager = commandManager;
|
||||
this.commandRegistrationHandler = commandRegistrationHandler;
|
||||
}
|
||||
|
|
@ -65,17 +73,19 @@ public class CommandTree<C extends CommandSender> {
|
|||
*/
|
||||
@Nonnull
|
||||
public static <C extends CommandSender> CommandTree<C> newTree(@Nonnull final CommandManager<C> commandManager,
|
||||
@Nonnull final CommandRegistrationHandler commandRegistrationHandler) {
|
||||
@Nonnull
|
||||
final CommandRegistrationHandler commandRegistrationHandler) {
|
||||
return new CommandTree<>(commandManager, commandRegistrationHandler);
|
||||
}
|
||||
|
||||
public Optional<Command<C>> parse(@Nonnull final CommandContext<C> commandContext, @Nonnull final Queue<String> args) throws NoSuchCommandException {
|
||||
public Optional<Command<C>> parse(@Nonnull final CommandContext<C> commandContext, @Nonnull final Queue<String> args) throws
|
||||
NoSuchCommandException {
|
||||
return parseCommand(commandContext, args, this.internalTree);
|
||||
}
|
||||
|
||||
private Optional<Command<C>> parseCommand(@Nonnull final CommandContext<C> commandContext, @Nonnull final Queue<String> commandQueue,
|
||||
private Optional<Command<C>> parseCommand(@Nonnull final CommandContext<C> commandContext,
|
||||
@Nonnull final Queue<String> commandQueue,
|
||||
@Nonnull final Node<CommandComponent<C, ?>> root) throws NoSuchCommandException {
|
||||
|
||||
final List<Node<CommandComponent<C, ?>>> children = root.getChildren();
|
||||
if (children.size() == 1 && !(children.get(0).getValue() instanceof StaticComponent)) {
|
||||
// The value has to be a variable
|
||||
|
|
@ -84,11 +94,20 @@ public class CommandTree<C extends CommandSender> {
|
|||
if (commandQueue.isEmpty()) {
|
||||
if (child.isLeaf()) {
|
||||
/* Not enough arguments */
|
||||
throw new InvalidSyntaxException(this.commandManager.getCommandSyntaxFormatter().apply(Arrays.asList(child.getValue().getOwningCommand().getComponents())),
|
||||
commandContext.getCommandSender(), this.getChain(root).stream().map(Node::getValue).collect(Collectors.toList()));
|
||||
throw new InvalidSyntaxException(this.commandManager.getCommandSyntaxFormatter()
|
||||
.apply(Arrays.asList(child.getValue()
|
||||
.getOwningCommand()
|
||||
.getComponents())),
|
||||
commandContext.getCommandSender(), this.getChain(root)
|
||||
.stream()
|
||||
.map(Node::getValue)
|
||||
.collect(Collectors.toList()));
|
||||
} else {
|
||||
throw new NoSuchCommandException(commandContext.getCommandSender(),
|
||||
this.getChain(root).stream().map(Node::getValue).collect(Collectors.toList()),
|
||||
this.getChain(root)
|
||||
.stream()
|
||||
.map(Node::getValue)
|
||||
.collect(Collectors.toList()),
|
||||
"");
|
||||
}
|
||||
}
|
||||
|
|
@ -100,8 +119,15 @@ public class CommandTree<C extends CommandSender> {
|
|||
return Optional.ofNullable(child.getValue().getOwningCommand());
|
||||
} else {
|
||||
/* Too many arguments. We have a unique path, so we can send the entire context */
|
||||
throw new InvalidSyntaxException(this.commandManager.getCommandSyntaxFormatter().apply(Arrays.asList(child.getValue().getOwningCommand().getComponents())),
|
||||
commandContext.getCommandSender(), this.getChain(root).stream().map(Node::getValue).collect(Collectors.toList()));
|
||||
throw new InvalidSyntaxException(this.commandManager.getCommandSyntaxFormatter()
|
||||
.apply(Arrays.asList(child.getValue()
|
||||
.getOwningCommand()
|
||||
.getComponents())),
|
||||
commandContext.getCommandSender(), this.getChain(root)
|
||||
.stream()
|
||||
.map(Node::getValue)
|
||||
.collect(
|
||||
Collectors.toList()));
|
||||
}
|
||||
} else {
|
||||
return this.parseCommand(commandContext, commandQueue, child);
|
||||
|
|
@ -111,7 +137,6 @@ public class CommandTree<C extends CommandSender> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* There are 0 or more static components as children. No variable child components are present */
|
||||
if (children.isEmpty()) {
|
||||
/* We are at the bottom. Check if there's a command attached, in which case we're done */
|
||||
|
|
@ -120,44 +145,23 @@ public class CommandTree<C extends CommandSender> {
|
|||
return Optional.of(root.getValue().getOwningCommand());
|
||||
} else {
|
||||
/* Too many arguments. We have a unique path, so we can send the entire context */
|
||||
throw new InvalidSyntaxException(this.commandManager.getCommandSyntaxFormatter().apply(Arrays.asList(root.getValue().getOwningCommand().getComponents())),
|
||||
commandContext.getCommandSender(), this.getChain(root).stream().map(Node::getValue).collect(Collectors.toList()));
|
||||
throw new InvalidSyntaxException(this.commandManager.getCommandSyntaxFormatter()
|
||||
.apply(Arrays.asList(root.getValue()
|
||||
.getOwningCommand()
|
||||
.getComponents())),
|
||||
commandContext.getCommandSender(), this.getChain(root)
|
||||
.stream()
|
||||
.map(Node::getValue)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
} else {
|
||||
/* TODO: Indicate that we could not resolve the command here */
|
||||
final List<CommandComponent<C, ?>> components = this.getChain(root).stream().map(Node::getValue).collect(Collectors.toList());
|
||||
final List<CommandComponent<C, ?>> components = this.getChain(root)
|
||||
.stream()
|
||||
.map(Node::getValue)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
final String popped = commandQueue.poll();
|
||||
if (popped == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
int low = 0;
|
||||
int high = children.size() - 1;
|
||||
|
||||
while (low <= high) {
|
||||
int mid = (low + high) / 2;
|
||||
|
||||
final Node<CommandComponent<?>> node = children.get(mid);
|
||||
assert node.getValue() != null;
|
||||
|
||||
final int comparison = node.getValue().getName().compareToIgnoreCase(popped);
|
||||
if (comparison < 0) {
|
||||
low = mid + 1;
|
||||
} else if (comparison > 0) {
|
||||
high = mid - 1;
|
||||
} else {
|
||||
if (node.isLeaf()) {
|
||||
return Optional.ofNullable(node.getValue().getOwningCommand());
|
||||
} else {
|
||||
return parseCommand(commandSender, commandQueue, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
final Iterator<Node<CommandComponent<C, ?>>> childIterator = root.getChildren().iterator();
|
||||
if (childIterator.hasNext()) {
|
||||
while (childIterator.hasNext()) {
|
||||
|
|
@ -171,14 +175,84 @@ public class CommandTree<C extends CommandSender> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We could not find a match */
|
||||
throw new NoSuchCommandException(commandContext.getCommandSender(),
|
||||
getChain(root).stream().map(Node::getValue).collect(Collectors.toList()),
|
||||
java.util.Objects.requireNonNull(commandQueue.peek()));
|
||||
stringOrEmpty(commandQueue.peek()));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
public List<String> getSuggestions(@Nonnull final CommandContext<C> context, @Nonnull final Queue<String> commandQueue) {
|
||||
return getSuggestions(context, commandQueue, this.internalTree);
|
||||
}
|
||||
|
||||
public List<String> getSuggestions(@Nonnull final CommandContext<C> commandContext,
|
||||
@Nonnull final Queue<String> commandQueue,
|
||||
@Nonnull final Node<CommandComponent<C, ?>> root) {
|
||||
final List<Node<CommandComponent<C, ?>>> children = root.getChildren();
|
||||
if (children.size() == 1 && !(children.get(0).getValue() instanceof StaticComponent)) {
|
||||
// The value has to be a variable
|
||||
final Node<CommandComponent<C, ?>> child = children.get(0);
|
||||
if (child.getValue() != null) {
|
||||
if (commandQueue.isEmpty()) {
|
||||
if (child.isLeaf()) {
|
||||
/* Child is leaf, and so no suggestions should be sent */
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
/* Send all suggestions */
|
||||
return child.getValue().getParser().suggestions(commandContext, "");
|
||||
}
|
||||
}
|
||||
final ComponentParseResult<?> result = child.getValue().getParser().parse(commandContext, commandQueue);
|
||||
if (result.getParsedValue().isPresent()) {
|
||||
if (child.isLeaf()) {
|
||||
/* Child is leaf, and so no suggestions should be sent */
|
||||
return Collections.emptyList();
|
||||
}
|
||||
commandContext.store(child.getValue().getName(), result.getParsedValue().get());
|
||||
return this.getSuggestions(commandContext, commandQueue, child);
|
||||
} else if (result.getFailure().isPresent()) {
|
||||
/* TODO: Return error */
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
/* There are 0 or more static components as children. No variable child components are present */
|
||||
if (children.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
final Iterator<Node<CommandComponent<C, ?>>> childIterator = root.getChildren().iterator();
|
||||
if (childIterator.hasNext()) {
|
||||
while (childIterator.hasNext()) {
|
||||
final Node<CommandComponent<C, ?>> child = childIterator.next();
|
||||
if (child.getValue() != null) {
|
||||
final ComponentParseResult<?> result = child.getValue().getParser().parse(commandContext, commandQueue);
|
||||
if (result.getParsedValue().isPresent()) {
|
||||
return this.getSuggestions(commandContext, commandQueue, child);
|
||||
} else if (result.getFailure().isPresent() && root.children.size() == 1) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final List<String> suggestions = new LinkedList<>();
|
||||
for (final Node<CommandComponent<C, ?>> component : root.getChildren()) {
|
||||
if (component.getValue() == null) {
|
||||
continue;
|
||||
}
|
||||
suggestions.addAll(
|
||||
component.getValue().getParser().suggestions(commandContext, stringOrEmpty(commandQueue.peek())));
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private String stringOrEmpty(@Nullable final String string) {
|
||||
if (string == null) {
|
||||
return "";
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -196,6 +270,7 @@ public class CommandTree<C extends CommandSender> {
|
|||
if (node.children.size() > 0) {
|
||||
node.children.sort(Comparator.comparing(Node::getValue));
|
||||
}
|
||||
tempNode.setParent(node);
|
||||
node = tempNode;
|
||||
}
|
||||
if (node.getValue() != null) {
|
||||
|
|
@ -260,7 +335,7 @@ public class CommandTree<C extends CommandSender> {
|
|||
Node<CommandComponent<C, ?>> tail = end;
|
||||
while (tail != null) {
|
||||
chain.add(tail);
|
||||
tail = end.getParent();
|
||||
tail = tail.getParent();
|
||||
}
|
||||
return Lists.reverse(chain);
|
||||
}
|
||||
|
|
@ -324,15 +399,15 @@ public class CommandTree<C extends CommandSender> {
|
|||
return Objects.hashCode(getChildren(), getValue());
|
||||
}
|
||||
|
||||
public void setParent(@Nullable final Node<T> parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Node<T> getParent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
public void setParent(@Nullable final Node<T> parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,8 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
|
|||
* @param <T> Argument Type
|
||||
* @return Component builder
|
||||
*/
|
||||
@Nonnull public static <C extends CommandSender, T> CommandComponent.Builder<C, T> ofType(@Nonnull final Class<T> clazz) {
|
||||
@Nonnull
|
||||
public static <C extends CommandSender, T> CommandComponent.Builder<C, T> ofType(@Nonnull final Class<T> clazz) {
|
||||
return new Builder<>();
|
||||
}
|
||||
|
||||
|
|
@ -99,7 +100,8 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
|
|||
*
|
||||
* @return Component name
|
||||
*/
|
||||
@Nonnull public String getName() {
|
||||
@Nonnull
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
|
|
@ -109,11 +111,14 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
|
|||
*
|
||||
* @return Command parser
|
||||
*/
|
||||
@Nonnull public ComponentParser<C, T> getParser() {
|
||||
@Nonnull
|
||||
public ComponentParser<C, T> getParser() {
|
||||
return this.parser;
|
||||
}
|
||||
|
||||
@Nonnull @Override public String toString() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("CommandComponent{name=%s}", this.name);
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +127,8 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
|
|||
*
|
||||
* @return Owning command
|
||||
*/
|
||||
@Nullable public Command<C> getOwningCommand() {
|
||||
@Nullable
|
||||
public Command<C> getOwningCommand() {
|
||||
return this.owningCommand;
|
||||
}
|
||||
|
||||
|
|
@ -188,7 +194,8 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
|
|||
* @param name Alphanumeric component name
|
||||
* @return Builder instance
|
||||
*/
|
||||
@Nonnull public Builder<C, T> named(@Nonnull final String name) {
|
||||
@Nonnull
|
||||
public Builder<C, T> named(@Nonnull final String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
|
@ -202,7 +209,8 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
|
|||
*
|
||||
* @return Builder instance
|
||||
*/
|
||||
@Nonnull public Builder<C, T> asRequired() {
|
||||
@Nonnull
|
||||
public Builder<C, T> asRequired() {
|
||||
this.required = true;
|
||||
return this;
|
||||
}
|
||||
|
|
@ -216,7 +224,8 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
|
|||
*
|
||||
* @return Builder instance
|
||||
*/
|
||||
@Nonnull public Builder<C, T> asOptional() {
|
||||
@Nonnull
|
||||
public Builder<C, T> asOptional() {
|
||||
this.required = false;
|
||||
return this;
|
||||
}
|
||||
|
|
@ -227,7 +236,8 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
|
|||
* @param parser Component parser
|
||||
* @return Builder instance
|
||||
*/
|
||||
@Nonnull public Builder<C, T> withParser(@Nonnull final ComponentParser<C, T> parser) {
|
||||
@Nonnull
|
||||
public Builder<C, T> withParser(@Nonnull final ComponentParser<C, T> parser) {
|
||||
this.parser = Objects.requireNonNull(parser, "Parser may not be null");
|
||||
return this;
|
||||
}
|
||||
|
|
@ -237,7 +247,8 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
|
|||
*
|
||||
* @return Constructed component
|
||||
*/
|
||||
@Nonnull public CommandComponent<C, T> build() {
|
||||
@Nonnull
|
||||
public CommandComponent<C, T> build() {
|
||||
return new CommandComponent<>(this.required, this.name, this.parser);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,10 +27,13 @@ import javax.annotation.Nonnull;
|
|||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
@FunctionalInterface public interface CommandSyntaxFormatter extends Function<List<CommandComponent<?, ?>>, String> {
|
||||
@FunctionalInterface
|
||||
public interface CommandSyntaxFormatter extends Function<List<CommandComponent<?, ?>>, String> {
|
||||
|
||||
CommandSyntaxFormatter STANDARD_COMMAND_SYNTAX_FORMATTER = new StandardCommandSyntaxFormatter();
|
||||
|
||||
@Override @Nonnull String apply(@Nonnull List<CommandComponent<?, ?>> commandComponents);
|
||||
@Override
|
||||
@Nonnull
|
||||
String apply(@Nonnull List<CommandComponent<?, ?>> commandComponents);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,10 @@ import com.intellectualsites.commands.sender.CommandSender;
|
|||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
|
||||
|
|
@ -40,11 +43,15 @@ public final class StaticComponent<C extends CommandSender> extends CommandCompo
|
|||
super(required, name, new StaticComponentParser<>(name, aliases));
|
||||
}
|
||||
|
||||
@Nonnull public static <C extends CommandSender> StaticComponent<C> required(@Nonnull final String name, @Nonnull final String ... aliases) {
|
||||
@Nonnull
|
||||
public static <C extends CommandSender> StaticComponent<C> required(@Nonnull final String name,
|
||||
@Nonnull final String... aliases) {
|
||||
return new StaticComponent<>(true, name, aliases);
|
||||
}
|
||||
|
||||
@Nonnull public static <C extends CommandSender> StaticComponent<C> optional(@Nonnull final String name, @Nonnull final String ... aliases) {
|
||||
@Nonnull
|
||||
public static <C extends CommandSender> StaticComponent<C> optional(@Nonnull final String name,
|
||||
@Nonnull final String... aliases) {
|
||||
return new StaticComponent<>(false, name, aliases);
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +66,10 @@ public final class StaticComponent<C extends CommandSender> extends CommandCompo
|
|||
this.acceptedStrings.addAll(Arrays.asList(aliases));
|
||||
}
|
||||
|
||||
@Nonnull @Override public ComponentParseResult<String> parse(@Nonnull final CommandContext<C> commandContext, @Nonnull final Queue<String> inputQueue) {
|
||||
@Nonnull
|
||||
@Override
|
||||
public ComponentParseResult<String> parse(@Nonnull final CommandContext<C> commandContext,
|
||||
@Nonnull final Queue<String> inputQueue) {
|
||||
final String string = inputQueue.peek();
|
||||
if (string == null) {
|
||||
return ComponentParseResult.failure(this.name);
|
||||
|
|
@ -74,6 +84,15 @@ public final class StaticComponent<C extends CommandSender> extends CommandCompo
|
|||
return ComponentParseResult.failure(this.name);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<String> suggestions(@Nonnull final CommandContext<C> commandContext, @Nonnull final String input) {
|
||||
if (this.name.toLowerCase(Locale.ENGLISH).startsWith(input)) {
|
||||
return Collections.singletonList(this.name);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,8 +70,7 @@ public class CommandContext<C extends CommandSender> {
|
|||
public <T> Optional<T> get(@Nonnull final String key) {
|
||||
final Object value = this.internalStorage.get(key);
|
||||
if (value != null) {
|
||||
@SuppressWarnings("ALL")
|
||||
final T castedValue = (T) value;
|
||||
@SuppressWarnings("ALL") final T castedValue = (T) value;
|
||||
return Optional.of(castedValue);
|
||||
} else {
|
||||
return Optional.empty();
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ public class CommandParseException extends IllegalArgumentException {
|
|||
* @param commandSender Sender who executed the command
|
||||
* @param currentChain Chain leading up to the exception
|
||||
*/
|
||||
protected CommandParseException(@Nonnull final CommandSender commandSender, @Nonnull final List<CommandComponent<?, ?>> currentChain) {
|
||||
protected CommandParseException(@Nonnull final CommandSender commandSender,
|
||||
@Nonnull final List<CommandComponent<?, ?>> currentChain) {
|
||||
this.commandSender = commandSender;
|
||||
this.currentChain = currentChain;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,12 +33,15 @@ public class InvalidSyntaxException extends CommandParseException {
|
|||
|
||||
private final String correctSyntax;
|
||||
|
||||
public InvalidSyntaxException(@Nonnull final String correctSyntax, @Nonnull final CommandSender commandSender, @Nonnull final List<CommandComponent<?, ?>> currentChain) {
|
||||
public InvalidSyntaxException(@Nonnull final String correctSyntax,
|
||||
@Nonnull final CommandSender commandSender,
|
||||
@Nonnull final List<CommandComponent<?, ?>> currentChain) {
|
||||
super(commandSender, currentChain);
|
||||
this.correctSyntax = correctSyntax;
|
||||
}
|
||||
|
||||
@Nonnull public String getCorrectSyntax() {
|
||||
@Nonnull
|
||||
public String getCorrectSyntax() {
|
||||
return this.correctSyntax;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ public class NoSuchCommandException extends CommandParseException {
|
|||
* @param currentChain Chain leading up to the exception
|
||||
* @param command Entered command (following the command chain)
|
||||
*/
|
||||
public NoSuchCommandException(@Nonnull final CommandSender commandSender, @Nonnull final List<CommandComponent<?, ?>> currentChain,
|
||||
public NoSuchCommandException(@Nonnull final CommandSender commandSender,
|
||||
@Nonnull final List<CommandComponent<?, ?>> currentChain,
|
||||
@Nonnull final String command) {
|
||||
super(commandSender, currentChain);
|
||||
this.suppliedCommand = command;
|
||||
|
|
@ -55,7 +56,8 @@ public class NoSuchCommandException extends CommandParseException {
|
|||
*
|
||||
* @return Supplied command
|
||||
*/
|
||||
@Nonnull public String getSuppliedCommand() {
|
||||
@Nonnull
|
||||
public String getSuppliedCommand() {
|
||||
return this.suppliedCommand;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,8 @@ public abstract class CommandExecutionCoordinator<C extends CommandSender> {
|
|||
*
|
||||
* @return Command tree
|
||||
*/
|
||||
@Nonnull protected CommandTree<C> getCommandTree() {
|
||||
@Nonnull
|
||||
protected CommandTree<C> getCommandTree() {
|
||||
return this.commandTree;
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +84,8 @@ public abstract class CommandExecutionCoordinator<C extends CommandSender> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> coordinateExecution(@Nonnull CommandContext<C> commandContext, @Nonnull Queue<String> input) {
|
||||
public CompletableFuture<CommandResult> coordinateExecution(@Nonnull CommandContext<C> commandContext,
|
||||
@Nonnull Queue<String> input) {
|
||||
final CompletableFuture<CommandResult> completableFuture = new CompletableFuture<>();
|
||||
try {
|
||||
this.getCommandTree().parse(commandContext, input).ifPresent(
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ import javax.annotation.Nonnull;
|
|||
*
|
||||
* @param <C> Command sender type
|
||||
*/
|
||||
@FunctionalInterface public interface CommandExecutionHandler<C extends CommandSender> {
|
||||
@FunctionalInterface
|
||||
public interface CommandExecutionHandler<C extends CommandSender> {
|
||||
|
||||
/**
|
||||
* Handle command execution
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ import javax.annotation.Nonnull;
|
|||
* platform the library is used in. This can do nothing, if
|
||||
* the target platform does not have its own concept of commands
|
||||
*/
|
||||
@FunctionalInterface public interface CommandRegistrationHandler {
|
||||
@FunctionalInterface
|
||||
public interface CommandRegistrationHandler {
|
||||
|
||||
/**
|
||||
* Command registration handler that does nothing
|
||||
|
|
|
|||
|
|
@ -31,17 +31,21 @@ public abstract class ComponentParseResult<T> {
|
|||
private ComponentParseResult() {
|
||||
}
|
||||
|
||||
@Nonnull public static <T> ComponentParseResult<T> failure(@Nonnull final String failure) {
|
||||
@Nonnull
|
||||
public static <T> ComponentParseResult<T> failure(@Nonnull final String failure) {
|
||||
return new ParseFailure<>(failure);
|
||||
}
|
||||
|
||||
@Nonnull public static <T> ComponentParseResult<T> success(@Nonnull final T value) {
|
||||
@Nonnull
|
||||
public static <T> ComponentParseResult<T> success(@Nonnull final T value) {
|
||||
return new ParseSuccess<>(value);
|
||||
}
|
||||
|
||||
@Nonnull public abstract Optional<T> getParsedValue();
|
||||
@Nonnull
|
||||
public abstract Optional<T> getParsedValue();
|
||||
|
||||
@Nonnull public abstract Optional<String> getFailure();
|
||||
@Nonnull
|
||||
public abstract Optional<String> getFailure();
|
||||
|
||||
|
||||
private static final class ParseSuccess<T> extends ComponentParseResult<T> {
|
||||
|
|
@ -52,11 +56,15 @@ public abstract class ComponentParseResult<T> {
|
|||
this.value = value;
|
||||
}
|
||||
|
||||
@Nonnull @Override public Optional<T> getParsedValue() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Optional<T> getParsedValue() {
|
||||
return Optional.of(this.value);
|
||||
}
|
||||
|
||||
@Nonnull @Override public Optional<String> getFailure() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Optional<String> getFailure() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
|
|
@ -71,11 +79,15 @@ public abstract class ComponentParseResult<T> {
|
|||
this.failure = failure;
|
||||
}
|
||||
|
||||
@Nonnull @Override public Optional<T> getParsedValue() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Optional<T> getParsedValue() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Nonnull @Override public Optional<String> getFailure() {
|
||||
@Nonnull
|
||||
@Override
|
||||
public Optional<String> getFailure() {
|
||||
return Optional.of(this.failure);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ import com.intellectualsites.commands.context.CommandContext;
|
|||
import com.intellectualsites.commands.sender.CommandSender;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
@FunctionalInterface
|
||||
|
|
@ -42,4 +44,9 @@ public interface ComponentParser<C extends CommandSender, T> {
|
|||
@Nonnull
|
||||
ComponentParseResult<T> parse(@Nonnull CommandContext<C> commandContext, @Nonnull Queue<String> inputQueue);
|
||||
|
||||
@Nonnull
|
||||
default List<String> suggestions(@Nonnull final CommandContext<C> commandContext, @Nonnull final String input) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue