Skip to content

Commit 7c89a3a

Browse files
committed
Merge branch 'v2_develop' of tig:tig/Terminal.Gui into v2_develop
2 parents 3794c34 + e0f61ab commit 7c89a3a

File tree

228 files changed

+7454
-7325
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

228 files changed

+7454
-7325
lines changed

Terminal.Gui/Application/Application.Initialization.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Terminal.Gui;
77

88
public static partial class Application // Initialization (Init/Shutdown)
99
{
10-
/// <summary>Initializes a new instance of <see cref="Terminal.Gui"/> Application.</summary>
10+
/// <summary>Initializes a new instance of a Terminal.Gui Application. <see cref="Shutdown"/> must be called when the application is closing.</summary>
1111
/// <para>Call this method once per instance (or after <see cref="Shutdown"/> has been called).</para>
1212
/// <para>
1313
/// This function loads the right <see cref="IConsoleDriver"/> for the platform, Creates a <see cref="Toplevel"/>. and

Terminal.Gui/Application/Application.Run.cs

+6-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public static Key ArrangeKey
7171
/// <param name="toplevel">The <see cref="Toplevel"/> to prepare execution for.</param>
7272
/// <remarks>
7373
/// This method prepares the provided <see cref="Toplevel"/> for running with the focus, it adds this to the list
74-
/// of <see cref="Toplevel"/>s, lays out the Subviews, focuses the first element, and draws the <see cref="Toplevel"/>
74+
/// of <see cref="Toplevel"/>s, lays out the SubViews, focuses the first element, and draws the <see cref="Toplevel"/>
7575
/// in the screen. This is usually followed by executing the <see cref="RunLoop"/> method, and then the
7676
/// <see cref="End(RunState)"/> method upon termination which will undo these changes.
7777
/// </remarks>
@@ -89,7 +89,11 @@ public static RunState Begin (Toplevel toplevel)
8989
//#endif
9090

9191
// Ensure the mouse is ungrabbed.
92-
MouseGrabView = null;
92+
if (MouseGrabView is { })
93+
{
94+
UngrabMouse ();
95+
MouseGrabView = null;
96+
}
9397

9498
var rs = new RunState (toplevel);
9599

Terminal.Gui/Application/ApplicationNavigation.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public ApplicationNavigation ()
3333
}
3434

3535
/// <summary>
36-
/// Gets whether <paramref name="view"/> is in the Subview hierarchy of <paramref name="start"/>.
36+
/// Gets whether <paramref name="view"/> is in the SubView hierarchy of <paramref name="start"/>.
3737
/// </summary>
3838
/// <param name="start"></param>
3939
/// <param name="view"></param>
@@ -50,7 +50,7 @@ public static bool IsInHierarchy (View? start, View? view)
5050
return true;
5151
}
5252

