Skip to content

Commit b1079e8

Browse files
committed
Merge branch 'v2_develop' of tig:tig/Terminal.Gui into v2_develop
2 parents 61462ff + 1919abe commit b1079e8

Some content is hidden

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

57 files changed

+5858
-4127
lines changed

.gitattributes

+9-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
# Set the default behavior for all files.
1+
# Set default behavior to automatically normalize line endings.
22
* text=auto
33

4-
# Normalized and converts to
5-
# native line endings on checkout.
6-
*.cs text
7-
8-
# Convert to LF line endings on checkout.
4+
# Explicitly declare text files you want to always be normalized and converted to native line endings on checkout.
5+
*.cs text eol=lf
6+
*.txt text eol=lf
7+
*.md text eol=lf
98
*.sh text eol=lf
9+
*.ps1 text eol=lf
1010

11-
# Binary files.
11+
# Denote all files that are truly binary and should not be modified.
1212
*.png binary
13-
*.jpg binary
13+
*.jpg binary
14+
*.gif binary
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System.Text;
2+
using BenchmarkDotNet.Attributes;
3+
using Tui = Terminal.Gui;
4+
5+
namespace Terminal.Gui.Benchmarks.ConsoleDrivers.EscSeqUtils;
6+
7+
/// <summary>
8+
/// Compares the Set and Append implementations in combination.
9+
/// </summary>
10+
/// <remarks>
11+
/// A bit misleading because *CursorPosition is called very seldom compared to the other operations
12+
/// but they are very similar in performance because they do very similar things.
13+
/// </remarks>
14+
[MemoryDiagnoser]
15+
[BenchmarkCategory (nameof (Tui.EscSeqUtils))]
16+
// Hide useless empty column from results.
17+
[HideColumns ("stringBuilder")]
18+
public class CSI_SetVsAppend
19+
{
20+
[Benchmark (Baseline = true)]
21+
[ArgumentsSource (nameof (StringBuilderSource))]
22+
public StringBuilder Set (StringBuilder stringBuilder)
23+
{
24+
stringBuilder.Append (Tui.EscSeqUtils.CSI_SetBackgroundColorRGB (1, 2, 3));
25+
stringBuilder.Append (Tui.EscSeqUtils.CSI_SetForegroundColorRGB (3, 2, 1));
26+
stringBuilder.Append (Tui.EscSeqUtils.CSI_SetCursorPosition (4, 2));
27+
// Clear to prevent out of memory exception from consecutive iterations.
28+
stringBuilder.Clear ();
29+
return stringBuilder;
30+
}
31+
32+
[Benchmark]
33+
[ArgumentsSource (nameof (StringBuilderSource))]
34+
public StringBuilder Append (StringBuilder stringBuilder)
35+
{
36+
Tui.EscSeqUtils.CSI_AppendBackgroundColorRGB (stringBuilder, 1, 2, 3);
37+
Tui.EscSeqUtils.CSI_AppendForegroundColorRGB (stringBuilder, 3, 2, 1);
38+
Tui.EscSeqUtils.CSI_AppendCursorPosition (stringBuilder, 4, 2);
39+
// Clear to prevent out of memory exception from consecutive iterations.
40+
stringBuilder.Clear ();
41+
return stringBuilder;
42+
}
43+
44+
public static IEnumerable<object> StringBuilderSource ()
45+
{
46+
return [new StringBuilder ()];
47+
}
48+
}

Terminal.Gui/Application/Application.Run.cs

