Skip to content

Commit

Permalink
Added word completion, exit on escape, home/end
Browse files Browse the repository at this point in the history
  • Loading branch information
sorrell committed Mar 17, 2017
1 parent 436a9f1 commit b5a4505
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 4 deletions.
100 changes: 98 additions & 2 deletions InteractivePrompt/InteractivePrompt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Cintio
Expand All @@ -20,24 +21,34 @@ private static void RewriteLine(List<char> input, int inputPosition)
Console.Write(String.Concat(input));
Console.SetCursorPosition(inputPosition + _prompt.Length, Console.CursorTop);
}
private static IEnumerable<string> GetMatch(List<string> s, string input)
{
s.Add(input);
for (int i = 0; i < s.Count; i = (i+1)%s.Count)
if (Regex.IsMatch(s[i], ".*(?:" + input + ").*", RegexOptions.IgnoreCase))
yield return s[i];
}
/// <summary>
/// Run will start an interactive prompt
/// </summary>
/// <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>
/// <param name="prompt">The prompt for the interactive shell</param>
/// <param name="startupMsg">Startup msg to display to user</param>
public static void Run(Func<string, List<char>, string> lambda, string prompt, string startupMsg)
public static void Run(Func<string, List<char>, string> lambda, string prompt, string startupMsg, List<string> completionList = null)
{
_prompt = prompt;
Console.WriteLine(startupMsg);
List<List<char>> inputHistory = new List<List<char>>();
IEnumerator<string> wordIterator = null;

while (true)
{
string completion = null;
List<char> input = new List<char>();
int inputPosition = 0;
int inputHistoryPosition = inputHistory.Count;

ConsoleKeyInfo key;
ConsoleKeyInfo key, lastKey = new ConsoleKeyInfo();
Console.Write(prompt);
do
{
Expand All @@ -58,6 +69,81 @@ public static void Run(Func<string, List<char>, string> lambda, string prompt, s
Console.SetCursorPosition(Console.CursorLeft + 1, Console.CursorTop);
}
}

else if (key.Key == ConsoleKey.Tab && completionList != null && completionList.Count > 0)
{
int tempPosition = inputPosition;
List<char> word = new List<char>();
while (tempPosition-- > 0 && !string.IsNullOrWhiteSpace(input[tempPosition].ToString()))
word.Insert(0, input[tempPosition]);

if (lastKey.Key == ConsoleKey.Tab)
{
wordIterator.MoveNext();
if (completion != null)
{
ClearLine(input);
for (var i = 0; i < completion.Length; i++)
{
input.RemoveAt(--inputPosition);
}
RewriteLine(input, inputPosition);
}
else
{
ClearLine(input);
for (var i = 0; i < string.Concat(word).Length; i++)
{
input.RemoveAt(--inputPosition);
}
RewriteLine(input, inputPosition);
}
}
else
{
ClearLine(input);
for (var i = 0; i < string.Concat(word).Length; i++)
{
input.RemoveAt(--inputPosition);
}
RewriteLine(input, inputPosition);
wordIterator = GetMatch(completionList, string.Concat(word)).GetEnumerator();
while (wordIterator.Current == null)
wordIterator.MoveNext();
}

completion = wordIterator.Current;
ClearLine(input);
foreach (var c in completion.ToCharArray())
{
input.Insert(inputPosition++, c);
}
RewriteLine(input, inputPosition);

}
else if (key.Key == ConsoleKey.Home || (key.Key == ConsoleKey.H && key.Modifiers == ConsoleModifiers.Control))
{
Console.WriteLine("crap");
inputPosition = 0;
Console.SetCursorPosition(prompt.Length, Console.CursorTop);
}

else if (key.Key == ConsoleKey.End || (key.Key == ConsoleKey.E && key.Modifiers == ConsoleModifiers.Control))
{
inputPosition = input.Count;
Console.SetCursorPosition(inputPosition + _prompt.Length, Console.CursorTop);
}

else if (key.Key == ConsoleKey.Delete)
{
if (inputPosition < input.Count)
{
input.RemoveAt(inputPosition);
ClearLine(input);
RewriteLine(input, inputPosition);
}
}

else if (key.Key == ConsoleKey.UpArrow)
{
if (inputHistoryPosition > 0)
Expand Down Expand Up @@ -103,12 +189,22 @@ public static void Run(Func<string, List<char>, string> lambda, string prompt, s
}
}

else if (key.Key == ConsoleKey.Escape)
{
if (lastKey.Key == ConsoleKey.Escape)
Environment.Exit(0);
else
Console.WriteLine("Press Escape again to exit.");
}

else if (key.Key != ConsoleKey.Enter)
{
input.Insert(inputPosition++, key.KeyChar);
RewriteLine(input, inputPosition);
}


lastKey = key;
} while (key.Key != ConsoleKey.Enter);

Console.WriteLine();
Expand Down
4 changes: 2 additions & 2 deletions InteractivePrompt/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.2.0")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyVersion("1.0.3.0")]
[assembly: AssemblyFileVersion("1.0.3.0")]

0 comments on commit b5a4505

Please sign in to comment.