Files
RobustToolbox/Robust.Client/Console/ClientConsoleHost.Completions.cs
Moony 0e1328675c Toolshed (#4197)
* Saving work

* Move shit to engine

* lord

* merg

* awa

* bql is kill

* forgot the fucking bike rack

* bql is kill for real

* pjb will kill me

* aughfhbdj

* yo ho here we go on my way to the MINES

* a

* adgddf

* gdsgvfvxshngfgh

* b

* hfsjhghj

* hbfdjjh

* tf you mean i have to document it

* follow C# standards

* Assorted cleanup and documentation pass, minor bugfix in ValueRefParser.

* Start porting old commands, remove that pesky prefix in favor of integrating with the shell.

* Fix valueref up a bit, improve autocomplete for it.

* e

* Toolshed type system adventure.

* a log

* a

* a e i o u

* awa

* fix tests

* Arithmetic commands.

* a

* parse improvements

---------

Co-authored-by: moonheart08 <moonheart08@users.noreply.github.com>
2023-08-02 16:06:16 -05:00

100 lines
2.9 KiB
C#

using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Robust.Shared;
using Robust.Shared.Console;
using Robust.Shared.Network.Messages;
namespace Robust.Client.Console;
internal sealed partial class ClientConsoleHost
{
private readonly Dictionary<int, PendingCompletion> _completionsPending = new();
private int _completionSeq;
public async Task<CompletionResult> GetCompletions(List<string> args, string argStr, CancellationToken cancel)
{
// Last element is the command currently being typed. May be empty.
// _logger.Debug($"Running completions: {string.Join(", ", args)}");
var delay = _cfg.GetCVar(CVars.ConCompletionDelay);
if (delay > 0)
await Task.Delay((int)(delay * 1000), cancel);
return await CalcCompletions(args, argStr, cancel);
}
private Task<CompletionResult> CalcCompletions(List<string> args, string argStr, CancellationToken cancel)
{
if (args.Count == 1)
{
// Typing out command name, handle this ourselves.
var cmdOptions = CompletionResult.FromOptions(
AvailableCommands.Values
.Where(c => CanExecute(c.Command))
.OrderBy(c => c.Command)
.Select(c => new CompletionOption(c.Command, c.Description)));
return Task.FromResult(cmdOptions);
}
if (!AvailableCommands.TryGetValue(args[0], out var cmd))
return Task.FromResult(CompletionResult.Empty);
return cmd.GetCompletionAsync(LocalShell, args.ToArray()[1..], argStr, cancel).AsTask();
}
private Task<CompletionResult> DoServerCompletions(List<string> args, string argStr, CancellationToken cancel)
{
var tcs = new TaskCompletionSource<CompletionResult>();
var cts = CancellationTokenSource.CreateLinkedTokenSource(cancel);
var seq = _completionSeq++;
var pending = new PendingCompletion
{
Cts = cts,
Tcs = tcs
};
var msg = new MsgConCompletion
{
Args = args.ToArray(),
ArgString = argStr,
Seq = seq
};
cts.Token.Register(() =>
{
tcs.SetCanceled(cts.Token);
cts.Dispose();
_completionsPending.Remove(seq);
}, true);
NetManager.ClientSendMessage(msg);
_completionsPending.Add(seq, pending);
return tcs.Task;
}
private void ProcessCompletionResp(MsgConCompletionResp message)
{
if (!_completionsPending.TryGetValue(message.Seq, out var pending))
return;
pending.Cts.Dispose();
pending.Tcs.SetResult(message.Result);
_completionsPending.Remove(message.Seq);
}
private struct PendingCompletion
{
public TaskCompletionSource<CompletionResult> Tcs;
public CancellationTokenSource Cts;
}
}