+5
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,11 @@ public static void Run (Toplevel view, Func<Exception, bool>? errorHandler = nul
411411
/// </summary>
412412
/// <param name="forceDraw">If <see langword="true"/> the entire View hierarchy will be redrawn. The default is <see langword="false"/> and should only be overriden for testing.</param>
413413
public static void LayoutAndDraw (bool forceDraw = false)
414+
{
415+
ApplicationImpl.Instance.LayoutAndDraw (forceDraw);
416+
}
417+
418+
internal static void LayoutAndDrawImpl (bool forceDraw = false)
414419
{
415420
bool neededLayout = View.Layout (TopLevels.Reverse (), Screen.Size);
416421

Terminal.Gui/Application/ApplicationImpl.cs

+6
Original file line numberDiff line numberDiff line change
@@ -294,4 +294,10 @@ public virtual bool RemoveTimeout (object token)
294294
{
295295
return Application.MainLoop?.TimedEvents.RemoveTimeout (token) ?? false;
296296
}
297+
298+
/// <inheritdoc />
299+
public virtual void LayoutAndDraw (bool forceDraw)
300+
{
301+
Application.LayoutAndDrawImpl (forceDraw);
302+
}
297303
}

Terminal.Gui/Application/IApplication.cs

+7
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,11 @@ public T Run<T> (Func<Exception, bool>? errorHandler = null, IConsoleDriver? dri
182182
/// <see langword="false"/>
183183
/// if the timeout is not found.</returns>
184184
bool RemoveTimeout (object token);
185+
186+
/// <summary>
187+
/// Causes any Toplevels that need layout to be laid out. Then draws any Toplevels that need display. Only Views that need to be laid out (see <see cref="View.NeedsLayout"/>) will be laid out.
188+
/// Only Views that need to be drawn (see <see cref="View.NeedsDraw"/>) will be drawn.
189+
/// </summary>
190+
/// <param name="forceDraw">If <see langword="true"/> the entire View hierarchy will be redrawn. The default is <see langword="false"/> and should only be overriden for testing.</param>
191+
void LayoutAndDraw (bool forceDraw);
185192
}

Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs

+101-70
Original file line numberDiff line numberDiff line change
@@ -411,25 +411,25 @@ public static string GetC1ControlChar (in char c)
411411
{
412412
// These control characters are used in the vtXXX emulation.
413413
return c switch
414-
{
415-
'D' => "IND", // Index
416-
'E' => "NEL", // Next Line
417-
'H' => "HTS", // Tab Set
418-
'M' => "RI", // Reverse Index
419-
'N' => "SS2", // Single Shift Select of G2 Character Set: affects next character only
420-
'O' => "SS3", // Single Shift Select of G3 Character Set: affects next character only
421-
'P' => "DCS", // Device Control String
422-
'V' => "SPA", // Start of Guarded Area
423-
'W' => "EPA", // End of Guarded Area
424-
'X' => "SOS", // Start of String
425-
'Z' => "DECID", // Return Terminal ID Obsolete form of CSI c (DA)
426-
'[' => "CSI", // Control Sequence Introducer
427-
'\\' => "ST", // String Terminator
428-
']' => "OSC", // Operating System Command
429-
'^' => "PM", // Privacy Message
430-
'_' => "APC", // Application Program Command
431-
_ => string.Empty
432-
};
414+
{
415+
'D' => "IND", // Index
416+
'E' => "NEL", // Next Line
417+
'H' => "HTS", // Tab Set
418+
'M' => "RI", // Reverse Index
419+
'N' => "SS2", // Single Shift Select of G2 Character Set: affects next character only
420+
'O' => "SS3", // Single Shift Select of G3 Character Set: affects next character only
421+
'P' => "DCS", // Device Control String
422+
'V' => "SPA", // Start of Guarded Area
423+
'W' => "EPA", // End of Guarded Area
424+
'X' => "SOS", // Start of String
425+
'Z' => "DECID", // Return Terminal ID Obsolete form of CSI c (DA)
426+
'[' => "CSI", // Control Sequence Introducer
427+
'\\' => "ST", // String Terminator
428+
']' => "OSC", // Operating System Command
429+
'^' => "PM", // Privacy Message
430+
'_' => "APC", // Application Program Command
431+
_ => string.Empty
432+
};
433433
}
434434

435435

@@ -462,46 +462,46 @@ public static ConsoleKey GetConsoleKey (char terminator, string? value, ref Cons
462462
}
463463

464464
return (terminator, value) switch
465-
{
466-
('A', _) => ConsoleKey.UpArrow,
467-
('B', _) => ConsoleKey.DownArrow,
468-
('C', _) => ConsoleKey.RightArrow,
469-
('D', _) => ConsoleKey.LeftArrow,
470-
('E', _) => ConsoleKey.Clear,
471-
('F', _) => ConsoleKey.End,
472-
('H', _) => ConsoleKey.Home,
473-
('P', _) => ConsoleKey.F1,
474-
('Q', _) => ConsoleKey.F2,
475-
('R', _) => ConsoleKey.F3,
476-
('S', _) => ConsoleKey.F4,
477-
('Z', _) => ConsoleKey.Tab,
478-
('~', "2") => ConsoleKey.Insert,
479-
('~', "3") => ConsoleKey.Delete,
480-
('~', "5") => ConsoleKey.PageUp,
481-
('~', "6") => ConsoleKey.PageDown,
482-
('~', "15") => ConsoleKey.F5,
483-
('~', "17") => ConsoleKey.F6,
484-
('~', "18") => ConsoleKey.F7,
485-
('~', "19") => ConsoleKey.F8,
486-
('~', "20") => ConsoleKey.F9,
487-
('~', "21") => ConsoleKey.F10,
488-
('~', "23") => ConsoleKey.F11,
489-
('~', "24") => ConsoleKey.F12,
490-
// These terminators are used by macOS on a numeric keypad without keys modifiers
491-
('l', null) => ConsoleKey.Add,
492-
('m', null) => ConsoleKey.Subtract,
493-
('p', null) => ConsoleKey.Insert,
494-
('q', null) => ConsoleKey.End,
495-
('r', null) => ConsoleKey.DownArrow,
496-
('s', null) => ConsoleKey.PageDown,
497-
('t', null) => ConsoleKey.LeftArrow,
498-
('u', null) => ConsoleKey.Clear,
499-
('v', null) => ConsoleKey.RightArrow,
500-
('w', null) => ConsoleKey.Home,
501-
('x', null) => ConsoleKey.UpArrow,
502-
('y', null) => ConsoleKey.PageUp,
503-
(_, _) => 0
504-
};
465+
{
466+
('A', _) => ConsoleKey.UpArrow,
467+
('B', _) => ConsoleKey.DownArrow,
468+
('C', _) => ConsoleKey.RightArrow,
469+
('D', _) => ConsoleKey.LeftArrow,
470+
('E', _) => ConsoleKey.Clear,
471+
('F', _) => ConsoleKey.End,
472+
('H', _) => ConsoleKey.Home,
473+
('P', _) => ConsoleKey.F1,
474+
('Q', _) => ConsoleKey.F2,
475+
('R', _) => ConsoleKey.F3,
476+
('S', _) => ConsoleKey.F4,
477+
('Z', _) => ConsoleKey.Tab,
478+
('~', "2") => ConsoleKey.Insert,
479+
('~', "3") => ConsoleKey.Delete,
480+
('~', "5") => ConsoleKey.PageUp,
481+
('~', "6") => ConsoleKey.PageDown,
482+
('~', "15") => ConsoleKey.F5,
483+
('~', "17") => ConsoleKey.F6,
484+
('~', "18") => ConsoleKey.F7,
485+
('~', "19") => ConsoleKey.F8,
486+
('~', "20") => ConsoleKey.F9,
487+
('~', "21") => ConsoleKey.F10,
488+
('~', "23") => ConsoleKey.F11,
489+
('~', "24") => ConsoleKey.F12,
490+
// These terminators are used by macOS on a numeric keypad without keys modifiers
491+
('l', null) => ConsoleKey.Add,
492+
('m', null) => ConsoleKey.Subtract,
493+
('p', null) => ConsoleKey.Insert,
494+
('q', null) => ConsoleKey.End,
495+
('r', null) => ConsoleKey.DownArrow,
496+
('s', null) => ConsoleKey.PageDown,
497+
('t', null) => ConsoleKey.LeftArrow,
498+
('u', null) => ConsoleKey.Clear,
499+
('v', null) => ConsoleKey.RightArrow,
500+
('w', null) => ConsoleKey.Home,
501+
('x', null) => ConsoleKey.UpArrow,
502+
('y', null) => ConsoleKey.PageUp,
503+
(_, _) => 0
504+
};
505505
}
506506

