Update javadocs

This commit is contained in:
chickeneer
2023-04-02 16:51:48 -05:00
parent fa29b4de22
commit e41896bf2f
13 changed files with 1087 additions and 931 deletions
@@ -77,7 +77,7 @@ loadScripts(document, 'script');</script>
<dd><a href="CommandCompletions.html" title="class in co.aikar.commands">CommandCompletions</a>&lt;<a href="CommandCompletions.html" title="type parameter in CommandCompletions">C</a> extends <a href="CommandCompletionContext.html" title="class in co.aikar.commands">CommandCompletionContext</a>&gt;</dd> <dd><a href="CommandCompletions.html" title="class in co.aikar.commands">CommandCompletions</a>&lt;<a href="CommandCompletions.html" title="type parameter in CommandCompletions">C</a> extends <a href="CommandCompletionContext.html" title="class in co.aikar.commands">CommandCompletionContext</a>&gt;</dd>
</dl> </dl>
<hr> <hr>
<div class="type-signature"><span class="modifiers">public static interface </span><span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-304">CommandCompletions.AsyncCommandCompletionHandler</a>&lt;C extends <a href="CommandCompletionContext.html" title="class in co.aikar.commands">CommandCompletionContext</a>&gt;</span><span class="extends-implements"> <div class="type-signature"><span class="modifiers">public static interface </span><span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-318">CommandCompletions.AsyncCommandCompletionHandler</a>&lt;C extends <a href="CommandCompletionContext.html" title="class in co.aikar.commands">CommandCompletionContext</a>&gt;</span><span class="extends-implements">
extends <a href="CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a>&lt;C&gt;</span></div> extends <a href="CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a>&lt;C&gt;</span></div>
</section> </section>
<section class="summary"> <section class="summary">
@@ -81,7 +81,7 @@ loadScripts(document, 'script');</script>
<dd><a href="CommandCompletions.html" title="class in co.aikar.commands">CommandCompletions</a>&lt;<a href="CommandCompletions.html" title="type parameter in CommandCompletions">C</a> extends <a href="CommandCompletionContext.html" title="class in co.aikar.commands">CommandCompletionContext</a>&gt;</dd> <dd><a href="CommandCompletions.html" title="class in co.aikar.commands">CommandCompletions</a>&lt;<a href="CommandCompletions.html" title="type parameter in CommandCompletions">C</a> extends <a href="CommandCompletionContext.html" title="class in co.aikar.commands">CommandCompletionContext</a>&gt;</dd>
</dl> </dl>
<hr> <hr>
<div class="type-signature"><span class="modifiers">public static interface </span><span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-300">CommandCompletions.CommandCompletionHandler</a>&lt;C extends <a href="CommandCompletionContext.html" title="class in co.aikar.commands">CommandCompletionContext</a>&gt;</span></div> <div class="type-signature"><span class="modifiers">public static interface </span><span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-314">CommandCompletions.CommandCompletionHandler</a>&lt;C extends <a href="CommandCompletionContext.html" title="class in co.aikar.commands">CommandCompletionContext</a>&gt;</span></div>
</section> </section>
<section class="summary"> <section class="summary">
<ul class="summary-list"> <ul class="summary-list">
@@ -116,7 +116,7 @@ loadScripts(document, 'script');</script>
<li> <li>
<section class="detail" id="getCompletions(C)"> <section class="detail" id="getCompletions(C)">
<h3 id="getCompletions(co.aikar.commands.CommandCompletionContext)">getCompletions</h3> <h3 id="getCompletions(co.aikar.commands.CommandCompletionContext)">getCompletions</h3>
<div class="member-signature"><span class="return-type"><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html" title="class or interface in java.util" class="external-link">Collection</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&gt;</span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.CommandCompletionHandler.html#line-301">getCompletions</a></span><wbr><span class="parameters">(<a href="CommandCompletions.CommandCompletionHandler.html" title="type parameter in CommandCompletions.CommandCompletionHandler">C</a>&nbsp;context)</span> <div class="member-signature"><span class="return-type"><a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html" title="class or interface in java.util" class="external-link">Collection</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&gt;</span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.CommandCompletionHandler.html#line-315">getCompletions</a></span><wbr><span class="parameters">(<a href="CommandCompletions.CommandCompletionHandler.html" title="type parameter in CommandCompletions.CommandCompletionHandler">C</a>&nbsp;context)</span>
throws <span class="exceptions"><a href="InvalidCommandArgument.html" title="class in co.aikar.commands">InvalidCommandArgument</a></span></div> throws <span class="exceptions"><a href="InvalidCommandArgument.html" title="class in co.aikar.commands">InvalidCommandArgument</a></span></div>
<dl class="notes"> <dl class="notes">
<dt>Throws:</dt> <dt>Throws:</dt>
@@ -86,7 +86,7 @@ loadScripts(document, 'script');</script>
<dd><a href="CommandCompletions.html" title="class in co.aikar.commands">CommandCompletions</a>&lt;<a href="CommandCompletions.html" title="type parameter in CommandCompletions">C</a> extends <a href="CommandCompletionContext.html" title="class in co.aikar.commands">CommandCompletionContext</a>&gt;</dd> <dd><a href="CommandCompletions.html" title="class in co.aikar.commands">CommandCompletions</a>&lt;<a href="CommandCompletions.html" title="type parameter in CommandCompletions">C</a> extends <a href="CommandCompletionContext.html" title="class in co.aikar.commands">CommandCompletionContext</a>&gt;</dd>
</dl> </dl>
<hr> <hr>
<div class="type-signature"><span class="modifiers">public static class </span><span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-307">CommandCompletions.SyncCompletionRequired</a></span> <div class="type-signature"><span class="modifiers">public static class </span><span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-321">CommandCompletions.SyncCompletionRequired</a></span>
<span class="extends-implements">extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/RuntimeException.html" title="class or interface in java.lang" class="external-link">RuntimeException</a></span></div> <span class="extends-implements">extends <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/RuntimeException.html" title="class or interface in java.lang" class="external-link">RuntimeException</a></span></div>
<dl class="notes"> <dl class="notes">
<dt>See Also:</dt> <dt>See Also:</dt>
@@ -136,7 +136,7 @@ loadScripts(document, 'script');</script>
<li> <li>
<section class="detail" id="&lt;init&gt;()"> <section class="detail" id="&lt;init&gt;()">
<h3>SyncCompletionRequired</h3> <h3>SyncCompletionRequired</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.SyncCompletionRequired.html#line-307">SyncCompletionRequired</a></span>()</div> <div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.SyncCompletionRequired.html#line-321">SyncCompletionRequired</a></span>()</div>
</section> </section>
</li> </li>
</ul> </ul>
@@ -168,6 +168,11 @@ loadScripts(document, 'script');</script>
<div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"> <div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">
<div class="block">Registers a completion handler such as @players to default apply to all command parameters of the specified types</div> <div class="block">Registers a completion handler such as @players to default apply to all command parameters of the specified types</div>
</div> </div>
<div class="col-first odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></code></div>
<div class="col-second odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#unregisterCompletion(java.lang.String)" class="member-name-link">unregisterCompletion</a><wbr>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id)</code></div>
<div class="col-last odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">
<div class="block">Unregister a completion handler.</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -214,9 +219,23 @@ loadScripts(document, 'script');</script>
</section> </section>
</li> </li>
<li> <li>
<section class="detail" id="unregisterCompletion(java.lang.String)">
<h3>unregisterCompletion</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-91">unregisterCompletion</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id)</span></div>
<div class="block">Unregister a completion handler.</div>
<dl class="notes">
<dt>Parameters:</dt>
<dd><code>id</code> - </dd>
<dt>Returns:</dt>
<dt>Throws:</dt>
<dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/IllegalStateException.html" title="class or interface in java.lang" class="external-link">IllegalStateException</a></code> - If the completion couldn't be found</dd>
</dl>
</section>
</li>
<li>
<section class="detail" id="registerAsyncCompletion(java.lang.String,co.aikar.commands.CommandCompletions.AsyncCommandCompletionHandler)"> <section class="detail" id="registerAsyncCompletion(java.lang.String,co.aikar.commands.CommandCompletions.AsyncCommandCompletionHandler)">
<h3>registerAsyncCompletion</h3> <h3>registerAsyncCompletion</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-100">registerAsyncCompletion</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id, <div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-114">registerAsyncCompletion</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id,
<a href="CommandCompletions.AsyncCommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.AsyncCommandCompletionHandler</a>&lt;<a href="CommandCompletions.html" title="type parameter in CommandCompletions">C</a>&gt;&nbsp;handler)</span></div> <a href="CommandCompletions.AsyncCommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.AsyncCommandCompletionHandler</a>&lt;<a href="CommandCompletions.html" title="type parameter in CommandCompletions">C</a>&gt;&nbsp;handler)</span></div>
<div class="block">Registr a completion handler to provide command completions based on the user input. <div class="block">Registr a completion handler to provide command completions based on the user input.
This handler is declared to be safe to be executed asynchronously. This handler is declared to be safe to be executed asynchronously.
@@ -238,7 +257,7 @@ loadScripts(document, 'script');</script>
<li> <li>
<section class="detail" id="registerStaticCompletion(java.lang.String,java.lang.String)"> <section class="detail" id="registerStaticCompletion(java.lang.String,java.lang.String)">
<h3>registerStaticCompletion</h3> <h3>registerStaticCompletion</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-114">registerStaticCompletion</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id, <div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-128">registerStaticCompletion</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id,
<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;list)</span></div> <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;list)</span></div>
<div class="block">Register a static list of command completions that will never change. <div class="block">Register a static list of command completions that will never change.
Like @CommandCompletion, values are | (PIPE) separated. Like @CommandCompletion, values are | (PIPE) separated.
@@ -255,7 +274,7 @@ loadScripts(document, 'script');</script>
<li> <li>
<section class="detail" id="registerStaticCompletion(java.lang.String,java.lang.String[])"> <section class="detail" id="registerStaticCompletion(java.lang.String,java.lang.String[])">
<h3>registerStaticCompletion</h3> <h3>registerStaticCompletion</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-125">registerStaticCompletion</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id, <div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-139">registerStaticCompletion</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id,
<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>[]&nbsp;completions)</span></div> <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>[]&nbsp;completions)</span></div>
<div class="block">Register a static list of command completions that will never change</div> <div class="block">Register a static list of command completions that will never change</div>
<dl class="notes"> <dl class="notes">
@@ -269,7 +288,7 @@ loadScripts(document, 'script');</script>
<li> <li>
<section class="detail" id="registerStaticCompletion(java.lang.String,java.util.function.Supplier)"> <section class="detail" id="registerStaticCompletion(java.lang.String,java.util.function.Supplier)">
<h3>registerStaticCompletion</h3> <h3>registerStaticCompletion</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-137">registerStaticCompletion</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id, <div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-151">registerStaticCompletion</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id,
<a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html" title="class or interface in java.util.function" class="external-link">Supplier</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html" title="class or interface in java.util" class="external-link">Collection</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&gt;&gt;&nbsp;supplier)</span></div> <a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html" title="class or interface in java.util.function" class="external-link">Supplier</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html" title="class or interface in java.util" class="external-link">Collection</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&gt;&gt;&nbsp;supplier)</span></div>
<div class="block">Register a static list of command completions that will never change. The list is obtained from the supplier <div class="block">Register a static list of command completions that will never change. The list is obtained from the supplier
immediately as part of this method call.</div> immediately as part of this method call.</div>
@@ -284,7 +303,7 @@ loadScripts(document, 'script');</script>
<li> <li>
<section class="detail" id="registerStaticCompletion(java.lang.String,java.util.Collection)"> <section class="detail" id="registerStaticCompletion(java.lang.String,java.util.Collection)">
<h3>registerStaticCompletion</h3> <h3>registerStaticCompletion</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-148">registerStaticCompletion</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id, <div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-162">registerStaticCompletion</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id,
<a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html" title="class or interface in java.util" class="external-link">Collection</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&gt;&nbsp;completions)</span></div> <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html" title="class or interface in java.util" class="external-link">Collection</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&gt;&nbsp;completions)</span></div>
<div class="block">Register a static list of command completions that will never change</div> <div class="block">Register a static list of command completions that will never change</div>
<dl class="notes"> <dl class="notes">
@@ -298,7 +317,7 @@ loadScripts(document, 'script');</script>
<li> <li>
<section class="detail" id="setDefaultCompletion(java.lang.String,java.lang.Class...)"> <section class="detail" id="setDefaultCompletion(java.lang.String,java.lang.Class...)">
<h3>setDefaultCompletion</h3> <h3>setDefaultCompletion</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-160">setDefaultCompletion</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id, <div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandCompletions.html#line-174">setDefaultCompletion</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id,
<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html" title="class or interface in java.lang" class="external-link">Class</a>...&nbsp;classes)</span></div> <a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html" title="class or interface in java.lang" class="external-link">Class</a>...&nbsp;classes)</span></div>
<div class="block">Registers a completion handler such as @players to default apply to all command parameters of the specified types <div class="block">Registers a completion handler such as @players to default apply to all command parameters of the specified types
<p> <p>
@@ -446,6 +446,17 @@ loadScripts(document, 'script');</script>
<div class="col-first even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>void</code></div> <div class="col-first even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>void</code></div>
<div class="col-second even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#setValidNamePredicate(java.util.function.Predicate)" class="member-name-link">setValidNamePredicate</a><wbr>(@NotNull <a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html" title="class or interface in java.util.function" class="external-link">Predicate</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&gt;&nbsp;isValidName)</code></div> <div class="col-second even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#setValidNamePredicate(java.util.function.Predicate)" class="member-name-link">setValidNamePredicate</a><wbr>(@NotNull <a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html" title="class or interface in java.util.function" class="external-link">Predicate</a>&lt;<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&gt;&nbsp;isValidName)</code></div>
<div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">&nbsp;</div> <div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">&nbsp;</div>
<div class="col-first odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>&lt;T&gt;&nbsp;void</code></div>
<div class="col-second odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#unregisterDependency(java.lang.Class)" class="member-name-link">unregisterDependency</a><wbr>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html" title="class or interface in java.lang" class="external-link">Class</a>&lt;? extends T&gt;&nbsp;clazz)</code></div>
<div class="col-last odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">
<div class="block">Unregisters an instance of the class, it will no longer be able to be injected</div>
</div>
<div class="col-first even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>&lt;T&gt;&nbsp;void</code></div>
<div class="col-second even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#unregisterDependency(java.lang.Class,java.lang.String)" class="member-name-link">unregisterDependency</a><wbr>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html" title="class or interface in java.lang" class="external-link">Class</a>&lt;? extends T&gt;&nbsp;clazz,
<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;key)</code></div>
<div class="col-last even-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">
<div class="block">Unregisters an instance of the class, it will no longer be able to be injected</div>
</div>
<div class="col-first odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>boolean</code></div> <div class="col-first odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code>boolean</code></div>
<div class="col-second odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#usePerIssuerLocale(boolean)" class="member-name-link">usePerIssuerLocale</a><wbr>(boolean&nbsp;setting)</code></div> <div class="col-second odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4"><code><a href="#usePerIssuerLocale(boolean)" class="member-name-link">usePerIssuerLocale</a><wbr>(boolean&nbsp;setting)</code></div>
<div class="col-last odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">&nbsp;</div> <div class="col-last odd-row-color method-summary-table method-summary-table-tab2 method-summary-table-tab4">&nbsp;</div>
@@ -1092,10 +1103,38 @@ loadScripts(document, 'script');</script>
</section> </section>
</li> </li>
<li> <li>
<section class="detail" id="unregisterDependency(java.lang.Class)">
<h3>unregisterDependency</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="type-parameters">&lt;T&gt;</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandManager.html#line-542">unregisterDependency</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html" title="class or interface in java.lang" class="external-link">Class</a>&lt;? extends T&gt;&nbsp;clazz)</span></div>
<div class="block">Unregisters an instance of the class, it will no longer be able to be injected</div>
<dl class="notes">
<dt>Parameters:</dt>
<dd><code>clazz</code> - the class the injector should look for to remove</dd>
<dt>Throws:</dt>
<dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/IllegalStateException.html" title="class or interface in java.lang" class="external-link">IllegalStateException</a></code> - If the dependency was not found.</dd>
</dl>
</section>
</li>
<li>
<section class="detail" id="unregisterDependency(java.lang.Class,java.lang.String)">
<h3>unregisterDependency</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="type-parameters">&lt;T&gt;</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandManager.html#line-553">unregisterDependency</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html" title="class or interface in java.lang" class="external-link">Class</a>&lt;? extends T&gt;&nbsp;clazz,
<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;key)</span></div>
<div class="block">Unregisters an instance of the class, it will no longer be able to be injected</div>
<dl class="notes">
<dt>Parameters:</dt>
<dd><code>clazz</code> - the class the injector should look for to remove</dd>
<dd><code>key</code> - the key which needs to be present if that</dd>
<dt>Throws:</dt>
<dd><code><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/IllegalStateException.html" title="class or interface in java.lang" class="external-link">IllegalStateException</a></code> - If the dependency was not found.</dd>
</dl>
</section>
</li>
<li>
<section class="detail" id="enableUnstableAPI(java.lang.String)"> <section class="detail" id="enableUnstableAPI(java.lang.String)">
<h3>enableUnstableAPI</h3> <h3>enableUnstableAPI</h3>
<div class="member-signature"><span class="annotations"><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Deprecated.html" title="class or interface in java.lang" class="external-link">@Deprecated</a> <div class="member-signature"><span class="annotations"><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Deprecated.html" title="class or interface in java.lang" class="external-link">@Deprecated</a>
</span><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandManager.html#line-576">enableUnstableAPI</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;api)</span></div> </span><span class="modifiers">public</span>&nbsp;<span class="return-type">void</span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandManager.html#line-601">enableUnstableAPI</a></span><wbr><span class="parameters">(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;api)</span></div>
<div class="deprecation-block"><span class="deprecated-label">Deprecated.</span> <div class="deprecation-block"><span class="deprecated-label">Deprecated.</span>
<div class="deprecation-comment">Use this with caution! If you enable and use Unstable API's, your next compile using ACF <div class="deprecation-comment">Use this with caution! If you enable and use Unstable API's, your next compile using ACF
may require you to update your implementation to those unstable API's</div> may require you to update your implementation to those unstable API's</div>
@@ -1105,7 +1144,7 @@ loadScripts(document, 'script');</script>
<li> <li>
<section class="detail" id="getCommandPrefix(co.aikar.commands.CommandIssuer)"> <section class="detail" id="getCommandPrefix(co.aikar.commands.CommandIssuer)">
<h3>getCommandPrefix</h3> <h3>getCommandPrefix</h3>
<div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a></span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandManager.html#line-595">getCommandPrefix</a></span><wbr><span class="parameters">(<a href="CommandIssuer.html" title="interface in co.aikar.commands">CommandIssuer</a>&nbsp;issuer)</span></div> <div class="member-signature"><span class="modifiers">public</span>&nbsp;<span class="return-type"><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a></span>&nbsp;<span class="element-name"><a href="../../../src-html/co/aikar/commands/CommandManager.html#line-620">getCommandPrefix</a></span><wbr><span class="parameters">(<a href="CommandIssuer.html" title="interface in co.aikar.commands">CommandIssuer</a>&nbsp;issuer)</span></div>
</section> </section>
</li> </li>
</ul> </ul>
@@ -112,6 +112,11 @@ loadScripts(document, 'script');</script>
<div class="col-last odd-row-color"> <div class="col-last odd-row-color">
<div class="block">Register a static list of command completions that will never change.</div> <div class="block">Register a static list of command completions that will never change.</div>
</div> </div>
<div class="col-first even-row-color"><code><a href="../CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></code></div>
<div class="col-second even-row-color"><span class="type-name-label">CommandCompletions.</span><code><a href="../CommandCompletions.html#unregisterCompletion(java.lang.String)" class="member-name-link">unregisterCompletion</a><wbr>(<a href="https://docs.oracle.com/javase/8/docs/api/java/lang/String.html" title="class or interface in java.lang" class="external-link">String</a>&nbsp;id)</code></div>
<div class="col-last even-row-color">
<div class="block">Unregister a completion handler.</div>
</div>
</div> </div>
<div class="caption"><span>Methods in <a href="../package-summary.html">co.aikar.commands</a> with parameters of type <a href="../CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></span></div> <div class="caption"><span>Methods in <a href="../package-summary.html">co.aikar.commands</a> with parameters of type <a href="../CommandCompletions.CommandCompletionHandler.html" title="interface in co.aikar.commands">CommandCompletions.CommandCompletionHandler</a></span></div>
<div class="summary-table three-column-summary"> <div class="summary-table three-column-summary">
+12
View File
@@ -1906,6 +1906,18 @@ loadScripts(document, 'script');</script>
<div class="deprecation-comment">Use <a href="co/aikar/commands/annotation/CatchUnknown.html" title="annotation in co.aikar.commands.annotation"><code>instead, which is more accurately named</code></a></div> <div class="deprecation-comment">Use <a href="co/aikar/commands/annotation/CatchUnknown.html" title="annotation in co.aikar.commands.annotation"><code>instead, which is more accurately named</code></a></div>
</div> </div>
</dd> </dd>
<dt><a href="co/aikar/commands/CommandCompletions.html#unregisterCompletion(java.lang.String)" class="member-name-link">unregisterCompletion(String)</a> - Method in class co.aikar.commands.<a href="co/aikar/commands/CommandCompletions.html" title="class in co.aikar.commands">CommandCompletions</a></dt>
<dd>
<div class="block">Unregister a completion handler.</div>
</dd>
<dt><a href="co/aikar/commands/CommandManager.html#unregisterDependency(java.lang.Class)" class="member-name-link">unregisterDependency(Class&lt;? extends T&gt;)</a> - Method in class co.aikar.commands.<a href="co/aikar/commands/CommandManager.html" title="class in co.aikar.commands">CommandManager</a></dt>
<dd>
<div class="block">Unregisters an instance of the class, it will no longer be able to be injected</div>
</dd>
<dt><a href="co/aikar/commands/CommandManager.html#unregisterDependency(java.lang.Class,java.lang.String)" class="member-name-link">unregisterDependency(Class&lt;? extends T&gt;, String)</a> - Method in class co.aikar.commands.<a href="co/aikar/commands/CommandManager.html" title="class in co.aikar.commands">CommandManager</a></dt>
<dd>
<div class="block">Unregisters an instance of the class, it will no longer be able to be injected</div>
</dd>
<dt><a href="co/aikar/commands/UnresolvedDependencyException.html" class="type-name-link" title="class in co.aikar.commands">UnresolvedDependencyException</a> - Exception in <a href="co/aikar/commands/package-summary.html">co.aikar.commands</a></dt> <dt><a href="co/aikar/commands/UnresolvedDependencyException.html" class="type-name-link" title="class in co.aikar.commands">UnresolvedDependencyException</a> - Exception in <a href="co/aikar/commands/package-summary.html">co.aikar.commands</a></dt>
<dd> <dd>
<div class="block">Thrown when a command mananger couldn't find a registered instance for a field that is marked with <div class="block">Thrown when a command mananger couldn't find a registered instance for a field that is marked with
File diff suppressed because one or more lines are too long
@@ -96,231 +96,245 @@
<span class="source-line-no">083</span><span id="line-83"> }</span> <span class="source-line-no">083</span><span id="line-83"> }</span>
<span class="source-line-no">084</span><span id="line-84"></span> <span class="source-line-no">084</span><span id="line-84"></span>
<span class="source-line-no">085</span><span id="line-85"> /**</span> <span class="source-line-no">085</span><span id="line-85"> /**</span>
<span class="source-line-no">086</span><span id="line-86"> * Registr a completion handler to provide command completions based on the user input.</span> <span class="source-line-no">086</span><span id="line-86"> * Unregister a completion handler.</span>
<span class="source-line-no">087</span><span id="line-87"> * This handler is declared to be safe to be executed asynchronously.</span> <span class="source-line-no">087</span><span id="line-87"> * @param id</span>
<span class="source-line-no">088</span><span id="line-88"> * &lt;p&gt;</span> <span class="source-line-no">088</span><span id="line-88"> * @return</span>
<span class="source-line-no">089</span><span id="line-89"> * Not all platforms support this, so if the platform does not support asynchronous execution,</span> <span class="source-line-no">089</span><span id="line-89"> * @throws IllegalStateException If the completion couldn't be found</span>
<span class="source-line-no">090</span><span id="line-90"> * your handler will be executed on the main thread.</span> <span class="source-line-no">090</span><span id="line-90"> */</span>
<span class="source-line-no">091</span><span id="line-91"> * &lt;p&gt;</span> <span class="source-line-no">091</span><span id="line-91"> public CommandCompletionHandler unregisterCompletion(String id) {</span>
<span class="source-line-no">092</span><span id="line-92"> * Use this anytime your handler does not need to access state that is not considered thread safe.</span> <span class="source-line-no">092</span><span id="line-92"> if (!this.completionMap.containsKey(id)) {</span>
<span class="source-line-no">093</span><span id="line-93"> * &lt;p&gt;</span> <span class="source-line-no">093</span><span id="line-93"> throw new IllegalStateException("The supplied key " + id + " does not exist in any completions");</span>
<span class="source-line-no">094</span><span id="line-94"> * Use context.isAsync() to determine if you are async or not.</span> <span class="source-line-no">094</span><span id="line-94"> }</span>
<span class="source-line-no">095</span><span id="line-95"> *</span> <span class="source-line-no">095</span><span id="line-95"></span>
<span class="source-line-no">096</span><span id="line-96"> * @param id</span> <span class="source-line-no">096</span><span id="line-96"> return this.completionMap.remove(id);</span>
<span class="source-line-no">097</span><span id="line-97"> * @param handler</span> <span class="source-line-no">097</span><span id="line-97"> }</span>
<span class="source-line-no">098</span><span id="line-98"> * @return</span> <span class="source-line-no">098</span><span id="line-98"></span>
<span class="source-line-no">099</span><span id="line-99"> */</span> <span class="source-line-no">099</span><span id="line-99"> /**</span>
<span class="source-line-no">100</span><span id="line-100"> public CommandCompletionHandler registerAsyncCompletion(String id, AsyncCommandCompletionHandler&lt;C&gt; handler) {</span> <span class="source-line-no">100</span><span id="line-100"> * Registr a completion handler to provide command completions based on the user input.</span>
<span class="source-line-no">101</span><span id="line-101"> return this.completionMap.put(prepareCompletionId(id), handler);</span> <span class="source-line-no">101</span><span id="line-101"> * This handler is declared to be safe to be executed asynchronously.</span>
<span class="source-line-no">102</span><span id="line-102"> }</span> <span class="source-line-no">102</span><span id="line-102"> * &lt;p&gt;</span>
<span class="source-line-no">103</span><span id="line-103"></span> <span class="source-line-no">103</span><span id="line-103"> * Not all platforms support this, so if the platform does not support asynchronous execution,</span>
<span class="source-line-no">104</span><span id="line-104"> /**</span> <span class="source-line-no">104</span><span id="line-104"> * your handler will be executed on the main thread.</span>
<span class="source-line-no">105</span><span id="line-105"> * Register a static list of command completions that will never change.</span> <span class="source-line-no">105</span><span id="line-105"> * &lt;p&gt;</span>
<span class="source-line-no">106</span><span id="line-106"> * Like @CommandCompletion, values are | (PIPE) separated.</span> <span class="source-line-no">106</span><span id="line-106"> * Use this anytime your handler does not need to access state that is not considered thread safe.</span>
<span class="source-line-no">107</span><span id="line-107"> * &lt;p&gt;</span> <span class="source-line-no">107</span><span id="line-107"> * &lt;p&gt;</span>
<span class="source-line-no">108</span><span id="line-108"> * Example: foo|bar|baz</span> <span class="source-line-no">108</span><span id="line-108"> * Use context.isAsync() to determine if you are async or not.</span>
<span class="source-line-no">109</span><span id="line-109"> *</span> <span class="source-line-no">109</span><span id="line-109"> *</span>
<span class="source-line-no">110</span><span id="line-110"> * @param id</span> <span class="source-line-no">110</span><span id="line-110"> * @param id</span>
<span class="source-line-no">111</span><span id="line-111"> * @param list</span> <span class="source-line-no">111</span><span id="line-111"> * @param handler</span>
<span class="source-line-no">112</span><span id="line-112"> * @return</span> <span class="source-line-no">112</span><span id="line-112"> * @return</span>
<span class="source-line-no">113</span><span id="line-113"> */</span> <span class="source-line-no">113</span><span id="line-113"> */</span>
<span class="source-line-no">114</span><span id="line-114"> public CommandCompletionHandler registerStaticCompletion(String id, String list) {</span> <span class="source-line-no">114</span><span id="line-114"> public CommandCompletionHandler registerAsyncCompletion(String id, AsyncCommandCompletionHandler&lt;C&gt; handler) {</span>
<span class="source-line-no">115</span><span id="line-115"> return registerStaticCompletion(id, ACFPatterns.PIPE.split(list));</span> <span class="source-line-no">115</span><span id="line-115"> return this.completionMap.put(prepareCompletionId(id), handler);</span>
<span class="source-line-no">116</span><span id="line-116"> }</span> <span class="source-line-no">116</span><span id="line-116"> }</span>
<span class="source-line-no">117</span><span id="line-117"></span> <span class="source-line-no">117</span><span id="line-117"></span>
<span class="source-line-no">118</span><span id="line-118"> /**</span> <span class="source-line-no">118</span><span id="line-118"> /**</span>
<span class="source-line-no">119</span><span id="line-119"> * Register a static list of command completions that will never change</span> <span class="source-line-no">119</span><span id="line-119"> * Register a static list of command completions that will never change.</span>
<span class="source-line-no">120</span><span id="line-120"> *</span> <span class="source-line-no">120</span><span id="line-120"> * Like @CommandCompletion, values are | (PIPE) separated.</span>
<span class="source-line-no">121</span><span id="line-121"> * @param id</span> <span class="source-line-no">121</span><span id="line-121"> * &lt;p&gt;</span>
<span class="source-line-no">122</span><span id="line-122"> * @param completions</span> <span class="source-line-no">122</span><span id="line-122"> * Example: foo|bar|baz</span>
<span class="source-line-no">123</span><span id="line-123"> * @return</span> <span class="source-line-no">123</span><span id="line-123"> *</span>
<span class="source-line-no">124</span><span id="line-124"> */</span> <span class="source-line-no">124</span><span id="line-124"> * @param id</span>
<span class="source-line-no">125</span><span id="line-125"> public CommandCompletionHandler registerStaticCompletion(String id, String[] completions) {</span> <span class="source-line-no">125</span><span id="line-125"> * @param list</span>
<span class="source-line-no">126</span><span id="line-126"> return registerStaticCompletion(id, Arrays.asList(completions));</span> <span class="source-line-no">126</span><span id="line-126"> * @return</span>
<span class="source-line-no">127</span><span id="line-127"> }</span> <span class="source-line-no">127</span><span id="line-127"> */</span>
<span class="source-line-no">128</span><span id="line-128"></span> <span class="source-line-no">128</span><span id="line-128"> public CommandCompletionHandler registerStaticCompletion(String id, String list) {</span>
<span class="source-line-no">129</span><span id="line-129"> /**</span> <span class="source-line-no">129</span><span id="line-129"> return registerStaticCompletion(id, ACFPatterns.PIPE.split(list));</span>
<span class="source-line-no">130</span><span id="line-130"> * Register a static list of command completions that will never change. The list is obtained from the supplier</span> <span class="source-line-no">130</span><span id="line-130"> }</span>
<span class="source-line-no">131</span><span id="line-131"> * immediately as part of this method call.</span> <span class="source-line-no">131</span><span id="line-131"></span>
<span class="source-line-no">132</span><span id="line-132"> *</span> <span class="source-line-no">132</span><span id="line-132"> /**</span>
<span class="source-line-no">133</span><span id="line-133"> * @param id</span> <span class="source-line-no">133</span><span id="line-133"> * Register a static list of command completions that will never change</span>
<span class="source-line-no">134</span><span id="line-134"> * @param supplier</span> <span class="source-line-no">134</span><span id="line-134"> *</span>
<span class="source-line-no">135</span><span id="line-135"> * @return</span> <span class="source-line-no">135</span><span id="line-135"> * @param id</span>
<span class="source-line-no">136</span><span id="line-136"> */</span> <span class="source-line-no">136</span><span id="line-136"> * @param completions</span>
<span class="source-line-no">137</span><span id="line-137"> public CommandCompletionHandler registerStaticCompletion(String id, Supplier&lt;Collection&lt;String&gt;&gt; supplier) {</span> <span class="source-line-no">137</span><span id="line-137"> * @return</span>
<span class="source-line-no">138</span><span id="line-138"> return registerStaticCompletion(id, supplier.get());</span> <span class="source-line-no">138</span><span id="line-138"> */</span>
<span class="source-line-no">139</span><span id="line-139"> }</span> <span class="source-line-no">139</span><span id="line-139"> public CommandCompletionHandler registerStaticCompletion(String id, String[] completions) {</span>
<span class="source-line-no">140</span><span id="line-140"></span> <span class="source-line-no">140</span><span id="line-140"> return registerStaticCompletion(id, Arrays.asList(completions));</span>
<span class="source-line-no">141</span><span id="line-141"> /**</span> <span class="source-line-no">141</span><span id="line-141"> }</span>
<span class="source-line-no">142</span><span id="line-142"> * Register a static list of command completions that will never change</span> <span class="source-line-no">142</span><span id="line-142"></span>
<span class="source-line-no">143</span><span id="line-143"> *</span> <span class="source-line-no">143</span><span id="line-143"> /**</span>
<span class="source-line-no">144</span><span id="line-144"> * @param id</span> <span class="source-line-no">144</span><span id="line-144"> * Register a static list of command completions that will never change. The list is obtained from the supplier</span>
<span class="source-line-no">145</span><span id="line-145"> * @param completions</span> <span class="source-line-no">145</span><span id="line-145"> * immediately as part of this method call.</span>
<span class="source-line-no">146</span><span id="line-146"> * @return</span> <span class="source-line-no">146</span><span id="line-146"> *</span>
<span class="source-line-no">147</span><span id="line-147"> */</span> <span class="source-line-no">147</span><span id="line-147"> * @param id</span>
<span class="source-line-no">148</span><span id="line-148"> public CommandCompletionHandler registerStaticCompletion(String id, Collection&lt;String&gt; completions) {</span> <span class="source-line-no">148</span><span id="line-148"> * @param supplier</span>
<span class="source-line-no">149</span><span id="line-149"> return registerAsyncCompletion(id, x -&gt; completions);</span> <span class="source-line-no">149</span><span id="line-149"> * @return</span>
<span class="source-line-no">150</span><span id="line-150"> }</span> <span class="source-line-no">150</span><span id="line-150"> */</span>
<span class="source-line-no">151</span><span id="line-151"></span> <span class="source-line-no">151</span><span id="line-151"> public CommandCompletionHandler registerStaticCompletion(String id, Supplier&lt;Collection&lt;String&gt;&gt; supplier) {</span>
<span class="source-line-no">152</span><span id="line-152"> /**</span> <span class="source-line-no">152</span><span id="line-152"> return registerStaticCompletion(id, supplier.get());</span>
<span class="source-line-no">153</span><span id="line-153"> * Registers a completion handler such as @players to default apply to all command parameters of the specified types</span> <span class="source-line-no">153</span><span id="line-153"> }</span>
<span class="source-line-no">154</span><span id="line-154"> * &lt;p&gt;</span> <span class="source-line-no">154</span><span id="line-154"></span>
<span class="source-line-no">155</span><span id="line-155"> * This enables automatic completion support for parameters without manually defining it for custom objects</span> <span class="source-line-no">155</span><span id="line-155"> /**</span>
<span class="source-line-no">156</span><span id="line-156"> *</span> <span class="source-line-no">156</span><span id="line-156"> * Register a static list of command completions that will never change</span>
<span class="source-line-no">157</span><span id="line-157"> * @param id</span> <span class="source-line-no">157</span><span id="line-157"> *</span>
<span class="source-line-no">158</span><span id="line-158"> * @param classes</span> <span class="source-line-no">158</span><span id="line-158"> * @param id</span>
<span class="source-line-no">159</span><span id="line-159"> */</span> <span class="source-line-no">159</span><span id="line-159"> * @param completions</span>
<span class="source-line-no">160</span><span id="line-160"> public void setDefaultCompletion(String id, Class... classes) {</span> <span class="source-line-no">160</span><span id="line-160"> * @return</span>
<span class="source-line-no">161</span><span id="line-161"> // get completion with specified id</span> <span class="source-line-no">161</span><span id="line-161"> */</span>
<span class="source-line-no">162</span><span id="line-162"> id = prepareCompletionId(id);</span> <span class="source-line-no">162</span><span id="line-162"> public CommandCompletionHandler registerStaticCompletion(String id, Collection&lt;String&gt; completions) {</span>
<span class="source-line-no">163</span><span id="line-163"> CommandCompletionHandler completion = completionMap.get(id);</span> <span class="source-line-no">163</span><span id="line-163"> return registerAsyncCompletion(id, x -&gt; completions);</span>
<span class="source-line-no">164</span><span id="line-164"></span> <span class="source-line-no">164</span><span id="line-164"> }</span>
<span class="source-line-no">165</span><span id="line-165"> if (completion == null) {</span> <span class="source-line-no">165</span><span id="line-165"></span>
<span class="source-line-no">166</span><span id="line-166"> // Throw something because no completion with specified id</span> <span class="source-line-no">166</span><span id="line-166"> /**</span>
<span class="source-line-no">167</span><span id="line-167"> throw new IllegalStateException("Completion not registered for " + id);</span> <span class="source-line-no">167</span><span id="line-167"> * Registers a completion handler such as @players to default apply to all command parameters of the specified types</span>
<span class="source-line-no">168</span><span id="line-168"> }</span> <span class="source-line-no">168</span><span id="line-168"> * &lt;p&gt;</span>
<span class="source-line-no">169</span><span id="line-169"></span> <span class="source-line-no">169</span><span id="line-169"> * This enables automatic completion support for parameters without manually defining it for custom objects</span>
<span class="source-line-no">170</span><span id="line-170"> for (Class clazz : classes) {</span> <span class="source-line-no">170</span><span id="line-170"> *</span>
<span class="source-line-no">171</span><span id="line-171"> defaultCompletions.put(clazz, id);</span> <span class="source-line-no">171</span><span id="line-171"> * @param id</span>
<span class="source-line-no">172</span><span id="line-172"> }</span> <span class="source-line-no">172</span><span id="line-172"> * @param classes</span>
<span class="source-line-no">173</span><span id="line-173"> }</span> <span class="source-line-no">173</span><span id="line-173"> */</span>
<span class="source-line-no">174</span><span id="line-174"></span> <span class="source-line-no">174</span><span id="line-174"> public void setDefaultCompletion(String id, Class... classes) {</span>
<span class="source-line-no">175</span><span id="line-175"> @NotNull</span> <span class="source-line-no">175</span><span id="line-175"> // get completion with specified id</span>
<span class="source-line-no">176</span><span id="line-176"> private static String prepareCompletionId(String id) {</span> <span class="source-line-no">176</span><span id="line-176"> id = prepareCompletionId(id);</span>
<span class="source-line-no">177</span><span id="line-177"> return (id.startsWith("@") ? "" : "@") + id.toLowerCase(Locale.ENGLISH);</span> <span class="source-line-no">177</span><span id="line-177"> CommandCompletionHandler completion = completionMap.get(id);</span>
<span class="source-line-no">178</span><span id="line-178"> }</span> <span class="source-line-no">178</span><span id="line-178"></span>
<span class="source-line-no">179</span><span id="line-179"></span> <span class="source-line-no">179</span><span id="line-179"> if (completion == null) {</span>
<span class="source-line-no">180</span><span id="line-180"> @NotNull</span> <span class="source-line-no">180</span><span id="line-180"> // Throw something because no completion with specified id</span>
<span class="source-line-no">181</span><span id="line-181"> List&lt;String&gt; of(RegisteredCommand cmd, CommandIssuer sender, String[] args, boolean isAsync) {</span> <span class="source-line-no">181</span><span id="line-181"> throw new IllegalStateException("Completion not registered for " + id);</span>
<span class="source-line-no">182</span><span id="line-182"> String[] completions = ACFPatterns.SPACE.split(cmd.complete);</span> <span class="source-line-no">182</span><span id="line-182"> }</span>
<span class="source-line-no">183</span><span id="line-183"> final int argIndex = args.length - 1;</span> <span class="source-line-no">183</span><span id="line-183"></span>
<span class="source-line-no">184</span><span id="line-184"></span> <span class="source-line-no">184</span><span id="line-184"> for (Class clazz : classes) {</span>
<span class="source-line-no">185</span><span id="line-185"> String input = args[argIndex];</span> <span class="source-line-no">185</span><span id="line-185"> defaultCompletions.put(clazz, id);</span>
<span class="source-line-no">186</span><span id="line-186"></span> <span class="source-line-no">186</span><span id="line-186"> }</span>
<span class="source-line-no">187</span><span id="line-187"> String completion = argIndex &lt; completions.length ? completions[argIndex] : null;</span> <span class="source-line-no">187</span><span id="line-187"> }</span>
<span class="source-line-no">188</span><span id="line-188"> if (completion == null || completion.isEmpty() || "*".equals(completion)) {</span> <span class="source-line-no">188</span><span id="line-188"></span>
<span class="source-line-no">189</span><span id="line-189"> completion = findDefaultCompletion(cmd, args);</span> <span class="source-line-no">189</span><span id="line-189"> @NotNull</span>
<span class="source-line-no">190</span><span id="line-190"> }</span> <span class="source-line-no">190</span><span id="line-190"> private static String prepareCompletionId(String id) {</span>
<span class="source-line-no">191</span><span id="line-191"></span> <span class="source-line-no">191</span><span id="line-191"> return (id.startsWith("@") ? "" : "@") + id.toLowerCase(Locale.ENGLISH);</span>
<span class="source-line-no">192</span><span id="line-192"> if (completion == null &amp;&amp; completions.length &gt; 0) {</span> <span class="source-line-no">192</span><span id="line-192"> }</span>
<span class="source-line-no">193</span><span id="line-193"> String last = completions[completions.length - 1];</span> <span class="source-line-no">193</span><span id="line-193"></span>
<span class="source-line-no">194</span><span id="line-194"> if (last.startsWith("repeat@")) {</span> <span class="source-line-no">194</span><span id="line-194"> @NotNull</span>
<span class="source-line-no">195</span><span id="line-195"> completion = last;</span> <span class="source-line-no">195</span><span id="line-195"> List&lt;String&gt; of(RegisteredCommand cmd, CommandIssuer sender, String[] args, boolean isAsync) {</span>
<span class="source-line-no">196</span><span id="line-196"> } else if (argIndex &gt;= completions.length &amp;&amp; cmd.parameters[cmd.parameters.length - 1].consumesRest) {</span> <span class="source-line-no">196</span><span id="line-196"> String[] completions = ACFPatterns.SPACE.split(cmd.complete);</span>
<span class="source-line-no">197</span><span id="line-197"> completion = last;</span> <span class="source-line-no">197</span><span id="line-197"> final int argIndex = args.length - 1;</span>
<span class="source-line-no">198</span><span id="line-198"> }</span> <span class="source-line-no">198</span><span id="line-198"></span>
<span class="source-line-no">199</span><span id="line-199"> }</span> <span class="source-line-no">199</span><span id="line-199"> String input = args[argIndex];</span>
<span class="source-line-no">200</span><span id="line-200"></span> <span class="source-line-no">200</span><span id="line-200"></span>
<span class="source-line-no">201</span><span id="line-201"> if (completion == null) {</span> <span class="source-line-no">201</span><span id="line-201"> String completion = argIndex &lt; completions.length ? completions[argIndex] : null;</span>
<span class="source-line-no">202</span><span id="line-202"> return Collections.singletonList(input);</span> <span class="source-line-no">202</span><span id="line-202"> if (completion == null || completion.isEmpty() || "*".equals(completion)) {</span>
<span class="source-line-no">203</span><span id="line-203"> }</span> <span class="source-line-no">203</span><span id="line-203"> completion = findDefaultCompletion(cmd, args);</span>
<span class="source-line-no">204</span><span id="line-204"></span> <span class="source-line-no">204</span><span id="line-204"> }</span>
<span class="source-line-no">205</span><span id="line-205"> return getCompletionValues(cmd, sender, completion, args, isAsync);</span> <span class="source-line-no">205</span><span id="line-205"></span>
<span class="source-line-no">206</span><span id="line-206"> }</span> <span class="source-line-no">206</span><span id="line-206"> if (completion == null &amp;&amp; completions.length &gt; 0) {</span>
<span class="source-line-no">207</span><span id="line-207"></span> <span class="source-line-no">207</span><span id="line-207"> String last = completions[completions.length - 1];</span>
<span class="source-line-no">208</span><span id="line-208"> String findDefaultCompletion(RegisteredCommand cmd, String[] args) {</span> <span class="source-line-no">208</span><span id="line-208"> if (last.startsWith("repeat@")) {</span>
<span class="source-line-no">209</span><span id="line-209"> int i = 0;</span> <span class="source-line-no">209</span><span id="line-209"> completion = last;</span>
<span class="source-line-no">210</span><span id="line-210"> for (CommandParameter param : cmd.parameters) {</span> <span class="source-line-no">210</span><span id="line-210"> } else if (argIndex &gt;= completions.length &amp;&amp; cmd.parameters[cmd.parameters.length - 1].consumesRest) {</span>
<span class="source-line-no">211</span><span id="line-211"> if (param.canConsumeInput() &amp;&amp; ++i == args.length) {</span> <span class="source-line-no">211</span><span id="line-211"> completion = last;</span>
<span class="source-line-no">212</span><span id="line-212"> Class type = param.getType();</span> <span class="source-line-no">212</span><span id="line-212"> }</span>
<span class="source-line-no">213</span><span id="line-213"> while (type != null) {</span> <span class="source-line-no">213</span><span id="line-213"> }</span>
<span class="source-line-no">214</span><span id="line-214"> String completion = this.defaultCompletions.get(type);</span> <span class="source-line-no">214</span><span id="line-214"></span>
<span class="source-line-no">215</span><span id="line-215"> if (completion != null) {</span> <span class="source-line-no">215</span><span id="line-215"> if (completion == null) {</span>
<span class="source-line-no">216</span><span id="line-216"> return completion;</span> <span class="source-line-no">216</span><span id="line-216"> return Collections.singletonList(input);</span>
<span class="source-line-no">217</span><span id="line-217"> }</span> <span class="source-line-no">217</span><span id="line-217"> }</span>
<span class="source-line-no">218</span><span id="line-218"> type = type.getSuperclass();</span> <span class="source-line-no">218</span><span id="line-218"></span>
<span class="source-line-no">219</span><span id="line-219"> }</span> <span class="source-line-no">219</span><span id="line-219"> return getCompletionValues(cmd, sender, completion, args, isAsync);</span>
<span class="source-line-no">220</span><span id="line-220"> if (param.getType().isEnum()) {</span> <span class="source-line-no">220</span><span id="line-220"> }</span>
<span class="source-line-no">221</span><span id="line-221"> CommandOperationContext ctx = CommandManager.getCurrentCommandOperationContext();</span> <span class="source-line-no">221</span><span id="line-221"></span>
<span class="source-line-no">222</span><span id="line-222"> //noinspection unchecked</span> <span class="source-line-no">222</span><span id="line-222"> String findDefaultCompletion(RegisteredCommand cmd, String[] args) {</span>
<span class="source-line-no">223</span><span id="line-223"> ctx.enumCompletionValues = ACFUtil.enumNames((Class&lt;? extends Enum&lt;?&gt;&gt;) param.getType());</span> <span class="source-line-no">223</span><span id="line-223"> int i = 0;</span>
<span class="source-line-no">224</span><span id="line-224"> return DEFAULT_ENUM_ID;</span> <span class="source-line-no">224</span><span id="line-224"> for (CommandParameter param : cmd.parameters) {</span>
<span class="source-line-no">225</span><span id="line-225"> }</span> <span class="source-line-no">225</span><span id="line-225"> if (param.canConsumeInput() &amp;&amp; ++i == args.length) {</span>
<span class="source-line-no">226</span><span id="line-226"> break;</span> <span class="source-line-no">226</span><span id="line-226"> Class type = param.getType();</span>
<span class="source-line-no">227</span><span id="line-227"> }</span> <span class="source-line-no">227</span><span id="line-227"> while (type != null) {</span>
<span class="source-line-no">228</span><span id="line-228"> }</span> <span class="source-line-no">228</span><span id="line-228"> String completion = this.defaultCompletions.get(type);</span>
<span class="source-line-no">229</span><span id="line-229"> return null;</span> <span class="source-line-no">229</span><span id="line-229"> if (completion != null) {</span>
<span class="source-line-no">230</span><span id="line-230"> }</span> <span class="source-line-no">230</span><span id="line-230"> return completion;</span>
<span class="source-line-no">231</span><span id="line-231"></span> <span class="source-line-no">231</span><span id="line-231"> }</span>
<span class="source-line-no">232</span><span id="line-232"> List&lt;String&gt; getCompletionValues(RegisteredCommand command, CommandIssuer sender, String completion, String[] args, boolean isAsync) {</span> <span class="source-line-no">232</span><span id="line-232"> type = type.getSuperclass();</span>
<span class="source-line-no">233</span><span id="line-233"> if (DEFAULT_ENUM_ID.equals(completion)) {</span> <span class="source-line-no">233</span><span id="line-233"> }</span>
<span class="source-line-no">234</span><span id="line-234"> CommandOperationContext&lt;?&gt; ctx = CommandManager.getCurrentCommandOperationContext();</span> <span class="source-line-no">234</span><span id="line-234"> if (param.getType().isEnum()) {</span>
<span class="source-line-no">235</span><span id="line-235"> return ctx.enumCompletionValues;</span> <span class="source-line-no">235</span><span id="line-235"> CommandOperationContext ctx = CommandManager.getCurrentCommandOperationContext();</span>
<span class="source-line-no">236</span><span id="line-236"> }</span> <span class="source-line-no">236</span><span id="line-236"> //noinspection unchecked</span>
<span class="source-line-no">237</span><span id="line-237"> boolean repeat = completion.startsWith("repeat@");</span> <span class="source-line-no">237</span><span id="line-237"> ctx.enumCompletionValues = ACFUtil.enumNames((Class&lt;? extends Enum&lt;?&gt;&gt;) param.getType());</span>
<span class="source-line-no">238</span><span id="line-238"> if (repeat) {</span> <span class="source-line-no">238</span><span id="line-238"> return DEFAULT_ENUM_ID;</span>
<span class="source-line-no">239</span><span id="line-239"> completion = completion.substring(6);</span> <span class="source-line-no">239</span><span id="line-239"> }</span>
<span class="source-line-no">240</span><span id="line-240"> }</span> <span class="source-line-no">240</span><span id="line-240"> break;</span>
<span class="source-line-no">241</span><span id="line-241"> completion = manager.getCommandReplacements().replace(completion);</span> <span class="source-line-no">241</span><span id="line-241"> }</span>
<span class="source-line-no">242</span><span id="line-242"></span> <span class="source-line-no">242</span><span id="line-242"> }</span>
<span class="source-line-no">243</span><span id="line-243"> List&lt;String&gt; allCompletions = new ArrayList&lt;&gt;();</span> <span class="source-line-no">243</span><span id="line-243"> return null;</span>
<span class="source-line-no">244</span><span id="line-244"> String input = args.length &gt; 0 ? args[args.length - 1] : "";</span> <span class="source-line-no">244</span><span id="line-244"> }</span>
<span class="source-line-no">245</span><span id="line-245"></span> <span class="source-line-no">245</span><span id="line-245"></span>
<span class="source-line-no">246</span><span id="line-246"> for (String value : ACFPatterns.PIPE.split(completion)) {</span> <span class="source-line-no">246</span><span id="line-246"> List&lt;String&gt; getCompletionValues(RegisteredCommand command, CommandIssuer sender, String completion, String[] args, boolean isAsync) {</span>
<span class="source-line-no">247</span><span id="line-247"> String[] complete = ACFPatterns.COLONEQUALS.split(value, 2);</span> <span class="source-line-no">247</span><span id="line-247"> if (DEFAULT_ENUM_ID.equals(completion)) {</span>
<span class="source-line-no">248</span><span id="line-248"> CommandCompletionHandler handler = this.completionMap.get(complete[0].toLowerCase(Locale.ENGLISH));</span> <span class="source-line-no">248</span><span id="line-248"> CommandOperationContext&lt;?&gt; ctx = CommandManager.getCurrentCommandOperationContext();</span>
<span class="source-line-no">249</span><span id="line-249"> if (handler != null) {</span> <span class="source-line-no">249</span><span id="line-249"> return ctx.enumCompletionValues;</span>
<span class="source-line-no">250</span><span id="line-250"> if (isAsync &amp;&amp; !(handler instanceof AsyncCommandCompletionHandler)) {</span> <span class="source-line-no">250</span><span id="line-250"> }</span>
<span class="source-line-no">251</span><span id="line-251"> ACFUtil.sneaky(new SyncCompletionRequired());</span> <span class="source-line-no">251</span><span id="line-251"> boolean repeat = completion.startsWith("repeat@");</span>
<span class="source-line-no">252</span><span id="line-252"> return null;</span> <span class="source-line-no">252</span><span id="line-252"> if (repeat) {</span>
<span class="source-line-no">253</span><span id="line-253"> }</span> <span class="source-line-no">253</span><span id="line-253"> completion = completion.substring(6);</span>
<span class="source-line-no">254</span><span id="line-254"> String config = complete.length == 1 ? null : complete[1];</span> <span class="source-line-no">254</span><span id="line-254"> }</span>
<span class="source-line-no">255</span><span id="line-255"> CommandCompletionContext context = manager.createCompletionContext(command, sender, input, config, args);</span> <span class="source-line-no">255</span><span id="line-255"> completion = manager.getCommandReplacements().replace(completion);</span>
<span class="source-line-no">256</span><span id="line-256"></span> <span class="source-line-no">256</span><span id="line-256"></span>
<span class="source-line-no">257</span><span id="line-257"> try {</span> <span class="source-line-no">257</span><span id="line-257"> List&lt;String&gt; allCompletions = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">258</span><span id="line-258"> //noinspection unchecked</span> <span class="source-line-no">258</span><span id="line-258"> String input = args.length &gt; 0 ? args[args.length - 1] : "";</span>
<span class="source-line-no">259</span><span id="line-259"> Collection&lt;String&gt; completions = handler.getCompletions(context);</span> <span class="source-line-no">259</span><span id="line-259"></span>
<span class="source-line-no">260</span><span id="line-260"></span> <span class="source-line-no">260</span><span id="line-260"> for (String value : ACFPatterns.PIPE.split(completion)) {</span>
<span class="source-line-no">261</span><span id="line-261"> //Handle completions with more than one word:</span> <span class="source-line-no">261</span><span id="line-261"> String[] complete = ACFPatterns.COLONEQUALS.split(value, 2);</span>
<span class="source-line-no">262</span><span id="line-262"> if (!repeat &amp;&amp; completions != null</span> <span class="source-line-no">262</span><span id="line-262"> CommandCompletionHandler handler = this.completionMap.get(complete[0].toLowerCase(Locale.ENGLISH));</span>
<span class="source-line-no">263</span><span id="line-263"> &amp;&amp; command.parameters[command.parameters.length - 1].consumesRest</span> <span class="source-line-no">263</span><span id="line-263"> if (handler != null) {</span>
<span class="source-line-no">264</span><span id="line-264"> &amp;&amp; args.length &gt; ACFPatterns.SPACE.split(command.complete).length) {</span> <span class="source-line-no">264</span><span id="line-264"> if (isAsync &amp;&amp; !(handler instanceof AsyncCommandCompletionHandler)) {</span>
<span class="source-line-no">265</span><span id="line-265"> String start = String.join(" ", args);</span> <span class="source-line-no">265</span><span id="line-265"> ACFUtil.sneaky(new SyncCompletionRequired());</span>
<span class="source-line-no">266</span><span id="line-266"> completions = completions.stream()</span> <span class="source-line-no">266</span><span id="line-266"> return null;</span>
<span class="source-line-no">267</span><span id="line-267"> .map(s -&gt; {</span> <span class="source-line-no">267</span><span id="line-267"> }</span>
<span class="source-line-no">268</span><span id="line-268"> if (s != null &amp;&amp; s.split(" ").length &gt;= args.length &amp;&amp; ApacheCommonsLangUtil.startsWithIgnoreCase(s, start)) {</span> <span class="source-line-no">268</span><span id="line-268"> String config = complete.length == 1 ? null : complete[1];</span>
<span class="source-line-no">269</span><span id="line-269"> String[] completionArgs = s.split(" ");</span> <span class="source-line-no">269</span><span id="line-269"> CommandCompletionContext context = manager.createCompletionContext(command, sender, input, config, args);</span>
<span class="source-line-no">270</span><span id="line-270"> return String.join(" ", Arrays.copyOfRange(completionArgs, args.length - 1, completionArgs.length));</span> <span class="source-line-no">270</span><span id="line-270"></span>
<span class="source-line-no">271</span><span id="line-271"> } else {</span> <span class="source-line-no">271</span><span id="line-271"> try {</span>
<span class="source-line-no">272</span><span id="line-272"> return s;</span> <span class="source-line-no">272</span><span id="line-272"> //noinspection unchecked</span>
<span class="source-line-no">273</span><span id="line-273"> }</span> <span class="source-line-no">273</span><span id="line-273"> Collection&lt;String&gt; completions = handler.getCompletions(context);</span>
<span class="source-line-no">274</span><span id="line-274"> }).collect(Collectors.toList());</span> <span class="source-line-no">274</span><span id="line-274"></span>
<span class="source-line-no">275</span><span id="line-275"> }</span> <span class="source-line-no">275</span><span id="line-275"> //Handle completions with more than one word:</span>
<span class="source-line-no">276</span><span id="line-276"></span> <span class="source-line-no">276</span><span id="line-276"> if (!repeat &amp;&amp; completions != null</span>
<span class="source-line-no">277</span><span id="line-277"> if (completions != null) {</span> <span class="source-line-no">277</span><span id="line-277"> &amp;&amp; command.parameters[command.parameters.length - 1].consumesRest</span>
<span class="source-line-no">278</span><span id="line-278"> allCompletions.addAll(completions);</span> <span class="source-line-no">278</span><span id="line-278"> &amp;&amp; args.length &gt; ACFPatterns.SPACE.split(command.complete).length) {</span>
<span class="source-line-no">279</span><span id="line-279"> continue;</span> <span class="source-line-no">279</span><span id="line-279"> String start = String.join(" ", args);</span>
<span class="source-line-no">280</span><span id="line-280"> }</span> <span class="source-line-no">280</span><span id="line-280"> completions = completions.stream()</span>
<span class="source-line-no">281</span><span id="line-281"> //noinspection ConstantIfStatement,ConstantConditions</span> <span class="source-line-no">281</span><span id="line-281"> .map(s -&gt; {</span>
<span class="source-line-no">282</span><span id="line-282"> if (false) { // Hack to fool compiler. since its sneakily thrown.</span> <span class="source-line-no">282</span><span id="line-282"> if (s != null &amp;&amp; s.split(" ").length &gt;= args.length &amp;&amp; ApacheCommonsLangUtil.startsWithIgnoreCase(s, start)) {</span>
<span class="source-line-no">283</span><span id="line-283"> throw new CommandCompletionTextLookupException();</span> <span class="source-line-no">283</span><span id="line-283"> String[] completionArgs = s.split(" ");</span>
<span class="source-line-no">284</span><span id="line-284"> }</span> <span class="source-line-no">284</span><span id="line-284"> return String.join(" ", Arrays.copyOfRange(completionArgs, args.length - 1, completionArgs.length));</span>
<span class="source-line-no">285</span><span id="line-285"> } catch (CommandCompletionTextLookupException ignored) {</span> <span class="source-line-no">285</span><span id="line-285"> } else {</span>
<span class="source-line-no">286</span><span id="line-286"> // This should only happen if some other feedback error occured.</span> <span class="source-line-no">286</span><span id="line-286"> return s;</span>
<span class="source-line-no">287</span><span id="line-287"> } catch (Exception e) {</span> <span class="source-line-no">287</span><span id="line-287"> }</span>
<span class="source-line-no">288</span><span id="line-288"> command.handleException(sender, Arrays.asList(args), e);</span> <span class="source-line-no">288</span><span id="line-288"> }).collect(Collectors.toList());</span>
<span class="source-line-no">289</span><span id="line-289"> }</span> <span class="source-line-no">289</span><span id="line-289"> }</span>
<span class="source-line-no">290</span><span id="line-290"> // Something went wrong in lookup, fall back to input</span> <span class="source-line-no">290</span><span id="line-290"></span>
<span class="source-line-no">291</span><span id="line-291"> return Collections.singletonList(input);</span> <span class="source-line-no">291</span><span id="line-291"> if (completions != null) {</span>
<span class="source-line-no">292</span><span id="line-292"> } else {</span> <span class="source-line-no">292</span><span id="line-292"> allCompletions.addAll(completions);</span>
<span class="source-line-no">293</span><span id="line-293"> // Plaintext value</span> <span class="source-line-no">293</span><span id="line-293"> continue;</span>
<span class="source-line-no">294</span><span id="line-294"> allCompletions.add(value);</span> <span class="source-line-no">294</span><span id="line-294"> }</span>
<span class="source-line-no">295</span><span id="line-295"> }</span> <span class="source-line-no">295</span><span id="line-295"> //noinspection ConstantIfStatement,ConstantConditions</span>
<span class="source-line-no">296</span><span id="line-296"> }</span> <span class="source-line-no">296</span><span id="line-296"> if (false) { // Hack to fool compiler. since its sneakily thrown.</span>
<span class="source-line-no">297</span><span id="line-297"> return allCompletions;</span> <span class="source-line-no">297</span><span id="line-297"> throw new CommandCompletionTextLookupException();</span>
<span class="source-line-no">298</span><span id="line-298"> }</span> <span class="source-line-no">298</span><span id="line-298"> }</span>
<span class="source-line-no">299</span><span id="line-299"></span> <span class="source-line-no">299</span><span id="line-299"> } catch (CommandCompletionTextLookupException ignored) {</span>
<span class="source-line-no">300</span><span id="line-300"> public interface CommandCompletionHandler&lt;C extends CommandCompletionContext&gt; {</span> <span class="source-line-no">300</span><span id="line-300"> // This should only happen if some other feedback error occured.</span>
<span class="source-line-no">301</span><span id="line-301"> Collection&lt;String&gt; getCompletions(C context) throws InvalidCommandArgument;</span> <span class="source-line-no">301</span><span id="line-301"> } catch (Exception e) {</span>
<span class="source-line-no">302</span><span id="line-302"> }</span> <span class="source-line-no">302</span><span id="line-302"> command.handleException(sender, Arrays.asList(args), e);</span>
<span class="source-line-no">303</span><span id="line-303"></span> <span class="source-line-no">303</span><span id="line-303"> }</span>
<span class="source-line-no">304</span><span id="line-304"> public interface AsyncCommandCompletionHandler&lt;C extends CommandCompletionContext&gt; extends CommandCompletionHandler&lt;C&gt; {</span> <span class="source-line-no">304</span><span id="line-304"> // Something went wrong in lookup, fall back to input</span>
<span class="source-line-no">305</span><span id="line-305"> }</span> <span class="source-line-no">305</span><span id="line-305"> return Collections.singletonList(input);</span>
<span class="source-line-no">306</span><span id="line-306"></span> <span class="source-line-no">306</span><span id="line-306"> } else {</span>
<span class="source-line-no">307</span><span id="line-307"> public static class SyncCompletionRequired extends RuntimeException {</span> <span class="source-line-no">307</span><span id="line-307"> // Plaintext value</span>
<span class="source-line-no">308</span><span id="line-308"> }</span> <span class="source-line-no">308</span><span id="line-308"> allCompletions.add(value);</span>
<span class="source-line-no">309</span><span id="line-309"></span> <span class="source-line-no">309</span><span id="line-309"> }</span>
<span class="source-line-no">310</span><span id="line-310">}</span> <span class="source-line-no">310</span><span id="line-310"> }</span>
<span class="source-line-no">311</span><span id="line-311"> return allCompletions;</span>
<span class="source-line-no">312</span><span id="line-312"> }</span>
<span class="source-line-no">313</span><span id="line-313"></span>
<span class="source-line-no">314</span><span id="line-314"> public interface CommandCompletionHandler&lt;C extends CommandCompletionContext&gt; {</span>
<span class="source-line-no">315</span><span id="line-315"> Collection&lt;String&gt; getCompletions(C context) throws InvalidCommandArgument;</span>
<span class="source-line-no">316</span><span id="line-316"> }</span>
<span class="source-line-no">317</span><span id="line-317"></span>
<span class="source-line-no">318</span><span id="line-318"> public interface AsyncCommandCompletionHandler&lt;C extends CommandCompletionContext&gt; extends CommandCompletionHandler&lt;C&gt; {</span>
<span class="source-line-no">319</span><span id="line-319"> }</span>
<span class="source-line-no">320</span><span id="line-320"></span>
<span class="source-line-no">321</span><span id="line-321"> public static class SyncCompletionRequired extends RuntimeException {</span>
<span class="source-line-no">322</span><span id="line-322"> }</span>
<span class="source-line-no">323</span><span id="line-323"></span>
<span class="source-line-no">324</span><span id="line-324">}</span>
@@ -96,231 +96,245 @@
<span class="source-line-no">083</span><span id="line-83"> }</span> <span class="source-line-no">083</span><span id="line-83"> }</span>
<span class="source-line-no">084</span><span id="line-84"></span> <span class="source-line-no">084</span><span id="line-84"></span>
<span class="source-line-no">085</span><span id="line-85"> /**</span> <span class="source-line-no">085</span><span id="line-85"> /**</span>
<span class="source-line-no">086</span><span id="line-86"> * Registr a completion handler to provide command completions based on the user input.</span> <span class="source-line-no">086</span><span id="line-86"> * Unregister a completion handler.</span>
<span class="source-line-no">087</span><span id="line-87"> * This handler is declared to be safe to be executed asynchronously.</span> <span class="source-line-no">087</span><span id="line-87"> * @param id</span>
<span class="source-line-no">088</span><span id="line-88"> * &lt;p&gt;</span> <span class="source-line-no">088</span><span id="line-88"> * @return</span>
<span class="source-line-no">089</span><span id="line-89"> * Not all platforms support this, so if the platform does not support asynchronous execution,</span> <span class="source-line-no">089</span><span id="line-89"> * @throws IllegalStateException If the completion couldn't be found</span>
<span class="source-line-no">090</span><span id="line-90"> * your handler will be executed on the main thread.</span> <span class="source-line-no">090</span><span id="line-90"> */</span>
<span class="source-line-no">091</span><span id="line-91"> * &lt;p&gt;</span> <span class="source-line-no">091</span><span id="line-91"> public CommandCompletionHandler unregisterCompletion(String id) {</span>
<span class="source-line-no">092</span><span id="line-92"> * Use this anytime your handler does not need to access state that is not considered thread safe.</span> <span class="source-line-no">092</span><span id="line-92"> if (!this.completionMap.containsKey(id)) {</span>
<span class="source-line-no">093</span><span id="line-93"> * &lt;p&gt;</span> <span class="source-line-no">093</span><span id="line-93"> throw new IllegalStateException("The supplied key " + id + " does not exist in any completions");</span>
<span class="source-line-no">094</span><span id="line-94"> * Use context.isAsync() to determine if you are async or not.</span> <span class="source-line-no">094</span><span id="line-94"> }</span>
<span class="source-line-no">095</span><span id="line-95"> *</span> <span class="source-line-no">095</span><span id="line-95"></span>
<span class="source-line-no">096</span><span id="line-96"> * @param id</span> <span class="source-line-no">096</span><span id="line-96"> return this.completionMap.remove(id);</span>
<span class="source-line-no">097</span><span id="line-97"> * @param handler</span> <span class="source-line-no">097</span><span id="line-97"> }</span>
<span class="source-line-no">098</span><span id="line-98"> * @return</span> <span class="source-line-no">098</span><span id="line-98"></span>
<span class="source-line-no">099</span><span id="line-99"> */</span> <span class="source-line-no">099</span><span id="line-99"> /**</span>
<span class="source-line-no">100</span><span id="line-100"> public CommandCompletionHandler registerAsyncCompletion(String id, AsyncCommandCompletionHandler&lt;C&gt; handler) {</span> <span class="source-line-no">100</span><span id="line-100"> * Registr a completion handler to provide command completions based on the user input.</span>
<span class="source-line-no">101</span><span id="line-101"> return this.completionMap.put(prepareCompletionId(id), handler);</span> <span class="source-line-no">101</span><span id="line-101"> * This handler is declared to be safe to be executed asynchronously.</span>
<span class="source-line-no">102</span><span id="line-102"> }</span> <span class="source-line-no">102</span><span id="line-102"> * &lt;p&gt;</span>
<span class="source-line-no">103</span><span id="line-103"></span> <span class="source-line-no">103</span><span id="line-103"> * Not all platforms support this, so if the platform does not support asynchronous execution,</span>
<span class="source-line-no">104</span><span id="line-104"> /**</span> <span class="source-line-no">104</span><span id="line-104"> * your handler will be executed on the main thread.</span>
<span class="source-line-no">105</span><span id="line-105"> * Register a static list of command completions that will never change.</span> <span class="source-line-no">105</span><span id="line-105"> * &lt;p&gt;</span>
<span class="source-line-no">106</span><span id="line-106"> * Like @CommandCompletion, values are | (PIPE) separated.</span> <span class="source-line-no">106</span><span id="line-106"> * Use this anytime your handler does not need to access state that is not considered thread safe.</span>
<span class="source-line-no">107</span><span id="line-107"> * &lt;p&gt;</span> <span class="source-line-no">107</span><span id="line-107"> * &lt;p&gt;</span>
<span class="source-line-no">108</span><span id="line-108"> * Example: foo|bar|baz</span> <span class="source-line-no">108</span><span id="line-108"> * Use context.isAsync() to determine if you are async or not.</span>
<span class="source-line-no">109</span><span id="line-109"> *</span> <span class="source-line-no">109</span><span id="line-109"> *</span>
<span class="source-line-no">110</span><span id="line-110"> * @param id</span> <span class="source-line-no">110</span><span id="line-110"> * @param id</span>
<span class="source-line-no">111</span><span id="line-111"> * @param list</span> <span class="source-line-no">111</span><span id="line-111"> * @param handler</span>
<span class="source-line-no">112</span><span id="line-112"> * @return</span> <span class="source-line-no">112</span><span id="line-112"> * @return</span>
<span class="source-line-no">113</span><span id="line-113"> */</span> <span class="source-line-no">113</span><span id="line-113"> */</span>
<span class="source-line-no">114</span><span id="line-114"> public CommandCompletionHandler registerStaticCompletion(String id, String list) {</span> <span class="source-line-no">114</span><span id="line-114"> public CommandCompletionHandler registerAsyncCompletion(String id, AsyncCommandCompletionHandler&lt;C&gt; handler) {</span>
<span class="source-line-no">115</span><span id="line-115"> return registerStaticCompletion(id, ACFPatterns.PIPE.split(list));</span> <span class="source-line-no">115</span><span id="line-115"> return this.completionMap.put(prepareCompletionId(id), handler);</span>
<span class="source-line-no">116</span><span id="line-116"> }</span> <span class="source-line-no">116</span><span id="line-116"> }</span>
<span class="source-line-no">117</span><span id="line-117"></span> <span class="source-line-no">117</span><span id="line-117"></span>
<span class="source-line-no">118</span><span id="line-118"> /**</span> <span class="source-line-no">118</span><span id="line-118"> /**</span>
<span class="source-line-no">119</span><span id="line-119"> * Register a static list of command completions that will never change</span> <span class="source-line-no">119</span><span id="line-119"> * Register a static list of command completions that will never change.</span>
<span class="source-line-no">120</span><span id="line-120"> *</span> <span class="source-line-no">120</span><span id="line-120"> * Like @CommandCompletion, values are | (PIPE) separated.</span>
<span class="source-line-no">121</span><span id="line-121"> * @param id</span> <span class="source-line-no">121</span><span id="line-121"> * &lt;p&gt;</span>
<span class="source-line-no">122</span><span id="line-122"> * @param completions</span> <span class="source-line-no">122</span><span id="line-122"> * Example: foo|bar|baz</span>
<span class="source-line-no">123</span><span id="line-123"> * @return</span> <span class="source-line-no">123</span><span id="line-123"> *</span>
<span class="source-line-no">124</span><span id="line-124"> */</span> <span class="source-line-no">124</span><span id="line-124"> * @param id</span>
<span class="source-line-no">125</span><span id="line-125"> public CommandCompletionHandler registerStaticCompletion(String id, String[] completions) {</span> <span class="source-line-no">125</span><span id="line-125"> * @param list</span>
<span class="source-line-no">126</span><span id="line-126"> return registerStaticCompletion(id, Arrays.asList(completions));</span> <span class="source-line-no">126</span><span id="line-126"> * @return</span>
<span class="source-line-no">127</span><span id="line-127"> }</span> <span class="source-line-no">127</span><span id="line-127"> */</span>
<span class="source-line-no">128</span><span id="line-128"></span> <span class="source-line-no">128</span><span id="line-128"> public CommandCompletionHandler registerStaticCompletion(String id, String list) {</span>
<span class="source-line-no">129</span><span id="line-129"> /**</span> <span class="source-line-no">129</span><span id="line-129"> return registerStaticCompletion(id, ACFPatterns.PIPE.split(list));</span>
<span class="source-line-no">130</span><span id="line-130"> * Register a static list of command completions that will never change. The list is obtained from the supplier</span> <span class="source-line-no">130</span><span id="line-130"> }</span>
<span class="source-line-no">131</span><span id="line-131"> * immediately as part of this method call.</span> <span class="source-line-no">131</span><span id="line-131"></span>
<span class="source-line-no">132</span><span id="line-132"> *</span> <span class="source-line-no">132</span><span id="line-132"> /**</span>
<span class="source-line-no">133</span><span id="line-133"> * @param id</span> <span class="source-line-no">133</span><span id="line-133"> * Register a static list of command completions that will never change</span>
<span class="source-line-no">134</span><span id="line-134"> * @param supplier</span> <span class="source-line-no">134</span><span id="line-134"> *</span>
<span class="source-line-no">135</span><span id="line-135"> * @return</span> <span class="source-line-no">135</span><span id="line-135"> * @param id</span>
<span class="source-line-no">136</span><span id="line-136"> */</span> <span class="source-line-no">136</span><span id="line-136"> * @param completions</span>
<span class="source-line-no">137</span><span id="line-137"> public CommandCompletionHandler registerStaticCompletion(String id, Supplier&lt;Collection&lt;String&gt;&gt; supplier) {</span> <span class="source-line-no">137</span><span id="line-137"> * @return</span>
<span class="source-line-no">138</span><span id="line-138"> return registerStaticCompletion(id, supplier.get());</span> <span class="source-line-no">138</span><span id="line-138"> */</span>
<span class="source-line-no">139</span><span id="line-139"> }</span> <span class="source-line-no">139</span><span id="line-139"> public CommandCompletionHandler registerStaticCompletion(String id, String[] completions) {</span>
<span class="source-line-no">140</span><span id="line-140"></span> <span class="source-line-no">140</span><span id="line-140"> return registerStaticCompletion(id, Arrays.asList(completions));</span>
<span class="source-line-no">141</span><span id="line-141"> /**</span> <span class="source-line-no">141</span><span id="line-141"> }</span>
<span class="source-line-no">142</span><span id="line-142"> * Register a static list of command completions that will never change</span> <span class="source-line-no">142</span><span id="line-142"></span>
<span class="source-line-no">143</span><span id="line-143"> *</span> <span class="source-line-no">143</span><span id="line-143"> /**</span>
<span class="source-line-no">144</span><span id="line-144"> * @param id</span> <span class="source-line-no">144</span><span id="line-144"> * Register a static list of command completions that will never change. The list is obtained from the supplier</span>
<span class="source-line-no">145</span><span id="line-145"> * @param completions</span> <span class="source-line-no">145</span><span id="line-145"> * immediately as part of this method call.</span>
<span class="source-line-no">146</span><span id="line-146"> * @return</span> <span class="source-line-no">146</span><span id="line-146"> *</span>
<span class="source-line-no">147</span><span id="line-147"> */</span> <span class="source-line-no">147</span><span id="line-147"> * @param id</span>
<span class="source-line-no">148</span><span id="line-148"> public CommandCompletionHandler registerStaticCompletion(String id, Collection&lt;String&gt; completions) {</span> <span class="source-line-no">148</span><span id="line-148"> * @param supplier</span>
<span class="source-line-no">149</span><span id="line-149"> return registerAsyncCompletion(id, x -&gt; completions);</span> <span class="source-line-no">149</span><span id="line-149"> * @return</span>
<span class="source-line-no">150</span><span id="line-150"> }</span> <span class="source-line-no">150</span><span id="line-150"> */</span>
<span class="source-line-no">151</span><span id="line-151"></span> <span class="source-line-no">151</span><span id="line-151"> public CommandCompletionHandler registerStaticCompletion(String id, Supplier&lt;Collection&lt;String&gt;&gt; supplier) {</span>
<span class="source-line-no">152</span><span id="line-152"> /**</span> <span class="source-line-no">152</span><span id="line-152"> return registerStaticCompletion(id, supplier.get());</span>
<span class="source-line-no">153</span><span id="line-153"> * Registers a completion handler such as @players to default apply to all command parameters of the specified types</span> <span class="source-line-no">153</span><span id="line-153"> }</span>
<span class="source-line-no">154</span><span id="line-154"> * &lt;p&gt;</span> <span class="source-line-no">154</span><span id="line-154"></span>
<span class="source-line-no">155</span><span id="line-155"> * This enables automatic completion support for parameters without manually defining it for custom objects</span> <span class="source-line-no">155</span><span id="line-155"> /**</span>
<span class="source-line-no">156</span><span id="line-156"> *</span> <span class="source-line-no">156</span><span id="line-156"> * Register a static list of command completions that will never change</span>
<span class="source-line-no">157</span><span id="line-157"> * @param id</span> <span class="source-line-no">157</span><span id="line-157"> *</span>
<span class="source-line-no">158</span><span id="line-158"> * @param classes</span> <span class="source-line-no">158</span><span id="line-158"> * @param id</span>
<span class="source-line-no">159</span><span id="line-159"> */</span> <span class="source-line-no">159</span><span id="line-159"> * @param completions</span>
<span class="source-line-no">160</span><span id="line-160"> public void setDefaultCompletion(String id, Class... classes) {</span> <span class="source-line-no">160</span><span id="line-160"> * @return</span>
<span class="source-line-no">161</span><span id="line-161"> // get completion with specified id</span> <span class="source-line-no">161</span><span id="line-161"> */</span>
<span class="source-line-no">162</span><span id="line-162"> id = prepareCompletionId(id);</span> <span class="source-line-no">162</span><span id="line-162"> public CommandCompletionHandler registerStaticCompletion(String id, Collection&lt;String&gt; completions) {</span>
<span class="source-line-no">163</span><span id="line-163"> CommandCompletionHandler completion = completionMap.get(id);</span> <span class="source-line-no">163</span><span id="line-163"> return registerAsyncCompletion(id, x -&gt; completions);</span>
<span class="source-line-no">164</span><span id="line-164"></span> <span class="source-line-no">164</span><span id="line-164"> }</span>
<span class="source-line-no">165</span><span id="line-165"> if (completion == null) {</span> <span class="source-line-no">165</span><span id="line-165"></span>
<span class="source-line-no">166</span><span id="line-166"> // Throw something because no completion with specified id</span> <span class="source-line-no">166</span><span id="line-166"> /**</span>
<span class="source-line-no">167</span><span id="line-167"> throw new IllegalStateException("Completion not registered for " + id);</span> <span class="source-line-no">167</span><span id="line-167"> * Registers a completion handler such as @players to default apply to all command parameters of the specified types</span>
<span class="source-line-no">168</span><span id="line-168"> }</span> <span class="source-line-no">168</span><span id="line-168"> * &lt;p&gt;</span>
<span class="source-line-no">169</span><span id="line-169"></span> <span class="source-line-no">169</span><span id="line-169"> * This enables automatic completion support for parameters without manually defining it for custom objects</span>
<span class="source-line-no">170</span><span id="line-170"> for (Class clazz : classes) {</span> <span class="source-line-no">170</span><span id="line-170"> *</span>
<span class="source-line-no">171</span><span id="line-171"> defaultCompletions.put(clazz, id);</span> <span class="source-line-no">171</span><span id="line-171"> * @param id</span>
<span class="source-line-no">172</span><span id="line-172"> }</span> <span class="source-line-no">172</span><span id="line-172"> * @param classes</span>
<span class="source-line-no">173</span><span id="line-173"> }</span> <span class="source-line-no">173</span><span id="line-173"> */</span>
<span class="source-line-no">174</span><span id="line-174"></span> <span class="source-line-no">174</span><span id="line-174"> public void setDefaultCompletion(String id, Class... classes) {</span>
<span class="source-line-no">175</span><span id="line-175"> @NotNull</span> <span class="source-line-no">175</span><span id="line-175"> // get completion with specified id</span>
<span class="source-line-no">176</span><span id="line-176"> private static String prepareCompletionId(String id) {</span> <span class="source-line-no">176</span><span id="line-176"> id = prepareCompletionId(id);</span>
<span class="source-line-no">177</span><span id="line-177"> return (id.startsWith("@") ? "" : "@") + id.toLowerCase(Locale.ENGLISH);</span> <span class="source-line-no">177</span><span id="line-177"> CommandCompletionHandler completion = completionMap.get(id);</span>
<span class="source-line-no">178</span><span id="line-178"> }</span> <span class="source-line-no">178</span><span id="line-178"></span>
<span class="source-line-no">179</span><span id="line-179"></span> <span class="source-line-no">179</span><span id="line-179"> if (completion == null) {</span>
<span class="source-line-no">180</span><span id="line-180"> @NotNull</span> <span class="source-line-no">180</span><span id="line-180"> // Throw something because no completion with specified id</span>
<span class="source-line-no">181</span><span id="line-181"> List&lt;String&gt; of(RegisteredCommand cmd, CommandIssuer sender, String[] args, boolean isAsync) {</span> <span class="source-line-no">181</span><span id="line-181"> throw new IllegalStateException("Completion not registered for " + id);</span>
<span class="source-line-no">182</span><span id="line-182"> String[] completions = ACFPatterns.SPACE.split(cmd.complete);</span> <span class="source-line-no">182</span><span id="line-182"> }</span>
<span class="source-line-no">183</span><span id="line-183"> final int argIndex = args.length - 1;</span> <span class="source-line-no">183</span><span id="line-183"></span>
<span class="source-line-no">184</span><span id="line-184"></span> <span class="source-line-no">184</span><span id="line-184"> for (Class clazz : classes) {</span>
<span class="source-line-no">185</span><span id="line-185"> String input = args[argIndex];</span> <span class="source-line-no">185</span><span id="line-185"> defaultCompletions.put(clazz, id);</span>
<span class="source-line-no">186</span><span id="line-186"></span> <span class="source-line-no">186</span><span id="line-186"> }</span>
<span class="source-line-no">187</span><span id="line-187"> String completion = argIndex &lt; completions.length ? completions[argIndex] : null;</span> <span class="source-line-no">187</span><span id="line-187"> }</span>
<span class="source-line-no">188</span><span id="line-188"> if (completion == null || completion.isEmpty() || "*".equals(completion)) {</span> <span class="source-line-no">188</span><span id="line-188"></span>
<span class="source-line-no">189</span><span id="line-189"> completion = findDefaultCompletion(cmd, args);</span> <span class="source-line-no">189</span><span id="line-189"> @NotNull</span>
<span class="source-line-no">190</span><span id="line-190"> }</span> <span class="source-line-no">190</span><span id="line-190"> private static String prepareCompletionId(String id) {</span>
<span class="source-line-no">191</span><span id="line-191"></span> <span class="source-line-no">191</span><span id="line-191"> return (id.startsWith("@") ? "" : "@") + id.toLowerCase(Locale.ENGLISH);</span>
<span class="source-line-no">192</span><span id="line-192"> if (completion == null &amp;&amp; completions.length &gt; 0) {</span> <span class="source-line-no">192</span><span id="line-192"> }</span>
<span class="source-line-no">193</span><span id="line-193"> String last = completions[completions.length - 1];</span> <span class="source-line-no">193</span><span id="line-193"></span>
<span class="source-line-no">194</span><span id="line-194"> if (last.startsWith("repeat@")) {</span> <span class="source-line-no">194</span><span id="line-194"> @NotNull</span>
<span class="source-line-no">195</span><span id="line-195"> completion = last;</span> <span class="source-line-no">195</span><span id="line-195"> List&lt;String&gt; of(RegisteredCommand cmd, CommandIssuer sender, String[] args, boolean isAsync) {</span>
<span class="source-line-no">196</span><span id="line-196"> } else if (argIndex &gt;= completions.length &amp;&amp; cmd.parameters[cmd.parameters.length - 1].consumesRest) {</span> <span class="source-line-no">196</span><span id="line-196"> String[] completions = ACFPatterns.SPACE.split(cmd.complete);</span>
<span class="source-line-no">197</span><span id="line-197"> completion = last;</span> <span class="source-line-no">197</span><span id="line-197"> final int argIndex = args.length - 1;</span>
<span class="source-line-no">198</span><span id="line-198"> }</span> <span class="source-line-no">198</span><span id="line-198"></span>
<span class="source-line-no">199</span><span id="line-199"> }</span> <span class="source-line-no">199</span><span id="line-199"> String input = args[argIndex];</span>
<span class="source-line-no">200</span><span id="line-200"></span> <span class="source-line-no">200</span><span id="line-200"></span>
<span class="source-line-no">201</span><span id="line-201"> if (completion == null) {</span> <span class="source-line-no">201</span><span id="line-201"> String completion = argIndex &lt; completions.length ? completions[argIndex] : null;</span>
<span class="source-line-no">202</span><span id="line-202"> return Collections.singletonList(input);</span> <span class="source-line-no">202</span><span id="line-202"> if (completion == null || completion.isEmpty() || "*".equals(completion)) {</span>
<span class="source-line-no">203</span><span id="line-203"> }</span> <span class="source-line-no">203</span><span id="line-203"> completion = findDefaultCompletion(cmd, args);</span>
<span class="source-line-no">204</span><span id="line-204"></span> <span class="source-line-no">204</span><span id="line-204"> }</span>
<span class="source-line-no">205</span><span id="line-205"> return getCompletionValues(cmd, sender, completion, args, isAsync);</span> <span class="source-line-no">205</span><span id="line-205"></span>
<span class="source-line-no">206</span><span id="line-206"> }</span> <span class="source-line-no">206</span><span id="line-206"> if (completion == null &amp;&amp; completions.length &gt; 0) {</span>
<span class="source-line-no">207</span><span id="line-207"></span> <span class="source-line-no">207</span><span id="line-207"> String last = completions[completions.length - 1];</span>
<span class="source-line-no">208</span><span id="line-208"> String findDefaultCompletion(RegisteredCommand cmd, String[] args) {</span> <span class="source-line-no">208</span><span id="line-208"> if (last.startsWith("repeat@")) {</span>
<span class="source-line-no">209</span><span id="line-209"> int i = 0;</span> <span class="source-line-no">209</span><span id="line-209"> completion = last;</span>
<span class="source-line-no">210</span><span id="line-210"> for (CommandParameter param : cmd.parameters) {</span> <span class="source-line-no">210</span><span id="line-210"> } else if (argIndex &gt;= completions.length &amp;&amp; cmd.parameters[cmd.parameters.length - 1].consumesRest) {</span>
<span class="source-line-no">211</span><span id="line-211"> if (param.canConsumeInput() &amp;&amp; ++i == args.length) {</span> <span class="source-line-no">211</span><span id="line-211"> completion = last;</span>
<span class="source-line-no">212</span><span id="line-212"> Class type = param.getType();</span> <span class="source-line-no">212</span><span id="line-212"> }</span>
<span class="source-line-no">213</span><span id="line-213"> while (type != null) {</span> <span class="source-line-no">213</span><span id="line-213"> }</span>
<span class="source-line-no">214</span><span id="line-214"> String completion = this.defaultCompletions.get(type);</span> <span class="source-line-no">214</span><span id="line-214"></span>
<span class="source-line-no">215</span><span id="line-215"> if (completion != null) {</span> <span class="source-line-no">215</span><span id="line-215"> if (completion == null) {</span>
<span class="source-line-no">216</span><span id="line-216"> return completion;</span> <span class="source-line-no">216</span><span id="line-216"> return Collections.singletonList(input);</span>
<span class="source-line-no">217</span><span id="line-217"> }</span> <span class="source-line-no">217</span><span id="line-217"> }</span>
<span class="source-line-no">218</span><span id="line-218"> type = type.getSuperclass();</span> <span class="source-line-no">218</span><span id="line-218"></span>
<span class="source-line-no">219</span><span id="line-219"> }</span> <span class="source-line-no">219</span><span id="line-219"> return getCompletionValues(cmd, sender, completion, args, isAsync);</span>
<span class="source-line-no">220</span><span id="line-220"> if (param.getType().isEnum()) {</span> <span class="source-line-no">220</span><span id="line-220"> }</span>
<span class="source-line-no">221</span><span id="line-221"> CommandOperationContext ctx = CommandManager.getCurrentCommandOperationContext();</span> <span class="source-line-no">221</span><span id="line-221"></span>
<span class="source-line-no">222</span><span id="line-222"> //noinspection unchecked</span> <span class="source-line-no">222</span><span id="line-222"> String findDefaultCompletion(RegisteredCommand cmd, String[] args) {</span>
<span class="source-line-no">223</span><span id="line-223"> ctx.enumCompletionValues = ACFUtil.enumNames((Class&lt;? extends Enum&lt;?&gt;&gt;) param.getType());</span> <span class="source-line-no">223</span><span id="line-223"> int i = 0;</span>
<span class="source-line-no">224</span><span id="line-224"> return DEFAULT_ENUM_ID;</span> <span class="source-line-no">224</span><span id="line-224"> for (CommandParameter param : cmd.parameters) {</span>
<span class="source-line-no">225</span><span id="line-225"> }</span> <span class="source-line-no">225</span><span id="line-225"> if (param.canConsumeInput() &amp;&amp; ++i == args.length) {</span>
<span class="source-line-no">226</span><span id="line-226"> break;</span> <span class="source-line-no">226</span><span id="line-226"> Class type = param.getType();</span>
<span class="source-line-no">227</span><span id="line-227"> }</span> <span class="source-line-no">227</span><span id="line-227"> while (type != null) {</span>
<span class="source-line-no">228</span><span id="line-228"> }</span> <span class="source-line-no">228</span><span id="line-228"> String completion = this.defaultCompletions.get(type);</span>
<span class="source-line-no">229</span><span id="line-229"> return null;</span> <span class="source-line-no">229</span><span id="line-229"> if (completion != null) {</span>
<span class="source-line-no">230</span><span id="line-230"> }</span> <span class="source-line-no">230</span><span id="line-230"> return completion;</span>
<span class="source-line-no">231</span><span id="line-231"></span> <span class="source-line-no">231</span><span id="line-231"> }</span>
<span class="source-line-no">232</span><span id="line-232"> List&lt;String&gt; getCompletionValues(RegisteredCommand command, CommandIssuer sender, String completion, String[] args, boolean isAsync) {</span> <span class="source-line-no">232</span><span id="line-232"> type = type.getSuperclass();</span>
<span class="source-line-no">233</span><span id="line-233"> if (DEFAULT_ENUM_ID.equals(completion)) {</span> <span class="source-line-no">233</span><span id="line-233"> }</span>
<span class="source-line-no">234</span><span id="line-234"> CommandOperationContext&lt;?&gt; ctx = CommandManager.getCurrentCommandOperationContext();</span> <span class="source-line-no">234</span><span id="line-234"> if (param.getType().isEnum()) {</span>
<span class="source-line-no">235</span><span id="line-235"> return ctx.enumCompletionValues;</span> <span class="source-line-no">235</span><span id="line-235"> CommandOperationContext ctx = CommandManager.getCurrentCommandOperationContext();</span>
<span class="source-line-no">236</span><span id="line-236"> }</span> <span class="source-line-no">236</span><span id="line-236"> //noinspection unchecked</span>
<span class="source-line-no">237</span><span id="line-237"> boolean repeat = completion.startsWith("repeat@");</span> <span class="source-line-no">237</span><span id="line-237"> ctx.enumCompletionValues = ACFUtil.enumNames((Class&lt;? extends Enum&lt;?&gt;&gt;) param.getType());</span>
<span class="source-line-no">238</span><span id="line-238"> if (repeat) {</span> <span class="source-line-no">238</span><span id="line-238"> return DEFAULT_ENUM_ID;</span>
<span class="source-line-no">239</span><span id="line-239"> completion = completion.substring(6);</span> <span class="source-line-no">239</span><span id="line-239"> }</span>
<span class="source-line-no">240</span><span id="line-240"> }</span> <span class="source-line-no">240</span><span id="line-240"> break;</span>
<span class="source-line-no">241</span><span id="line-241"> completion = manager.getCommandReplacements().replace(completion);</span> <span class="source-line-no">241</span><span id="line-241"> }</span>
<span class="source-line-no">242</span><span id="line-242"></span> <span class="source-line-no">242</span><span id="line-242"> }</span>
<span class="source-line-no">243</span><span id="line-243"> List&lt;String&gt; allCompletions = new ArrayList&lt;&gt;();</span> <span class="source-line-no">243</span><span id="line-243"> return null;</span>
<span class="source-line-no">244</span><span id="line-244"> String input = args.length &gt; 0 ? args[args.length - 1] : "";</span> <span class="source-line-no">244</span><span id="line-244"> }</span>
<span class="source-line-no">245</span><span id="line-245"></span> <span class="source-line-no">245</span><span id="line-245"></span>
<span class="source-line-no">246</span><span id="line-246"> for (String value : ACFPatterns.PIPE.split(completion)) {</span> <span class="source-line-no">246</span><span id="line-246"> List&lt;String&gt; getCompletionValues(RegisteredCommand command, CommandIssuer sender, String completion, String[] args, boolean isAsync) {</span>
<span class="source-line-no">247</span><span id="line-247"> String[] complete = ACFPatterns.COLONEQUALS.split(value, 2);</span> <span class="source-line-no">247</span><span id="line-247"> if (DEFAULT_ENUM_ID.equals(completion)) {</span>
<span class="source-line-no">248</span><span id="line-248"> CommandCompletionHandler handler = this.completionMap.get(complete[0].toLowerCase(Locale.ENGLISH));</span> <span class="source-line-no">248</span><span id="line-248"> CommandOperationContext&lt;?&gt; ctx = CommandManager.getCurrentCommandOperationContext();</span>
<span class="source-line-no">249</span><span id="line-249"> if (handler != null) {</span> <span class="source-line-no">249</span><span id="line-249"> return ctx.enumCompletionValues;</span>
<span class="source-line-no">250</span><span id="line-250"> if (isAsync &amp;&amp; !(handler instanceof AsyncCommandCompletionHandler)) {</span> <span class="source-line-no">250</span><span id="line-250"> }</span>
<span class="source-line-no">251</span><span id="line-251"> ACFUtil.sneaky(new SyncCompletionRequired());</span> <span class="source-line-no">251</span><span id="line-251"> boolean repeat = completion.startsWith("repeat@");</span>
<span class="source-line-no">252</span><span id="line-252"> return null;</span> <span class="source-line-no">252</span><span id="line-252"> if (repeat) {</span>
<span class="source-line-no">253</span><span id="line-253"> }</span> <span class="source-line-no">253</span><span id="line-253"> completion = completion.substring(6);</span>
<span class="source-line-no">254</span><span id="line-254"> String config = complete.length == 1 ? null : complete[1];</span> <span class="source-line-no">254</span><span id="line-254"> }</span>
<span class="source-line-no">255</span><span id="line-255"> CommandCompletionContext context = manager.createCompletionContext(command, sender, input, config, args);</span> <span class="source-line-no">255</span><span id="line-255"> completion = manager.getCommandReplacements().replace(completion);</span>
<span class="source-line-no">256</span><span id="line-256"></span> <span class="source-line-no">256</span><span id="line-256"></span>
<span class="source-line-no">257</span><span id="line-257"> try {</span> <span class="source-line-no">257</span><span id="line-257"> List&lt;String&gt; allCompletions = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">258</span><span id="line-258"> //noinspection unchecked</span> <span class="source-line-no">258</span><span id="line-258"> String input = args.length &gt; 0 ? args[args.length - 1] : "";</span>
<span class="source-line-no">259</span><span id="line-259"> Collection&lt;String&gt; completions = handler.getCompletions(context);</span> <span class="source-line-no">259</span><span id="line-259"></span>
<span class="source-line-no">260</span><span id="line-260"></span> <span class="source-line-no">260</span><span id="line-260"> for (String value : ACFPatterns.PIPE.split(completion)) {</span>
<span class="source-line-no">261</span><span id="line-261"> //Handle completions with more than one word:</span> <span class="source-line-no">261</span><span id="line-261"> String[] complete = ACFPatterns.COLONEQUALS.split(value, 2);</span>
<span class="source-line-no">262</span><span id="line-262"> if (!repeat &amp;&amp; completions != null</span> <span class="source-line-no">262</span><span id="line-262"> CommandCompletionHandler handler = this.completionMap.get(complete[0].toLowerCase(Locale.ENGLISH));</span>
<span class="source-line-no">263</span><span id="line-263"> &amp;&amp; command.parameters[command.parameters.length - 1].consumesRest</span> <span class="source-line-no">263</span><span id="line-263"> if (handler != null) {</span>
<span class="source-line-no">264</span><span id="line-264"> &amp;&amp; args.length &gt; ACFPatterns.SPACE.split(command.complete).length) {</span> <span class="source-line-no">264</span><span id="line-264"> if (isAsync &amp;&amp; !(handler instanceof AsyncCommandCompletionHandler)) {</span>
<span class="source-line-no">265</span><span id="line-265"> String start = String.join(" ", args);</span> <span class="source-line-no">265</span><span id="line-265"> ACFUtil.sneaky(new SyncCompletionRequired());</span>
<span class="source-line-no">266</span><span id="line-266"> completions = completions.stream()</span> <span class="source-line-no">266</span><span id="line-266"> return null;</span>
<span class="source-line-no">267</span><span id="line-267"> .map(s -&gt; {</span> <span class="source-line-no">267</span><span id="line-267"> }</span>
<span class="source-line-no">268</span><span id="line-268"> if (s != null &amp;&amp; s.split(" ").length &gt;= args.length &amp;&amp; ApacheCommonsLangUtil.startsWithIgnoreCase(s, start)) {</span> <span class="source-line-no">268</span><span id="line-268"> String config = complete.length == 1 ? null : complete[1];</span>
<span class="source-line-no">269</span><span id="line-269"> String[] completionArgs = s.split(" ");</span> <span class="source-line-no">269</span><span id="line-269"> CommandCompletionContext context = manager.createCompletionContext(command, sender, input, config, args);</span>
<span class="source-line-no">270</span><span id="line-270"> return String.join(" ", Arrays.copyOfRange(completionArgs, args.length - 1, completionArgs.length));</span> <span class="source-line-no">270</span><span id="line-270"></span>
<span class="source-line-no">271</span><span id="line-271"> } else {</span> <span class="source-line-no">271</span><span id="line-271"> try {</span>
<span class="source-line-no">272</span><span id="line-272"> return s;</span> <span class="source-line-no">272</span><span id="line-272"> //noinspection unchecked</span>
<span class="source-line-no">273</span><span id="line-273"> }</span> <span class="source-line-no">273</span><span id="line-273"> Collection&lt;String&gt; completions = handler.getCompletions(context);</span>
<span class="source-line-no">274</span><span id="line-274"> }).collect(Collectors.toList());</span> <span class="source-line-no">274</span><span id="line-274"></span>
<span class="source-line-no">275</span><span id="line-275"> }</span> <span class="source-line-no">275</span><span id="line-275"> //Handle completions with more than one word:</span>
<span class="source-line-no">276</span><span id="line-276"></span> <span class="source-line-no">276</span><span id="line-276"> if (!repeat &amp;&amp; completions != null</span>
<span class="source-line-no">277</span><span id="line-277"> if (completions != null) {</span> <span class="source-line-no">277</span><span id="line-277"> &amp;&amp; command.parameters[command.parameters.length - 1].consumesRest</span>
<span class="source-line-no">278</span><span id="line-278"> allCompletions.addAll(completions);</span> <span class="source-line-no">278</span><span id="line-278"> &amp;&amp; args.length &gt; ACFPatterns.SPACE.split(command.complete).length) {</span>
<span class="source-line-no">279</span><span id="line-279"> continue;</span> <span class="source-line-no">279</span><span id="line-279"> String start = String.join(" ", args);</span>
<span class="source-line-no">280</span><span id="line-280"> }</span> <span class="source-line-no">280</span><span id="line-280"> completions = completions.stream()</span>
<span class="source-line-no">281</span><span id="line-281"> //noinspection ConstantIfStatement,ConstantConditions</span> <span class="source-line-no">281</span><span id="line-281"> .map(s -&gt; {</span>
<span class="source-line-no">282</span><span id="line-282"> if (false) { // Hack to fool compiler. since its sneakily thrown.</span> <span class="source-line-no">282</span><span id="line-282"> if (s != null &amp;&amp; s.split(" ").length &gt;= args.length &amp;&amp; ApacheCommonsLangUtil.startsWithIgnoreCase(s, start)) {</span>
<span class="source-line-no">283</span><span id="line-283"> throw new CommandCompletionTextLookupException();</span> <span class="source-line-no">283</span><span id="line-283"> String[] completionArgs = s.split(" ");</span>
<span class="source-line-no">284</span><span id="line-284"> }</span> <span class="source-line-no">284</span><span id="line-284"> return String.join(" ", Arrays.copyOfRange(completionArgs, args.length - 1, completionArgs.length));</span>
<span class="source-line-no">285</span><span id="line-285"> } catch (CommandCompletionTextLookupException ignored) {</span> <span class="source-line-no">285</span><span id="line-285"> } else {</span>
<span class="source-line-no">286</span><span id="line-286"> // This should only happen if some other feedback error occured.</span> <span class="source-line-no">286</span><span id="line-286"> return s;</span>
<span class="source-line-no">287</span><span id="line-287"> } catch (Exception e) {</span> <span class="source-line-no">287</span><span id="line-287"> }</span>
<span class="source-line-no">288</span><span id="line-288"> command.handleException(sender, Arrays.asList(args), e);</span> <span class="source-line-no">288</span><span id="line-288"> }).collect(Collectors.toList());</span>
<span class="source-line-no">289</span><span id="line-289"> }</span> <span class="source-line-no">289</span><span id="line-289"> }</span>
<span class="source-line-no">290</span><span id="line-290"> // Something went wrong in lookup, fall back to input</span> <span class="source-line-no">290</span><span id="line-290"></span>
<span class="source-line-no">291</span><span id="line-291"> return Collections.singletonList(input);</span> <span class="source-line-no">291</span><span id="line-291"> if (completions != null) {</span>
<span class="source-line-no">292</span><span id="line-292"> } else {</span> <span class="source-line-no">292</span><span id="line-292"> allCompletions.addAll(completions);</span>
<span class="source-line-no">293</span><span id="line-293"> // Plaintext value</span> <span class="source-line-no">293</span><span id="line-293"> continue;</span>
<span class="source-line-no">294</span><span id="line-294"> allCompletions.add(value);</span> <span class="source-line-no">294</span><span id="line-294"> }</span>
<span class="source-line-no">295</span><span id="line-295"> }</span> <span class="source-line-no">295</span><span id="line-295"> //noinspection ConstantIfStatement,ConstantConditions</span>
<span class="source-line-no">296</span><span id="line-296"> }</span> <span class="source-line-no">296</span><span id="line-296"> if (false) { // Hack to fool compiler. since its sneakily thrown.</span>
<span class="source-line-no">297</span><span id="line-297"> return allCompletions;</span> <span class="source-line-no">297</span><span id="line-297"> throw new CommandCompletionTextLookupException();</span>
<span class="source-line-no">298</span><span id="line-298"> }</span> <span class="source-line-no">298</span><span id="line-298"> }</span>
<span class="source-line-no">299</span><span id="line-299"></span> <span class="source-line-no">299</span><span id="line-299"> } catch (CommandCompletionTextLookupException ignored) {</span>
<span class="source-line-no">300</span><span id="line-300"> public interface CommandCompletionHandler&lt;C extends CommandCompletionContext&gt; {</span> <span class="source-line-no">300</span><span id="line-300"> // This should only happen if some other feedback error occured.</span>
<span class="source-line-no">301</span><span id="line-301"> Collection&lt;String&gt; getCompletions(C context) throws InvalidCommandArgument;</span> <span class="source-line-no">301</span><span id="line-301"> } catch (Exception e) {</span>
<span class="source-line-no">302</span><span id="line-302"> }</span> <span class="source-line-no">302</span><span id="line-302"> command.handleException(sender, Arrays.asList(args), e);</span>
<span class="source-line-no">303</span><span id="line-303"></span> <span class="source-line-no">303</span><span id="line-303"> }</span>
<span class="source-line-no">304</span><span id="line-304"> public interface AsyncCommandCompletionHandler&lt;C extends CommandCompletionContext&gt; extends CommandCompletionHandler&lt;C&gt; {</span> <span class="source-line-no">304</span><span id="line-304"> // Something went wrong in lookup, fall back to input</span>
<span class="source-line-no">305</span><span id="line-305"> }</span> <span class="source-line-no">305</span><span id="line-305"> return Collections.singletonList(input);</span>
<span class="source-line-no">306</span><span id="line-306"></span> <span class="source-line-no">306</span><span id="line-306"> } else {</span>
<span class="source-line-no">307</span><span id="line-307"> public static class SyncCompletionRequired extends RuntimeException {</span> <span class="source-line-no">307</span><span id="line-307"> // Plaintext value</span>
<span class="source-line-no">308</span><span id="line-308"> }</span> <span class="source-line-no">308</span><span id="line-308"> allCompletions.add(value);</span>
<span class="source-line-no">309</span><span id="line-309"></span> <span class="source-line-no">309</span><span id="line-309"> }</span>
<span class="source-line-no">310</span><span id="line-310">}</span> <span class="source-line-no">310</span><span id="line-310"> }</span>
<span class="source-line-no">311</span><span id="line-311"> return allCompletions;</span>
<span class="source-line-no">312</span><span id="line-312"> }</span>
<span class="source-line-no">313</span><span id="line-313"></span>
<span class="source-line-no">314</span><span id="line-314"> public interface CommandCompletionHandler&lt;C extends CommandCompletionContext&gt; {</span>
<span class="source-line-no">315</span><span id="line-315"> Collection&lt;String&gt; getCompletions(C context) throws InvalidCommandArgument;</span>
<span class="source-line-no">316</span><span id="line-316"> }</span>
<span class="source-line-no">317</span><span id="line-317"></span>
<span class="source-line-no">318</span><span id="line-318"> public interface AsyncCommandCompletionHandler&lt;C extends CommandCompletionContext&gt; extends CommandCompletionHandler&lt;C&gt; {</span>
<span class="source-line-no">319</span><span id="line-319"> }</span>
<span class="source-line-no">320</span><span id="line-320"></span>
<span class="source-line-no">321</span><span id="line-321"> public static class SyncCompletionRequired extends RuntimeException {</span>
<span class="source-line-no">322</span><span id="line-322"> }</span>
<span class="source-line-no">323</span><span id="line-323"></span>
<span class="source-line-no">324</span><span id="line-324">}</span>
@@ -96,231 +96,245 @@
<span class="source-line-no">083</span><span id="line-83"> }</span> <span class="source-line-no">083</span><span id="line-83"> }</span>
<span class="source-line-no">084</span><span id="line-84"></span> <span class="source-line-no">084</span><span id="line-84"></span>
<span class="source-line-no">085</span><span id="line-85"> /**</span> <span class="source-line-no">085</span><span id="line-85"> /**</span>
<span class="source-line-no">086</span><span id="line-86"> * Registr a completion handler to provide command completions based on the user input.</span> <span class="source-line-no">086</span><span id="line-86"> * Unregister a completion handler.</span>
<span class="source-line-no">087</span><span id="line-87"> * This handler is declared to be safe to be executed asynchronously.</span> <span class="source-line-no">087</span><span id="line-87"> * @param id</span>
<span class="source-line-no">088</span><span id="line-88"> * &lt;p&gt;</span> <span class="source-line-no">088</span><span id="line-88"> * @return</span>
<span class="source-line-no">089</span><span id="line-89"> * Not all platforms support this, so if the platform does not support asynchronous execution,</span> <span class="source-line-no">089</span><span id="line-89"> * @throws IllegalStateException If the completion couldn't be found</span>
<span class="source-line-no">090</span><span id="line-90"> * your handler will be executed on the main thread.</span> <span class="source-line-no">090</span><span id="line-90"> */</span>
<span class="source-line-no">091</span><span id="line-91"> * &lt;p&gt;</span> <span class="source-line-no">091</span><span id="line-91"> public CommandCompletionHandler unregisterCompletion(String id) {</span>
<span class="source-line-no">092</span><span id="line-92"> * Use this anytime your handler does not need to access state that is not considered thread safe.</span> <span class="source-line-no">092</span><span id="line-92"> if (!this.completionMap.containsKey(id)) {</span>
<span class="source-line-no">093</span><span id="line-93"> * &lt;p&gt;</span> <span class="source-line-no">093</span><span id="line-93"> throw new IllegalStateException("The supplied key " + id + " does not exist in any completions");</span>
<span class="source-line-no">094</span><span id="line-94"> * Use context.isAsync() to determine if you are async or not.</span> <span class="source-line-no">094</span><span id="line-94"> }</span>
<span class="source-line-no">095</span><span id="line-95"> *</span> <span class="source-line-no">095</span><span id="line-95"></span>
<span class="source-line-no">096</span><span id="line-96"> * @param id</span> <span class="source-line-no">096</span><span id="line-96"> return this.completionMap.remove(id);</span>
<span class="source-line-no">097</span><span id="line-97"> * @param handler</span> <span class="source-line-no">097</span><span id="line-97"> }</span>
<span class="source-line-no">098</span><span id="line-98"> * @return</span> <span class="source-line-no">098</span><span id="line-98"></span>
<span class="source-line-no">099</span><span id="line-99"> */</span> <span class="source-line-no">099</span><span id="line-99"> /**</span>
<span class="source-line-no">100</span><span id="line-100"> public CommandCompletionHandler registerAsyncCompletion(String id, AsyncCommandCompletionHandler&lt;C&gt; handler) {</span> <span class="source-line-no">100</span><span id="line-100"> * Registr a completion handler to provide command completions based on the user input.</span>
<span class="source-line-no">101</span><span id="line-101"> return this.completionMap.put(prepareCompletionId(id), handler);</span> <span class="source-line-no">101</span><span id="line-101"> * This handler is declared to be safe to be executed asynchronously.</span>
<span class="source-line-no">102</span><span id="line-102"> }</span> <span class="source-line-no">102</span><span id="line-102"> * &lt;p&gt;</span>
<span class="source-line-no">103</span><span id="line-103"></span> <span class="source-line-no">103</span><span id="line-103"> * Not all platforms support this, so if the platform does not support asynchronous execution,</span>
<span class="source-line-no">104</span><span id="line-104"> /**</span> <span class="source-line-no">104</span><span id="line-104"> * your handler will be executed on the main thread.</span>
<span class="source-line-no">105</span><span id="line-105"> * Register a static list of command completions that will never change.</span> <span class="source-line-no">105</span><span id="line-105"> * &lt;p&gt;</span>
<span class="source-line-no">106</span><span id="line-106"> * Like @CommandCompletion, values are | (PIPE) separated.</span> <span class="source-line-no">106</span><span id="line-106"> * Use this anytime your handler does not need to access state that is not considered thread safe.</span>
<span class="source-line-no">107</span><span id="line-107"> * &lt;p&gt;</span> <span class="source-line-no">107</span><span id="line-107"> * &lt;p&gt;</span>
<span class="source-line-no">108</span><span id="line-108"> * Example: foo|bar|baz</span> <span class="source-line-no">108</span><span id="line-108"> * Use context.isAsync() to determine if you are async or not.</span>
<span class="source-line-no">109</span><span id="line-109"> *</span> <span class="source-line-no">109</span><span id="line-109"> *</span>
<span class="source-line-no">110</span><span id="line-110"> * @param id</span> <span class="source-line-no">110</span><span id="line-110"> * @param id</span>
<span class="source-line-no">111</span><span id="line-111"> * @param list</span> <span class="source-line-no">111</span><span id="line-111"> * @param handler</span>
<span class="source-line-no">112</span><span id="line-112"> * @return</span> <span class="source-line-no">112</span><span id="line-112"> * @return</span>
<span class="source-line-no">113</span><span id="line-113"> */</span> <span class="source-line-no">113</span><span id="line-113"> */</span>
<span class="source-line-no">114</span><span id="line-114"> public CommandCompletionHandler registerStaticCompletion(String id, String list) {</span> <span class="source-line-no">114</span><span id="line-114"> public CommandCompletionHandler registerAsyncCompletion(String id, AsyncCommandCompletionHandler&lt;C&gt; handler) {</span>
<span class="source-line-no">115</span><span id="line-115"> return registerStaticCompletion(id, ACFPatterns.PIPE.split(list));</span> <span class="source-line-no">115</span><span id="line-115"> return this.completionMap.put(prepareCompletionId(id), handler);</span>
<span class="source-line-no">116</span><span id="line-116"> }</span> <span class="source-line-no">116</span><span id="line-116"> }</span>
<span class="source-line-no">117</span><span id="line-117"></span> <span class="source-line-no">117</span><span id="line-117"></span>
<span class="source-line-no">118</span><span id="line-118"> /**</span> <span class="source-line-no">118</span><span id="line-118"> /**</span>
<span class="source-line-no">119</span><span id="line-119"> * Register a static list of command completions that will never change</span> <span class="source-line-no">119</span><span id="line-119"> * Register a static list of command completions that will never change.</span>
<span class="source-line-no">120</span><span id="line-120"> *</span> <span class="source-line-no">120</span><span id="line-120"> * Like @CommandCompletion, values are | (PIPE) separated.</span>
<span class="source-line-no">121</span><span id="line-121"> * @param id</span> <span class="source-line-no">121</span><span id="line-121"> * &lt;p&gt;</span>
<span class="source-line-no">122</span><span id="line-122"> * @param completions</span> <span class="source-line-no">122</span><span id="line-122"> * Example: foo|bar|baz</span>
<span class="source-line-no">123</span><span id="line-123"> * @return</span> <span class="source-line-no">123</span><span id="line-123"> *</span>
<span class="source-line-no">124</span><span id="line-124"> */</span> <span class="source-line-no">124</span><span id="line-124"> * @param id</span>
<span class="source-line-no">125</span><span id="line-125"> public CommandCompletionHandler registerStaticCompletion(String id, String[] completions) {</span> <span class="source-line-no">125</span><span id="line-125"> * @param list</span>
<span class="source-line-no">126</span><span id="line-126"> return registerStaticCompletion(id, Arrays.asList(completions));</span> <span class="source-line-no">126</span><span id="line-126"> * @return</span>
<span class="source-line-no">127</span><span id="line-127"> }</span> <span class="source-line-no">127</span><span id="line-127"> */</span>
<span class="source-line-no">128</span><span id="line-128"></span> <span class="source-line-no">128</span><span id="line-128"> public CommandCompletionHandler registerStaticCompletion(String id, String list) {</span>
<span class="source-line-no">129</span><span id="line-129"> /**</span> <span class="source-line-no">129</span><span id="line-129"> return registerStaticCompletion(id, ACFPatterns.PIPE.split(list));</span>
<span class="source-line-no">130</span><span id="line-130"> * Register a static list of command completions that will never change. The list is obtained from the supplier</span> <span class="source-line-no">130</span><span id="line-130"> }</span>
<span class="source-line-no">131</span><span id="line-131"> * immediately as part of this method call.</span> <span class="source-line-no">131</span><span id="line-131"></span>
<span class="source-line-no">132</span><span id="line-132"> *</span> <span class="source-line-no">132</span><span id="line-132"> /**</span>
<span class="source-line-no">133</span><span id="line-133"> * @param id</span> <span class="source-line-no">133</span><span id="line-133"> * Register a static list of command completions that will never change</span>
<span class="source-line-no">134</span><span id="line-134"> * @param supplier</span> <span class="source-line-no">134</span><span id="line-134"> *</span>
<span class="source-line-no">135</span><span id="line-135"> * @return</span> <span class="source-line-no">135</span><span id="line-135"> * @param id</span>
<span class="source-line-no">136</span><span id="line-136"> */</span> <span class="source-line-no">136</span><span id="line-136"> * @param completions</span>
<span class="source-line-no">137</span><span id="line-137"> public CommandCompletionHandler registerStaticCompletion(String id, Supplier&lt;Collection&lt;String&gt;&gt; supplier) {</span> <span class="source-line-no">137</span><span id="line-137"> * @return</span>
<span class="source-line-no">138</span><span id="line-138"> return registerStaticCompletion(id, supplier.get());</span> <span class="source-line-no">138</span><span id="line-138"> */</span>
<span class="source-line-no">139</span><span id="line-139"> }</span> <span class="source-line-no">139</span><span id="line-139"> public CommandCompletionHandler registerStaticCompletion(String id, String[] completions) {</span>
<span class="source-line-no">140</span><span id="line-140"></span> <span class="source-line-no">140</span><span id="line-140"> return registerStaticCompletion(id, Arrays.asList(completions));</span>
<span class="source-line-no">141</span><span id="line-141"> /**</span> <span class="source-line-no">141</span><span id="line-141"> }</span>
<span class="source-line-no">142</span><span id="line-142"> * Register a static list of command completions that will never change</span> <span class="source-line-no">142</span><span id="line-142"></span>
<span class="source-line-no">143</span><span id="line-143"> *</span> <span class="source-line-no">143</span><span id="line-143"> /**</span>
<span class="source-line-no">144</span><span id="line-144"> * @param id</span> <span class="source-line-no">144</span><span id="line-144"> * Register a static list of command completions that will never change. The list is obtained from the supplier</span>
<span class="source-line-no">145</span><span id="line-145"> * @param completions</span> <span class="source-line-no">145</span><span id="line-145"> * immediately as part of this method call.</span>
<span class="source-line-no">146</span><span id="line-146"> * @return</span> <span class="source-line-no">146</span><span id="line-146"> *</span>
<span class="source-line-no">147</span><span id="line-147"> */</span> <span class="source-line-no">147</span><span id="line-147"> * @param id</span>
<span class="source-line-no">148</span><span id="line-148"> public CommandCompletionHandler registerStaticCompletion(String id, Collection&lt;String&gt; completions) {</span> <span class="source-line-no">148</span><span id="line-148"> * @param supplier</span>
<span class="source-line-no">149</span><span id="line-149"> return registerAsyncCompletion(id, x -&gt; completions);</span> <span class="source-line-no">149</span><span id="line-149"> * @return</span>
<span class="source-line-no">150</span><span id="line-150"> }</span> <span class="source-line-no">150</span><span id="line-150"> */</span>
<span class="source-line-no">151</span><span id="line-151"></span> <span class="source-line-no">151</span><span id="line-151"> public CommandCompletionHandler registerStaticCompletion(String id, Supplier&lt;Collection&lt;String&gt;&gt; supplier) {</span>
<span class="source-line-no">152</span><span id="line-152"> /**</span> <span class="source-line-no">152</span><span id="line-152"> return registerStaticCompletion(id, supplier.get());</span>
<span class="source-line-no">153</span><span id="line-153"> * Registers a completion handler such as @players to default apply to all command parameters of the specified types</span> <span class="source-line-no">153</span><span id="line-153"> }</span>
<span class="source-line-no">154</span><span id="line-154"> * &lt;p&gt;</span> <span class="source-line-no">154</span><span id="line-154"></span>
<span class="source-line-no">155</span><span id="line-155"> * This enables automatic completion support for parameters without manually defining it for custom objects</span> <span class="source-line-no">155</span><span id="line-155"> /**</span>
<span class="source-line-no">156</span><span id="line-156"> *</span> <span class="source-line-no">156</span><span id="line-156"> * Register a static list of command completions that will never change</span>
<span class="source-line-no">157</span><span id="line-157"> * @param id</span> <span class="source-line-no">157</span><span id="line-157"> *</span>
<span class="source-line-no">158</span><span id="line-158"> * @param classes</span> <span class="source-line-no">158</span><span id="line-158"> * @param id</span>
<span class="source-line-no">159</span><span id="line-159"> */</span> <span class="source-line-no">159</span><span id="line-159"> * @param completions</span>
<span class="source-line-no">160</span><span id="line-160"> public void setDefaultCompletion(String id, Class... classes) {</span> <span class="source-line-no">160</span><span id="line-160"> * @return</span>
<span class="source-line-no">161</span><span id="line-161"> // get completion with specified id</span> <span class="source-line-no">161</span><span id="line-161"> */</span>
<span class="source-line-no">162</span><span id="line-162"> id = prepareCompletionId(id);</span> <span class="source-line-no">162</span><span id="line-162"> public CommandCompletionHandler registerStaticCompletion(String id, Collection&lt;String&gt; completions) {</span>
<span class="source-line-no">163</span><span id="line-163"> CommandCompletionHandler completion = completionMap.get(id);</span> <span class="source-line-no">163</span><span id="line-163"> return registerAsyncCompletion(id, x -&gt; completions);</span>
<span class="source-line-no">164</span><span id="line-164"></span> <span class="source-line-no">164</span><span id="line-164"> }</span>
<span class="source-line-no">165</span><span id="line-165"> if (completion == null) {</span> <span class="source-line-no">165</span><span id="line-165"></span>
<span class="source-line-no">166</span><span id="line-166"> // Throw something because no completion with specified id</span> <span class="source-line-no">166</span><span id="line-166"> /**</span>
<span class="source-line-no">167</span><span id="line-167"> throw new IllegalStateException("Completion not registered for " + id);</span> <span class="source-line-no">167</span><span id="line-167"> * Registers a completion handler such as @players to default apply to all command parameters of the specified types</span>
<span class="source-line-no">168</span><span id="line-168"> }</span> <span class="source-line-no">168</span><span id="line-168"> * &lt;p&gt;</span>
<span class="source-line-no">169</span><span id="line-169"></span> <span class="source-line-no">169</span><span id="line-169"> * This enables automatic completion support for parameters without manually defining it for custom objects</span>
<span class="source-line-no">170</span><span id="line-170"> for (Class clazz : classes) {</span> <span class="source-line-no">170</span><span id="line-170"> *</span>
<span class="source-line-no">171</span><span id="line-171"> defaultCompletions.put(clazz, id);</span> <span class="source-line-no">171</span><span id="line-171"> * @param id</span>
<span class="source-line-no">172</span><span id="line-172"> }</span> <span class="source-line-no">172</span><span id="line-172"> * @param classes</span>
<span class="source-line-no">173</span><span id="line-173"> }</span> <span class="source-line-no">173</span><span id="line-173"> */</span>
<span class="source-line-no">174</span><span id="line-174"></span> <span class="source-line-no">174</span><span id="line-174"> public void setDefaultCompletion(String id, Class... classes) {</span>
<span class="source-line-no">175</span><span id="line-175"> @NotNull</span> <span class="source-line-no">175</span><span id="line-175"> // get completion with specified id</span>
<span class="source-line-no">176</span><span id="line-176"> private static String prepareCompletionId(String id) {</span> <span class="source-line-no">176</span><span id="line-176"> id = prepareCompletionId(id);</span>
<span class="source-line-no">177</span><span id="line-177"> return (id.startsWith("@") ? "" : "@") + id.toLowerCase(Locale.ENGLISH);</span> <span class="source-line-no">177</span><span id="line-177"> CommandCompletionHandler completion = completionMap.get(id);</span>
<span class="source-line-no">178</span><span id="line-178"> }</span> <span class="source-line-no">178</span><span id="line-178"></span>
<span class="source-line-no">179</span><span id="line-179"></span> <span class="source-line-no">179</span><span id="line-179"> if (completion == null) {</span>
<span class="source-line-no">180</span><span id="line-180"> @NotNull</span> <span class="source-line-no">180</span><span id="line-180"> // Throw something because no completion with specified id</span>
<span class="source-line-no">181</span><span id="line-181"> List&lt;String&gt; of(RegisteredCommand cmd, CommandIssuer sender, String[] args, boolean isAsync) {</span> <span class="source-line-no">181</span><span id="line-181"> throw new IllegalStateException("Completion not registered for " + id);</span>
<span class="source-line-no">182</span><span id="line-182"> String[] completions = ACFPatterns.SPACE.split(cmd.complete);</span> <span class="source-line-no">182</span><span id="line-182"> }</span>
<span class="source-line-no">183</span><span id="line-183"> final int argIndex = args.length - 1;</span> <span class="source-line-no">183</span><span id="line-183"></span>
<span class="source-line-no">184</span><span id="line-184"></span> <span class="source-line-no">184</span><span id="line-184"> for (Class clazz : classes) {</span>
<span class="source-line-no">185</span><span id="line-185"> String input = args[argIndex];</span> <span class="source-line-no">185</span><span id="line-185"> defaultCompletions.put(clazz, id);</span>
<span class="source-line-no">186</span><span id="line-186"></span> <span class="source-line-no">186</span><span id="line-186"> }</span>
<span class="source-line-no">187</span><span id="line-187"> String completion = argIndex &lt; completions.length ? completions[argIndex] : null;</span> <span class="source-line-no">187</span><span id="line-187"> }</span>
<span class="source-line-no">188</span><span id="line-188"> if (completion == null || completion.isEmpty() || "*".equals(completion)) {</span> <span class="source-line-no">188</span><span id="line-188"></span>
<span class="source-line-no">189</span><span id="line-189"> completion = findDefaultCompletion(cmd, args);</span> <span class="source-line-no">189</span><span id="line-189"> @NotNull</span>
<span class="source-line-no">190</span><span id="line-190"> }</span> <span class="source-line-no">190</span><span id="line-190"> private static String prepareCompletionId(String id) {</span>
<span class="source-line-no">191</span><span id="line-191"></span> <span class="source-line-no">191</span><span id="line-191"> return (id.startsWith("@") ? "" : "@") + id.toLowerCase(Locale.ENGLISH);</span>
<span class="source-line-no">192</span><span id="line-192"> if (completion == null &amp;&amp; completions.length &gt; 0) {</span> <span class="source-line-no">192</span><span id="line-192"> }</span>
<span class="source-line-no">193</span><span id="line-193"> String last = completions[completions.length - 1];</span> <span class="source-line-no">193</span><span id="line-193"></span>
<span class="source-line-no">194</span><span id="line-194"> if (last.startsWith("repeat@")) {</span> <span class="source-line-no">194</span><span id="line-194"> @NotNull</span>
<span class="source-line-no">195</span><span id="line-195"> completion = last;</span> <span class="source-line-no">195</span><span id="line-195"> List&lt;String&gt; of(RegisteredCommand cmd, CommandIssuer sender, String[] args, boolean isAsync) {</span>
<span class="source-line-no">196</span><span id="line-196"> } else if (argIndex &gt;= completions.length &amp;&amp; cmd.parameters[cmd.parameters.length - 1].consumesRest) {</span> <span class="source-line-no">196</span><span id="line-196"> String[] completions = ACFPatterns.SPACE.split(cmd.complete);</span>
<span class="source-line-no">197</span><span id="line-197"> completion = last;</span> <span class="source-line-no">197</span><span id="line-197"> final int argIndex = args.length - 1;</span>
<span class="source-line-no">198</span><span id="line-198"> }</span> <span class="source-line-no">198</span><span id="line-198"></span>
<span class="source-line-no">199</span><span id="line-199"> }</span> <span class="source-line-no">199</span><span id="line-199"> String input = args[argIndex];</span>
<span class="source-line-no">200</span><span id="line-200"></span> <span class="source-line-no">200</span><span id="line-200"></span>
<span class="source-line-no">201</span><span id="line-201"> if (completion == null) {</span> <span class="source-line-no">201</span><span id="line-201"> String completion = argIndex &lt; completions.length ? completions[argIndex] : null;</span>
<span class="source-line-no">202</span><span id="line-202"> return Collections.singletonList(input);</span> <span class="source-line-no">202</span><span id="line-202"> if (completion == null || completion.isEmpty() || "*".equals(completion)) {</span>
<span class="source-line-no">203</span><span id="line-203"> }</span> <span class="source-line-no">203</span><span id="line-203"> completion = findDefaultCompletion(cmd, args);</span>
<span class="source-line-no">204</span><span id="line-204"></span> <span class="source-line-no">204</span><span id="line-204"> }</span>
<span class="source-line-no">205</span><span id="line-205"> return getCompletionValues(cmd, sender, completion, args, isAsync);</span> <span class="source-line-no">205</span><span id="line-205"></span>
<span class="source-line-no">206</span><span id="line-206"> }</span> <span class="source-line-no">206</span><span id="line-206"> if (completion == null &amp;&amp; completions.length &gt; 0) {</span>
<span class="source-line-no">207</span><span id="line-207"></span> <span class="source-line-no">207</span><span id="line-207"> String last = completions[completions.length - 1];</span>
<span class="source-line-no">208</span><span id="line-208"> String findDefaultCompletion(RegisteredCommand cmd, String[] args) {</span> <span class="source-line-no">208</span><span id="line-208"> if (last.startsWith("repeat@")) {</span>
<span class="source-line-no">209</span><span id="line-209"> int i = 0;</span> <span class="source-line-no">209</span><span id="line-209"> completion = last;</span>
<span class="source-line-no">210</span><span id="line-210"> for (CommandParameter param : cmd.parameters) {</span> <span class="source-line-no">210</span><span id="line-210"> } else if (argIndex &gt;= completions.length &amp;&amp; cmd.parameters[cmd.parameters.length - 1].consumesRest) {</span>
<span class="source-line-no">211</span><span id="line-211"> if (param.canConsumeInput() &amp;&amp; ++i == args.length) {</span> <span class="source-line-no">211</span><span id="line-211"> completion = last;</span>
<span class="source-line-no">212</span><span id="line-212"> Class type = param.getType();</span> <span class="source-line-no">212</span><span id="line-212"> }</span>
<span class="source-line-no">213</span><span id="line-213"> while (type != null) {</span> <span class="source-line-no">213</span><span id="line-213"> }</span>
<span class="source-line-no">214</span><span id="line-214"> String completion = this.defaultCompletions.get(type);</span> <span class="source-line-no">214</span><span id="line-214"></span>
<span class="source-line-no">215</span><span id="line-215"> if (completion != null) {</span> <span class="source-line-no">215</span><span id="line-215"> if (completion == null) {</span>
<span class="source-line-no">216</span><span id="line-216"> return completion;</span> <span class="source-line-no">216</span><span id="line-216"> return Collections.singletonList(input);</span>
<span class="source-line-no">217</span><span id="line-217"> }</span> <span class="source-line-no">217</span><span id="line-217"> }</span>
<span class="source-line-no">218</span><span id="line-218"> type = type.getSuperclass();</span> <span class="source-line-no">218</span><span id="line-218"></span>
<span class="source-line-no">219</span><span id="line-219"> }</span> <span class="source-line-no">219</span><span id="line-219"> return getCompletionValues(cmd, sender, completion, args, isAsync);</span>
<span class="source-line-no">220</span><span id="line-220"> if (param.getType().isEnum()) {</span> <span class="source-line-no">220</span><span id="line-220"> }</span>
<span class="source-line-no">221</span><span id="line-221"> CommandOperationContext ctx = CommandManager.getCurrentCommandOperationContext();</span> <span class="source-line-no">221</span><span id="line-221"></span>
<span class="source-line-no">222</span><span id="line-222"> //noinspection unchecked</span> <span class="source-line-no">222</span><span id="line-222"> String findDefaultCompletion(RegisteredCommand cmd, String[] args) {</span>
<span class="source-line-no">223</span><span id="line-223"> ctx.enumCompletionValues = ACFUtil.enumNames((Class&lt;? extends Enum&lt;?&gt;&gt;) param.getType());</span> <span class="source-line-no">223</span><span id="line-223"> int i = 0;</span>
<span class="source-line-no">224</span><span id="line-224"> return DEFAULT_ENUM_ID;</span> <span class="source-line-no">224</span><span id="line-224"> for (CommandParameter param : cmd.parameters) {</span>
<span class="source-line-no">225</span><span id="line-225"> }</span> <span class="source-line-no">225</span><span id="line-225"> if (param.canConsumeInput() &amp;&amp; ++i == args.length) {</span>
<span class="source-line-no">226</span><span id="line-226"> break;</span> <span class="source-line-no">226</span><span id="line-226"> Class type = param.getType();</span>
<span class="source-line-no">227</span><span id="line-227"> }</span> <span class="source-line-no">227</span><span id="line-227"> while (type != null) {</span>
<span class="source-line-no">228</span><span id="line-228"> }</span> <span class="source-line-no">228</span><span id="line-228"> String completion = this.defaultCompletions.get(type);</span>
<span class="source-line-no">229</span><span id="line-229"> return null;</span> <span class="source-line-no">229</span><span id="line-229"> if (completion != null) {</span>
<span class="source-line-no">230</span><span id="line-230"> }</span> <span class="source-line-no">230</span><span id="line-230"> return completion;</span>
<span class="source-line-no">231</span><span id="line-231"></span> <span class="source-line-no">231</span><span id="line-231"> }</span>
<span class="source-line-no">232</span><span id="line-232"> List&lt;String&gt; getCompletionValues(RegisteredCommand command, CommandIssuer sender, String completion, String[] args, boolean isAsync) {</span> <span class="source-line-no">232</span><span id="line-232"> type = type.getSuperclass();</span>
<span class="source-line-no">233</span><span id="line-233"> if (DEFAULT_ENUM_ID.equals(completion)) {</span> <span class="source-line-no">233</span><span id="line-233"> }</span>
<span class="source-line-no">234</span><span id="line-234"> CommandOperationContext&lt;?&gt; ctx = CommandManager.getCurrentCommandOperationContext();</span> <span class="source-line-no">234</span><span id="line-234"> if (param.getType().isEnum()) {</span>
<span class="source-line-no">235</span><span id="line-235"> return ctx.enumCompletionValues;</span> <span class="source-line-no">235</span><span id="line-235"> CommandOperationContext ctx = CommandManager.getCurrentCommandOperationContext();</span>
<span class="source-line-no">236</span><span id="line-236"> }</span> <span class="source-line-no">236</span><span id="line-236"> //noinspection unchecked</span>
<span class="source-line-no">237</span><span id="line-237"> boolean repeat = completion.startsWith("repeat@");</span> <span class="source-line-no">237</span><span id="line-237"> ctx.enumCompletionValues = ACFUtil.enumNames((Class&lt;? extends Enum&lt;?&gt;&gt;) param.getType());</span>
<span class="source-line-no">238</span><span id="line-238"> if (repeat) {</span> <span class="source-line-no">238</span><span id="line-238"> return DEFAULT_ENUM_ID;</span>
<span class="source-line-no">239</span><span id="line-239"> completion = completion.substring(6);</span> <span class="source-line-no">239</span><span id="line-239"> }</span>
<span class="source-line-no">240</span><span id="line-240"> }</span> <span class="source-line-no">240</span><span id="line-240"> break;</span>
<span class="source-line-no">241</span><span id="line-241"> completion = manager.getCommandReplacements().replace(completion);</span> <span class="source-line-no">241</span><span id="line-241"> }</span>
<span class="source-line-no">242</span><span id="line-242"></span> <span class="source-line-no">242</span><span id="line-242"> }</span>
<span class="source-line-no">243</span><span id="line-243"> List&lt;String&gt; allCompletions = new ArrayList&lt;&gt;();</span> <span class="source-line-no">243</span><span id="line-243"> return null;</span>
<span class="source-line-no">244</span><span id="line-244"> String input = args.length &gt; 0 ? args[args.length - 1] : "";</span> <span class="source-line-no">244</span><span id="line-244"> }</span>
<span class="source-line-no">245</span><span id="line-245"></span> <span class="source-line-no">245</span><span id="line-245"></span>
<span class="source-line-no">246</span><span id="line-246"> for (String value : ACFPatterns.PIPE.split(completion)) {</span> <span class="source-line-no">246</span><span id="line-246"> List&lt;String&gt; getCompletionValues(RegisteredCommand command, CommandIssuer sender, String completion, String[] args, boolean isAsync) {</span>
<span class="source-line-no">247</span><span id="line-247"> String[] complete = ACFPatterns.COLONEQUALS.split(value, 2);</span> <span class="source-line-no">247</span><span id="line-247"> if (DEFAULT_ENUM_ID.equals(completion)) {</span>
<span class="source-line-no">248</span><span id="line-248"> CommandCompletionHandler handler = this.completionMap.get(complete[0].toLowerCase(Locale.ENGLISH));</span> <span class="source-line-no">248</span><span id="line-248"> CommandOperationContext&lt;?&gt; ctx = CommandManager.getCurrentCommandOperationContext();</span>
<span class="source-line-no">249</span><span id="line-249"> if (handler != null) {</span> <span class="source-line-no">249</span><span id="line-249"> return ctx.enumCompletionValues;</span>
<span class="source-line-no">250</span><span id="line-250"> if (isAsync &amp;&amp; !(handler instanceof AsyncCommandCompletionHandler)) {</span> <span class="source-line-no">250</span><span id="line-250"> }</span>
<span class="source-line-no">251</span><span id="line-251"> ACFUtil.sneaky(new SyncCompletionRequired());</span> <span class="source-line-no">251</span><span id="line-251"> boolean repeat = completion.startsWith("repeat@");</span>
<span class="source-line-no">252</span><span id="line-252"> return null;</span> <span class="source-line-no">252</span><span id="line-252"> if (repeat) {</span>
<span class="source-line-no">253</span><span id="line-253"> }</span> <span class="source-line-no">253</span><span id="line-253"> completion = completion.substring(6);</span>
<span class="source-line-no">254</span><span id="line-254"> String config = complete.length == 1 ? null : complete[1];</span> <span class="source-line-no">254</span><span id="line-254"> }</span>
<span class="source-line-no">255</span><span id="line-255"> CommandCompletionContext context = manager.createCompletionContext(command, sender, input, config, args);</span> <span class="source-line-no">255</span><span id="line-255"> completion = manager.getCommandReplacements().replace(completion);</span>
<span class="source-line-no">256</span><span id="line-256"></span> <span class="source-line-no">256</span><span id="line-256"></span>
<span class="source-line-no">257</span><span id="line-257"> try {</span> <span class="source-line-no">257</span><span id="line-257"> List&lt;String&gt; allCompletions = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">258</span><span id="line-258"> //noinspection unchecked</span> <span class="source-line-no">258</span><span id="line-258"> String input = args.length &gt; 0 ? args[args.length - 1] : "";</span>
<span class="source-line-no">259</span><span id="line-259"> Collection&lt;String&gt; completions = handler.getCompletions(context);</span> <span class="source-line-no">259</span><span id="line-259"></span>
<span class="source-line-no">260</span><span id="line-260"></span> <span class="source-line-no">260</span><span id="line-260"> for (String value : ACFPatterns.PIPE.split(completion)) {</span>
<span class="source-line-no">261</span><span id="line-261"> //Handle completions with more than one word:</span> <span class="source-line-no">261</span><span id="line-261"> String[] complete = ACFPatterns.COLONEQUALS.split(value, 2);</span>
<span class="source-line-no">262</span><span id="line-262"> if (!repeat &amp;&amp; completions != null</span> <span class="source-line-no">262</span><span id="line-262"> CommandCompletionHandler handler = this.completionMap.get(complete[0].toLowerCase(Locale.ENGLISH));</span>
<span class="source-line-no">263</span><span id="line-263"> &amp;&amp; command.parameters[command.parameters.length - 1].consumesRest</span> <span class="source-line-no">263</span><span id="line-263"> if (handler != null) {</span>
<span class="source-line-no">264</span><span id="line-264"> &amp;&amp; args.length &gt; ACFPatterns.SPACE.split(command.complete).length) {</span> <span class="source-line-no">264</span><span id="line-264"> if (isAsync &amp;&amp; !(handler instanceof AsyncCommandCompletionHandler)) {</span>
<span class="source-line-no">265</span><span id="line-265"> String start = String.join(" ", args);</span> <span class="source-line-no">265</span><span id="line-265"> ACFUtil.sneaky(new SyncCompletionRequired());</span>
<span class="source-line-no">266</span><span id="line-266"> completions = completions.stream()</span> <span class="source-line-no">266</span><span id="line-266"> return null;</span>
<span class="source-line-no">267</span><span id="line-267"> .map(s -&gt; {</span> <span class="source-line-no">267</span><span id="line-267"> }</span>
<span class="source-line-no">268</span><span id="line-268"> if (s != null &amp;&amp; s.split(" ").length &gt;= args.length &amp;&amp; ApacheCommonsLangUtil.startsWithIgnoreCase(s, start)) {</span> <span class="source-line-no">268</span><span id="line-268"> String config = complete.length == 1 ? null : complete[1];</span>
<span class="source-line-no">269</span><span id="line-269"> String[] completionArgs = s.split(" ");</span> <span class="source-line-no">269</span><span id="line-269"> CommandCompletionContext context = manager.createCompletionContext(command, sender, input, config, args);</span>
<span class="source-line-no">270</span><span id="line-270"> return String.join(" ", Arrays.copyOfRange(completionArgs, args.length - 1, completionArgs.length));</span> <span class="source-line-no">270</span><span id="line-270"></span>
<span class="source-line-no">271</span><span id="line-271"> } else {</span> <span class="source-line-no">271</span><span id="line-271"> try {</span>
<span class="source-line-no">272</span><span id="line-272"> return s;</span> <span class="source-line-no">272</span><span id="line-272"> //noinspection unchecked</span>
<span class="source-line-no">273</span><span id="line-273"> }</span> <span class="source-line-no">273</span><span id="line-273"> Collection&lt;String&gt; completions = handler.getCompletions(context);</span>
<span class="source-line-no">274</span><span id="line-274"> }).collect(Collectors.toList());</span> <span class="source-line-no">274</span><span id="line-274"></span>
<span class="source-line-no">275</span><span id="line-275"> }</span> <span class="source-line-no">275</span><span id="line-275"> //Handle completions with more than one word:</span>
<span class="source-line-no">276</span><span id="line-276"></span> <span class="source-line-no">276</span><span id="line-276"> if (!repeat &amp;&amp; completions != null</span>
<span class="source-line-no">277</span><span id="line-277"> if (completions != null) {</span> <span class="source-line-no">277</span><span id="line-277"> &amp;&amp; command.parameters[command.parameters.length - 1].consumesRest</span>
<span class="source-line-no">278</span><span id="line-278"> allCompletions.addAll(completions);</span> <span class="source-line-no">278</span><span id="line-278"> &amp;&amp; args.length &gt; ACFPatterns.SPACE.split(command.complete).length) {</span>
<span class="source-line-no">279</span><span id="line-279"> continue;</span> <span class="source-line-no">279</span><span id="line-279"> String start = String.join(" ", args);</span>
<span class="source-line-no">280</span><span id="line-280"> }</span> <span class="source-line-no">280</span><span id="line-280"> completions = completions.stream()</span>
<span class="source-line-no">281</span><span id="line-281"> //noinspection ConstantIfStatement,ConstantConditions</span> <span class="source-line-no">281</span><span id="line-281"> .map(s -&gt; {</span>
<span class="source-line-no">282</span><span id="line-282"> if (false) { // Hack to fool compiler. since its sneakily thrown.</span> <span class="source-line-no">282</span><span id="line-282"> if (s != null &amp;&amp; s.split(" ").length &gt;= args.length &amp;&amp; ApacheCommonsLangUtil.startsWithIgnoreCase(s, start)) {</span>
<span class="source-line-no">283</span><span id="line-283"> throw new CommandCompletionTextLookupException();</span> <span class="source-line-no">283</span><span id="line-283"> String[] completionArgs = s.split(" ");</span>
<span class="source-line-no">284</span><span id="line-284"> }</span> <span class="source-line-no">284</span><span id="line-284"> return String.join(" ", Arrays.copyOfRange(completionArgs, args.length - 1, completionArgs.length));</span>
<span class="source-line-no">285</span><span id="line-285"> } catch (CommandCompletionTextLookupException ignored) {</span> <span class="source-line-no">285</span><span id="line-285"> } else {</span>
<span class="source-line-no">286</span><span id="line-286"> // This should only happen if some other feedback error occured.</span> <span class="source-line-no">286</span><span id="line-286"> return s;</span>
<span class="source-line-no">287</span><span id="line-287"> } catch (Exception e) {</span> <span class="source-line-no">287</span><span id="line-287"> }</span>
<span class="source-line-no">288</span><span id="line-288"> command.handleException(sender, Arrays.asList(args), e);</span> <span class="source-line-no">288</span><span id="line-288"> }).collect(Collectors.toList());</span>
<span class="source-line-no">289</span><span id="line-289"> }</span> <span class="source-line-no">289</span><span id="line-289"> }</span>
<span class="source-line-no">290</span><span id="line-290"> // Something went wrong in lookup, fall back to input</span> <span class="source-line-no">290</span><span id="line-290"></span>
<span class="source-line-no">291</span><span id="line-291"> return Collections.singletonList(input);</span> <span class="source-line-no">291</span><span id="line-291"> if (completions != null) {</span>
<span class="source-line-no">292</span><span id="line-292"> } else {</span> <span class="source-line-no">292</span><span id="line-292"> allCompletions.addAll(completions);</span>
<span class="source-line-no">293</span><span id="line-293"> // Plaintext value</span> <span class="source-line-no">293</span><span id="line-293"> continue;</span>
<span class="source-line-no">294</span><span id="line-294"> allCompletions.add(value);</span> <span class="source-line-no">294</span><span id="line-294"> }</span>
<span class="source-line-no">295</span><span id="line-295"> }</span> <span class="source-line-no">295</span><span id="line-295"> //noinspection ConstantIfStatement,ConstantConditions</span>
<span class="source-line-no">296</span><span id="line-296"> }</span> <span class="source-line-no">296</span><span id="line-296"> if (false) { // Hack to fool compiler. since its sneakily thrown.</span>
<span class="source-line-no">297</span><span id="line-297"> return allCompletions;</span> <span class="source-line-no">297</span><span id="line-297"> throw new CommandCompletionTextLookupException();</span>
<span class="source-line-no">298</span><span id="line-298"> }</span> <span class="source-line-no">298</span><span id="line-298"> }</span>
<span class="source-line-no">299</span><span id="line-299"></span> <span class="source-line-no">299</span><span id="line-299"> } catch (CommandCompletionTextLookupException ignored) {</span>
<span class="source-line-no">300</span><span id="line-300"> public interface CommandCompletionHandler&lt;C extends CommandCompletionContext&gt; {</span> <span class="source-line-no">300</span><span id="line-300"> // This should only happen if some other feedback error occured.</span>
<span class="source-line-no">301</span><span id="line-301"> Collection&lt;String&gt; getCompletions(C context) throws InvalidCommandArgument;</span> <span class="source-line-no">301</span><span id="line-301"> } catch (Exception e) {</span>
<span class="source-line-no">302</span><span id="line-302"> }</span> <span class="source-line-no">302</span><span id="line-302"> command.handleException(sender, Arrays.asList(args), e);</span>
<span class="source-line-no">303</span><span id="line-303"></span> <span class="source-line-no">303</span><span id="line-303"> }</span>
<span class="source-line-no">304</span><span id="line-304"> public interface AsyncCommandCompletionHandler&lt;C extends CommandCompletionContext&gt; extends CommandCompletionHandler&lt;C&gt; {</span> <span class="source-line-no">304</span><span id="line-304"> // Something went wrong in lookup, fall back to input</span>
<span class="source-line-no">305</span><span id="line-305"> }</span> <span class="source-line-no">305</span><span id="line-305"> return Collections.singletonList(input);</span>
<span class="source-line-no">306</span><span id="line-306"></span> <span class="source-line-no">306</span><span id="line-306"> } else {</span>
<span class="source-line-no">307</span><span id="line-307"> public static class SyncCompletionRequired extends RuntimeException {</span> <span class="source-line-no">307</span><span id="line-307"> // Plaintext value</span>
<span class="source-line-no">308</span><span id="line-308"> }</span> <span class="source-line-no">308</span><span id="line-308"> allCompletions.add(value);</span>
<span class="source-line-no">309</span><span id="line-309"></span> <span class="source-line-no">309</span><span id="line-309"> }</span>
<span class="source-line-no">310</span><span id="line-310">}</span> <span class="source-line-no">310</span><span id="line-310"> }</span>
<span class="source-line-no">311</span><span id="line-311"> return allCompletions;</span>
<span class="source-line-no">312</span><span id="line-312"> }</span>
<span class="source-line-no">313</span><span id="line-313"></span>
<span class="source-line-no">314</span><span id="line-314"> public interface CommandCompletionHandler&lt;C extends CommandCompletionContext&gt; {</span>
<span class="source-line-no">315</span><span id="line-315"> Collection&lt;String&gt; getCompletions(C context) throws InvalidCommandArgument;</span>
<span class="source-line-no">316</span><span id="line-316"> }</span>
<span class="source-line-no">317</span><span id="line-317"></span>
<span class="source-line-no">318</span><span id="line-318"> public interface AsyncCommandCompletionHandler&lt;C extends CommandCompletionContext&gt; extends CommandCompletionHandler&lt;C&gt; {</span>
<span class="source-line-no">319</span><span id="line-319"> }</span>
<span class="source-line-no">320</span><span id="line-320"></span>
<span class="source-line-no">321</span><span id="line-321"> public static class SyncCompletionRequired extends RuntimeException {</span>
<span class="source-line-no">322</span><span id="line-322"> }</span>
<span class="source-line-no">323</span><span id="line-323"></span>
<span class="source-line-no">324</span><span id="line-324">}</span>
@@ -96,231 +96,245 @@
<span class="source-line-no">083</span><span id="line-83"> }</span> <span class="source-line-no">083</span><span id="line-83"> }</span>
<span class="source-line-no">084</span><span id="line-84"></span> <span class="source-line-no">084</span><span id="line-84"></span>
<span class="source-line-no">085</span><span id="line-85"> /**</span> <span class="source-line-no">085</span><span id="line-85"> /**</span>
<span class="source-line-no">086</span><span id="line-86"> * Registr a completion handler to provide command completions based on the user input.</span> <span class="source-line-no">086</span><span id="line-86"> * Unregister a completion handler.</span>
<span class="source-line-no">087</span><span id="line-87"> * This handler is declared to be safe to be executed asynchronously.</span> <span class="source-line-no">087</span><span id="line-87"> * @param id</span>
<span class="source-line-no">088</span><span id="line-88"> * &lt;p&gt;</span> <span class="source-line-no">088</span><span id="line-88"> * @return</span>
<span class="source-line-no">089</span><span id="line-89"> * Not all platforms support this, so if the platform does not support asynchronous execution,</span> <span class="source-line-no">089</span><span id="line-89"> * @throws IllegalStateException If the completion couldn't be found</span>
<span class="source-line-no">090</span><span id="line-90"> * your handler will be executed on the main thread.</span> <span class="source-line-no">090</span><span id="line-90"> */</span>
<span class="source-line-no">091</span><span id="line-91"> * &lt;p&gt;</span> <span class="source-line-no">091</span><span id="line-91"> public CommandCompletionHandler unregisterCompletion(String id) {</span>
<span class="source-line-no">092</span><span id="line-92"> * Use this anytime your handler does not need to access state that is not considered thread safe.</span> <span class="source-line-no">092</span><span id="line-92"> if (!this.completionMap.containsKey(id)) {</span>
<span class="source-line-no">093</span><span id="line-93"> * &lt;p&gt;</span> <span class="source-line-no">093</span><span id="line-93"> throw new IllegalStateException("The supplied key " + id + " does not exist in any completions");</span>
<span class="source-line-no">094</span><span id="line-94"> * Use context.isAsync() to determine if you are async or not.</span> <span class="source-line-no">094</span><span id="line-94"> }</span>
<span class="source-line-no">095</span><span id="line-95"> *</span> <span class="source-line-no">095</span><span id="line-95"></span>
<span class="source-line-no">096</span><span id="line-96"> * @param id</span> <span class="source-line-no">096</span><span id="line-96"> return this.completionMap.remove(id);</span>
<span class="source-line-no">097</span><span id="line-97"> * @param handler</span> <span class="source-line-no">097</span><span id="line-97"> }</span>
<span class="source-line-no">098</span><span id="line-98"> * @return</span> <span class="source-line-no">098</span><span id="line-98"></span>
<span class="source-line-no">099</span><span id="line-99"> */</span> <span class="source-line-no">099</span><span id="line-99"> /**</span>
<span class="source-line-no">100</span><span id="line-100"> public CommandCompletionHandler registerAsyncCompletion(String id, AsyncCommandCompletionHandler&lt;C&gt; handler) {</span> <span class="source-line-no">100</span><span id="line-100"> * Registr a completion handler to provide command completions based on the user input.</span>
<span class="source-line-no">101</span><span id="line-101"> return this.completionMap.put(prepareCompletionId(id), handler);</span> <span class="source-line-no">101</span><span id="line-101"> * This handler is declared to be safe to be executed asynchronously.</span>
<span class="source-line-no">102</span><span id="line-102"> }</span> <span class="source-line-no">102</span><span id="line-102"> * &lt;p&gt;</span>
<span class="source-line-no">103</span><span id="line-103"></span> <span class="source-line-no">103</span><span id="line-103"> * Not all platforms support this, so if the platform does not support asynchronous execution,</span>
<span class="source-line-no">104</span><span id="line-104"> /**</span> <span class="source-line-no">104</span><span id="line-104"> * your handler will be executed on the main thread.</span>
<span class="source-line-no">105</span><span id="line-105"> * Register a static list of command completions that will never change.</span> <span class="source-line-no">105</span><span id="line-105"> * &lt;p&gt;</span>
<span class="source-line-no">106</span><span id="line-106"> * Like @CommandCompletion, values are | (PIPE) separated.</span> <span class="source-line-no">106</span><span id="line-106"> * Use this anytime your handler does not need to access state that is not considered thread safe.</span>
<span class="source-line-no">107</span><span id="line-107"> * &lt;p&gt;</span> <span class="source-line-no">107</span><span id="line-107"> * &lt;p&gt;</span>
<span class="source-line-no">108</span><span id="line-108"> * Example: foo|bar|baz</span> <span class="source-line-no">108</span><span id="line-108"> * Use context.isAsync() to determine if you are async or not.</span>
<span class="source-line-no">109</span><span id="line-109"> *</span> <span class="source-line-no">109</span><span id="line-109"> *</span>
<span class="source-line-no">110</span><span id="line-110"> * @param id</span> <span class="source-line-no">110</span><span id="line-110"> * @param id</span>
<span class="source-line-no">111</span><span id="line-111"> * @param list</span> <span class="source-line-no">111</span><span id="line-111"> * @param handler</span>
<span class="source-line-no">112</span><span id="line-112"> * @return</span> <span class="source-line-no">112</span><span id="line-112"> * @return</span>
<span class="source-line-no">113</span><span id="line-113"> */</span> <span class="source-line-no">113</span><span id="line-113"> */</span>
<span class="source-line-no">114</span><span id="line-114"> public CommandCompletionHandler registerStaticCompletion(String id, String list) {</span> <span class="source-line-no">114</span><span id="line-114"> public CommandCompletionHandler registerAsyncCompletion(String id, AsyncCommandCompletionHandler&lt;C&gt; handler) {</span>
<span class="source-line-no">115</span><span id="line-115"> return registerStaticCompletion(id, ACFPatterns.PIPE.split(list));</span> <span class="source-line-no">115</span><span id="line-115"> return this.completionMap.put(prepareCompletionId(id), handler);</span>
<span class="source-line-no">116</span><span id="line-116"> }</span> <span class="source-line-no">116</span><span id="line-116"> }</span>
<span class="source-line-no">117</span><span id="line-117"></span> <span class="source-line-no">117</span><span id="line-117"></span>
<span class="source-line-no">118</span><span id="line-118"> /**</span> <span class="source-line-no">118</span><span id="line-118"> /**</span>
<span class="source-line-no">119</span><span id="line-119"> * Register a static list of command completions that will never change</span> <span class="source-line-no">119</span><span id="line-119"> * Register a static list of command completions that will never change.</span>
<span class="source-line-no">120</span><span id="line-120"> *</span> <span class="source-line-no">120</span><span id="line-120"> * Like @CommandCompletion, values are | (PIPE) separated.</span>
<span class="source-line-no">121</span><span id="line-121"> * @param id</span> <span class="source-line-no">121</span><span id="line-121"> * &lt;p&gt;</span>
<span class="source-line-no">122</span><span id="line-122"> * @param completions</span> <span class="source-line-no">122</span><span id="line-122"> * Example: foo|bar|baz</span>
<span class="source-line-no">123</span><span id="line-123"> * @return</span> <span class="source-line-no">123</span><span id="line-123"> *</span>
<span class="source-line-no">124</span><span id="line-124"> */</span> <span class="source-line-no">124</span><span id="line-124"> * @param id</span>
<span class="source-line-no">125</span><span id="line-125"> public CommandCompletionHandler registerStaticCompletion(String id, String[] completions) {</span> <span class="source-line-no">125</span><span id="line-125"> * @param list</span>
<span class="source-line-no">126</span><span id="line-126"> return registerStaticCompletion(id, Arrays.asList(completions));</span> <span class="source-line-no">126</span><span id="line-126"> * @return</span>
<span class="source-line-no">127</span><span id="line-127"> }</span> <span class="source-line-no">127</span><span id="line-127"> */</span>
<span class="source-line-no">128</span><span id="line-128"></span> <span class="source-line-no">128</span><span id="line-128"> public CommandCompletionHandler registerStaticCompletion(String id, String list) {</span>
<span class="source-line-no">129</span><span id="line-129"> /**</span> <span class="source-line-no">129</span><span id="line-129"> return registerStaticCompletion(id, ACFPatterns.PIPE.split(list));</span>
<span class="source-line-no">130</span><span id="line-130"> * Register a static list of command completions that will never change. The list is obtained from the supplier</span> <span class="source-line-no">130</span><span id="line-130"> }</span>
<span class="source-line-no">131</span><span id="line-131"> * immediately as part of this method call.</span> <span class="source-line-no">131</span><span id="line-131"></span>
<span class="source-line-no">132</span><span id="line-132"> *</span> <span class="source-line-no">132</span><span id="line-132"> /**</span>
<span class="source-line-no">133</span><span id="line-133"> * @param id</span> <span class="source-line-no">133</span><span id="line-133"> * Register a static list of command completions that will never change</span>
<span class="source-line-no">134</span><span id="line-134"> * @param supplier</span> <span class="source-line-no">134</span><span id="line-134"> *</span>
<span class="source-line-no">135</span><span id="line-135"> * @return</span> <span class="source-line-no">135</span><span id="line-135"> * @param id</span>
<span class="source-line-no">136</span><span id="line-136"> */</span> <span class="source-line-no">136</span><span id="line-136"> * @param completions</span>
<span class="source-line-no">137</span><span id="line-137"> public CommandCompletionHandler registerStaticCompletion(String id, Supplier&lt;Collection&lt;String&gt;&gt; supplier) {</span> <span class="source-line-no">137</span><span id="line-137"> * @return</span>
<span class="source-line-no">138</span><span id="line-138"> return registerStaticCompletion(id, supplier.get());</span> <span class="source-line-no">138</span><span id="line-138"> */</span>
<span class="source-line-no">139</span><span id="line-139"> }</span> <span class="source-line-no">139</span><span id="line-139"> public CommandCompletionHandler registerStaticCompletion(String id, String[] completions) {</span>
<span class="source-line-no">140</span><span id="line-140"></span> <span class="source-line-no">140</span><span id="line-140"> return registerStaticCompletion(id, Arrays.asList(completions));</span>
<span class="source-line-no">141</span><span id="line-141"> /**</span> <span class="source-line-no">141</span><span id="line-141"> }</span>
<span class="source-line-no">142</span><span id="line-142"> * Register a static list of command completions that will never change</span> <span class="source-line-no">142</span><span id="line-142"></span>
<span class="source-line-no">143</span><span id="line-143"> *</span> <span class="source-line-no">143</span><span id="line-143"> /**</span>
<span class="source-line-no">144</span><span id="line-144"> * @param id</span> <span class="source-line-no">144</span><span id="line-144"> * Register a static list of command completions that will never change. The list is obtained from the supplier</span>
<span class="source-line-no">145</span><span id="line-145"> * @param completions</span> <span class="source-line-no">145</span><span id="line-145"> * immediately as part of this method call.</span>
<span class="source-line-no">146</span><span id="line-146"> * @return</span> <span class="source-line-no">146</span><span id="line-146"> *</span>
<span class="source-line-no">147</span><span id="line-147"> */</span> <span class="source-line-no">147</span><span id="line-147"> * @param id</span>
<span class="source-line-no">148</span><span id="line-148"> public CommandCompletionHandler registerStaticCompletion(String id, Collection&lt;String&gt; completions) {</span> <span class="source-line-no">148</span><span id="line-148"> * @param supplier</span>
<span class="source-line-no">149</span><span id="line-149"> return registerAsyncCompletion(id, x -&gt; completions);</span> <span class="source-line-no">149</span><span id="line-149"> * @return</span>
<span class="source-line-no">150</span><span id="line-150"> }</span> <span class="source-line-no">150</span><span id="line-150"> */</span>
<span class="source-line-no">151</span><span id="line-151"></span> <span class="source-line-no">151</span><span id="line-151"> public CommandCompletionHandler registerStaticCompletion(String id, Supplier&lt;Collection&lt;String&gt;&gt; supplier) {</span>
<span class="source-line-no">152</span><span id="line-152"> /**</span> <span class="source-line-no">152</span><span id="line-152"> return registerStaticCompletion(id, supplier.get());</span>
<span class="source-line-no">153</span><span id="line-153"> * Registers a completion handler such as @players to default apply to all command parameters of the specified types</span> <span class="source-line-no">153</span><span id="line-153"> }</span>
<span class="source-line-no">154</span><span id="line-154"> * &lt;p&gt;</span> <span class="source-line-no">154</span><span id="line-154"></span>
<span class="source-line-no">155</span><span id="line-155"> * This enables automatic completion support for parameters without manually defining it for custom objects</span> <span class="source-line-no">155</span><span id="line-155"> /**</span>
<span class="source-line-no">156</span><span id="line-156"> *</span> <span class="source-line-no">156</span><span id="line-156"> * Register a static list of command completions that will never change</span>
<span class="source-line-no">157</span><span id="line-157"> * @param id</span> <span class="source-line-no">157</span><span id="line-157"> *</span>
<span class="source-line-no">158</span><span id="line-158"> * @param classes</span> <span class="source-line-no">158</span><span id="line-158"> * @param id</span>
<span class="source-line-no">159</span><span id="line-159"> */</span> <span class="source-line-no">159</span><span id="line-159"> * @param completions</span>
<span class="source-line-no">160</span><span id="line-160"> public void setDefaultCompletion(String id, Class... classes) {</span> <span class="source-line-no">160</span><span id="line-160"> * @return</span>
<span class="source-line-no">161</span><span id="line-161"> // get completion with specified id</span> <span class="source-line-no">161</span><span id="line-161"> */</span>
<span class="source-line-no">162</span><span id="line-162"> id = prepareCompletionId(id);</span> <span class="source-line-no">162</span><span id="line-162"> public CommandCompletionHandler registerStaticCompletion(String id, Collection&lt;String&gt; completions) {</span>
<span class="source-line-no">163</span><span id="line-163"> CommandCompletionHandler completion = completionMap.get(id);</span> <span class="source-line-no">163</span><span id="line-163"> return registerAsyncCompletion(id, x -&gt; completions);</span>
<span class="source-line-no">164</span><span id="line-164"></span> <span class="source-line-no">164</span><span id="line-164"> }</span>
<span class="source-line-no">165</span><span id="line-165"> if (completion == null) {</span> <span class="source-line-no">165</span><span id="line-165"></span>
<span class="source-line-no">166</span><span id="line-166"> // Throw something because no completion with specified id</span> <span class="source-line-no">166</span><span id="line-166"> /**</span>
<span class="source-line-no">167</span><span id="line-167"> throw new IllegalStateException("Completion not registered for " + id);</span> <span class="source-line-no">167</span><span id="line-167"> * Registers a completion handler such as @players to default apply to all command parameters of the specified types</span>
<span class="source-line-no">168</span><span id="line-168"> }</span> <span class="source-line-no">168</span><span id="line-168"> * &lt;p&gt;</span>
<span class="source-line-no">169</span><span id="line-169"></span> <span class="source-line-no">169</span><span id="line-169"> * This enables automatic completion support for parameters without manually defining it for custom objects</span>
<span class="source-line-no">170</span><span id="line-170"> for (Class clazz : classes) {</span> <span class="source-line-no">170</span><span id="line-170"> *</span>
<span class="source-line-no">171</span><span id="line-171"> defaultCompletions.put(clazz, id);</span> <span class="source-line-no">171</span><span id="line-171"> * @param id</span>
<span class="source-line-no">172</span><span id="line-172"> }</span> <span class="source-line-no">172</span><span id="line-172"> * @param classes</span>
<span class="source-line-no">173</span><span id="line-173"> }</span> <span class="source-line-no">173</span><span id="line-173"> */</span>
<span class="source-line-no">174</span><span id="line-174"></span> <span class="source-line-no">174</span><span id="line-174"> public void setDefaultCompletion(String id, Class... classes) {</span>
<span class="source-line-no">175</span><span id="line-175"> @NotNull</span> <span class="source-line-no">175</span><span id="line-175"> // get completion with specified id</span>
<span class="source-line-no">176</span><span id="line-176"> private static String prepareCompletionId(String id) {</span> <span class="source-line-no">176</span><span id="line-176"> id = prepareCompletionId(id);</span>
<span class="source-line-no">177</span><span id="line-177"> return (id.startsWith("@") ? "" : "@") + id.toLowerCase(Locale.ENGLISH);</span> <span class="source-line-no">177</span><span id="line-177"> CommandCompletionHandler completion = completionMap.get(id);</span>
<span class="source-line-no">178</span><span id="line-178"> }</span> <span class="source-line-no">178</span><span id="line-178"></span>
<span class="source-line-no">179</span><span id="line-179"></span> <span class="source-line-no">179</span><span id="line-179"> if (completion == null) {</span>
<span class="source-line-no">180</span><span id="line-180"> @NotNull</span> <span class="source-line-no">180</span><span id="line-180"> // Throw something because no completion with specified id</span>
<span class="source-line-no">181</span><span id="line-181"> List&lt;String&gt; of(RegisteredCommand cmd, CommandIssuer sender, String[] args, boolean isAsync) {</span> <span class="source-line-no">181</span><span id="line-181"> throw new IllegalStateException("Completion not registered for " + id);</span>
<span class="source-line-no">182</span><span id="line-182"> String[] completions = ACFPatterns.SPACE.split(cmd.complete);</span> <span class="source-line-no">182</span><span id="line-182"> }</span>
<span class="source-line-no">183</span><span id="line-183"> final int argIndex = args.length - 1;</span> <span class="source-line-no">183</span><span id="line-183"></span>
<span class="source-line-no">184</span><span id="line-184"></span> <span class="source-line-no">184</span><span id="line-184"> for (Class clazz : classes) {</span>
<span class="source-line-no">185</span><span id="line-185"> String input = args[argIndex];</span> <span class="source-line-no">185</span><span id="line-185"> defaultCompletions.put(clazz, id);</span>
<span class="source-line-no">186</span><span id="line-186"></span> <span class="source-line-no">186</span><span id="line-186"> }</span>
<span class="source-line-no">187</span><span id="line-187"> String completion = argIndex &lt; completions.length ? completions[argIndex] : null;</span> <span class="source-line-no">187</span><span id="line-187"> }</span>
<span class="source-line-no">188</span><span id="line-188"> if (completion == null || completion.isEmpty() || "*".equals(completion)) {</span> <span class="source-line-no">188</span><span id="line-188"></span>
<span class="source-line-no">189</span><span id="line-189"> completion = findDefaultCompletion(cmd, args);</span> <span class="source-line-no">189</span><span id="line-189"> @NotNull</span>
<span class="source-line-no">190</span><span id="line-190"> }</span> <span class="source-line-no">190</span><span id="line-190"> private static String prepareCompletionId(String id) {</span>
<span class="source-line-no">191</span><span id="line-191"></span> <span class="source-line-no">191</span><span id="line-191"> return (id.startsWith("@") ? "" : "@") + id.toLowerCase(Locale.ENGLISH);</span>
<span class="source-line-no">192</span><span id="line-192"> if (completion == null &amp;&amp; completions.length &gt; 0) {</span> <span class="source-line-no">192</span><span id="line-192"> }</span>
<span class="source-line-no">193</span><span id="line-193"> String last = completions[completions.length - 1];</span> <span class="source-line-no">193</span><span id="line-193"></span>
<span class="source-line-no">194</span><span id="line-194"> if (last.startsWith("repeat@")) {</span> <span class="source-line-no">194</span><span id="line-194"> @NotNull</span>
<span class="source-line-no">195</span><span id="line-195"> completion = last;</span> <span class="source-line-no">195</span><span id="line-195"> List&lt;String&gt; of(RegisteredCommand cmd, CommandIssuer sender, String[] args, boolean isAsync) {</span>
<span class="source-line-no">196</span><span id="line-196"> } else if (argIndex &gt;= completions.length &amp;&amp; cmd.parameters[cmd.parameters.length - 1].consumesRest) {</span> <span class="source-line-no">196</span><span id="line-196"> String[] completions = ACFPatterns.SPACE.split(cmd.complete);</span>
<span class="source-line-no">197</span><span id="line-197"> completion = last;</span> <span class="source-line-no">197</span><span id="line-197"> final int argIndex = args.length - 1;</span>
<span class="source-line-no">198</span><span id="line-198"> }</span> <span class="source-line-no">198</span><span id="line-198"></span>
<span class="source-line-no">199</span><span id="line-199"> }</span> <span class="source-line-no">199</span><span id="line-199"> String input = args[argIndex];</span>
<span class="source-line-no">200</span><span id="line-200"></span> <span class="source-line-no">200</span><span id="line-200"></span>
<span class="source-line-no">201</span><span id="line-201"> if (completion == null) {</span> <span class="source-line-no">201</span><span id="line-201"> String completion = argIndex &lt; completions.length ? completions[argIndex] : null;</span>
<span class="source-line-no">202</span><span id="line-202"> return Collections.singletonList(input);</span> <span class="source-line-no">202</span><span id="line-202"> if (completion == null || completion.isEmpty() || "*".equals(completion)) {</span>
<span class="source-line-no">203</span><span id="line-203"> }</span> <span class="source-line-no">203</span><span id="line-203"> completion = findDefaultCompletion(cmd, args);</span>
<span class="source-line-no">204</span><span id="line-204"></span> <span class="source-line-no">204</span><span id="line-204"> }</span>
<span class="source-line-no">205</span><span id="line-205"> return getCompletionValues(cmd, sender, completion, args, isAsync);</span> <span class="source-line-no">205</span><span id="line-205"></span>
<span class="source-line-no">206</span><span id="line-206"> }</span> <span class="source-line-no">206</span><span id="line-206"> if (completion == null &amp;&amp; completions.length &gt; 0) {</span>
<span class="source-line-no">207</span><span id="line-207"></span> <span class="source-line-no">207</span><span id="line-207"> String last = completions[completions.length - 1];</span>
<span class="source-line-no">208</span><span id="line-208"> String findDefaultCompletion(RegisteredCommand cmd, String[] args) {</span> <span class="source-line-no">208</span><span id="line-208"> if (last.startsWith("repeat@")) {</span>
<span class="source-line-no">209</span><span id="line-209"> int i = 0;</span> <span class="source-line-no">209</span><span id="line-209"> completion = last;</span>
<span class="source-line-no">210</span><span id="line-210"> for (CommandParameter param : cmd.parameters) {</span> <span class="source-line-no">210</span><span id="line-210"> } else if (argIndex &gt;= completions.length &amp;&amp; cmd.parameters[cmd.parameters.length - 1].consumesRest) {</span>
<span class="source-line-no">211</span><span id="line-211"> if (param.canConsumeInput() &amp;&amp; ++i == args.length) {</span> <span class="source-line-no">211</span><span id="line-211"> completion = last;</span>
<span class="source-line-no">212</span><span id="line-212"> Class type = param.getType();</span> <span class="source-line-no">212</span><span id="line-212"> }</span>
<span class="source-line-no">213</span><span id="line-213"> while (type != null) {</span> <span class="source-line-no">213</span><span id="line-213"> }</span>
<span class="source-line-no">214</span><span id="line-214"> String completion = this.defaultCompletions.get(type);</span> <span class="source-line-no">214</span><span id="line-214"></span>
<span class="source-line-no">215</span><span id="line-215"> if (completion != null) {</span> <span class="source-line-no">215</span><span id="line-215"> if (completion == null) {</span>
<span class="source-line-no">216</span><span id="line-216"> return completion;</span> <span class="source-line-no">216</span><span id="line-216"> return Collections.singletonList(input);</span>
<span class="source-line-no">217</span><span id="line-217"> }</span> <span class="source-line-no">217</span><span id="line-217"> }</span>
<span class="source-line-no">218</span><span id="line-218"> type = type.getSuperclass();</span> <span class="source-line-no">218</span><span id="line-218"></span>
<span class="source-line-no">219</span><span id="line-219"> }</span> <span class="source-line-no">219</span><span id="line-219"> return getCompletionValues(cmd, sender, completion, args, isAsync);</span>
<span class="source-line-no">220</span><span id="line-220"> if (param.getType().isEnum()) {</span> <span class="source-line-no">220</span><span id="line-220"> }</span>
<span class="source-line-no">221</span><span id="line-221"> CommandOperationContext ctx = CommandManager.getCurrentCommandOperationContext();</span> <span class="source-line-no">221</span><span id="line-221"></span>
<span class="source-line-no">222</span><span id="line-222"> //noinspection unchecked</span> <span class="source-line-no">222</span><span id="line-222"> String findDefaultCompletion(RegisteredCommand cmd, String[] args) {</span>
<span class="source-line-no">223</span><span id="line-223"> ctx.enumCompletionValues = ACFUtil.enumNames((Class&lt;? extends Enum&lt;?&gt;&gt;) param.getType());</span> <span class="source-line-no">223</span><span id="line-223"> int i = 0;</span>
<span class="source-line-no">224</span><span id="line-224"> return DEFAULT_ENUM_ID;</span> <span class="source-line-no">224</span><span id="line-224"> for (CommandParameter param : cmd.parameters) {</span>
<span class="source-line-no">225</span><span id="line-225"> }</span> <span class="source-line-no">225</span><span id="line-225"> if (param.canConsumeInput() &amp;&amp; ++i == args.length) {</span>
<span class="source-line-no">226</span><span id="line-226"> break;</span> <span class="source-line-no">226</span><span id="line-226"> Class type = param.getType();</span>
<span class="source-line-no">227</span><span id="line-227"> }</span> <span class="source-line-no">227</span><span id="line-227"> while (type != null) {</span>
<span class="source-line-no">228</span><span id="line-228"> }</span> <span class="source-line-no">228</span><span id="line-228"> String completion = this.defaultCompletions.get(type);</span>
<span class="source-line-no">229</span><span id="line-229"> return null;</span> <span class="source-line-no">229</span><span id="line-229"> if (completion != null) {</span>
<span class="source-line-no">230</span><span id="line-230"> }</span> <span class="source-line-no">230</span><span id="line-230"> return completion;</span>
<span class="source-line-no">231</span><span id="line-231"></span> <span class="source-line-no">231</span><span id="line-231"> }</span>
<span class="source-line-no">232</span><span id="line-232"> List&lt;String&gt; getCompletionValues(RegisteredCommand command, CommandIssuer sender, String completion, String[] args, boolean isAsync) {</span> <span class="source-line-no">232</span><span id="line-232"> type = type.getSuperclass();</span>
<span class="source-line-no">233</span><span id="line-233"> if (DEFAULT_ENUM_ID.equals(completion)) {</span> <span class="source-line-no">233</span><span id="line-233"> }</span>
<span class="source-line-no">234</span><span id="line-234"> CommandOperationContext&lt;?&gt; ctx = CommandManager.getCurrentCommandOperationContext();</span> <span class="source-line-no">234</span><span id="line-234"> if (param.getType().isEnum()) {</span>
<span class="source-line-no">235</span><span id="line-235"> return ctx.enumCompletionValues;</span> <span class="source-line-no">235</span><span id="line-235"> CommandOperationContext ctx = CommandManager.getCurrentCommandOperationContext();</span>
<span class="source-line-no">236</span><span id="line-236"> }</span> <span class="source-line-no">236</span><span id="line-236"> //noinspection unchecked</span>
<span class="source-line-no">237</span><span id="line-237"> boolean repeat = completion.startsWith("repeat@");</span> <span class="source-line-no">237</span><span id="line-237"> ctx.enumCompletionValues = ACFUtil.enumNames((Class&lt;? extends Enum&lt;?&gt;&gt;) param.getType());</span>
<span class="source-line-no">238</span><span id="line-238"> if (repeat) {</span> <span class="source-line-no">238</span><span id="line-238"> return DEFAULT_ENUM_ID;</span>
<span class="source-line-no">239</span><span id="line-239"> completion = completion.substring(6);</span> <span class="source-line-no">239</span><span id="line-239"> }</span>
<span class="source-line-no">240</span><span id="line-240"> }</span> <span class="source-line-no">240</span><span id="line-240"> break;</span>
<span class="source-line-no">241</span><span id="line-241"> completion = manager.getCommandReplacements().replace(completion);</span> <span class="source-line-no">241</span><span id="line-241"> }</span>
<span class="source-line-no">242</span><span id="line-242"></span> <span class="source-line-no">242</span><span id="line-242"> }</span>
<span class="source-line-no">243</span><span id="line-243"> List&lt;String&gt; allCompletions = new ArrayList&lt;&gt;();</span> <span class="source-line-no">243</span><span id="line-243"> return null;</span>
<span class="source-line-no">244</span><span id="line-244"> String input = args.length &gt; 0 ? args[args.length - 1] : "";</span> <span class="source-line-no">244</span><span id="line-244"> }</span>
<span class="source-line-no">245</span><span id="line-245"></span> <span class="source-line-no">245</span><span id="line-245"></span>
<span class="source-line-no">246</span><span id="line-246"> for (String value : ACFPatterns.PIPE.split(completion)) {</span> <span class="source-line-no">246</span><span id="line-246"> List&lt;String&gt; getCompletionValues(RegisteredCommand command, CommandIssuer sender, String completion, String[] args, boolean isAsync) {</span>
<span class="source-line-no">247</span><span id="line-247"> String[] complete = ACFPatterns.COLONEQUALS.split(value, 2);</span> <span class="source-line-no">247</span><span id="line-247"> if (DEFAULT_ENUM_ID.equals(completion)) {</span>
<span class="source-line-no">248</span><span id="line-248"> CommandCompletionHandler handler = this.completionMap.get(complete[0].toLowerCase(Locale.ENGLISH));</span> <span class="source-line-no">248</span><span id="line-248"> CommandOperationContext&lt;?&gt; ctx = CommandManager.getCurrentCommandOperationContext();</span>
<span class="source-line-no">249</span><span id="line-249"> if (handler != null) {</span> <span class="source-line-no">249</span><span id="line-249"> return ctx.enumCompletionValues;</span>
<span class="source-line-no">250</span><span id="line-250"> if (isAsync &amp;&amp; !(handler instanceof AsyncCommandCompletionHandler)) {</span> <span class="source-line-no">250</span><span id="line-250"> }</span>
<span class="source-line-no">251</span><span id="line-251"> ACFUtil.sneaky(new SyncCompletionRequired());</span> <span class="source-line-no">251</span><span id="line-251"> boolean repeat = completion.startsWith("repeat@");</span>
<span class="source-line-no">252</span><span id="line-252"> return null;</span> <span class="source-line-no">252</span><span id="line-252"> if (repeat) {</span>
<span class="source-line-no">253</span><span id="line-253"> }</span> <span class="source-line-no">253</span><span id="line-253"> completion = completion.substring(6);</span>
<span class="source-line-no">254</span><span id="line-254"> String config = complete.length == 1 ? null : complete[1];</span> <span class="source-line-no">254</span><span id="line-254"> }</span>
<span class="source-line-no">255</span><span id="line-255"> CommandCompletionContext context = manager.createCompletionContext(command, sender, input, config, args);</span> <span class="source-line-no">255</span><span id="line-255"> completion = manager.getCommandReplacements().replace(completion);</span>
<span class="source-line-no">256</span><span id="line-256"></span> <span class="source-line-no">256</span><span id="line-256"></span>
<span class="source-line-no">257</span><span id="line-257"> try {</span> <span class="source-line-no">257</span><span id="line-257"> List&lt;String&gt; allCompletions = new ArrayList&lt;&gt;();</span>
<span class="source-line-no">258</span><span id="line-258"> //noinspection unchecked</span> <span class="source-line-no">258</span><span id="line-258"> String input = args.length &gt; 0 ? args[args.length - 1] : "";</span>
<span class="source-line-no">259</span><span id="line-259"> Collection&lt;String&gt; completions = handler.getCompletions(context);</span> <span class="source-line-no">259</span><span id="line-259"></span>
<span class="source-line-no">260</span><span id="line-260"></span> <span class="source-line-no">260</span><span id="line-260"> for (String value : ACFPatterns.PIPE.split(completion)) {</span>
<span class="source-line-no">261</span><span id="line-261"> //Handle completions with more than one word:</span> <span class="source-line-no">261</span><span id="line-261"> String[] complete = ACFPatterns.COLONEQUALS.split(value, 2);</span>
<span class="source-line-no">262</span><span id="line-262"> if (!repeat &amp;&amp; completions != null</span> <span class="source-line-no">262</span><span id="line-262"> CommandCompletionHandler handler = this.completionMap.get(complete[0].toLowerCase(Locale.ENGLISH));</span>
<span class="source-line-no">263</span><span id="line-263"> &amp;&amp; command.parameters[command.parameters.length - 1].consumesRest</span> <span class="source-line-no">263</span><span id="line-263"> if (handler != null) {</span>
<span class="source-line-no">264</span><span id="line-264"> &amp;&amp; args.length &gt; ACFPatterns.SPACE.split(command.complete).length) {</span> <span class="source-line-no">264</span><span id="line-264"> if (isAsync &amp;&amp; !(handler instanceof AsyncCommandCompletionHandler)) {</span>
<span class="source-line-no">265</span><span id="line-265"> String start = String.join(" ", args);</span> <span class="source-line-no">265</span><span id="line-265"> ACFUtil.sneaky(new SyncCompletionRequired());</span>
<span class="source-line-no">266</span><span id="line-266"> completions = completions.stream()</span> <span class="source-line-no">266</span><span id="line-266"> return null;</span>
<span class="source-line-no">267</span><span id="line-267"> .map(s -&gt; {</span> <span class="source-line-no">267</span><span id="line-267"> }</span>
<span class="source-line-no">268</span><span id="line-268"> if (s != null &amp;&amp; s.split(" ").length &gt;= args.length &amp;&amp; ApacheCommonsLangUtil.startsWithIgnoreCase(s, start)) {</span> <span class="source-line-no">268</span><span id="line-268"> String config = complete.length == 1 ? null : complete[1];</span>
<span class="source-line-no">269</span><span id="line-269"> String[] completionArgs = s.split(" ");</span> <span class="source-line-no">269</span><span id="line-269"> CommandCompletionContext context = manager.createCompletionContext(command, sender, input, config, args);</span>
<span class="source-line-no">270</span><span id="line-270"> return String.join(" ", Arrays.copyOfRange(completionArgs, args.length - 1, completionArgs.length));</span> <span class="source-line-no">270</span><span id="line-270"></span>
<span class="source-line-no">271</span><span id="line-271"> } else {</span> <span class="source-line-no">271</span><span id="line-271"> try {</span>
<span class="source-line-no">272</span><span id="line-272"> return s;</span> <span class="source-line-no">272</span><span id="line-272"> //noinspection unchecked</span>
<span class="source-line-no">273</span><span id="line-273"> }</span> <span class="source-line-no">273</span><span id="line-273"> Collection&lt;String&gt; completions = handler.getCompletions(context);</span>
<span class="source-line-no">274</span><span id="line-274"> }).collect(Collectors.toList());</span> <span class="source-line-no">274</span><span id="line-274"></span>
<span class="source-line-no">275</span><span id="line-275"> }</span> <span class="source-line-no">275</span><span id="line-275"> //Handle completions with more than one word:</span>
<span class="source-line-no">276</span><span id="line-276"></span> <span class="source-line-no">276</span><span id="line-276"> if (!repeat &amp;&amp; completions != null</span>
<span class="source-line-no">277</span><span id="line-277"> if (completions != null) {</span> <span class="source-line-no">277</span><span id="line-277"> &amp;&amp; command.parameters[command.parameters.length - 1].consumesRest</span>
<span class="source-line-no">278</span><span id="line-278"> allCompletions.addAll(completions);</span> <span class="source-line-no">278</span><span id="line-278"> &amp;&amp; args.length &gt; ACFPatterns.SPACE.split(command.complete).length) {</span>
<span class="source-line-no">279</span><span id="line-279"> continue;</span> <span class="source-line-no">279</span><span id="line-279"> String start = String.join(" ", args);</span>
<span class="source-line-no">280</span><span id="line-280"> }</span> <span class="source-line-no">280</span><span id="line-280"> completions = completions.stream()</span>
<span class="source-line-no">281</span><span id="line-281"> //noinspection ConstantIfStatement,ConstantConditions</span> <span class="source-line-no">281</span><span id="line-281"> .map(s -&gt; {</span>
<span class="source-line-no">282</span><span id="line-282"> if (false) { // Hack to fool compiler. since its sneakily thrown.</span> <span class="source-line-no">282</span><span id="line-282"> if (s != null &amp;&amp; s.split(" ").length &gt;= args.length &amp;&amp; ApacheCommonsLangUtil.startsWithIgnoreCase(s, start)) {</span>
<span class="source-line-no">283</span><span id="line-283"> throw new CommandCompletionTextLookupException();</span> <span class="source-line-no">283</span><span id="line-283"> String[] completionArgs = s.split(" ");</span>
<span class="source-line-no">284</span><span id="line-284"> }</span> <span class="source-line-no">284</span><span id="line-284"> return String.join(" ", Arrays.copyOfRange(completionArgs, args.length - 1, completionArgs.length));</span>
<span class="source-line-no">285</span><span id="line-285"> } catch (CommandCompletionTextLookupException ignored) {</span> <span class="source-line-no">285</span><span id="line-285"> } else {</span>
<span class="source-line-no">286</span><span id="line-286"> // This should only happen if some other feedback error occured.</span> <span class="source-line-no">286</span><span id="line-286"> return s;</span>
<span class="source-line-no">287</span><span id="line-287"> } catch (Exception e) {</span> <span class="source-line-no">287</span><span id="line-287"> }</span>
<span class="source-line-no">288</span><span id="line-288"> command.handleException(sender, Arrays.asList(args), e);</span> <span class="source-line-no">288</span><span id="line-288"> }).collect(Collectors.toList());</span>
<span class="source-line-no">289</span><span id="line-289"> }</span> <span class="source-line-no">289</span><span id="line-289"> }</span>
<span class="source-line-no">290</span><span id="line-290"> // Something went wrong in lookup, fall back to input</span> <span class="source-line-no">290</span><span id="line-290"></span>
<span class="source-line-no">291</span><span id="line-291"> return Collections.singletonList(input);</span> <span class="source-line-no">291</span><span id="line-291"> if (completions != null) {</span>
<span class="source-line-no">292</span><span id="line-292"> } else {</span> <span class="source-line-no">292</span><span id="line-292"> allCompletions.addAll(completions);</span>
<span class="source-line-no">293</span><span id="line-293"> // Plaintext value</span> <span class="source-line-no">293</span><span id="line-293"> continue;</span>
<span class="source-line-no">294</span><span id="line-294"> allCompletions.add(value);</span> <span class="source-line-no">294</span><span id="line-294"> }</span>
<span class="source-line-no">295</span><span id="line-295"> }</span> <span class="source-line-no">295</span><span id="line-295"> //noinspection ConstantIfStatement,ConstantConditions</span>
<span class="source-line-no">296</span><span id="line-296"> }</span> <span class="source-line-no">296</span><span id="line-296"> if (false) { // Hack to fool compiler. since its sneakily thrown.</span>
<span class="source-line-no">297</span><span id="line-297"> return allCompletions;</span> <span class="source-line-no">297</span><span id="line-297"> throw new CommandCompletionTextLookupException();</span>
<span class="source-line-no">298</span><span id="line-298"> }</span> <span class="source-line-no">298</span><span id="line-298"> }</span>
<span class="source-line-no">299</span><span id="line-299"></span> <span class="source-line-no">299</span><span id="line-299"> } catch (CommandCompletionTextLookupException ignored) {</span>
<span class="source-line-no">300</span><span id="line-300"> public interface CommandCompletionHandler&lt;C extends CommandCompletionContext&gt; {</span> <span class="source-line-no">300</span><span id="line-300"> // This should only happen if some other feedback error occured.</span>
<span class="source-line-no">301</span><span id="line-301"> Collection&lt;String&gt; getCompletions(C context) throws InvalidCommandArgument;</span> <span class="source-line-no">301</span><span id="line-301"> } catch (Exception e) {</span>
<span class="source-line-no">302</span><span id="line-302"> }</span> <span class="source-line-no">302</span><span id="line-302"> command.handleException(sender, Arrays.asList(args), e);</span>
<span class="source-line-no">303</span><span id="line-303"></span> <span class="source-line-no">303</span><span id="line-303"> }</span>
<span class="source-line-no">304</span><span id="line-304"> public interface AsyncCommandCompletionHandler&lt;C extends CommandCompletionContext&gt; extends CommandCompletionHandler&lt;C&gt; {</span> <span class="source-line-no">304</span><span id="line-304"> // Something went wrong in lookup, fall back to input</span>
<span class="source-line-no">305</span><span id="line-305"> }</span> <span class="source-line-no">305</span><span id="line-305"> return Collections.singletonList(input);</span>
<span class="source-line-no">306</span><span id="line-306"></span> <span class="source-line-no">306</span><span id="line-306"> } else {</span>
<span class="source-line-no">307</span><span id="line-307"> public static class SyncCompletionRequired extends RuntimeException {</span> <span class="source-line-no">307</span><span id="line-307"> // Plaintext value</span>
<span class="source-line-no">308</span><span id="line-308"> }</span> <span class="source-line-no">308</span><span id="line-308"> allCompletions.add(value);</span>
<span class="source-line-no">309</span><span id="line-309"></span> <span class="source-line-no">309</span><span id="line-309"> }</span>
<span class="source-line-no">310</span><span id="line-310">}</span> <span class="source-line-no">310</span><span id="line-310"> }</span>
<span class="source-line-no">311</span><span id="line-311"> return allCompletions;</span>
<span class="source-line-no">312</span><span id="line-312"> }</span>
<span class="source-line-no">313</span><span id="line-313"></span>
<span class="source-line-no">314</span><span id="line-314"> public interface CommandCompletionHandler&lt;C extends CommandCompletionContext&gt; {</span>
<span class="source-line-no">315</span><span id="line-315"> Collection&lt;String&gt; getCompletions(C context) throws InvalidCommandArgument;</span>
<span class="source-line-no">316</span><span id="line-316"> }</span>
<span class="source-line-no">317</span><span id="line-317"></span>
<span class="source-line-no">318</span><span id="line-318"> public interface AsyncCommandCompletionHandler&lt;C extends CommandCompletionContext&gt; extends CommandCompletionHandler&lt;C&gt; {</span>
<span class="source-line-no">319</span><span id="line-319"> }</span>
<span class="source-line-no">320</span><span id="line-320"></span>
<span class="source-line-no">321</span><span id="line-321"> public static class SyncCompletionRequired extends RuntimeException {</span>
<span class="source-line-no">322</span><span id="line-322"> }</span>
<span class="source-line-no">323</span><span id="line-323"></span>
<span class="source-line-no">324</span><span id="line-324">}</span>
@@ -545,70 +545,95 @@
<span class="source-line-no">532</span><span id="line-532"></span> <span class="source-line-no">532</span><span id="line-532"></span>
<span class="source-line-no">533</span><span id="line-533"> dependencies.put(clazz, key, instance);</span> <span class="source-line-no">533</span><span id="line-533"> dependencies.put(clazz, key, instance);</span>
<span class="source-line-no">534</span><span id="line-534"> }</span> <span class="source-line-no">534</span><span id="line-534"> }</span>
<span class="source-line-no">535</span><span id="line-535"></span> <span class="source-line-no">535</span><span id="line-535"> </span>
<span class="source-line-no">536</span><span id="line-536"> /**</span> <span class="source-line-no">536</span><span id="line-536"> /**</span>
<span class="source-line-no">537</span><span id="line-537"> * Attempts to inject instances of classes registered with {@link CommandManager#registerDependency(Class, Object)}</span> <span class="source-line-no">537</span><span id="line-537"> * Unregisters an instance of the class, it will no longer be able to be injected</span>
<span class="source-line-no">538</span><span id="line-538"> * into all fields of the class and its superclasses that are marked with {@link Dependency}.</span> <span class="source-line-no">538</span><span id="line-538"> * </span>
<span class="source-line-no">539</span><span id="line-539"> *</span> <span class="source-line-no">539</span><span id="line-539"> * @param clazz the class the injector should look for to remove</span>
<span class="source-line-no">540</span><span id="line-540"> * @param baseCommand the instance which fields should be filled</span> <span class="source-line-no">540</span><span id="line-540"> * @throws IllegalStateException If the dependency was not found.</span>
<span class="source-line-no">541</span><span id="line-541"> */</span> <span class="source-line-no">541</span><span id="line-541"> */</span>
<span class="source-line-no">542</span><span id="line-542"> void injectDependencies(BaseCommand baseCommand) {</span> <span class="source-line-no">542</span><span id="line-542"> public &lt;T&gt; void unregisterDependency(Class&lt;? extends T&gt; clazz) {</span>
<span class="source-line-no">543</span><span id="line-543"> Class clazz = baseCommand.getClass();</span> <span class="source-line-no">543</span><span id="line-543"> unregisterDependency(clazz, clazz.getName());</span>
<span class="source-line-no">544</span><span id="line-544"> do {</span> <span class="source-line-no">544</span><span id="line-544"> }</span>
<span class="source-line-no">545</span><span id="line-545"> for (Field field : clazz.getDeclaredFields()) {</span> <span class="source-line-no">545</span><span id="line-545"></span>
<span class="source-line-no">546</span><span id="line-546"> if (annotations.hasAnnotation(field, Dependency.class)) {</span> <span class="source-line-no">546</span><span id="line-546"> /**</span>
<span class="source-line-no">547</span><span id="line-547"> String dependency = annotations.getAnnotationValue(field, Dependency.class);</span> <span class="source-line-no">547</span><span id="line-547"> * Unregisters an instance of the class, it will no longer be able to be injected</span>
<span class="source-line-no">548</span><span id="line-548"> String key = (key = dependency).isEmpty() ? field.getType().getName() : key;</span> <span class="source-line-no">548</span><span id="line-548"> * </span>
<span class="source-line-no">549</span><span id="line-549"> Object object = dependencies.row(field.getType()).get(key);</span> <span class="source-line-no">549</span><span id="line-549"> * @param clazz the class the injector should look for to remove</span>
<span class="source-line-no">550</span><span id="line-550"> if (object == null) {</span> <span class="source-line-no">550</span><span id="line-550"> * @param key the key which needs to be present if that</span>
<span class="source-line-no">551</span><span id="line-551"> throw new UnresolvedDependencyException("Could not find a registered instance of " +</span> <span class="source-line-no">551</span><span id="line-551"> * @throws IllegalStateException If the dependency was not found.</span>
<span class="source-line-no">552</span><span id="line-552"> field.getType().getName() + " with key " + key + " for field " + field.getName() +</span> <span class="source-line-no">552</span><span id="line-552"> */</span>
<span class="source-line-no">553</span><span id="line-553"> " in class " + baseCommand.getClass().getName());</span> <span class="source-line-no">553</span><span id="line-553"> public &lt;T&gt; void unregisterDependency(Class&lt;? extends T&gt; clazz, String key) {</span>
<span class="source-line-no">554</span><span id="line-554"> }</span> <span class="source-line-no">554</span><span id="line-554"> if (!dependencies.containsKey(clazz, key)) {</span>
<span class="source-line-no">555</span><span id="line-555"></span> <span class="source-line-no">555</span><span id="line-555"> throw new IllegalStateException("Unable to unregister a dependency of " + clazz.getName() + " with the key " + key + " because it wasn't registered");</span>
<span class="source-line-no">556</span><span id="line-556"> try {</span> <span class="source-line-no">556</span><span id="line-556"> }</span>
<span class="source-line-no">557</span><span id="line-557"> boolean accessible = field.isAccessible();</span> <span class="source-line-no">557</span><span id="line-557"></span>
<span class="source-line-no">558</span><span id="line-558"> if (!accessible) {</span> <span class="source-line-no">558</span><span id="line-558"> dependencies.remove(clazz, key);</span>
<span class="source-line-no">559</span><span id="line-559"> field.setAccessible(true);</span> <span class="source-line-no">559</span><span id="line-559"> }</span>
<span class="source-line-no">560</span><span id="line-560"> }</span> <span class="source-line-no">560</span><span id="line-560"></span>
<span class="source-line-no">561</span><span id="line-561"> field.set(baseCommand, object);</span> <span class="source-line-no">561</span><span id="line-561"> /**</span>
<span class="source-line-no">562</span><span id="line-562"> field.setAccessible(accessible);</span> <span class="source-line-no">562</span><span id="line-562"> * Attempts to inject instances of classes registered with {@link CommandManager#registerDependency(Class, Object)}</span>
<span class="source-line-no">563</span><span id="line-563"> } catch (IllegalAccessException e) {</span> <span class="source-line-no">563</span><span id="line-563"> * into all fields of the class and its superclasses that are marked with {@link Dependency}.</span>
<span class="source-line-no">564</span><span id="line-564"> e.printStackTrace(); //TODO should we print our own exception here to make a more descriptive error?</span> <span class="source-line-no">564</span><span id="line-564"> *</span>
<span class="source-line-no">565</span><span id="line-565"> }</span> <span class="source-line-no">565</span><span id="line-565"> * @param baseCommand the instance which fields should be filled</span>
<span class="source-line-no">566</span><span id="line-566"> }</span> <span class="source-line-no">566</span><span id="line-566"> */</span>
<span class="source-line-no">567</span><span id="line-567"> }</span> <span class="source-line-no">567</span><span id="line-567"> void injectDependencies(BaseCommand baseCommand) {</span>
<span class="source-line-no">568</span><span id="line-568"> clazz = clazz.getSuperclass();</span> <span class="source-line-no">568</span><span id="line-568"> Class clazz = baseCommand.getClass();</span>
<span class="source-line-no">569</span><span id="line-569"> } while (!clazz.equals(BaseCommand.class));</span> <span class="source-line-no">569</span><span id="line-569"> do {</span>
<span class="source-line-no">570</span><span id="line-570"> }</span> <span class="source-line-no">570</span><span id="line-570"> for (Field field : clazz.getDeclaredFields()) {</span>
<span class="source-line-no">571</span><span id="line-571"></span> <span class="source-line-no">571</span><span id="line-571"> if (annotations.hasAnnotation(field, Dependency.class)) {</span>
<span class="source-line-no">572</span><span id="line-572"> /**</span> <span class="source-line-no">572</span><span id="line-572"> String dependency = annotations.getAnnotationValue(field, Dependency.class);</span>
<span class="source-line-no">573</span><span id="line-573"> * @deprecated Use this with caution! If you enable and use Unstable API's, your next compile using ACF</span> <span class="source-line-no">573</span><span id="line-573"> String key = (key = dependency).isEmpty() ? field.getType().getName() : key;</span>
<span class="source-line-no">574</span><span id="line-574"> * may require you to update your implementation to those unstable API's</span> <span class="source-line-no">574</span><span id="line-574"> Object object = dependencies.row(field.getType()).get(key);</span>
<span class="source-line-no">575</span><span id="line-575"> */</span> <span class="source-line-no">575</span><span id="line-575"> if (object == null) {</span>
<span class="source-line-no">576</span><span id="line-576"> @Deprecated</span> <span class="source-line-no">576</span><span id="line-576"> throw new UnresolvedDependencyException("Could not find a registered instance of " +</span>
<span class="source-line-no">577</span><span id="line-577"> public void enableUnstableAPI(String api) {</span> <span class="source-line-no">577</span><span id="line-577"> field.getType().getName() + " with key " + key + " for field " + field.getName() +</span>
<span class="source-line-no">578</span><span id="line-578"> unstableAPIs.add(api);</span> <span class="source-line-no">578</span><span id="line-578"> " in class " + baseCommand.getClass().getName());</span>
<span class="source-line-no">579</span><span id="line-579"> }</span> <span class="source-line-no">579</span><span id="line-579"> }</span>
<span class="source-line-no">580</span><span id="line-580"></span> <span class="source-line-no">580</span><span id="line-580"></span>
<span class="source-line-no">581</span><span id="line-581"> void verifyUnstableAPI(String api) {</span> <span class="source-line-no">581</span><span id="line-581"> try {</span>
<span class="source-line-no">582</span><span id="line-582"> if (!unstableAPIs.contains(api)) {</span> <span class="source-line-no">582</span><span id="line-582"> boolean accessible = field.isAccessible();</span>
<span class="source-line-no">583</span><span id="line-583"> throw new IllegalStateException("Using an unstable API that has not been enabled ( " + api + "). See https://acfunstable.emc.gs");</span> <span class="source-line-no">583</span><span id="line-583"> if (!accessible) {</span>
<span class="source-line-no">584</span><span id="line-584"> }</span> <span class="source-line-no">584</span><span id="line-584"> field.setAccessible(true);</span>
<span class="source-line-no">585</span><span id="line-585"> }</span> <span class="source-line-no">585</span><span id="line-585"> }</span>
<span class="source-line-no">586</span><span id="line-586"></span> <span class="source-line-no">586</span><span id="line-586"> field.set(baseCommand, object);</span>
<span class="source-line-no">587</span><span id="line-587"> boolean hasUnstableAPI(String api) {</span> <span class="source-line-no">587</span><span id="line-587"> field.setAccessible(accessible);</span>
<span class="source-line-no">588</span><span id="line-588"> return unstableAPIs.contains(api);</span> <span class="source-line-no">588</span><span id="line-588"> } catch (IllegalAccessException e) {</span>
<span class="source-line-no">589</span><span id="line-589"> }</span> <span class="source-line-no">589</span><span id="line-589"> e.printStackTrace(); //TODO should we print our own exception here to make a more descriptive error?</span>
<span class="source-line-no">590</span><span id="line-590"></span> <span class="source-line-no">590</span><span id="line-590"> }</span>
<span class="source-line-no">591</span><span id="line-591"> Annotations getAnnotations() {</span> <span class="source-line-no">591</span><span id="line-591"> }</span>
<span class="source-line-no">592</span><span id="line-592"> return annotations;</span> <span class="source-line-no">592</span><span id="line-592"> }</span>
<span class="source-line-no">593</span><span id="line-593"> }</span> <span class="source-line-no">593</span><span id="line-593"> clazz = clazz.getSuperclass();</span>
<span class="source-line-no">594</span><span id="line-594"></span> <span class="source-line-no">594</span><span id="line-594"> } while (!clazz.equals(BaseCommand.class));</span>
<span class="source-line-no">595</span><span id="line-595"> public String getCommandPrefix(CommandIssuer issuer) {</span> <span class="source-line-no">595</span><span id="line-595"> }</span>
<span class="source-line-no">596</span><span id="line-596"> return "";</span> <span class="source-line-no">596</span><span id="line-596"></span>
<span class="source-line-no">597</span><span id="line-597"> }</span> <span class="source-line-no">597</span><span id="line-597"> /**</span>
<span class="source-line-no">598</span><span id="line-598">}</span> <span class="source-line-no">598</span><span id="line-598"> * @deprecated Use this with caution! If you enable and use Unstable API's, your next compile using ACF</span>
<span class="source-line-no">599</span><span id="line-599"> * may require you to update your implementation to those unstable API's</span>
<span class="source-line-no">600</span><span id="line-600"> */</span>
<span class="source-line-no">601</span><span id="line-601"> @Deprecated</span>
<span class="source-line-no">602</span><span id="line-602"> public void enableUnstableAPI(String api) {</span>
<span class="source-line-no">603</span><span id="line-603"> unstableAPIs.add(api);</span>
<span class="source-line-no">604</span><span id="line-604"> }</span>
<span class="source-line-no">605</span><span id="line-605"></span>
<span class="source-line-no">606</span><span id="line-606"> void verifyUnstableAPI(String api) {</span>
<span class="source-line-no">607</span><span id="line-607"> if (!unstableAPIs.contains(api)) {</span>
<span class="source-line-no">608</span><span id="line-608"> throw new IllegalStateException("Using an unstable API that has not been enabled ( " + api + "). See https://acfunstable.emc.gs");</span>
<span class="source-line-no">609</span><span id="line-609"> }</span>
<span class="source-line-no">610</span><span id="line-610"> }</span>
<span class="source-line-no">611</span><span id="line-611"></span>
<span class="source-line-no">612</span><span id="line-612"> boolean hasUnstableAPI(String api) {</span>
<span class="source-line-no">613</span><span id="line-613"> return unstableAPIs.contains(api);</span>
<span class="source-line-no">614</span><span id="line-614"> }</span>
<span class="source-line-no">615</span><span id="line-615"></span>
<span class="source-line-no">616</span><span id="line-616"> Annotations getAnnotations() {</span>
<span class="source-line-no">617</span><span id="line-617"> return annotations;</span>
<span class="source-line-no">618</span><span id="line-618"> }</span>
<span class="source-line-no">619</span><span id="line-619"></span>
<span class="source-line-no">620</span><span id="line-620"> public String getCommandPrefix(CommandIssuer issuer) {</span>
<span class="source-line-no">621</span><span id="line-621"> return "";</span>
<span class="source-line-no">622</span><span id="line-622"> }</span>
<span class="source-line-no">623</span><span id="line-623">}</span>