-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReader.cs
163 lines (152 loc) · 6.45 KB
/
Reader.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
* File Name : Reader.cs
* From : https://github.com/tonerdo/readline/blob/master/src/ReadLine/ReadLine.cs
* Last Updated : Chen Jaofeng @ 2023/06/05
*/
using CJF.CommandLine.Abstractions;
using System.Runtime.Versioning;
namespace CJF.CommandLine;
#region Public Static Class : ReadLine
/// <summary>靜態類別 <see cref="Reader"/>。</summary>
[UnsupportedOSPlatform("browser")]
static class Reader
{
private static readonly Dictionary<string, List<string>> _HistoryPool;
private static bool _Stop = false;
#region Private Static Construct Method : ReadLine()
static Reader()
{
_HistoryPool = new Dictionary<string, List<string>>();
}
#endregion
/// <summary>是否啟用歷史紀錄。</summary>
public static bool HistoryEnabled { get; set; } = true;
/// <summary>取得或設定當前歷史紀錄清單的名稱。</summary>
internal static string PoolName { get; private set; } = "";
/// <summary>設定或取得密碼輸入時的顯示字元。</summary>
public static char? PasswordChar { get; set; }
/// <summary>新增歷史指令。</summary>
/// <param name="text">指令。</param>
public static void AddHistory(params string[] text) => _HistoryPool[PoolName].AddRange(text);
/// <summary>取得歷史指令清單。</summary>
public static IEnumerable<string> GetHistory() => _HistoryPool[PoolName];
/// <summary>清除當前歷史清單的紀錄。</summary>
public static void ClearHistory() => _HistoryPool[PoolName] = new List<string>();
/// <summary>取得或設定自動完成處理程序。</summary>
public static Func<string, int, string[]?>? AutoCompletionHandler { private get; set; } = null;
/// <summary>刪除最後一筆歷史紀錄。</summary>
public static void RemoveLastHistory() => _HistoryPool[PoolName].RemoveAt(_HistoryPool[PoolName].Count - 1);
#region Public Static Method : string Read(string prompt = "", ConsoleColor? promptColor = null, string @default = "")
/// <summary>讀取使用者輸入的文字。</summary>
/// <param name="prompt">提示文字。</param>
/// <param name="promptColor">提示文字的顏色。</param>
/// <param name="default">預設已輸入的文字。</param>
/// <returns>使用者輸入的文字。</returns>
public static string Read(string prompt = "", ConsoleColor? promptColor = null, string @default = "")
{
if (!string.IsNullOrWhiteSpace(prompt))
{
if (promptColor is not null)
{
ConsoleColor cc = Console.ForegroundColor;
Console.ForegroundColor = promptColor.Value;
Console.Write(prompt);
Console.ForegroundColor = cc;
}
else
Console.Write(prompt);
}
_HistoryPool.TryGetValue(PoolName, out List<string>? pool);
var keyHandler = new KeyHandler(new Console2(), pool, AutoCompletionHandler);
_Stop = false;
try
{
string text = GetText(keyHandler, @default);
if (text.EndsWith('\x1B'))
return Read(prompt, promptColor, text.TrimEnd('\x1B'));
else
{
if (!string.IsNullOrWhiteSpace(text) && HistoryEnabled && _HistoryPool.ContainsKey(PoolName))
{
var exists = _HistoryPool[PoolName].Exists(x => x == text);
// 2021/05/19 : 歷史紀錄為空、輸入的命令不在歷史紀錄內或者最後一筆紀錄不和輸入的命令相同
if (_HistoryPool[PoolName].Count == 0 || !exists || _HistoryPool[PoolName].Last() != text)
_HistoryPool[PoolName].Add(text);
}
}
return text;
}
catch (Exception ex)
{
Console.WriteLine($"\x1B[91m !!! \x1B[39m [{nameof(CliCenter)}] {ex.Message}");
return string.Empty;
}
}
#endregion
#region Publuc Static Method : string ReadPassword(string prompt = "", char? pwdChar = null)
/// <summary>讀取使用者輸入的密碼。</summary>
/// <param name="prompt">提示文字。</param>
/// <param name="pwdChar">顯示用的密碼字元。</param>
/// <returns>使用者輸入的密碼。</returns>
public static string ReadPassword(string prompt = "", char? pwdChar = null)
{
if (!string.IsNullOrWhiteSpace(prompt)) Console.Write(prompt);
if (!pwdChar.HasValue)
pwdChar = PasswordChar;
KeyHandler keyHandler = new(new Console2() { PasswordMode = true, PasswordChar = pwdChar }, null, null);
_Stop = false;
return GetText(keyHandler);
}
#endregion
#region Public Static Method : void ExitRead()
/// <summary>結束讀取。</summary>
public static void ExitRead()
{
_Stop = true;
}
#endregion
#region Internal Static Method : void SetPool(string poolName)
/// <summary>設定歷史紀錄清單的名稱。</summary>
internal static void SetPool(string poolName)
{
PoolName = poolName;
if (!_HistoryPool.ContainsKey(poolName))
_HistoryPool.Add(poolName, new List<string>());
}
#endregion
#region Private Method : string GetText(KeyHandler keyHandler, string @default = "")
/// <summary>取得使用者輸入的文字。</summary>
/// <param name="keyHandler">鍵盤處理程序。</param>
/// <param name="default">預設已輸入的文字。</param>
/// <returns>使用者輸入的文字。</returns>
private static string GetText(KeyHandler keyHandler, string @default = "")
{
if (!string.IsNullOrEmpty(@default))
{
foreach (char c in @default)
keyHandler.WriteChar(c);
}
ConsoleKeyInfo keyInfo = Console.ReadKey(true);
while (!_Stop && keyInfo.Key != ConsoleKey.Enter)
{
try
{
keyHandler.Handle(keyInfo);
if (keyInfo.KeyChar == '?') break;
else if (keyInfo.Key == ConsoleKey.Tab && keyHandler.IsMultiAutoCompleteResult())
return keyHandler.Text + '\x1B';
else
keyInfo = Console.ReadKey(true);
}
catch
{
keyInfo = Console.ReadKey(true);
}
}
Console.WriteLine();
Console.CursorVisible = true;
return keyHandler.Text;
}
#endregion
}
#endregion