diff --git a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs index 22859f6165..97c294de75 100644 --- a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs +++ b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs @@ -218,12 +218,23 @@ public IEnumerable> ProcessInput (params Tuple [] input) return output; } + public IEnumerable> Release () + { + foreach (var h in held) + { + yield return h; + } + ResetState (); + } + public override void ClearHeld () => held.Clear (); protected override string HeldToString () => new string (held.Select (h => h.Item1).ToArray ()); protected override void AddToHeld (char c) => held.Add (new Tuple (c, default!)); - } + + +} internal class AnsiResponseParser : AnsiResponseParserBase { @@ -235,7 +246,13 @@ public string ProcessInput (string input) ProcessInputBase (i => input [i], c => output.Append (c), input.Length); return output.ToString (); } + public string Release () + { + var output = held.ToString (); + ResetState (); + return output; + } public override void ClearHeld () => held.Clear (); protected override string HeldToString () => held.ToString (); diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 77a4416925..4a9a8360a9 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -1457,6 +1457,11 @@ internal override MainLoop Init () } private bool firstTime = true; + + /// + /// How long after Esc has been pressed before we give up on getting an Ansi escape sequence + /// + private TimeSpan _escTimeout = TimeSpan.FromMilliseconds (50); public AnsiResponseParser Parser { get; set; } = new (); internal void ProcessInput (WindowsConsole.InputRecord inputEvent) @@ -1566,6 +1571,11 @@ internal void ProcessInputAfterParsing (WindowsConsole.InputRecord inputEvent) // TODO: keydown/keyup badness + foreach (var i in ShouldRelease ()) + { + yield return i; + } + foreach (Tuple output in Parser.ProcessInput (Tuple.Create(inputEvent.KeyEvent.UnicodeChar,inputEvent))) { @@ -1573,6 +1583,19 @@ internal void ProcessInputAfterParsing (WindowsConsole.InputRecord inputEvent) } } + public IEnumerable ShouldRelease () + { + + if (Parser.State == ParserState.ExpectingBracket && + DateTime.Now - Parser.StateChangedAt > _escTimeout) + { + foreach (Tuple output in Parser.Release ()) + { + yield return output.Item2; + } + } + } + #if HACK_CHECK_WINCHANGED private void ChangeWin (object s, SizeChangedEventArgs e) { @@ -2276,6 +2299,11 @@ bool IMainLoopDriver.EventsPending () void IMainLoopDriver.Iteration () { + foreach(var i in ((WindowsDriver)_consoleDriver).ShouldRelease()) + { + ((WindowsDriver)_consoleDriver).ProcessInput (i); + } + while (_resultQueue.Count > 0) { WindowsConsole.InputRecord [] inputRecords = _resultQueue.Dequeue (); diff --git a/UnitTests/ConsoleDrivers/AnsiResponseParserTests.cs b/UnitTests/ConsoleDrivers/AnsiResponseParserTests.cs index 01102ccc93..17198ddcb5 100644 --- a/UnitTests/ConsoleDrivers/AnsiResponseParserTests.cs +++ b/UnitTests/ConsoleDrivers/AnsiResponseParserTests.cs @@ -1,7 +1,5 @@ using System.Diagnostics; using System.Text; -using Microsoft.VisualStudio.TestPlatform.Utilities; -using Terminal.Gui; using Xunit.Abstractions; namespace UnitTests.ConsoleDrivers;