Skip to content

Commit b5a4505

Browse files
committed
Added word completion, exit on escape, home/end
1 parent 436a9f1 commit b5a4505

File tree

2 files changed

+100
-4
lines changed

2 files changed

+100
-4
lines changed

InteractivePrompt/InteractivePrompt.cs

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Text;
5+
using System.Text.RegularExpressions;
56
using System.Threading.Tasks;
67

78
namespace Cintio
@@ -20,24 +21,34 @@ private static void RewriteLine(List<char> input, int inputPosition)
2021
Console.Write(String.Concat(input));
2122
Console.SetCursorPosition(inputPosition + _prompt.Length, Console.CursorTop);
2223
}
24+
private static IEnumerable<string> GetMatch(List<string> s, string input)
25+
{
26+
s.Add(input);
27+
for (int i = 0; i < s.Count; i = (i+1)%s.Count)
28+
if (Regex.IsMatch(s[i], ".*(?:" + input + ").*", RegexOptions.IgnoreCase))
29+
yield return s[i];
30+
}
2331
/// <summary>
2432
/// Run will start an interactive prompt
2533
/// </summary>
2634
/// <param name="lambda">This func is provided for the user to handle the input. Input is provided in both string and List&lt;char&gt;. A return response is provided as a string.</param>
2735
/// <param name="prompt">The prompt for the interactive shell</param>
2836
/// <param name="startupMsg">Startup msg to display to user</param>
29-
public static void Run(Func<string, List<char>, string> lambda, string prompt, string startupMsg)
37+
public static void Run(Func<string, List<char>, string> lambda, string prompt, string startupMsg, List<string> completionList = null)
3038
{
3139
_prompt = prompt;
3240
Console.WriteLine(startupMsg);
3341
List<List<char>> inputHistory = new List<List<char>>();
42+
IEnumerator<string> wordIterator = null;
43+
3444
while (true)
3545
{
46+
string completion = null;
3647
List<char> input = new List<char>();
3748
int inputPosition = 0;
3849
int inputHistoryPosition = inputHistory.Count;
3950

40-
ConsoleKeyInfo key;
51+
ConsoleKeyInfo key, lastKey = new ConsoleKeyInfo();
4152
Console.Write(prompt);
4253
do
4354
{
@@ -58,6 +69,81 @@ public static void Run(Func<string, List<char>, string> lambda, string prompt, s
5869
Console.SetCursorPosition(Console.CursorLeft + 1, Console.CursorTop);
5970
}
6071
}
72+
73+
else if (key.Key == ConsoleKey.Tab && completionList != null && completionList.Count > 0)
74+
{
75+
int tempPosition = inputPosition;
76+
List<char> word = new List<char>();
77+
while (tempPosition-- > 0 && !string.IsNullOrWhiteSpace(input[tempPosition].ToString()))
78+
word.Insert(0, input[tempPosition]);
79+
80+
if (lastKey.Key == ConsoleKey.Tab)
81+
{
82+
wordIterator.MoveNext();
83+
if (completion != null)
84+
{
85+
ClearLine(input);
86+
for (var i = 0; i < completion.Length; i++)
87+
{
88+
input.RemoveAt(--inputPosition);
89+
}
90+
RewriteLine(input, inputPosition);
91+
}
92+
else
93+
{
94+
ClearLine(input);
95+
for (var i = 0; i < string.Concat(word).Length; i++)
96+
{
97+
input.RemoveAt(--inputPosition);
98+
}
99+
RewriteLine(input, inputPosition);
100+
}
101+
}
102+
else
103+
{
104+
ClearLine(input);
105+
for (var i = 0; i < string.Concat(word).Length; i++)
106+
{
107+
input.RemoveAt(--inputPosition);
108+
}
109+
RewriteLine(input, inputPosition);
110+
wordIterator = GetMatch(completionList, string.Concat(word)).GetEnumerator();
111+
while (wordIterator.Current == null)
112+
wordIterator.MoveNext();
113+
}
114+
115+
completion = wordIterator.Current;
116+
ClearLine(input);
117+
foreach (var c in completion.ToCharArray())
118+
{
119+
input.Insert(inputPosition++, c);
120+
}
121+
RewriteLine(input, inputPosition);
122+
123+
}
124+
else if (key.Key == ConsoleKey.Home || (key.Key == ConsoleKey.H && key.Modifiers == ConsoleModifiers.Control))
125+
{
126+
Console.WriteLine("crap");
127+
inputPosition = 0;
128+
Console.SetCursorPosition(prompt.Length, Console.CursorTop);
129+
}
130+
131+
else if (key.Key == ConsoleKey.End || (key.Key == ConsoleKey.E && key.Modifiers == ConsoleModifiers.Control))
132+
{
133+
inputPosition = input.Count;
134+
Console.SetCursorPosition(inputPosition + _prompt.Length, Console.CursorTop);
135+
}
136+
137+
else if (key.Key == ConsoleKey.Delete)
138+
{
139+
if (inputPosition < input.Count)
140+
{
141+
input.RemoveAt(inputPosition);
142+
ClearLine(input);
143+
RewriteLine(input, inputPosition);
144+
}
145+
}
146+
61147
else if (key.Key == ConsoleKey.UpArrow)
62148
{
63149
if (inputHistoryPosition > 0)
@@ -103,12 +189,22 @@ public static void Run(Func<string, List<char>, string> lambda, string prompt, s
103189
}
104190
}
105191

192+
else if (key.Key == ConsoleKey.Escape)
193+
{
194+
if (lastKey.Key == ConsoleKey.Escape)
195+
Environment.Exit(0);
196+
else
197+
Console.WriteLine("Press Escape again to exit.");
198+
}
199+
106200
else if (key.Key != ConsoleKey.Enter)
107201
{
108202
input.Insert(inputPosition++, key.KeyChar);
109203
RewriteLine(input, inputPosition);
110204
}
111205

206+
207+
lastKey = key;
112208
} while (key.Key != ConsoleKey.Enter);
113209

114210
Console.WriteLine();

InteractivePrompt/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("1.0.2.0")]
36-
[assembly: AssemblyFileVersion("1.0.2.0")]
35+
[assembly: AssemblyVersion("1.0.3.0")]
36+
[assembly: AssemblyFileVersion("1.0.3.0")]

0 commit comments

Comments
 (0)