diff --git a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs index 92b9d2304..68fe3391a 100644 --- a/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs +++ b/Terminal.Gui/ConsoleDrivers/AnsiResponseParser.cs @@ -5,8 +5,7 @@ namespace Terminal.Gui; internal class AnsiResponseParser { private readonly StringBuilder held = new (); - private string? currentTerminator; - private Action? currentResponse; + private readonly List<(string terminator, Action response)> expectedResponses = new (); private readonly List> _ignorers = new (); @@ -20,7 +19,7 @@ internal class AnsiResponseParser // Current state of the parser private ParserState currentState = ParserState.Normal; - private HashSet _knownTerminators = new HashSet (); + private readonly HashSet _knownTerminators = new (); /* * ANSI Input Sequences @@ -58,6 +57,7 @@ internal class AnsiResponseParser _knownTerminators.Add ("K"); _knownTerminators.Add ("L"); _knownTerminators.Add ("M"); + // No - N or O _knownTerminators.Add ("P"); _knownTerminators.Add ("Q"); @@ -82,7 +82,6 @@ internal class AnsiResponseParser _knownTerminators.Add ("h"); _knownTerminators.Add ("i"); - _knownTerminators.Add ("l"); _knownTerminators.Add ("m"); _knownTerminators.Add ("n"); @@ -139,7 +138,7 @@ internal class AnsiResponseParser break; case ParserState.ExpectingBracket: - if (currentChar == '[' ) + if (currentChar == '[') { // Detected '[' , transition to InResponse state currentState = ParserState.InResponse; @@ -194,15 +193,18 @@ internal class AnsiResponseParser private string HandleHeldContent () { var cur = held.ToString (); - // If we're expecting a specific terminator, check if the content matches - if (currentTerminator != null && cur.EndsWith (currentTerminator)) + + // Check for expected responses + (string terminator, Action response) matchingResponse = expectedResponses.FirstOrDefault (r => cur.EndsWith (r.terminator)); + + if (matchingResponse.response != null) { - DispatchResponse (); + DispatchResponse (matchingResponse.response); + expectedResponses.Remove (matchingResponse); return string.Empty; } - if (_knownTerminators.Any (cur.EndsWith) && cur.StartsWith (EscSeqUtils.CSI)) { // Detected a response that we were not expecting @@ -222,12 +224,10 @@ internal class AnsiResponseParser return string.Empty; } - private void DispatchResponse () + private void DispatchResponse (Action response) { // If it matches the expected response, invoke the callback and return nothing for output - currentResponse?.Invoke (held.ToString ()); - currentResponse = null; - currentTerminator = null; + response?.Invoke (held.ToString ()); ResetState (); } @@ -235,9 +235,5 @@ internal class AnsiResponseParser /// Registers a new expected ANSI response with a specific terminator and a callback for when the response is /// completed. /// - public void ExpectResponse (string terminator, Action response) - { - currentTerminator = terminator; - currentResponse = response; - } + public void ExpectResponse (string terminator, Action response) { expectedResponses.Add ((terminator, response)); } }