507507
/// <summary>
@@ -512,18 +512,18 @@ public static ConsoleKey GetConsoleKey (char terminator, string? value, ref Cons
512512
public static ConsoleModifiers GetConsoleModifiers (string? value)
513513
{
514514
return value switch
515-
{
516-
"2" => ConsoleModifiers.Shift,
517-
"3" => ConsoleModifiers.Alt,
518-
"4" => ConsoleModifiers.Shift | ConsoleModifiers.Alt,
519-
"5" => ConsoleModifiers.Control,
520-
"6" => ConsoleModifiers.Shift | ConsoleModifiers.Control,
521-
"7" => ConsoleModifiers.Alt | ConsoleModifiers.Control,
522-
"8" => ConsoleModifiers.Shift | ConsoleModifiers.Alt | ConsoleModifiers.Control,
523-
_ => 0
524-
};
515+
{
516+
"2" => ConsoleModifiers.Shift,
517+
"3" => ConsoleModifiers.Alt,
518+
"4" => ConsoleModifiers.Shift | ConsoleModifiers.Alt,
519+
"5" => ConsoleModifiers.Control,
520+
"6" => ConsoleModifiers.Shift | ConsoleModifiers.Control,
521+
"7" => ConsoleModifiers.Alt | ConsoleModifiers.Control,
522+
"8" => ConsoleModifiers.Shift | ConsoleModifiers.Alt | ConsoleModifiers.Control,
523+
_ => 0
524+
};
525525
}
526-
#nullable restore
526+
#nullable restore
527527

528528
/// <summary>
529529
/// Gets all the needed information about an escape sequence.
@@ -1675,6 +1675,19 @@ public static ConsoleKeyInfo [] ToConsoleKeyInfoArray (string ansi)
16751675
/// <returns></returns>
16761676
public static string CSI_SetCursorPosition (int row, int col) { return $"{CSI}{row};{col}H"; }
16771677

1678+
/// <summary>
1679+
/// ESC [ y ; x H - CUP Cursor Position - Cursor moves to x ; y coordinate within the viewport, where x is the column
1680+
/// of the y line
1681+
/// </summary>
1682+
/// <param name="builder">StringBuilder where to append the cursor position sequence.</param>
1683+
/// <param name="row">Origin is (1,1).</param>
1684+
/// <param name="col">Origin is (1,1).</param>
1685+
public static void CSI_AppendCursorPosition (StringBuilder builder, int row, int col)
1686+
{
1687+
// InterpolatedStringHandler is composed in stack, skipping the string allocation.
1688+
builder.Append ($"{CSI}{row};{col}H");
1689+
}
1690+
16781691
//ESC [ <y> ; <x> f - HVP Horizontal Vertical Position* Cursor moves to<x>; <y> coordinate within the viewport, where <x> is the column of the<y> line
16791692
//ESC [ s - ANSISYSSC Save Cursor – Ansi.sys emulation **With no parameters, performs a save cursor operation like DECSC
16801693
//ESC [ u - ANSISYSRC Restore Cursor – Ansi.sys emulation **With no parameters, performs a restore cursor operation like DECRC
@@ -1785,11 +1798,29 @@ public enum DECSCUSR_Style
17851798
/// </summary>
17861799
public static string CSI_SetForegroundColorRGB (int r, int g, int b) { return $"{CSI}38;2;{r};{g};{b}m"; }
17871800

1801+
/// <summary>
1802+
/// ESC[38;2;{r};{g};{b}m Append foreground color as RGB to StringBuilder.
1803+
/// </summary>
1804+
public static void CSI_AppendForegroundColorRGB (StringBuilder builder, int r, int g, int b)
1805+
{
1806+
// InterpolatedStringHandler is composed in stack, skipping the string allocation.
1807+
builder.Append ($"{CSI}38;2;{r};{g};{b}m");
1808+
}
1809+
17881810
/// <summary>
17891811
/// ESC[48;2;{r};{g};{b}m Set background color as RGB.
17901812
/// </summary>
17911813
public static string CSI_SetBackgroundColorRGB (int r, int g, int b) { return $"{CSI}48;2;{r};{g};{b}m"; }
17921814

1815+
/// <summary>
1816+
/// ESC[48;2;{r};{g};{b}m Append background color as RGB to StringBuilder.
1817+
/// </summary>
1818+
public static void CSI_AppendBackgroundColorRGB (StringBuilder builder, int r, int g, int b)
1819+
{
1820+
// InterpolatedStringHandler is composed in stack, skipping the string allocation.
1821+
builder.Append ($"{CSI}48;2;{r};{g};{b}m");
1822+
}
1823+
17931824
#endregion
17941825

17951826
#region Requests

Terminal.Gui/ConsoleDrivers/V2/ApplicationV2.cs

+8
Original file line numberDiff line numberDiff line change
@@ -232,4 +232,12 @@ public override void Invoke (Action action)
232232

233233
/// <inheritdoc/>
234234
public override bool RemoveTimeout (object token) { return _timedEvents.RemoveTimeout (token); }
235+
236+
/// <inheritdoc />
237+
public override void LayoutAndDraw (bool forceDraw)
238+
{
239+
// No more ad-hoc drawing, you must wait for iteration to do it
240+
Application.Top?.SetNeedsDraw();
241+
Application.Top?.SetNeedsLayout ();
242+
}
235243
}

