Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inclusion change suggestion via arrows #5

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
@@ -1,4 +1,5 @@
project.lock.json/
obj/
bin/
.vscode/
.vscode/
.vs/
210 changes: 158 additions & 52 deletions Hinter.cs
Expand Up @@ -5,56 +5,162 @@

namespace HinterLib
{
public class Hinter
{
public static string ReadHintedLine<T, TResult>(IEnumerable<T> hintSource, Func<T, TResult> hintField, string inputRegex = ".*", ConsoleColor hintColor = ConsoleColor.DarkGray)
{
ConsoleKeyInfo input;

var suggestion = string.Empty;
var userInput = string.Empty;
var readLine = string.Empty;

while (ConsoleKey.Enter != (input = Console.ReadKey()).Key)
{
if (input.Key == ConsoleKey.Backspace)
userInput = userInput.Any() ? userInput.Remove(userInput.Length - 1, 1) : string.Empty;

else if (input.Key == ConsoleKey.Tab)
userInput = suggestion ?? userInput;

else if (input != null && Regex.IsMatch(input.KeyChar.ToString(), inputRegex))
userInput += input.KeyChar;

suggestion = hintSource.Select(item => hintField(item).ToString())
.FirstOrDefault(item => item.Length > userInput.Length && item.Substring(0, userInput.Length) == userInput);

readLine = suggestion == null ? userInput : suggestion;

ClearCurrentConsoleLine();

Console.Write(userInput);

var originalColor = Console.ForegroundColor;

Console.ForegroundColor = hintColor;

if (userInput.Any()) Console.Write(readLine.Substring(userInput.Length, readLine.Length - userInput.Length));

Console.ForegroundColor = originalColor;
}

Console.WriteLine(readLine);

return userInput.Any() ? readLine : string.Empty;
}

private static void ClearCurrentConsoleLine()
{
int currentLineCursor = Console.CursorTop;
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, currentLineCursor);
}
}
public static class Hinter
{
public static string ReadHintedLine<T, TResult>(IEnumerable<T> hintSource, Func<T, TResult> hintField, string inputRegex = ".*", ConsoleColor hintColor = ConsoleColor.DarkGray)
{
ConsoleKeyInfo input;

var hint = new Hint();
var suggestion = string.Empty;
var userInput = string.Empty;
var readLine = string.Empty;

hint.makeListHints(hintSource, hintField, userInput);

while (ConsoleKey.Enter != (input = Console.ReadKey()).Key)
{
if (input.Key == ConsoleKey.Backspace)
userInput = _removeFinalChar(userInput);

else if (input.Key == ConsoleKey.Tab || input.Key == ConsoleKey.RightArrow)
userInput = suggestion ?? userInput;

else if (input != null && Regex.IsMatch(input.KeyChar.ToString(), inputRegex))
userInput += input.KeyChar;

if (input.Key == ConsoleKey.UpArrow)
{
userInput = _removeFinalChar(userInput);
suggestion = hint.nextHint;
}
else if (input.Key == ConsoleKey.DownArrow)
{
userInput = _removeFinalChar(userInput);
suggestion = hint.previousHint;
}
else if (input.Key == ConsoleKey.LeftArrow || input.Key == ConsoleKey.Escape)
{
userInput = _removeFinalChar(userInput);
suggestion = userInput;
}
else
{
if (userInput != "")
{
hint.makeListHints(hintSource, hintField, userInput);
suggestion = hint.currentHint;
}
else
suggestion = userInput;
}

readLine = suggestion == null ? userInput : suggestion;

ClearCurrentConsoleLine();

Console.Write(userInput);

var originalColor = Console.ForegroundColor;

Console.ForegroundColor = hintColor;

Console.Write(readLine.Substring(userInput.Length, readLine.Length - userInput.Length));

Console.ForegroundColor = originalColor;
}

Console.WriteLine(readLine);

return userInput.Any() ? readLine : string.Empty;

}

private static void ClearCurrentConsoleLine()
{
int cursorTop = Console.CursorTop;
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, cursorTop);
}

private static string _removeFinalChar(string userInput)
{
return (userInput.Length > 0) ? userInput.Substring(0, userInput.Length - 1) : userInput;
}
}

public class Hint
{
private List<string> _hintList;
private int _hintIndex;

public Hint()
{
_hintList = new List<string>();
_hintIndex = 0;
}
public bool makeListHints<T, TResult>(IEnumerable<T> hintSource, Func<T, TResult> hintField, string userInput)
{
try
{
_hintIndex = 0;
_hintList = Enumerable.Where(Enumerable.Select(hintSource, (T item) => hintField(item).ToString()), (string item) => item.Length > userInput.Length && item.Substring(0, userInput.Length) == userInput).ToList();
if (_hintList.Count() == 0)
_hintList.Add(null);
return true;
}
catch
{
return false;
}
}

public void resetCurrentHint()
{
_hintIndex = 0;
}

public string nextHint
{
get
{
_hintIndex = _calcNextHintIndex();
return _hintList[_hintIndex];
}
}

public string previousHint
{
get
{
_hintIndex = _calcPreviousHintIndex();
return _hintList[_hintIndex];
}
}

public string currentHint
{
get
{
return _hintList[_hintIndex];
}
}

private int _calcNextHintIndex()
{
if (_hintList.Count() > 1)
return (_hintIndex + 1) % _hintList.Count();
else
return 0;
}

private int _calcPreviousHintIndex()
{
if (_hintList.Count() > 1)
return (_hintIndex - 1) < 0 ? _hintList.Count() - 1 : _hintIndex - 1;
else
return 0;
}
}
}
4 changes: 2 additions & 2 deletions Hinter.csproj
Expand Up @@ -3,14 +3,14 @@
<PropertyGroup>
<Description>Adds hinting capabilities to console applications</Description>
<AssemblyTitle>hinter</AssemblyTitle>
<VersionPrefix>1.1.0</VersionPrefix>
<VersionPrefix>1.2.0</VersionPrefix>
<Authors>Fabio Junqueira</Authors>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<AssemblyName>hinter</AssemblyName>
<PackageId>hinter</PackageId>
<PackageTags>console;hinting;hint;autocomplete;completion</PackageTags>
<PackageProjectUrl>http://www.github.com/fjunqueira/hinter</PackageProjectUrl>
<PackageLicenseUrl>https://opensource.org/licenses/MIT</PackageLicenseUrl>
<NetStandardImplicitPackageVersion>1.6.0</NetStandardImplicitPackageVersion>
<NetStandardImplicitPackageVersion>1.7.0</NetStandardImplicitPackageVersion>
</PropertyGroup>
</Project>