2
2
using System . Collections . Generic ;
3
3
using System . Linq ;
4
4
using System . Text ;
5
+ using System . Text . RegularExpressions ;
5
6
using System . Threading . Tasks ;
6
7
7
8
namespace Cintio
@@ -20,24 +21,34 @@ private static void RewriteLine(List<char> input, int inputPosition)
20
21
Console . Write ( String . Concat ( input ) ) ;
21
22
Console . SetCursorPosition ( inputPosition + _prompt . Length , Console . CursorTop ) ;
22
23
}
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
+ }
23
31
/// <summary>
24
32
/// Run will start an interactive prompt
25
33
/// </summary>
26
34
/// <param name="lambda">This func is provided for the user to handle the input. Input is provided in both string and List<char>. A return response is provided as a string.</param>
27
35
/// <param name="prompt">The prompt for the interactive shell</param>
28
36
/// <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 )
30
38
{
31
39
_prompt = prompt ;
32
40
Console . WriteLine ( startupMsg ) ;
33
41
List < List < char > > inputHistory = new List < List < char > > ( ) ;
42
+ IEnumerator < string > wordIterator = null ;
43
+
34
44
while ( true )
35
45
{
46
+ string completion = null ;
36
47
List < char > input = new List < char > ( ) ;
37
48
int inputPosition = 0 ;
38
49
int inputHistoryPosition = inputHistory . Count ;
39
50
40
- ConsoleKeyInfo key ;
51
+ ConsoleKeyInfo key , lastKey = new ConsoleKeyInfo ( ) ;
41
52
Console . Write ( prompt ) ;
42
53
do
43
54
{
@@ -58,6 +69,81 @@ public static void Run(Func<string, List<char>, string> lambda, string prompt, s
58
69
Console . SetCursorPosition ( Console . CursorLeft + 1 , Console . CursorTop ) ;
59
70
}
60
71
}
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
+
61
147
else if ( key . Key == ConsoleKey . UpArrow )
62
148
{
63
149
if ( inputHistoryPosition > 0 )
@@ -103,12 +189,22 @@ public static void Run(Func<string, List<char>, string> lambda, string prompt, s
103
189
}
104
190
}
105
191
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
+
106
200
else if ( key . Key != ConsoleKey . Enter )
107
201
{
108
202
input . Insert ( inputPosition ++ , key . KeyChar ) ;
109
203
RewriteLine ( input , inputPosition ) ;
110
204
}
111
205
206
+
207
+ lastKey = key ;
112
208
} while ( key . Key != ConsoleKey . Enter ) ;
113
209
114
210
Console . WriteLine ( ) ;
0 commit comments