Terminal.Gui/ConsoleDrivers/V2/ConsoleDriverFacade.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -231,14 +231,14 @@ public virtual string GetVersionInfo ()
231231

232232
if (InputProcessor is WindowsInputProcessor)
233233
{
234-
type = "(win)";
234+
type = "win";
235235
}
236236
else if (InputProcessor is NetInputProcessor)
237237
{
238-
type = "(net)";
238+
type = "net";
239239
}
240240

241-
return GetType ().Name.TrimEnd ('`', '1') + type;
241+
return "v2" + type;
242242
}
243243

244244
/// <summary>Tests if the specified rune is supported by the driver.</summary>

Terminal.Gui/ConsoleDrivers/V2/Logging.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public static void Error (
6767
}
6868

6969
/// <summary>
70-
/// Logs a critical message including the class and method name.
70+
/// Logs a fatal/critical message including the class and method name.
7171
/// </summary>
7272
/// <param name="message"></param>
7373
/// <param name="caller"></param>
@@ -115,7 +115,7 @@ public static void Information (
115115
}
116116

117117
/// <summary>
118-
/// Logs a trace message including the class and method name.
118+
/// Logs a trace/verbose message including the class and method name.
119119
/// </summary>
120120
/// <param name="message"></param>
121121
/// <param name="caller"></param>

Terminal.Gui/ConsoleDrivers/V2/MainLoop.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,7 @@ internal void IterationImpl ()
130130
{
131131
Logging.Redraws.Add (1);
132132

133-
// TODO: Test only
134-
Application.LayoutAndDraw (true);
133+
Application.LayoutAndDrawImpl (true);
135134

136135
Out.Write (OutputBuffer);
137136

0 commit comments

Comments
 (0)