53-
foreach (View subView in start.Subviews)
53+
foreach (View subView in start.SubViews)
5454
{
5555
if (view == subView)
5656
{

Terminal.Gui/ConsoleDrivers/AnsiEscapeSequence.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public class AnsiEscapeSequence
3333
/// to the oldest outstanding request.
3434
/// </para>
3535
/// </summary>
36-
public required string Terminator { get; init; }
36+
public required string? Terminator { get; init; }
3737

3838

3939

Terminal.Gui/ConsoleDrivers/AnsiEscapeSequenceRequest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class AnsiEscapeSequenceRequest : AnsiEscapeSequence
1212
/// Invoked when the console responds with an ANSI response code that matches the
1313
/// <see cref="AnsiEscapeSequence.Terminator"/>
1414
/// </summary>
15-
public required Action<string> ResponseReceived { get; init; }
15+
public required Action<string?> ResponseReceived { get; init; }
1616

1717
/// <summary>
1818
/// Invoked if the console fails to responds to the ANSI response code

Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiMouseParser.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ public class AnsiMouseParser
1717
/// </summary>
1818
/// <param name="cur"></param>
1919
/// <returns></returns>
20-
public bool IsMouse (string cur)
20+
public bool IsMouse (string? cur)
2121
{
2222
// Typically in this format
2323
// ESC [ < {button_code};{x_pos};{y_pos}{final_byte}
24-
return cur.EndsWith ('M') || cur.EndsWith ('m');
24+
return cur!.EndsWith ('M') || cur.EndsWith ('m');
2525
}
2626

2727
/// <summary>
@@ -30,10 +30,10 @@ public bool IsMouse (string cur)
3030
/// </summary>
3131
/// <param name="input"></param>
3232
/// <returns></returns>
33-
public MouseEventArgs? ProcessMouseInput (string input)
33+
public MouseEventArgs? ProcessMouseInput (string? input)
3434
{
3535
// Match mouse wheel events first
36-
Match match = _mouseEventPattern.Match (input);
36+
Match match = _mouseEventPattern.Match (input!);
3737

3838
if (match.Success)
3939
{

Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiRequestScheduler.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ private bool SendOrSchedule (AnsiEscapeSequenceRequest request, bool addToQueue)
108108

109109
private void EvictStaleRequests ()
110110
{
111-
foreach (string stale in _lastSend.Where (v => IsStale (v.Value)).Select (k => k.Key))
111+
foreach (string? stale in _lastSend.Where (v => IsStale (v.Value)).Select (k => k.Key))
112112
{
113113
EvictStaleRequests (stale);
114114
}
@@ -123,9 +123,9 @@ private void EvictStaleRequests ()
123123
/// </summary>
124124
/// <param name="withTerminator"></param>
125125
/// <returns></returns>
126-
private bool EvictStaleRequests (string withTerminator)
126+
private bool EvictStaleRequests (string? withTerminator)
127127
{
128-
if (_lastSend.TryGetValue (withTerminator, out DateTime dt))
128+
if (_lastSend.TryGetValue (withTerminator!, out DateTime dt))
129129
{
130130
if (IsStale (dt))
131131
{
@@ -178,7 +178,7 @@ public bool RunSchedule (bool force = false)
178178

179179
private void Send (AnsiEscapeSequenceRequest r)
180180
{
181-
_lastSend.AddOrUpdate (r.Terminator, _ => Now (), (_, _) => Now ());
181+
_lastSend.AddOrUpdate (r.Terminator!, _ => Now (), (_, _) => Now ());
182182
_parser.ExpectResponse (r.Terminator, r.ResponseReceived, r.Abandoned, false);
183183
r.Send ();
184184
}
@@ -206,7 +206,7 @@ private bool CanSend (AnsiEscapeSequenceRequest r, out ReasonCannotSend reason)
206206

207207
private bool ShouldThrottle (AnsiEscapeSequenceRequest r)
208208
{
209-
if (_lastSend.TryGetValue (r.Terminator, out DateTime value))
209+
if (_lastSend.TryGetValue (r.Terminator!, out DateTime value))
210210
{
211211
return Now () - value < _throttle;
212212
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#nullable enable
22
namespace Terminal.Gui;
33

4-
internal record AnsiResponseExpectation (string Terminator, Action<IHeld> Response, Action? Abandoned)
4+
internal record AnsiResponseExpectation (string? Terminator, Action<IHeld> Response, Action? Abandoned)
55
{
6-
public bool Matches (string cur) { return cur.EndsWith (Terminator); }
6+
public bool Matches (string? cur) { return cur!.EndsWith (Terminator!); }
77
}

Terminal.Gui/ConsoleDrivers/AnsiResponseParser/AnsiResponseParser.cs

+49-47
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,32 @@ namespace Terminal.Gui;
66

77
internal abstract class AnsiResponseParserBase : IAnsiResponseParser
88
{
9-
private const char Escape = '\x1B';
9+
private const char ESCAPE = '\x1B';
1010
private readonly AnsiMouseParser _mouseParser = new ();
11+
#pragma warning disable IDE1006 // Naming Styles
1112
protected readonly AnsiKeyboardParser _keyboardParser = new ();
1213
protected object _lockExpectedResponses = new ();
1314

1415
protected object _lockState = new ();
16+
protected readonly IHeld _heldContent;
17+
18+
/// <summary>
19+
/// Responses we are expecting to come in.
20+
/// </summary>
21+
protected readonly List<AnsiResponseExpectation> _expectedResponses = [];
22+
23+
/// <summary>
24+
/// Collection of responses that we <see cref="StopExpecting"/>.
25+
/// </summary>
26+
protected readonly List<AnsiResponseExpectation> _lateResponses = [];
27+
28+
/// <summary>
29+
/// Responses that you want to look out for that will come in continuously e.g. mouse events.
30+
/// Key is the terminator.
31+
/// </summary>
32+
protected readonly List<AnsiResponseExpectation> _persistentExpectations = [];
33+
34+
#pragma warning restore IDE1006 // Naming Styles
1535

1636
/// <summary>
1737
/// Event raised when mouse events are detected - requires setting <see cref="HandleMouse"/> to true
@@ -35,22 +55,6 @@ internal abstract class AnsiResponseParserBase : IAnsiResponseParser
3555
/// </summary>
3656
public bool HandleKeyboard { get; set; } = false;
3757

38-
/// <summary>
39-
/// Responses we are expecting to come in.
40-
/// </summary>
41-
protected readonly List<AnsiResponseExpectation> _expectedResponses = [];
42-
43-
/// <summary>
44-
/// Collection of responses that we <see cref="StopExpecting"/>.
45-
/// </summary>
46-
protected readonly List<AnsiResponseExpectation> _lateResponses = [];
47-
48-
/// <summary>
49-
/// Responses that you want to look out for that will come in continuously e.g. mouse events.
50-
/// Key is the terminator.
51-
/// </summary>
52-
protected readonly List<AnsiResponseExpectation> _persistentExpectations = [];
53-
5458
private AnsiResponseParserState _state = AnsiResponseParserState.Normal;
5559

5660
/// <inheritdoc/>
@@ -64,8 +68,6 @@ protected set
6468
}
6569
}
6670

67-
protected readonly IHeld _heldContent;
68-
6971
/// <summary>
7072
/// When <see cref="State"/> was last changed.
7173
/// </summary>
@@ -74,17 +76,17 @@ protected set
7476
// These all are valid terminators on ansi responses,
7577
// see CSI in https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s
7678
// No - N or O
77-
protected readonly HashSet<char> _knownTerminators = new (
78-
[
79-
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
80-
81-
// No - N or O
82-
'P', 'Q', 'R', 'S', 'T', 'W', 'X', 'Z',
83-
'^', '`', '~',
84-
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
85-
'l', 'm', 'n',
86-
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
87-
]);
79+
protected readonly HashSet<char> _knownTerminators =
80+
[
81+
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
82+
83+
// No - N or O
84+
'P', 'Q', 'R', 'S', 'T', 'W', 'X', 'Z',
85+
'^', '`', '~',
86+
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
87+
'l', 'm', 'n',
88+
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
89+
];
8890

8991
protected AnsiResponseParserBase (IHeld heldContent) { _heldContent = heldContent; }
9092

@@ -137,7 +139,7 @@ int inputLength
137139
char currentChar = getCharAtIndex (index);
138140
object currentObj = getObjectAtIndex (index);
139141

140-
bool isEscape = currentChar == Escape;
142+
bool isEscape = currentChar == ESCAPE;
141143

142144
switch (State)
143145
{
@@ -233,7 +235,7 @@ protected void TryLastMinuteSequences ()
233235
{
234236
lock (_lockState)
235237
{
236-
string cur = _heldContent.HeldToString ();
238+
string? cur = _heldContent.HeldToString ();
237239

238240
if (HandleKeyboard)
239241
{
@@ -250,7 +252,7 @@ protected void TryLastMinuteSequences ()
250252

251253
// We have something totally unexpected, not a CSI and
252254
// still Esc+<something>. So give last minute swallow chance
253-
if (cur.Length >= 2 && cur [0] == Escape)
255+
if (cur!.Length >= 2 && cur [0] == ESCAPE)
254256
{
255257
// Maybe swallow anyway if user has custom delegate
256258
bool swallow = ShouldSwallowUnexpectedResponse ();
@@ -270,7 +272,7 @@ protected bool ShouldReleaseHeldContent ()
270272
{
271273
lock (_lockState)
272274
{
273-
string cur = _heldContent.HeldToString ();
275+
string? cur = _heldContent.HeldToString ();
274276

275277
if (HandleMouse && IsMouse (cur))
276278
{
@@ -328,7 +330,7 @@ protected bool ShouldReleaseHeldContent ()
328330

329331
// Finally if it is a valid ansi response but not one we are expect (e.g. its mouse activity)
330332
// then we can release it back to input processing stream
331-
if (_knownTerminators.Contains (cur.Last ()) && cur.StartsWith (EscSeqUtils.CSI))
333+
if (_knownTerminators.Contains (cur!.Last ()) && cur!.StartsWith (EscSeqUtils.CSI))
332334
{
333335
// We have found a terminator so bail
334336
State = AnsiResponseParserState.Normal;
@@ -354,7 +356,7 @@ protected bool ShouldReleaseHeldContent ()
354356
return false; // Continue accumulating
355357
}
356358

357-
private void RaiseMouseEvent (string cur)
359+
private void RaiseMouseEvent (string? cur)
358360
{
359361
MouseEventArgs? ev = _mouseParser.ProcessMouseInput (cur);
360362

@@ -364,9 +366,9 @@ private void RaiseMouseEvent (string cur)
364366
}
365367
}
366368

367-
private bool IsMouse (string cur) { return _mouseParser.IsMouse (cur); }
369+
private bool IsMouse (string? cur) { return _mouseParser.IsMouse (cur); }
368370

369-
protected void RaiseKeyboardEvent (AnsiKeyboardParserPattern pattern, string cur)
371+
protected void RaiseKeyboardEvent (AnsiKeyboardParserPattern pattern, string? cur)
370372
{
371373
Key? k = pattern.GetKey (cur);
372374

@@ -394,7 +396,7 @@ protected void RaiseKeyboardEvent (AnsiKeyboardParserPattern pattern, string cur
394396
/// <returns></returns>
395397
protected abstract bool ShouldSwallowUnexpectedResponse ();
396398

397-
private bool MatchResponse (string cur, List<AnsiResponseExpectation> collection, bool invokeCallback, bool removeExpectation)
399+
private bool MatchResponse (string? cur, List<AnsiResponseExpectation> collection, bool invokeCallback, bool removeExpectation)
398400
{
399401
// Check for expected responses
400402
AnsiResponseExpectation? matchingResponse = collection.FirstOrDefault (r => r.Matches (cur));
@@ -422,7 +424,7 @@ private bool MatchResponse (string cur, List<AnsiResponseExpectation> collection
422424
}
423425

424426
/// <inheritdoc/>
425-
public void ExpectResponse (string terminator, Action<string> response, Action? abandoned, bool persistent)
427+
public void ExpectResponse (string? terminator, Action<string?> response, Action? abandoned, bool persistent)
426428
{
427429
lock (_lockExpectedResponses)
428430
{
@@ -438,17 +440,17 @@ public void ExpectResponse (string terminator, Action<string> response, Action?
438440
}
439441

440442
/// <inheritdoc/>
441-
public bool IsExpecting (string terminator)
443+
public bool IsExpecting (string? terminator)
442444
{
443445
lock (_lockExpectedResponses)
444446
{
445447
// If any of the new terminator matches any existing terminators characters it's a collision so true.
446-
return _expectedResponses.Any (r => r.Terminator.Intersect (terminator).Any ());
448+
return _expectedResponses.Any (r => r.Terminator!.Intersect (terminator!).Any ());
447449
}
448450
}
449451

450452
/// <inheritdoc/>
451-
public void StopExpecting (string terminator, bool persistent)
453+
public void StopExpecting (string? terminator, bool persistent)
452454
{
453455
lock (_lockExpectedResponses)
454456
{
@@ -530,7 +532,7 @@ public Tuple<char, T> [] Release ()
530532
/// <param name="response"></param>
531533
/// <param name="abandoned"></param>
532534
/// <param name="persistent"></param>
533-
public void ExpectResponseT (string terminator, Action<IEnumerable<Tuple<char, T>>> response, Action? abandoned, bool persistent)
535+
public void ExpectResponseT (string? terminator, Action<IEnumerable<Tuple<char, T>>> response, Action? abandoned, bool persistent)
534536
{
535537
lock (_lockExpectedResponses)
536538
{
@@ -562,7 +564,7 @@ internal class AnsiResponseParser () : AnsiResponseParserBase (new StringHeld ()
562564
/// keystrokes 'swallowed' (i.e. not returned to input stream).
563565
/// </para>
564566
/// </summary>
565-
public Func<string, bool> UnknownResponseHandler { get; set; } = _ => false;
567+
public Func<string?, bool> UnknownResponseHandler { get; set; } = _ => false;
566568

567569
public string ProcessInput (string input)
568570
{
@@ -583,13 +585,13 @@ private void AppendOutput (StringBuilder output, char c)
583585
output.Append (c);
584586
}
585587

586-
public string Release ()
588+
public string? Release ()
587589
{
588590
lock (_lockState)
589591
{
590592
TryLastMinuteSequences ();
591593

592-
string output = _heldContent.HeldToString ();
594+
string? output = _heldContent.HeldToString ();
593595
ResetState ();
594596

595597
return output;

Terminal.Gui/ConsoleDrivers/AnsiResponseParser/GenericHeld.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ internal class GenericHeld<T> : IHeld
1111

1212
public void ClearHeld () { held.Clear (); }
1313

14-
public string HeldToString () { return new (held.Select (h => h.Item1).ToArray ()); }
14+
public string? HeldToString () { return new (held.Select (h => h.Item1).ToArray ()); }
1515

1616
public IEnumerable<object> HeldToObjects () { return held; }
1717

0 commit comments

Comments
 (0)