From 86e81d0814c760b34659ec01865f4ca88ee4152b Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Mon, 25 Sep 2017 14:32:29 -0700 Subject: [PATCH 01/21] Updated to support .NET Core 2.0. Updated to support .NET Framework v4.7. Consolidated various redundant code statements and expressions. Repacked for multi-frameworks. Updated versioning. --- .gitignore | 202 +++++++++++++++++++++- ReadLine.1.2.1.nupkg | Bin 0 -> 23402 bytes appveyor.yml | 14 -- src/ReadLine/Abstractions/Console2.cs | 4 +- src/ReadLine/Abstractions/IConsole.cs | 2 +- src/ReadLine/KeyHandler.cs | 212 +++++++++++------------- src/ReadLine/Properties/AssemblyInfo.cs | 11 +- src/ReadLine/ReadLine.cs | 15 +- src/ReadLine/ReadLine.csproj | 8 +- src/ReadLine/snKey.snk | Bin 0 -> 596 bytes 10 files changed, 321 insertions(+), 147 deletions(-) create mode 100644 ReadLine.1.2.1.nupkg delete mode 100644 appveyor.yml create mode 100644 src/ReadLine/snKey.snk diff --git a/.gitignore b/.gitignore index c304b65..08b1161 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,201 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ [Bb]in/ [Oo]bj/ -.vscode -.DS_Store -*.user -project.lock.json + +# Visual Studo 2015 cache/options directory .vs/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding addin-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +*.[Cc]ache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# NuGet +NuGet/ + +# Git +.gitignore +.gitattributes diff --git a/ReadLine.1.2.1.nupkg b/ReadLine.1.2.1.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..539f03f8285a1042d6ca16fe72aa436ca8eadcce GIT binary patch literal 23402 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%0DTqS}GLTq`FQ1-w~27l*0nQj3l{q=UYJ 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 E1C|9o0ssI2 literal 0 HcmV?d00001 diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 48621ea..0000000 --- a/appveyor.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: '{build}' -configuration: - - Debug - - Release -build_script: - - echo "Building for %CONFIGURATION%" - - ps: .\build.ps1 %CONFIGURATION% -artifacts: - - path: .\artifacts\*.nupkg - name: NuGet -test_script: - - ps: .\test.ps1 -cache: - - '%USERPROFILE%\.nuget\packages' diff --git a/src/ReadLine/Abstractions/Console2.cs b/src/ReadLine/Abstractions/Console2.cs index 8536b8b..101b637 100644 --- a/src/ReadLine/Abstractions/Console2.cs +++ b/src/ReadLine/Abstractions/Console2.cs @@ -1,6 +1,6 @@ using System; -namespace Internal.ReadLine.Abstractions +namespace ReadLine.Abstractions { internal class Console2 : IConsole { @@ -25,7 +25,7 @@ public void SetCursorPosition(int left, int top) public void Write(string value) { if (PasswordMode) - value = new String(default(char), value.Length); + value = new string(default(char), value.Length); Console.Write(value); } diff --git a/src/ReadLine/Abstractions/IConsole.cs b/src/ReadLine/Abstractions/IConsole.cs index 5241515..df29a86 100644 --- a/src/ReadLine/Abstractions/IConsole.cs +++ b/src/ReadLine/Abstractions/IConsole.cs @@ -1,4 +1,4 @@ -namespace Internal.ReadLine.Abstractions +namespace ReadLine.Abstractions { internal interface IConsole { diff --git a/src/ReadLine/KeyHandler.cs b/src/ReadLine/KeyHandler.cs index de6cd9e..3314a47 100644 --- a/src/ReadLine/KeyHandler.cs +++ b/src/ReadLine/KeyHandler.cs @@ -1,32 +1,31 @@ -using Internal.ReadLine.Abstractions; - using System; using System.Collections.Generic; using System.Text; +using ReadLine.Abstractions; -namespace Internal.ReadLine +namespace ReadLine { internal class KeyHandler { private int _cursorPos; private int _cursorLimit; - private StringBuilder _text; - private List _history; + private readonly StringBuilder _text; + private readonly List _history; private int _historyIndex; private ConsoleKeyInfo _keyInfo; - private Dictionary _keyActions; + private readonly Dictionary _keyActions; private string[] _completions; private int _completionStart; private int _completionsIndex; - private IConsole Console2; + private readonly IConsole _console2; private bool IsStartOfLine() => _cursorPos == 0; private bool IsEndOfLine() => _cursorPos == _cursorLimit; - private bool IsStartOfBuffer() => Console2.CursorLeft == 0; + private bool IsStartOfBuffer() => _console2.CursorLeft == 0; - private bool IsEndOfBuffer() => Console2.CursorLeft == Console2.BufferWidth - 1; + private bool IsEndOfBuffer() => _console2.CursorLeft == _console2.BufferWidth - 1; private bool IsInAutoCompleteMode() => _completions != null; private void MoveCursorLeft() @@ -35,9 +34,9 @@ private void MoveCursorLeft() return; if (IsStartOfBuffer()) - Console2.SetCursorPosition(Console2.BufferWidth - 1, Console2.CursorTop - 1); + _console2.SetCursorPosition(_console2.BufferWidth - 1, _console2.CursorTop - 1); else - Console2.SetCursorPosition(Console2.CursorLeft - 1, Console2.CursorTop); + _console2.SetCursorPosition(_console2.CursorLeft - 1, _console2.CursorTop); _cursorPos--; } @@ -51,7 +50,7 @@ private void MoveCursorHome() private string BuildKeyInput() { return (_keyInfo.Modifiers != ConsoleModifiers.Control && _keyInfo.Modifiers != ConsoleModifiers.Shift) ? - _keyInfo.Key.ToString() : _keyInfo.Modifiers.ToString() + _keyInfo.Key.ToString(); + _keyInfo.Key.ToString() : _keyInfo.Modifiers + _keyInfo.Key.ToString(); } private void MoveCursorRight() @@ -60,9 +59,9 @@ private void MoveCursorRight() return; if (IsEndOfBuffer()) - Console2.SetCursorPosition(0, Console2.CursorTop + 1); + _console2.SetCursorPosition(0, _console2.CursorTop + 1); else - Console2.SetCursorPosition(Console2.CursorLeft + 1, Console2.CursorTop); + _console2.SetCursorPosition(_console2.CursorLeft + 1, _console2.CursorTop); _cursorPos++; } @@ -83,13 +82,13 @@ private void ClearLine() private void WriteNewString(string str) { ClearLine(); - foreach (char character in str) + foreach (var character in str) WriteChar(character); } private void WriteString(string str) { - foreach (char character in str) + foreach (var character in str) WriteChar(character); } @@ -100,17 +99,17 @@ private void WriteChar(char c) if (IsEndOfLine()) { _text.Append(c); - Console2.Write(c.ToString()); + _console2.Write(c.ToString()); _cursorPos++; } else { - int left = Console2.CursorLeft; - int top = Console2.CursorTop; - string str = _text.ToString().Substring(_cursorPos); + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + var str = _text.ToString().Substring(_cursorPos); _text.Insert(_cursorPos, c); - Console2.Write(c.ToString() + str); - Console2.SetCursorPosition(left, top); + _console2.Write(c + str); + _console2.SetCursorPosition(left, top); MoveCursorRight(); } @@ -123,13 +122,13 @@ private void Backspace() return; MoveCursorLeft(); - int index = _cursorPos; + var index = _cursorPos; _text.Remove(index, 1); - string replacement = _text.ToString().Substring(index); - int left = Console2.CursorLeft; - int top = Console2.CursorTop; - Console2.Write(string.Format("{0} ", replacement)); - Console2.SetCursorPosition(left, top); + var replacement = _text.ToString().Substring(index); + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + _console2.Write(string.Format("{0} ", replacement)); + _console2.SetCursorPosition(left, top); _cursorLimit--; } @@ -138,13 +137,13 @@ private void Delete() if (IsEndOfLine()) return; - int index = _cursorPos; + var index = _cursorPos; _text.Remove(index, 1); - string replacement = _text.ToString().Substring(index); - int left = Console2.CursorLeft; - int top = Console2.CursorTop; - Console2.Write(string.Format("{0} ", replacement)); - Console2.SetCursorPosition(left, top); + var replacement = _text.ToString().Substring(index); + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + _console2.Write(string.Format("{0} ", replacement)); + _console2.SetCursorPosition(left, top); _cursorLimit--; } @@ -211,91 +210,83 @@ private void ResetAutoComplete() _completionsIndex = 0; } - public string Text - { - get - { - return _text.ToString(); - } - } + public string Text => _text.ToString(); public KeyHandler(IConsole console, List history, Func autoCompleteHandler) { - Console2 = console; + _console2 = console; _historyIndex = history.Count; _history = history; _text = new StringBuilder(); - _keyActions = new Dictionary(); - - _keyActions["LeftArrow"] = MoveCursorLeft; - _keyActions["Home"] = MoveCursorHome; - _keyActions["End"] = MoveCursorEnd; - _keyActions["ControlA"] = MoveCursorHome; - _keyActions["ControlB"] = MoveCursorLeft; - _keyActions["RightArrow"] = MoveCursorRight; - _keyActions["ControlF"] = MoveCursorRight; - _keyActions["ControlE"] = MoveCursorEnd; - _keyActions["Backspace"] = Backspace; - _keyActions["Delete"] = Delete; - _keyActions["ControlH"] = Backspace; - _keyActions["ControlL"] = ClearLine; - _keyActions["UpArrow"] = PrevHistory; - _keyActions["ControlP"] = PrevHistory; - _keyActions["DownArrow"] = NextHistory; - _keyActions["ControlN"] = NextHistory; - _keyActions["ControlU"] = () => - { - while (!IsStartOfLine()) - Backspace(); - }; - _keyActions["ControlK"] = () => - { - int pos = _cursorPos; - MoveCursorEnd(); - while (_cursorPos > pos) - Backspace(); - }; - _keyActions["ControlW"] = () => - { - while (!IsStartOfLine() && _text[_cursorPos - 1] != ' ') - Backspace(); - }; - - _keyActions["Tab"] = () => - { - if (IsInAutoCompleteMode()) - { - NextAutoComplete(); - } - else - { - if (autoCompleteHandler == null || !IsEndOfLine()) - return; - - char[] anyOf = new char[] { ' ', '.', '/', '\\', ':' }; - string text = _text.ToString(); - - _completionStart = text.LastIndexOfAny(anyOf); - _completionStart = _completionStart == -1 ? 0 : _completionStart + 1; - - _completions = autoCompleteHandler.Invoke(text, _completionStart); - _completions = _completions?.Length == 0 ? null : _completions; + _keyActions = new Dictionary { + ["LeftArrow"] = MoveCursorLeft, + ["Home"] = MoveCursorHome, + ["End"] = MoveCursorEnd, + ["ControlA"] = MoveCursorHome, + ["ControlB"] = MoveCursorLeft, + ["RightArrow"] = MoveCursorRight, + ["ControlF"] = MoveCursorRight, + ["ControlE"] = MoveCursorEnd, + ["Backspace"] = Backspace, + ["Delete"] = Delete, + ["ControlH"] = Backspace, + ["ControlL"] = ClearLine, + ["UpArrow"] = PrevHistory, + ["ControlP"] = PrevHistory, + ["DownArrow"] = NextHistory, + ["ControlN"] = NextHistory, + ["ControlU"] = () => { + while (!IsStartOfLine()) + Backspace(); + }, + ["ControlK"] = () => { + var pos = _cursorPos; + MoveCursorEnd(); + while (_cursorPos > pos) + Backspace(); + }, + ["ControlW"] = () => { + while (!IsStartOfLine() && _text[_cursorPos - 1] != ' ') + Backspace(); + }, + ["Tab"] = () => { + if (IsInAutoCompleteMode()) { + NextAutoComplete(); + } else { + if (autoCompleteHandler == null || !IsEndOfLine()) + return; + + var anyOf = new[] { + ' ', + '.', + '/', + '\\', + ':' + }; + var text = _text.ToString(); + + _completionStart = text.LastIndexOfAny(anyOf); + _completionStart = _completionStart == -1 ? 0 : _completionStart + 1; + + _completions = autoCompleteHandler.Invoke(text, _completionStart); + _completions = _completions?.Length == 0 ? null : _completions; + + if (_completions == null) + return; + + StartAutoComplete(); + } + }, + ["ShiftTab"] = () => { + if (IsInAutoCompleteMode()) { + PreviousAutoComplete(); + } + } + }; - if (_completions == null) - return; - StartAutoComplete(); - } - }; - _keyActions["ShiftTab"] = () => - { - if (IsInAutoCompleteMode()) - { - PreviousAutoComplete(); - } - }; } public void Handle(ConsoleKeyInfo keyInfo) @@ -306,8 +297,7 @@ public void Handle(ConsoleKeyInfo keyInfo) if (IsInAutoCompleteMode() && _keyInfo.Key != ConsoleKey.Tab) ResetAutoComplete(); - Action action; - _keyActions.TryGetValue(BuildKeyInput(), out action); + _keyActions.TryGetValue(BuildKeyInput(), out var action); action = action ?? WriteChar; action.Invoke(); } diff --git a/src/ReadLine/Properties/AssemblyInfo.cs b/src/ReadLine/Properties/AssemblyInfo.cs index 5303f1b..d75da54 100644 --- a/src/ReadLine/Properties/AssemblyInfo.cs +++ b/src/ReadLine/Properties/AssemblyInfo.cs @@ -1,6 +1,5 @@ -[assembly:System.Reflection.AssemblyTitleAttribute("ReadLine")] -[assembly:System.Reflection.AssemblyDescriptionAttribute("A GNU-Readline like library for .NET/.NET Core")] -[assembly:System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly:System.Reflection.AssemblyVersionAttribute("1.0.0.0")] -[assembly:System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] -[assembly:System.Runtime.CompilerServices.InternalsVisibleTo("ReadLine.Tests")] \ No newline at end of file +[assembly:System.Reflection.AssemblyTitle("ReadLine")] +[assembly:System.Reflection.AssemblyDescription("A GNU-Readline like library for .NET/.NET Core")] +[assembly:System.Reflection.AssemblyFileVersion("1.2.1")] +[assembly:System.Reflection.AssemblyVersion("1.2.1")] +[assembly:System.Reflection.AssemblyInformationalVersion("1.2.1")] \ No newline at end of file diff --git a/src/ReadLine/ReadLine.cs b/src/ReadLine/ReadLine.cs index 9e518bf..6888c8d 100755 --- a/src/ReadLine/ReadLine.cs +++ b/src/ReadLine/ReadLine.cs @@ -1,9 +1,8 @@ -using Internal.ReadLine; -using Internal.ReadLine.Abstractions; - +using System; using System.Collections.Generic; +using ReadLine.Abstractions; -namespace System +namespace ReadLine { public static class ReadLine { @@ -26,7 +25,7 @@ public static string Read(string prompt = "", string defaultInput = "") Console.Write(prompt); _keyHandler = new KeyHandler(new Console2() { PasswordMode = PasswordMode }, _history, AutoCompletionHandler); - ConsoleKeyInfo keyInfo = Console.ReadKey(true); + var keyInfo = Console.ReadKey(true); while (keyInfo.Key != ConsoleKey.Enter) { @@ -36,8 +35,8 @@ public static string Read(string prompt = "", string defaultInput = "") Console.WriteLine(); - string text = _keyHandler.Text; - if (String.IsNullOrWhiteSpace(text) && !String.IsNullOrWhiteSpace(defaultInput)) + var text = _keyHandler.Text; + if (string.IsNullOrWhiteSpace(text) && !string.IsNullOrWhiteSpace(defaultInput)) text = defaultInput; else _history.Add(text); @@ -45,4 +44,4 @@ public static string Read(string prompt = "", string defaultInput = "") return text; } } -} +} \ No newline at end of file diff --git a/src/ReadLine/ReadLine.csproj b/src/ReadLine/ReadLine.csproj index 37b44a4..6527cff 100755 --- a/src/ReadLine/ReadLine.csproj +++ b/src/ReadLine/ReadLine.csproj @@ -5,7 +5,7 @@ ReadLine 1.2.0 Toni Solarin-Sodara - netstandard1.3;net45 + netcoreapp2.0;net47 portable ReadLine ReadLine @@ -20,6 +20,8 @@ false false false + true + snKey.snk @@ -31,4 +33,8 @@ + + + + diff --git a/src/ReadLine/snKey.snk b/src/ReadLine/snKey.snk new file mode 100644 index 0000000000000000000000000000000000000000..31d343f7ffb8b441e96796c72c12e59df3f01bc8 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50096IwzSrIOAl%ND{mC5MNCm#^UI19snt8D zBKPnkxE*N*oqW$y^Iby9cC2Vu7oP#Y8qQQC6Rnx83pQcM ze-hRbx=$b{y`;qLnMI4bKiGtV=Ss)d9Vt^&Ah1f6CzSxKkVx4@bM;B`nOayqAezUk zKYx0Hs3XugN6sPl=A7DN6|V|{vQXEt!1V_-B-|hL%)K2^b#rhA7uOscFGjq{bmXDq zRDIv#52F8oIzHet6=vhu`!r+fAdBBmGJJlHHRgZ6uI}xJ{}X&?qrPxaE1Cpg+OyP5 z?CZgfif=Z6BziDmnh8zx)y?65(@yK4(swR8#f)RLPw`i4bHo3AHTDrYY~8dzS+25! zV-OAEyIx&!^{qC7gec9u&tAXr^T+1TRkR4Y zs>yK17VV+kl~GunwWB{BmWx*8=VWnh^JnU=syMSD?#)TEr_xtC5D4dW@OM5_9U3x@ z?t`#-h~7TVa{!cFtkNzxdJ-m573do73b{Pz|n3_?S`k2q+oFk1Ld7(y=9~T5~XznI`vwo*=+$FyN literal 0 HcmV?d00001 From 413c9230fbf269b2697f700431c9d0ba2eb4508e Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Mon, 25 Sep 2017 14:42:05 -0700 Subject: [PATCH 02/21] Code formatted. Replaced string formatting with string interpolation. --- src/ReadLine/Abstractions/Console2.cs | 42 +- src/ReadLine/Abstractions/IConsole.cs | 24 +- src/ReadLine/KeyHandler.cs | 506 +++++++++++------------- src/ReadLine/Properties/AssemblyInfo.cs | 10 +- src/ReadLine/ReadLine.cs | 79 ++-- 5 files changed, 311 insertions(+), 350 deletions(-) diff --git a/src/ReadLine/Abstractions/Console2.cs b/src/ReadLine/Abstractions/Console2.cs index 101b637..f7188d2 100644 --- a/src/ReadLine/Abstractions/Console2.cs +++ b/src/ReadLine/Abstractions/Console2.cs @@ -1,35 +1,31 @@ using System; -namespace ReadLine.Abstractions -{ - internal class Console2 : IConsole - { - public int CursorLeft => Console.CursorLeft; +namespace ReadLine.Abstractions { + internal class Console2 : IConsole { + public int CursorLeft => Console.CursorLeft; - public int CursorTop => Console.CursorTop; + public int CursorTop => Console.CursorTop; - public int BufferWidth => Console.BufferWidth; + public int BufferWidth => Console.BufferWidth; - public int BufferHeight => Console.BufferHeight; + public int BufferHeight => Console.BufferHeight; - public bool PasswordMode { get; set; } + public bool PasswordMode { get; set; } - public void SetBufferSize(int width, int height) => Console.SetBufferSize(width, height); + public void SetBufferSize(int width, int height) => Console.SetBufferSize(width, height); - public void SetCursorPosition(int left, int top) - { - if (!PasswordMode) - Console.SetCursorPosition(left, top); - } - - public void Write(string value) - { - if (PasswordMode) - value = new string(default(char), value.Length); + public void SetCursorPosition(int left, int top) { + if (!PasswordMode) + Console.SetCursorPosition(left, top); + } - Console.Write(value); - } + public void Write(string value) { + if (PasswordMode) + value = new string(default(char), value.Length); - public void WriteLine(string value) => Console.WriteLine(value); + Console.Write(value); } + + public void WriteLine(string value) => Console.WriteLine(value); + } } \ No newline at end of file diff --git a/src/ReadLine/Abstractions/IConsole.cs b/src/ReadLine/Abstractions/IConsole.cs index df29a86..f730d2d 100644 --- a/src/ReadLine/Abstractions/IConsole.cs +++ b/src/ReadLine/Abstractions/IConsole.cs @@ -1,14 +1,12 @@ -namespace ReadLine.Abstractions -{ - internal interface IConsole - { - int CursorLeft { get; } - int CursorTop { get; } - int BufferWidth { get; } - int BufferHeight { get; } - void SetCursorPosition(int left, int top); - void SetBufferSize(int width, int height); - void Write(string value); - void WriteLine(string value); - } +namespace ReadLine.Abstractions { + internal interface IConsole { + int CursorLeft { get; } + int CursorTop { get; } + int BufferWidth { get; } + int BufferHeight { get; } + void SetCursorPosition(int left, int top); + void SetBufferSize(int width, int height); + void Write(string value); + void WriteLine(string value); + } } \ No newline at end of file diff --git a/src/ReadLine/KeyHandler.cs b/src/ReadLine/KeyHandler.cs index 3314a47..f86564b 100644 --- a/src/ReadLine/KeyHandler.cs +++ b/src/ReadLine/KeyHandler.cs @@ -3,303 +3,273 @@ using System.Text; using ReadLine.Abstractions; -namespace ReadLine -{ - internal class KeyHandler - { - private int _cursorPos; - private int _cursorLimit; - private readonly StringBuilder _text; - private readonly List _history; - private int _historyIndex; - private ConsoleKeyInfo _keyInfo; - private readonly Dictionary _keyActions; - private string[] _completions; - private int _completionStart; - private int _completionsIndex; - private readonly IConsole _console2; - - private bool IsStartOfLine() => _cursorPos == 0; - - private bool IsEndOfLine() => _cursorPos == _cursorLimit; - - private bool IsStartOfBuffer() => _console2.CursorLeft == 0; - - private bool IsEndOfBuffer() => _console2.CursorLeft == _console2.BufferWidth - 1; - private bool IsInAutoCompleteMode() => _completions != null; - - private void MoveCursorLeft() - { - if (IsStartOfLine()) - return; - - if (IsStartOfBuffer()) - _console2.SetCursorPosition(_console2.BufferWidth - 1, _console2.CursorTop - 1); - else - _console2.SetCursorPosition(_console2.CursorLeft - 1, _console2.CursorTop); - - _cursorPos--; - } - - private void MoveCursorHome() - { - while (!IsStartOfLine()) - MoveCursorLeft(); - } - - private string BuildKeyInput() - { - return (_keyInfo.Modifiers != ConsoleModifiers.Control && _keyInfo.Modifiers != ConsoleModifiers.Shift) ? - _keyInfo.Key.ToString() : _keyInfo.Modifiers + _keyInfo.Key.ToString(); - } - - private void MoveCursorRight() - { - if (IsEndOfLine()) - return; +namespace ReadLine { + internal class KeyHandler { + private int _cursorPos; + private int _cursorLimit; + private readonly StringBuilder _text; + private readonly List _history; + private int _historyIndex; + private ConsoleKeyInfo _keyInfo; + private readonly Dictionary _keyActions; + private string[] _completions; + private int _completionStart; + private int _completionsIndex; + private readonly IConsole _console2; + + private bool IsStartOfLine() => _cursorPos == 0; + + private bool IsEndOfLine() => _cursorPos == _cursorLimit; + + private bool IsStartOfBuffer() => _console2.CursorLeft == 0; + + private bool IsEndOfBuffer() => _console2.CursorLeft == _console2.BufferWidth - 1; + private bool IsInAutoCompleteMode() => _completions != null; + + private void MoveCursorLeft() { + if (IsStartOfLine()) + return; + + if (IsStartOfBuffer()) + _console2.SetCursorPosition(_console2.BufferWidth - 1, _console2.CursorTop - 1); + else + _console2.SetCursorPosition(_console2.CursorLeft - 1, _console2.CursorTop); + + _cursorPos--; + } - if (IsEndOfBuffer()) - _console2.SetCursorPosition(0, _console2.CursorTop + 1); - else - _console2.SetCursorPosition(_console2.CursorLeft + 1, _console2.CursorTop); + private void MoveCursorHome() { + while (!IsStartOfLine()) + MoveCursorLeft(); + } - _cursorPos++; - } + private string BuildKeyInput() { + return (_keyInfo.Modifiers != ConsoleModifiers.Control && _keyInfo.Modifiers != ConsoleModifiers.Shift) ? _keyInfo.Key.ToString() : _keyInfo.Modifiers + _keyInfo.Key.ToString(); + } - private void MoveCursorEnd() - { - while (!IsEndOfLine()) - MoveCursorRight(); - } + private void MoveCursorRight() { + if (IsEndOfLine()) + return; - private void ClearLine() - { - MoveCursorEnd(); - while (!IsStartOfLine()) - Backspace(); - } + if (IsEndOfBuffer()) + _console2.SetCursorPosition(0, _console2.CursorTop + 1); + else + _console2.SetCursorPosition(_console2.CursorLeft + 1, _console2.CursorTop); - private void WriteNewString(string str) - { - ClearLine(); - foreach (var character in str) - WriteChar(character); - } + _cursorPos++; + } - private void WriteString(string str) - { - foreach (var character in str) - WriteChar(character); - } + private void MoveCursorEnd() { + while (!IsEndOfLine()) + MoveCursorRight(); + } - private void WriteChar() => WriteChar(_keyInfo.KeyChar); - - private void WriteChar(char c) - { - if (IsEndOfLine()) - { - _text.Append(c); - _console2.Write(c.ToString()); - _cursorPos++; - } - else - { - var left = _console2.CursorLeft; - var top = _console2.CursorTop; - var str = _text.ToString().Substring(_cursorPos); - _text.Insert(_cursorPos, c); - _console2.Write(c + str); - _console2.SetCursorPosition(left, top); - MoveCursorRight(); - } - - _cursorLimit++; - } + private void ClearLine() { + MoveCursorEnd(); + while (!IsStartOfLine()) + Backspace(); + } - private void Backspace() - { - if (IsStartOfLine()) - return; - - MoveCursorLeft(); - var index = _cursorPos; - _text.Remove(index, 1); - var replacement = _text.ToString().Substring(index); - var left = _console2.CursorLeft; - var top = _console2.CursorTop; - _console2.Write(string.Format("{0} ", replacement)); - _console2.SetCursorPosition(left, top); - _cursorLimit--; - } + private void WriteNewString(string str) { + ClearLine(); + foreach (var character in str) + WriteChar(character); + } - private void Delete() - { - if (IsEndOfLine()) - return; - - var index = _cursorPos; - _text.Remove(index, 1); - var replacement = _text.ToString().Substring(index); - var left = _console2.CursorLeft; - var top = _console2.CursorTop; - _console2.Write(string.Format("{0} ", replacement)); - _console2.SetCursorPosition(left, top); - _cursorLimit--; - } + private void WriteString(string str) { + foreach (var character in str) + WriteChar(character); + } - private void StartAutoComplete() - { - while (_cursorPos > _completionStart) - Backspace(); + private void WriteChar() => WriteChar(_keyInfo.KeyChar); + + private void WriteChar(char c) { + if (IsEndOfLine()) { + _text.Append(c); + _console2.Write(c.ToString()); + _cursorPos++; + } else { + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + var str = _text.ToString().Substring(_cursorPos); + _text.Insert(_cursorPos, c); + _console2.Write(c + str); + _console2.SetCursorPosition(left, top); + MoveCursorRight(); + } + + _cursorLimit++; + } - _completionsIndex = 0; + private void Backspace() { + if (IsStartOfLine()) + return; + + MoveCursorLeft(); + var index = _cursorPos; + _text.Remove(index, 1); + var replacement = _text.ToString().Substring(index); + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + _console2.Write($"{replacement} "); + _console2.SetCursorPosition(left, top); + _cursorLimit--; + } - WriteString(_completions[_completionsIndex]); - } + private void Delete() { + if (IsEndOfLine()) + return; + + var index = _cursorPos; + _text.Remove(index, 1); + var replacement = _text.ToString().Substring(index); + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + _console2.Write($"{replacement} "); + _console2.SetCursorPosition(left, top); + _cursorLimit--; + } - private void NextAutoComplete() - { - while (_cursorPos > _completionStart) - Backspace(); + private void StartAutoComplete() { + while (_cursorPos > _completionStart) + Backspace(); - _completionsIndex++; + _completionsIndex = 0; - if (_completionsIndex == _completions.Length) - _completionsIndex = 0; + WriteString(_completions[_completionsIndex]); + } - WriteString(_completions[_completionsIndex]); - } + private void NextAutoComplete() { + while (_cursorPos > _completionStart) + Backspace(); - private void PreviousAutoComplete() - { - while (_cursorPos > _completionStart) - Backspace(); + _completionsIndex++; - _completionsIndex--; + if (_completionsIndex == _completions.Length) + _completionsIndex = 0; - if (_completionsIndex == -1) - _completionsIndex = _completions.Length - 1; + WriteString(_completions[_completionsIndex]); + } - WriteString(_completions[_completionsIndex]); - } + private void PreviousAutoComplete() { + while (_cursorPos > _completionStart) + Backspace(); - private void PrevHistory() - { - if (_historyIndex > 0) - { - _historyIndex--; - WriteNewString(_history[_historyIndex]); - } - } + _completionsIndex--; - private void NextHistory() - { - if (_historyIndex < _history.Count) - { - _historyIndex++; - if (_historyIndex == _history.Count) - ClearLine(); - else - WriteNewString(_history[_historyIndex]); - } - } + if (_completionsIndex == -1) + _completionsIndex = _completions.Length - 1; - private void ResetAutoComplete() - { - _completions = null; - _completionsIndex = 0; - } + WriteString(_completions[_completionsIndex]); + } - public string Text => _text.ToString(); - - public KeyHandler(IConsole console, List history, Func autoCompleteHandler) - { - _console2 = console; - - _historyIndex = history.Count; - _history = history; - _text = new StringBuilder(); - _keyActions = new Dictionary { - ["LeftArrow"] = MoveCursorLeft, - ["Home"] = MoveCursorHome, - ["End"] = MoveCursorEnd, - ["ControlA"] = MoveCursorHome, - ["ControlB"] = MoveCursorLeft, - ["RightArrow"] = MoveCursorRight, - ["ControlF"] = MoveCursorRight, - ["ControlE"] = MoveCursorEnd, - ["Backspace"] = Backspace, - ["Delete"] = Delete, - ["ControlH"] = Backspace, - ["ControlL"] = ClearLine, - ["UpArrow"] = PrevHistory, - ["ControlP"] = PrevHistory, - ["DownArrow"] = NextHistory, - ["ControlN"] = NextHistory, - ["ControlU"] = () => { - while (!IsStartOfLine()) - Backspace(); - }, - ["ControlK"] = () => { - var pos = _cursorPos; - MoveCursorEnd(); - while (_cursorPos > pos) - Backspace(); - }, - ["ControlW"] = () => { - while (!IsStartOfLine() && _text[_cursorPos - 1] != ' ') - Backspace(); - }, - ["Tab"] = () => { - if (IsInAutoCompleteMode()) { - NextAutoComplete(); - } else { - if (autoCompleteHandler == null || !IsEndOfLine()) - return; - - var anyOf = new[] { - ' ', - '.', - '/', - '\\', - ':' - }; - var text = _text.ToString(); - - _completionStart = text.LastIndexOfAny(anyOf); - _completionStart = _completionStart == -1 ? 0 : _completionStart + 1; - - _completions = autoCompleteHandler.Invoke(text, _completionStart); - _completions = _completions?.Length == 0 ? null : _completions; - - if (_completions == null) - return; - - StartAutoComplete(); - } - }, - ["ShiftTab"] = () => { - if (IsInAutoCompleteMode()) { - PreviousAutoComplete(); - } - } - }; + private void PrevHistory() { + if (_historyIndex > 0) { + _historyIndex--; + WriteNewString(_history[_historyIndex]); + } + } + private void NextHistory() { + if (_historyIndex < _history.Count) { + _historyIndex++; + if (_historyIndex == _history.Count) + ClearLine(); + else + WriteNewString(_history[_historyIndex]); + } + } + private void ResetAutoComplete() { + _completions = null; + _completionsIndex = 0; + } + public string Text => _text.ToString(); + + public KeyHandler(IConsole console, List history, Func autoCompleteHandler) { + _console2 = console; + + _historyIndex = history.Count; + _history = history; + _text = new StringBuilder(); + _keyActions = new Dictionary { + ["LeftArrow"] = MoveCursorLeft, + ["Home"] = MoveCursorHome, + ["End"] = MoveCursorEnd, + ["ControlA"] = MoveCursorHome, + ["ControlB"] = MoveCursorLeft, + ["RightArrow"] = MoveCursorRight, + ["ControlF"] = MoveCursorRight, + ["ControlE"] = MoveCursorEnd, + ["Backspace"] = Backspace, + ["Delete"] = Delete, + ["ControlH"] = Backspace, + ["ControlL"] = ClearLine, + ["UpArrow"] = PrevHistory, + ["ControlP"] = PrevHistory, + ["DownArrow"] = NextHistory, + ["ControlN"] = NextHistory, + ["ControlU"] = () => { + while (!IsStartOfLine()) + Backspace(); + }, + ["ControlK"] = () => { + var pos = _cursorPos; + MoveCursorEnd(); + while (_cursorPos > pos) + Backspace(); + }, + ["ControlW"] = () => { + while (!IsStartOfLine() && _text[_cursorPos - 1] != ' ') + Backspace(); + }, + ["Tab"] = () => { + if (IsInAutoCompleteMode()) { + NextAutoComplete(); + } else { + if (autoCompleteHandler == null || !IsEndOfLine()) + return; + + var anyOf = new[] { + ' ', + '.', + '/', + '\\', + ':' + }; + var text = _text.ToString(); + + _completionStart = text.LastIndexOfAny(anyOf); + _completionStart = _completionStart == -1 ? 0 : _completionStart + 1; + + _completions = autoCompleteHandler.Invoke(text, _completionStart); + _completions = _completions?.Length == 0 ? null : _completions; + + if (_completions == null) + return; + + StartAutoComplete(); + } + }, + ["ShiftTab"] = () => { + if (IsInAutoCompleteMode()) { + PreviousAutoComplete(); + } } + }; + } - public void Handle(ConsoleKeyInfo keyInfo) - { - _keyInfo = keyInfo; + public void Handle(ConsoleKeyInfo keyInfo) { + _keyInfo = keyInfo; - // If in auto complete mode and Tab wasn't pressed - if (IsInAutoCompleteMode() && _keyInfo.Key != ConsoleKey.Tab) - ResetAutoComplete(); + // If in auto complete mode and Tab wasn't pressed + if (IsInAutoCompleteMode() && _keyInfo.Key != ConsoleKey.Tab) + ResetAutoComplete(); - _keyActions.TryGetValue(BuildKeyInput(), out var action); - action = action ?? WriteChar; - action.Invoke(); - } + _keyActions.TryGetValue(BuildKeyInput(), out var action); + action = action ?? WriteChar; + action.Invoke(); } -} + } +} \ No newline at end of file diff --git a/src/ReadLine/Properties/AssemblyInfo.cs b/src/ReadLine/Properties/AssemblyInfo.cs index d75da54..9d08c04 100644 --- a/src/ReadLine/Properties/AssemblyInfo.cs +++ b/src/ReadLine/Properties/AssemblyInfo.cs @@ -1,5 +1,5 @@ -[assembly:System.Reflection.AssemblyTitle("ReadLine")] -[assembly:System.Reflection.AssemblyDescription("A GNU-Readline like library for .NET/.NET Core")] -[assembly:System.Reflection.AssemblyFileVersion("1.2.1")] -[assembly:System.Reflection.AssemblyVersion("1.2.1")] -[assembly:System.Reflection.AssemblyInformationalVersion("1.2.1")] \ No newline at end of file +[assembly: System.Reflection.AssemblyTitle("ReadLine")] +[assembly: System.Reflection.AssemblyDescription("A GNU-Readline like library for .NET/.NET Core")] +[assembly: System.Reflection.AssemblyFileVersion("1.2.1")] +[assembly: System.Reflection.AssemblyVersion("1.2.1")] +[assembly: System.Reflection.AssemblyInformationalVersion("1.2.1")] \ No newline at end of file diff --git a/src/ReadLine/ReadLine.cs b/src/ReadLine/ReadLine.cs index 6888c8d..67d7a81 100755 --- a/src/ReadLine/ReadLine.cs +++ b/src/ReadLine/ReadLine.cs @@ -2,46 +2,43 @@ using System.Collections.Generic; using ReadLine.Abstractions; -namespace ReadLine -{ - public static class ReadLine - { - private static KeyHandler _keyHandler; - private static List _history; - - static ReadLine() - { - _history = new List(); - } - - public static void AddHistory(params string[] text) => _history.AddRange(text); - public static List GetHistory() => _history; - public static void ClearHistory() => _history = new List(); - public static Func AutoCompletionHandler { private get; set; } - public static bool PasswordMode { private get; set; } - - public static string Read(string prompt = "", string defaultInput = "") - { - Console.Write(prompt); - - _keyHandler = new KeyHandler(new Console2() { PasswordMode = PasswordMode }, _history, AutoCompletionHandler); - var keyInfo = Console.ReadKey(true); - - while (keyInfo.Key != ConsoleKey.Enter) - { - _keyHandler.Handle(keyInfo); - keyInfo = Console.ReadKey(true); - } - - Console.WriteLine(); - - var text = _keyHandler.Text; - if (string.IsNullOrWhiteSpace(text) && !string.IsNullOrWhiteSpace(defaultInput)) - text = defaultInput; - else - _history.Add(text); - - return text; - } +namespace ReadLine { + public static class ReadLine { + private static KeyHandler _keyHandler; + private static List _history; + + static ReadLine() { + _history = new List(); + } + + public static void AddHistory(params string[] text) => _history.AddRange(text); + public static List GetHistory() => _history; + public static void ClearHistory() => _history = new List(); + public static Func AutoCompletionHandler { private get; set; } + public static bool PasswordMode { private get; set; } + + public static string Read(string prompt = "", string defaultInput = "") { + Console.Write(prompt); + + _keyHandler = new KeyHandler(new Console2() { + PasswordMode = PasswordMode + }, _history, AutoCompletionHandler); + var keyInfo = Console.ReadKey(true); + + while (keyInfo.Key != ConsoleKey.Enter) { + _keyHandler.Handle(keyInfo); + keyInfo = Console.ReadKey(true); + } + + Console.WriteLine(); + + var text = _keyHandler.Text; + if (string.IsNullOrWhiteSpace(text) && !string.IsNullOrWhiteSpace(defaultInput)) + text = defaultInput; + else + _history.Add(text); + + return text; } + } } \ No newline at end of file From 83def26cb84b5fb2f42f0656bc361c92b6a9848f Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Mon, 25 Sep 2017 14:45:51 -0700 Subject: [PATCH 03/21] Revert file deletion for *.yml. --- appveyor.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..48621ea --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,14 @@ +version: '{build}' +configuration: + - Debug + - Release +build_script: + - echo "Building for %CONFIGURATION%" + - ps: .\build.ps1 %CONFIGURATION% +artifacts: + - path: .\artifacts\*.nupkg + name: NuGet +test_script: + - ps: .\test.ps1 +cache: + - '%USERPROFILE%\.nuget\packages' From b42ac5c8e7052366257204e9b43e58ac46ffa271 Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Mon, 25 Sep 2017 15:13:28 -0700 Subject: [PATCH 04/21] Updated libraries and targeting builds for the test projects. --- ReadLine.sln | 66 +- src/ReadLine.Demo/Program.cs | 46 +- src/ReadLine.Demo/ReadLine.Demo.csproj | 3 +- src/ReadLine/Abstractions/IConsole.cs | 2 +- src/ReadLine/KeyHandler.cs | 2 +- src/ReadLine/ReadLine.csproj | 3 +- test/ReadLine.Tests/Abstractions/Console2.cs | 89 ++- test/ReadLine.Tests/KeyHandlerTests.cs | 699 +++++++++---------- test/ReadLine.Tests/ReadLine.Tests.csproj | 9 +- test/ReadLine.Tests/ReadLineTests.cs | 69 +- 10 files changed, 476 insertions(+), 512 deletions(-) diff --git a/ReadLine.sln b/ReadLine.sln index 90c6480..2feb5f2 100755 --- a/ReadLine.sln +++ b/ReadLine.sln @@ -1,17 +1,16 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26124.0 +VisualStudioVersion = 15.0.26730.16 MinimumVisualStudioVersion = 15.0.26124.0 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{06FC0E85-E73C-4DC1-B6FD-A583B7B1DFE4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReadLine", "src\ReadLine\ReadLine.csproj", "{9EB290C9-BB52-4B24-9779-5A816AC75E18}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine", "src\ReadLine\ReadLine.csproj", "{9EB290C9-BB52-4B24-9779-5A816AC75E18}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReadLine.Demo", "src\ReadLine.Demo\ReadLine.Demo.csproj", "{4C512FD1-A0E8-4908-B0A4-B0D85947716A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine.Demo", "src\ReadLine.Demo\ReadLine.Demo.csproj", "{4C512FD1-A0E8-4908-B0A4-B0D85947716A}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{38C56AEB-DB08-4CBF-AAC0-EBFC2B0EE045}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReadLine.Tests", "test\ReadLine.Tests\ReadLine.Tests.csproj", "{631582D9-EEEA-4F9D-8069-71ECA24ED282}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine.Tests", "test\ReadLine.Tests\ReadLine.Tests.csproj", "{631582D9-EEEA-4F9D-8069-71ECA24ED282}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -22,50 +21,53 @@ Global Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Debug|x64.ActiveCfg = Debug|x64 - {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Debug|x64.Build.0 = Debug|x64 - {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Debug|x86.ActiveCfg = Debug|x86 - {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Debug|x86.Build.0 = Debug|x86 + {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Debug|x64.ActiveCfg = Debug|Any CPU + {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Debug|x64.Build.0 = Debug|Any CPU + {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Debug|x86.ActiveCfg = Debug|Any CPU + {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Debug|x86.Build.0 = Debug|Any CPU {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Release|Any CPU.ActiveCfg = Release|Any CPU {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Release|Any CPU.Build.0 = Release|Any CPU - {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Release|x64.ActiveCfg = Release|x64 - {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Release|x64.Build.0 = Release|x64 - {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Release|x86.ActiveCfg = Release|x86 - {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Release|x86.Build.0 = Release|x86 + {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Release|x64.ActiveCfg = Release|Any CPU + {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Release|x64.Build.0 = Release|Any CPU + {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Release|x86.ActiveCfg = Release|Any CPU + {9EB290C9-BB52-4B24-9779-5A816AC75E18}.Release|x86.Build.0 = Release|Any CPU {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Debug|x64.ActiveCfg = Debug|x64 - {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Debug|x64.Build.0 = Debug|x64 - {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Debug|x86.ActiveCfg = Debug|x86 - {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Debug|x86.Build.0 = Debug|x86 + {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Debug|x64.ActiveCfg = Debug|Any CPU + {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Debug|x64.Build.0 = Debug|Any CPU + {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Debug|x86.ActiveCfg = Debug|Any CPU + {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Debug|x86.Build.0 = Debug|Any CPU {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Release|Any CPU.ActiveCfg = Release|Any CPU {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Release|Any CPU.Build.0 = Release|Any CPU - {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Release|x64.ActiveCfg = Release|x64 - {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Release|x64.Build.0 = Release|x64 - {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Release|x86.ActiveCfg = Release|x86 - {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Release|x86.Build.0 = Release|x86 + {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Release|x64.ActiveCfg = Release|Any CPU + {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Release|x64.Build.0 = Release|Any CPU + {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Release|x86.ActiveCfg = Release|Any CPU + {4C512FD1-A0E8-4908-B0A4-B0D85947716A}.Release|x86.Build.0 = Release|Any CPU {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Debug|Any CPU.Build.0 = Debug|Any CPU - {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Debug|x64.ActiveCfg = Debug|x64 - {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Debug|x64.Build.0 = Debug|x64 - {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Debug|x86.ActiveCfg = Debug|x86 - {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Debug|x86.Build.0 = Debug|x86 + {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Debug|x64.ActiveCfg = Debug|Any CPU + {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Debug|x64.Build.0 = Debug|Any CPU + {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Debug|x86.ActiveCfg = Debug|Any CPU + {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Debug|x86.Build.0 = Debug|Any CPU {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Release|Any CPU.ActiveCfg = Release|Any CPU {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Release|Any CPU.Build.0 = Release|Any CPU - {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Release|x64.ActiveCfg = Release|x64 - {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Release|x64.Build.0 = Release|x64 - {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Release|x86.ActiveCfg = Release|x86 - {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Release|x86.Build.0 = Release|x86 + {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Release|x64.ActiveCfg = Release|Any CPU + {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Release|x64.Build.0 = Release|Any CPU + {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Release|x86.ActiveCfg = Release|Any CPU + {631582D9-EEEA-4F9D-8069-71ECA24ED282}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {9EB290C9-BB52-4B24-9779-5A816AC75E18} = {06FC0E85-E73C-4DC1-B6FD-A583B7B1DFE4} {4C512FD1-A0E8-4908-B0A4-B0D85947716A} = {06FC0E85-E73C-4DC1-B6FD-A583B7B1DFE4} {631582D9-EEEA-4F9D-8069-71ECA24ED282} = {38C56AEB-DB08-4CBF-AAC0-EBFC2B0EE045} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {90E42483-9D9A-4800-B1FE-B5044432D28F} + EndGlobalSection EndGlobal diff --git a/src/ReadLine.Demo/Program.cs b/src/ReadLine.Demo/Program.cs index 8678b59..dda85d6 100755 --- a/src/ReadLine.Demo/Program.cs +++ b/src/ReadLine.Demo/Program.cs @@ -1,28 +1,30 @@ using System; -namespace ConsoleApplication -{ - public class Program - { - public static void Main(string[] args) - { - Console.WriteLine("ReadLine Library Demo"); - Console.WriteLine("---------------------"); - Console.WriteLine(); +namespace ReadLine.Demo { + public class Program { + public static void Main(string[] args) { + Console.WriteLine("ReadLine Library Demo"); + Console.WriteLine("---------------------"); + Console.WriteLine(); - string[] history = new string[] { "ls -a", "dotnet run", "git init" }; - ReadLine.AddHistory(history); + string[] history = { + "ls -a", + "dotnet run", + "git init" + }; + ReadLine.AddHistory(history); - ReadLine.AutoCompletionHandler = (t, s) => - { - if (t.StartsWith("git ")) - return new string[] { "init", "clone", "pull", "push" }; - else - return null; - }; - - string input = ReadLine.Read("(prompt)> "); - Console.Write(input); + ReadLine.AutoCompletionHandler = (t, s) => t.StartsWith("git ") + ? new[] { + "init", + "clone", + "pull", + "push" } + : null; + + var input = ReadLine.Read("(prompt)> "); + Console.Write(input); } -} + } +} \ No newline at end of file diff --git a/src/ReadLine.Demo/ReadLine.Demo.csproj b/src/ReadLine.Demo/ReadLine.Demo.csproj index e91366a..de7d7b5 100755 --- a/src/ReadLine.Demo/ReadLine.Demo.csproj +++ b/src/ReadLine.Demo/ReadLine.Demo.csproj @@ -1,13 +1,12 @@  - netcoreapp1.1 + netcoreapp2.0 portable ReadLine.Demo Exe ReadLine.Demo $(PackageTargetFallback);dnxcore50 - 1.1.1 diff --git a/src/ReadLine/Abstractions/IConsole.cs b/src/ReadLine/Abstractions/IConsole.cs index f730d2d..6b764bc 100644 --- a/src/ReadLine/Abstractions/IConsole.cs +++ b/src/ReadLine/Abstractions/IConsole.cs @@ -1,5 +1,5 @@ namespace ReadLine.Abstractions { - internal interface IConsole { + public interface IConsole { int CursorLeft { get; } int CursorTop { get; } int BufferWidth { get; } diff --git a/src/ReadLine/KeyHandler.cs b/src/ReadLine/KeyHandler.cs index f86564b..5a2a225 100644 --- a/src/ReadLine/KeyHandler.cs +++ b/src/ReadLine/KeyHandler.cs @@ -4,7 +4,7 @@ using ReadLine.Abstractions; namespace ReadLine { - internal class KeyHandler { + public class KeyHandler { private int _cursorPos; private int _cursorLimit; private readonly StringBuilder _text; diff --git a/src/ReadLine/ReadLine.csproj b/src/ReadLine/ReadLine.csproj index 6527cff..1b75189 100755 --- a/src/ReadLine/ReadLine.csproj +++ b/src/ReadLine/ReadLine.csproj @@ -4,7 +4,7 @@ A GNU-Readline like library for .NET/.NET Core ReadLine 1.2.0 - Toni Solarin-Sodara + Toni Solarin-Sodara;Latency McLaughlin netcoreapp2.0;net47 portable ReadLine @@ -22,6 +22,7 @@ false true snKey.snk + true diff --git a/test/ReadLine.Tests/Abstractions/Console2.cs b/test/ReadLine.Tests/Abstractions/Console2.cs index d87f23d..c84ce25 100644 --- a/test/ReadLine.Tests/Abstractions/Console2.cs +++ b/test/ReadLine.Tests/Abstractions/Console2.cs @@ -1,50 +1,43 @@ -using Internal.ReadLine.Abstractions; - -namespace ReadLine.Tests.Abstractions -{ - internal class Console2 : IConsole - { - public int CursorLeft => _cursorLeft; - - public int CursorTop => _cursorTop; - - public int BufferWidth => _bufferWidth; - - public int BufferHeight => _bufferHeight; - - private int _cursorLeft; - private int _cursorTop; - private int _bufferWidth; - private int _bufferHeight; - - public Console2() - { - _cursorLeft = 0; - _cursorTop = 0; - _bufferWidth = 100; - _bufferHeight = 100; - } - - public void SetBufferSize(int width, int height) - { - _bufferWidth = width; - _bufferHeight = height; - } - - public void SetCursorPosition(int left, int top) - { - _cursorLeft = left; - _cursorTop = top; - } - - public void Write(string value) - { - _cursorLeft += value.Length; - } - - public void WriteLine(string value) - { - _cursorLeft += value.Length; - } +using ReadLine.Abstractions; + +namespace ReadLine.Tests.Abstractions { + internal class Console2 : IConsole { + public int CursorLeft => _cursorLeft; + + public int CursorTop => _cursorTop; + + public int BufferWidth => _bufferWidth; + + public int BufferHeight => _bufferHeight; + + private int _cursorLeft; + private int _cursorTop; + private int _bufferWidth; + private int _bufferHeight; + + public Console2() { + _cursorLeft = 0; + _cursorTop = 0; + _bufferWidth = 100; + _bufferHeight = 100; + } + + public void SetBufferSize(int width, int height) { + _bufferWidth = width; + _bufferHeight = height; + } + + public void SetCursorPosition(int left, int top) { + _cursorLeft = left; + _cursorTop = top; + } + + public void Write(string value) { + _cursorLeft += value.Length; + } + + public void WriteLine(string value) { + _cursorLeft += value.Length; } + } } \ No newline at end of file diff --git a/test/ReadLine.Tests/KeyHandlerTests.cs b/test/ReadLine.Tests/KeyHandlerTests.cs index 8d4644e..259b3f4 100644 --- a/test/ReadLine.Tests/KeyHandlerTests.cs +++ b/test/ReadLine.Tests/KeyHandlerTests.cs @@ -1,423 +1,396 @@ using System; using System.Collections.Generic; using Xunit; - using ReadLine.Tests.Abstractions; -using Internal.ReadLine; namespace ReadLine.Tests { - public class KeyHandlerTests - { - private KeyHandler _keyHandler; - private ConsoleKeyInfo _keyInfo; - private List _history; - private string[] _completions; + public class KeyHandlerTests { + private KeyHandler _keyHandler; + private ConsoleKeyInfo _keyInfo; + private readonly List _history; + private readonly string[] _completions; + + public KeyHandlerTests() { + _completions = new[] { + "World", + "Angel", + "Love" + }; + _history = new List(new[] { + "dotnet run", + "git init", + "clear" + }); + _keyHandler = new KeyHandler(new Console2(), _history, null); + + _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('e', ConsoleKey.E, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); + _keyHandler.Handle(_keyInfo); + } + + [Fact] + public void TestWriteChar() { + Assert.Equal("Hello", _keyHandler.Text); + + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hello World", _keyHandler.Text); + } + + [Fact] + public void TestBackspace() { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hell", _keyHandler.Text); + } + + [Fact] + public void TestDelete() { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hell", _keyHandler.Text); + } + + [Fact] + public void TestDelete_EndOfLine() { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hello", _keyHandler.Text); + } + + [Fact] + public void TestControlH() { + _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, true); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hell", _keyHandler.Text); + } + + [Fact] + public void TestHome() { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('S', ConsoleKey.S, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("SHello", _keyHandler.Text); + } + + [Fact] + public void TestControlA() { + _keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, true); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('S', ConsoleKey.S, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("SHello", _keyHandler.Text); + } + + [Fact] + public void TestEnd() { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hello!", _keyHandler.Text); + } + + [Fact] + public void TestControlE() { + _keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, true); + _keyHandler.Handle(_keyInfo); - public KeyHandlerTests() - { - _completions = new string[] { "World", "Angel", "Love" }; - _history = new List(new string[] { "dotnet run", "git init", "clear" }); - _keyHandler = new KeyHandler(new Console2(), _history, null); - - _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('e', ConsoleKey.E, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('E', ConsoleKey.E, false, false, true); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); - _keyHandler.Handle(_keyInfo); - } + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestWriteChar() - { - Assert.Equal("Hello", _keyHandler.Text); + Assert.Equal("Hello!", _keyHandler.Text); + } - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestLeftArrow() { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hell No", _keyHandler.Text); + } - _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("Hello World", _keyHandler.Text); - } + [Fact] + public void TestControlB() { + _keyInfo = new ConsoleKeyInfo('B', ConsoleKey.B, false, false, true); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hell No", _keyHandler.Text); + } - [Fact] - public void TestBackspace() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestRightArrow() { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hell", _keyHandler.Text); - } + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.RightArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestDelete() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hell", _keyHandler.Text); - } + Assert.Equal("Hello!", _keyHandler.Text); + } - [Fact] - public void TestDelete_EndOfLine() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestControlF() { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello", _keyHandler.Text); - } + _keyInfo = new ConsoleKeyInfo('F', ConsoleKey.F, false, false, true); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestControlH() - { - _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, true); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hell", _keyHandler.Text); - } + Assert.Equal("Hello!", _keyHandler.Text); + } - [Fact] - public void TestHome() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestControlL() { + _keyInfo = new ConsoleKeyInfo('L', ConsoleKey.L, false, false, true); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('S', ConsoleKey.S, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal(string.Empty, _keyHandler.Text); + } - Assert.Equal("SHello", _keyHandler.Text); - } + [Fact] + public void TestUpArrow() { + for (int i = _history.Count - 1; i >= 0; i--) { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestControlA() - { - _keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, true); - _keyHandler.Handle(_keyInfo); + Assert.Equal(_history[i], _keyHandler.Text); + } + } - _keyInfo = new ConsoleKeyInfo('S', ConsoleKey.S, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestControlP() { + for (int i = _history.Count - 1; i >= 0; i--) { + _keyInfo = new ConsoleKeyInfo('P', ConsoleKey.P, false, false, true); + _keyHandler.Handle(_keyInfo); - Assert.Equal("SHello", _keyHandler.Text); - } + Assert.Equal(_history[i], _keyHandler.Text); + } + } - [Fact] - public void TestEnd() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestDownArrow() { + for (int i = _history.Count - 1; i >= 0; i--) { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + } - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); - _keyHandler.Handle(_keyInfo); + foreach (var t in _history) { + Assert.Equal(t, _keyHandler.Text); - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.DownArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + } + } - Assert.Equal("Hello!", _keyHandler.Text); - } + [Fact] + public void TestControlN() { + for (int i = _history.Count - 1; i >= 0; i--) { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + } - [Fact] - public void TestControlE() - { - _keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, true); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('E', ConsoleKey.E, false, false, true); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("Hello!", _keyHandler.Text); - } - - [Fact] - public void TestLeftArrow() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("Hell No", _keyHandler.Text); - } - - [Fact] - public void TestControlB() - { - _keyInfo = new ConsoleKeyInfo('B', ConsoleKey.B, false, false, true); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("Hell No", _keyHandler.Text); - } - - [Fact] - public void TestRightArrow() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.RightArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("Hello!", _keyHandler.Text); - } - - [Fact] - public void TestControlF() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('F', ConsoleKey.F, false, false, true); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("Hello!", _keyHandler.Text); - } - - [Fact] - public void TestControlL() - { - _keyInfo = new ConsoleKeyInfo('L', ConsoleKey.L, false, false, true); - _keyHandler.Handle(_keyInfo); - - Assert.Equal(string.Empty, _keyHandler.Text); - } - - [Fact] - public void TestUpArrow() - { - for (int i = _history.Count - 1; i >= 0 ; i--) - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal(_history[i], _keyHandler.Text); - } - } - - [Fact] - public void TestControlP() - { - for (int i = _history.Count - 1; i >= 0 ; i--) - { - _keyInfo = new ConsoleKeyInfo('P', ConsoleKey.P, false, false, true); - _keyHandler.Handle(_keyInfo); - - Assert.Equal(_history[i], _keyHandler.Text); - } - } - - [Fact] - public void TestDownArrow() - { - for (int i = _history.Count - 1; i >= 0 ; i--) - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - } - - for (int i = 0; i < _history.Count; i++) - { - Assert.Equal(_history[i], _keyHandler.Text); - - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.DownArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - } - } - - [Fact] - public void TestControlN() - { - for (int i = _history.Count - 1; i >= 0 ; i--) - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - } - - for (int i = 0; i < _history.Count; i++) - { - Assert.Equal(_history[i], _keyHandler.Text); - - _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, true); - _keyHandler.Handle(_keyInfo); - } - } - - [Fact] - public void TestControlU() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('U', ConsoleKey.U, false, false, true); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("o", _keyHandler.Text); - - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('U', ConsoleKey.U, false, false, true); - _keyHandler.Handle(_keyInfo); - - Assert.Equal(string.Empty, _keyHandler.Text); - } - - [Fact] - public void TestControlK() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("Hell", _keyHandler.Text); - - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); - _keyHandler.Handle(_keyInfo); - - Assert.Equal(string.Empty, _keyHandler.Text); - } - - [Fact] - public void TestControlW() - { - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); + foreach (var t in _history) { + Assert.Equal(t, _keyHandler.Text); - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, true); + _keyHandler.Handle(_keyInfo); + } + } - _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestControlU() { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('U', ConsoleKey.U, false, false, true); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal("o", _keyHandler.Text); - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello ", _keyHandler.Text); + _keyInfo = new ConsoleKeyInfo('U', ConsoleKey.U, false, false, true); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal(string.Empty, _keyHandler.Text); + } - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestControlK() { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal(string.Empty, _keyHandler.Text); - } + _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestTab() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal("Hell", _keyHandler.Text); - // Nothing happens when no auto complete handler is set - Assert.Equal("Hello", _keyHandler.Text); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyHandler = new KeyHandler(new Console2(), _history, (t, s) => _completions); + _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal(string.Empty, _keyHandler.Text); + } - _keyInfo = new ConsoleKeyInfo('i', ConsoleKey.I, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestControlW() { + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); + _keyHandler.Handle(_keyInfo); - for (int i = 0; i < _completions.Length; i++) - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal($"Hi {_completions[i]}", _keyHandler.Text); - } - } + _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hello ", _keyHandler.Text); + + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); + _keyHandler.Handle(_keyInfo); + + Assert.Equal(string.Empty, _keyHandler.Text); + } + + [Fact] + public void TestTab() { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + _keyHandler.Handle(_keyInfo); + + // Nothing happens when no auto complete handler is set + Assert.Equal("Hello", _keyHandler.Text); + + _keyHandler = new KeyHandler(new Console2(), _history, (t, s) => _completions); + + _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('i', ConsoleKey.I, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); + + foreach (var t in _completions) { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal($"Hi {t}", _keyHandler.Text); + } + } - [Fact] - public void TestBackwardsTab() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestBackwardsTab() { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + _keyHandler.Handle(_keyInfo); - // Nothing happens when no auto complete handler is set - Assert.Equal("Hello", _keyHandler.Text); + // Nothing happens when no auto complete handler is set + Assert.Equal("Hello", _keyHandler.Text); - _keyHandler = new KeyHandler(new Console2(), _history, (t, s) => _completions); + _keyHandler = new KeyHandler(new Console2(), _history, (t, s) => _completions); - _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('i', ConsoleKey.I, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('i', ConsoleKey.I, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); - // Bring up the first Autocomplete - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); - _keyHandler.Handle(_keyInfo); + // Bring up the first Autocomplete + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + _keyHandler.Handle(_keyInfo); - for (int i = _completions.Length - 1; i >= 0; i--) - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, true, false, false); - _keyHandler.Handle(_keyInfo); + for (var i = _completions.Length - 1; i >= 0; i--) { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, true, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal($"Hi {_completions[i]}", _keyHandler.Text); - } - } + Assert.Equal($"Hi {_completions[i]}", _keyHandler.Text); + } } -} + } +} \ No newline at end of file diff --git a/test/ReadLine.Tests/ReadLine.Tests.csproj b/test/ReadLine.Tests/ReadLine.Tests.csproj index 48c09a1..a0e11ab 100755 --- a/test/ReadLine.Tests/ReadLine.Tests.csproj +++ b/test/ReadLine.Tests/ReadLine.Tests.csproj @@ -1,13 +1,12 @@  - netcoreapp1.1 + netcoreapp2.0 portable ReadLine.Tests ReadLine.Tests true $(PackageTargetFallback);dotnet5.4;portable-net451+win8 - 1.1.1 @@ -15,10 +14,10 @@ - - + + - + diff --git a/test/ReadLine.Tests/ReadLineTests.cs b/test/ReadLine.Tests/ReadLineTests.cs index 7debc6a..fdcd3a2 100755 --- a/test/ReadLine.Tests/ReadLineTests.cs +++ b/test/ReadLine.Tests/ReadLineTests.cs @@ -2,45 +2,40 @@ using System.Linq; using Xunit; -using static System.ReadLine; - -namespace ReadLine.Tests -{ - public class ReadLineTests : IDisposable - { - public ReadLineTests() - { - string[] history = new string[] { "ls -a", "dotnet run", "git init" }; - AddHistory(history); - } +namespace ReadLine.Tests { + public class ReadLineTests : IDisposable { + public ReadLineTests() { + string[] history = { + "ls -a", + "dotnet run", + "git init" + }; + ReadLine.AddHistory(history); + } - [Fact] - public void TestNoInitialHistory() - { - Assert.Equal(3, GetHistory().Count); - } + [Fact] + public void TestNoInitialHistory() { + Assert.Equal(3, ReadLine.GetHistory().Count); + } - [Fact] - public void TestUpdatesHistory() - { - AddHistory("mkdir"); - Assert.Equal(4, GetHistory().Count); - Assert.Equal("mkdir", GetHistory().Last()); - } + [Fact] + public void TestUpdatesHistory() { + ReadLine.AddHistory("mkdir"); + Assert.Equal(4, ReadLine.GetHistory().Count); + Assert.Equal("mkdir", ReadLine.GetHistory().Last()); + } - [Fact] - public void TestGetCorrectHistory() - { - Assert.Equal("ls -a", GetHistory()[0]); - Assert.Equal("dotnet run", GetHistory()[1]); - Assert.Equal("git init", GetHistory()[2]); - } + [Fact] + public void TestGetCorrectHistory() { + Assert.Equal("ls -a", ReadLine.GetHistory()[0]); + Assert.Equal("dotnet run", ReadLine.GetHistory()[1]); + Assert.Equal("git init", ReadLine.GetHistory()[2]); + } - public void Dispose() - { - // If all above tests pass - // clear history works - ClearHistory(); - } + public void Dispose() { + // If all above tests pass + // clear history works + ReadLine.ClearHistory(); } -} + } +} \ No newline at end of file From bc732feb1853a0518dc858d942331c36d8fc5598 Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Mon, 25 Sep 2017 16:53:27 -0700 Subject: [PATCH 05/21] Updated MSBuild configuration and assembly dependancies. --- ReadLine.1.2.1.nupkg | Bin 23402 -> 0 bytes artifacts/ReadLine.1.2.1.nupkg | Bin 0 -> 18932 bytes src/ReadLine.Demo/ReadLine.Demo.csproj | 1 - src/ReadLine/ReadLine.csproj | 30 +++++++++++++++++----- test/ReadLine.Tests/ReadLine.Tests.csproj | 1 - 5 files changed, 24 insertions(+), 8 deletions(-) delete mode 100644 ReadLine.1.2.1.nupkg create mode 100644 artifacts/ReadLine.1.2.1.nupkg diff --git a/ReadLine.1.2.1.nupkg b/ReadLine.1.2.1.nupkg deleted file mode 100644 index 539f03f8285a1042d6ca16fe72aa436ca8eadcce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23402 zcmb5V1#BJ7vhQn%W2QJ}W@ct)W@axlGegYGY{$%Y%uF%F49m<+%gjtS-@f~4-*cYc z)jK0qOQY_tsV>!w)c^Ulk}TvGIIw>%PZw@kJKwbPb8s-Qe+(WB56sXRVC%xj@J~xr zhy_NK|NUP>|9f-U*~=&BX=h914sdp{aiF;VF|l#5 zaIkZ7bF&(Av2mGj{cC-HbMb#9TtMk>#e4^Y0E78g#V8ECpo&9)fk{Atfg%5`nE#fy z|6A2GtI680F`;bWg79I^P&(Ju<+K?Rjp(Q#Dd7g5`v8-O)?{1qO4P(oKqqq#hXQk#sxg#Ed>w^(+gHDts z@Cw-US8ZsAV6Yeyn!Hj9@s66zPyn@=znUiYsp{zxX4%+$*VdZsW*G=gUB6XiC2*=l zZ2!*sbG2Ec)co}gqJIh=8&`?04EK z19l~PU*pQsZS?bQp*fTk_<7em5=jq6hq<^g_}-4B3W0eifrUt5^g4{Ch8}daH?x6} z6ih!YX5*^G{`i}@=Yj{h&c@-=tV=I3?I~=op~hE2@ag9uSI1 zx`~YJs5*W>P>8}+44M((`_L8abLud<0qds-eYBX*WS#CC4zcn*0y;BhpW+)Edjbmc zYEWd5BPlE&7cwy~HLwreY|q4wphT9Za>sg$gl`s96aG-D-Di?wGB~mZJX;dgNv`uV z4@X$cXGfJ@u+4TQYlbA9DL;X+#kJ{{j}yDljR@~6Q^(kK6hp71bQ^BNE!=O?u?7CX z-x!5j*xL#a**g5p<3FElnfwe=-rUG^Y3p9PYUk4<@S}b&^%^91Eg(v-xk70FWHoBJ zFzhVXcCuJ_r-z;-{IAtGY4q#Y=(oS0Cps`NjK9@rYh}V{4{&8;|IhnuW^4O@E6Q^n zA4k0dH^Ik?jZWH89a&mk|1}%4$ony!Q-J9$69}Lykpz(SM@98&?nq)ZIM=_>hs7nW zBQ{&VcR?0tyEEVO+Gg?3v zKf6&hXUWy`nSOkq;@*1xYquAbpK*%Hfe{G40&fYRZxu%zFTHuUPhuQ?^dgw!J)O@< zi;o+V17)_1X)d|aob2ebWewVtgt(0+7p@%U7N#4};U=n6ZK>7ObX&V?SZBm1a}chV zw9|ZQb+0)3m{q{6NUc$|u2qEuECEU=4QYK%|G6BT8P%w1#XtrBB=zS{J#D)EX9?&T zVHNk@?^-+~0IC)thb74o>Fc0?oo`rQHw}Lzd!5P=9JHLiwY5w<>znMF&EBuGJ@@oU z!nPUrY}!5Lxz@xaYxIo$uB#a&>7EL;@7XFCd!HqfB8?RbXibuOl@ey~Pug@Yyt(CL ziClbb2jcH{^3`hy6{__-e1Ku%-rs^lAri_+tIgr%!;|%>onBiv-RdyS-e04XHzJDJ z4h5HcWeZP<&S{~?i!^pIdkd1z3ICAK!z}Sc9FtGAs~y(NC&59QwbcmOh3W8JYY0q{ zm&h-y7pV@<(P0va4Dm;L$7hV9!}vhqi;r$)&Fgy6|iM7X!?$ zjVGvq?~*39_}x11;Gwr!w6aFla9#um)}na+2MJvC{SFaXC&a^Ke)DBj`J+)%g(^+kzYYyPtt&55XN8uG}+ zq5!D5RDG6;}gJ~Dxyc%Paj8wocZ#93c#@Xzp-*}lFoA-J(D1;du zMBMLDqsddzw{j~qE(T`VDb?20D;nfg+A@pIvF`dypv#CP@${tJo-o@7oSwJ1q#A9R zhftf5o-Q4Tut*By2<2ildP5;H4?G2TNNtqS^wRU#W0weip&_tKX zW>ZSFVY5vJWwvfI@n$VV;{gjKX_s9M9d`>yDtWyD=csq8*H9~JOm^}%|3tMzrETE3 zI@H?o7|zPernqEu4r<+i$G}N{7}w|bZ>1}5_Pe*Yx|}sM8x>CA%R_O0Rt^4$s1k@e z@iTTcUsJR@{YkD|{uO1;z;SX^>B(#mZlq3bG^ndJTQQ8=o{fT4Gm)VjW0$xZh^I}^ zvU5X2PsCY2I3(1ikDUUgODCOsEGVf>!F)I-w;}w zp}b|rHqU_*ziY6hrrqx_uaUxrg0cP>tX;*iJXHXhn-!3J=<_V+)4;v5xW3qsy&p0W z_`yjbvhm)wN~*2fCXnKBepWn;lP83sQ0TRhNbF5oxv6{dfPZ{`=>B_a_(OXs(`g9K zhfBrdY;@Xzey{U$x|yR={qZRy%i+rwj7{)jIWPN0{wmO$FulSj{Ha54!!*S3seCCJ z69GL@dK&6SsdN=WDdXuSRJv;S=o{z#BSP}jmyAU?JG2*{!p|UqA1~-TIVdm4BE5hf zaPOr4ENR09?OWss?#sWUzGf02ZlbeTNw|JY8cprZo`j;z@w%0Ui+hXjyRKdgmbH;N^yqdo-MgtuaqX)y0l@R>Y{x(p1M1c69bed0Aq z8B4!c5M4>3nrN)QeTS-?QQM@`5#|*Ai0>=ckhd9V&WCP7%wKCdWsfzV_yWp8nS&OQ z&#x|;xr8qhScd2rUI(|%_7QSG`JfCH5X;TCEtB^Ndmy=i4#pK)n=I!TfmF;hc(3it z-X4y~pPuavL8>Dse5Ye8KTf%w;VsB!8hfm8-6q<)v8bojnFa+XtH47e& zGguP<37<7ins}MwTkOqUgS_up&*J0V;ZGhCan0DyikyVG3A^)|JEkQ+L+V+N`3c2c zC5GJKVngB}avx_p3!mfSFBY-h`z1wZ?ZtCN;<40)`~~rO9<7XV z)(e4qb=new4>LtPMU~#6Kfk41&lKl7yi$ELzk??{{voiK5A-Ya(g6|1j9Q^Kz^Dp7O8_&dV*??67GGDRZ z2PF;Ju)5Dl=?6i*YL{4#tUBcH@$n4SieOeZ`~%smf!D zxW8KRDj~X&!Cf26N%3!0n@u00_;7?TH*ydDL|0CD%@#eAwL^8ftcs5CF%<14@2)K| z7Dk?NKqWP3Jrb4UMG&v5WV1$6S3h=Ddiq4oDar=qX7gMooc4D)2vEI+ZRdnWf0Zqo zeJGW-100*A!`jxVusBP7BPvb9%n5M!vYeQ*_87+q8;M{&EZcjPQ!MD20wK+Wsu@ zf(AjkK-}42+1-{r7 zae&svT7%qY&huO6s6Z(1u%KZOZoU<$48&HgkMfcNJPQ4Y1ulj3Fr=`RW=-7{_uX{? z%R&Sg@642*MA*4w`_&Yo9aX&VVEE;y=c4b>CeRUY83O&5erNuneEzdNmyw>{WFdTs zsQ;zg)&Rl|k>x$9j}5DXj3>ZNojQOLYkLK;(lh{}kl^crQx!~*L41#E6sgNwt~9wN zga8$|#$Y*>LA^;9W`ac`&1ODp#S+y55H&(elZsJek)AM$^ z11I07o?M4kMLCf>9^_~o?iCJL7E@9Wv~q1*Qx#XR9gyX{tcE9-P1#%*$8}Xl87PzM z2RRwrr^j@D<(3X;Sm*Ez4I9G~Z|$}1G1;GU^Yg4`%H$1+yVTkNh|V*nc=eGU2hJbM z8uqZq^@|rTC$#kEejT;(YiCRz(0%XT{OwBN0_1leo6;3+S6d~q-F8!6%S2rXZ4)>!hIT>dBMcT1Iy*!Y$eDe?onp?lN`mQQ8LBbZ)GWOHu_| zSkUtv_6t|sdtZHShZqjyIo}GLjA>D8T1%>CT16kBA$BaroXh!?7?9LQm=Q=$Oza_O zSsbzsLYi2TcC$!eZC=OmUA&pjp}6Uq&Lt=Fy&rnw|Fn>g1xz8WJ*zx8j)^-zc2rQq zxAS#t1u(vFS+^4mxzyKj^6s>$vgD~`R#_AOL3`M5qVc2_Q$m-rB#&h;_ z!{PwoY9#?Owt-U(53BY)x*H5RxcRE0rP@6QbHm{x6N0NwGSG_0K z*HuZ$+cH~49u=#536UWobxyaIy3Z- zq)U(%MS}R@|Fp3uW=-w;G`1h}jXsUzne0<~Wdt;u`KVy0<}t~-%w^-ZP64SJqQQBq zPzcA}X@c3wPg|K5%r;%PIrS?T4-QIZ`Xb}bv<1FA(8^ltGJw%-iKKcgi{!Q*i*#>8 z7~)MSvrgW45V8AtqUGiDT?{jPaJwQGzbY#PDHafn&2ll2>TjDB{K3HnG3;;mH{3AU z&m_BA_tZdn`(QeGZ;Mje?^vzB^NmSQ>J&Ezpq9m3KBIyRyK9BDE-<7YaC9J}xg;^1 z>B81=aBvFbC z3r?&bTno{W@(nf+9m%B#M2xXb&s!>q913YZ0wdWk04IBU53DSxL!B)=6{Rhbypy^U zV=A>d)eIN1DVH#viFA}(vMH~WfDb`|XIQta?)%~jVa(MFE)a;8TO$wvjxm4>v6DJO zz{DvAY?81L-KpK=b#|41wduuXDjJtl1^lKfKQ8^1?TE^dz3^^4_egGJ9}(CNF@eQW zWEZgwrIeNCQn9Lma-_VllQZQtp9qudf*&yiq2n6bL`^j+b=RnNgwnrr<2a)Q7W8HJ zdmm*?Ji+3dpziX>Rxsje^YFTw{qNC-9BEzWS>!zDTpvC}?~~KtGHg@^_2u$KW|FpB zzY{4A0l%XGXLE8xdg~dcZEk}}ko*H{nS&j8n09Ga->s!NZUqaSV}HJ%v#w-F-i z8f=oDELhTW(r@~-JX7A%v!0LQJ90G?Qr$4VLIx@y|DuW%_Gp%1AK;oX6;+@JMXR+M z!5*d;Z4X|HOugC8R`#Uzy4^aCmp&!j&!@b??i*rK;k--*Y;L7qxpXN?_nS|%+Kb%K~W^juT>&N4DH-k8$r`DAAO~e z(dL9Eydv@uOCq&~lG^ZMEFzY1f;m!G=$|A_bhO&H_+9|&V!o_Gt1wHH5+ zv15zt*&4`64Nb=zhIxiM=uGz@bJJqzaN~VpZ1)rAlW^io!!HtjiR&WM6ZECzdhp=0 z={^D-`tUlRqSFH*zer(-YC$_2MR+X1gEu6|W58UI6XKrLR4%bv$L@y&BryiquBl$W zpDa{qs@HDL6s`M0MN_6x7FjW~oe%2T5K$puH z%E!h>dJx}pBE>#i_;D!3S3Vp(iA&mNTx1A;bohd?%EQqN<|+lZu8sSoA#-_JN0dRY z4xW%e zTCVx)C3(aY$I$1uJo%VT*^uGMtD9tL@8m6p@Sz*nH147D<7bd-98HP%25ia~&ToVq z%^5S4wg-{K`hetp9M(w$&d7$?&bFOJ=M>s6BV!4#OJ55f;`sqL;IOfDe2l3zsOryP z^2xtfv{CH{kf<%Q=;eR#Xj}y;VXh;E^r3%JOW?V!9 zaOats(oB^NScI!NRAWNTj2)C8vCsiE2bFj#k&Iz)^4h|w2so>OOolxK*?Po+fwf#` z9{HKgviP9IOe*_5s|Y`EE<>$AKFDMs=9r|4`;2*(z|DJB)1~v62d26?EHYf~hkb8( z?;7LbrF(d<_E|06Tek$#vlO=T4a;7gSg}?Qo=8dMF6{&ZqY}Ra*yL1V_kPR?_3F=a zWklCu&D*pq@vv{5TNa>tgBDWOToLi}9C$dOM8VavElA}Vj3nJ;La1H5f80t1CVAPS zI%D7BxsH@dKvJ$D6eq3=WcyXr*Kc_$-2e;H;U^2-InfeJ>#2JSh#Q{t2eLD7Y*2S!v+`I7fX zp!Lr@TEXNC`|u0wW-n)%fJ$SybH!2U^(Lb#S%9*rc58xLJsr3yM~P3Ilt&9?lFsKk zgIO#$RkN#|%(Qy}r7D=;!M(P7J?i4f-0-p-YElEvu$*a*I?NuPah~rfiw;Aj51r6# zL3;}9jTSgKAf^?Exv*}4eW*zLHez6W7|x`5UTieP*Pz6;^-$HF&gg-!@4>7t9j1jb zSf9Vyb#A_+6~R{u(nfq%S^FFpBr`%$BVsO?|)s$Q@KW z&0(+(IBiaj!|mbF?y?^mqsmFJgGs=i^H^H}E=chD@^HX8^FmWHYLer~1az6Ae~a#| z=q?Y=MQ2(sKm$A!&-AtT*LSY_m1M%8Y(5b&!|Sl1%H~X9bv>_d@FxyJogvX1>NC!$ z&6x_ipS}vByBq}jgO{y1u6p_+fp7iYHX|AfR(&0&LQI{#){6{r3zHe~;4_*J<~Gx} zgbgj=bA%*L<*-;dgc1^CYkinRIeD!Ag0E@aLK%|IV<;Zi4=9lxWtcWUCn$oz{@Jjr zMBa%C7j05ORau@vOE^NBjJZu06}1bet}0uESDF9hm7pvdquf`1g-PQZrt8V`bVC-p zL7QC_auOo4$v<1tw&x4sdoML$!5uSn?~ClhpEy(5vPH|fXeV#wIKS(@~gu00?* zJN_2+{PmT{oD!M9jWI2qnI|OX4@&`FoGyVc(#ZlqE9^;qo^)vr1Ev`-$&kbXyKr16 z@g_e>8B95djHCsvbilgWt!gWc?1_K&8FjOPx3OeP9xKbC@_BHZ?`)F0B`=PY1{Y=szS+%jLNa-NPU4PT>XKaY8q9wv~ zwpBZ$P%|nbWf1wp;T=tWlpfi}7lWMyFKc_3(xfpJibG6Ys}Njescgv%dy z52j~RL?Z@elvYw$wd;*K?b2?x!bLJZgsROEx9Kd?Vb$d%*7Cg+HCBK%*78o)sMqw) zglhuif<-CP6gAy3Y{gxB%9r`je@n1Ryf=Z&bbgCc;|iOVPAMEji5zN!_g2Jk@>(x* zpRQIJzCLA;>09P2GZeaM-e<*mfhVM4_+viY;i_!IOKH*-YVK?4xm>N;>LlCP9o8fN z)E&y;f=O|}X(lw!pg#N#)KeIa$ZG8(@jGx@ow1=^{O7ld#CmxI2yNJZC@bW8WqHk>_SH7B&;4@%`Vr zv!ZRPf((K|cjZUe#p*ZI^8sSssJb@A>4`3S{J~Aj@^=x@Al(V=W1i?czhcJxmZkPf zv@3@7-Dh;?o`Yu?^Sy|u{Ug7%_(VvUy)ocE)1evOFAAF;%!v;$pvz6r<_t z7YCAV2%1!;o|$HnZXEJnXg?I?O|z3EcTzuz!WUdQ@=OpzC`hqh$C z(}8xZ$2n8m7SS`1V^IPU*9GV?7q@LX4*vS%mVSb;TNx`&3VLP&zcOk_TBAEY5QL1 zGk5R4?)>~I#gaAuiX+F`QOo~}vh#twDWb$wHyxl<)kqz5vJi>|{ zIG0|@Jy_sIw%JSw~Yh_!hJ=0NL zSm>tccGdh~uS%T`M8GipbyC36IuGp}%h zC8O*}cc+>Skw#9WWj8qzR;!}Y3=H=67Iqxm8LEPOZBiGb&!LwWSiu+_PWhkp*__ zMFThz&W~o#8hEBv<~m&2$+&BKkYU^tE8k=F)!-oc@{!{*=s4TkwHsgL_?hdKJ%{-@ zZ0bP_10&LG@vyOga;tPIRYQyDEdzn=3=}e5iNfi|ni(q<=k>;B#Y^AVWtaG3Z(1&6vJtW$K{!hhDoG@0F7VpW6kw$+sKVsj9Ya zFIUj4WLMr|M5e$aSdM*~^YdVF(ybrVOhn4i=SP^wo%m$|7;*0+T9Dvd-#UK&+)uE- z79y!$d?I55c8S|DTx?N`!WQ?_kwg}JW1p`=24xUdjKs6r7OggE_1j-YQxv3XV%nZ{ zV;ljQ>G4;EX6qH1W90Yk7NNtF;&QC#GMLHW)&`OMv|8_REWya+TuG1b!YENa6lDhr z4RIsl29wUO2c^Dwu5!D|jSIiW846KG!f-=2( zT=;=?x^hWG4th7sgj$_ zrAy)TD`RjaEb&BS+^3%W2P%-ekOMl8m*MT==LcG?;YThdvLH&A$I<6yW=b2qBcVK`kLKw1!gfR@K*o-*B}e z_;3CTdp9rL9Mj`nD;L;73*YXkz!>AcXPjrES|+{+xqB$3nNQyl(Fa0AX03J$Ycm9P zK}cUqZPGQ_Nf=@2ZV+(y_FY0Wp) zo;T){>nY_fRtU{PPM0?>i6A*r@80f!;YHaKgU|lHqB}IOjzxbcP^Z;)-WS_AHnm_` z-|Li5P$cVXZANK;j=fw!UCG`UK4H(((p-GE^NJt5|EvG#=(q*@p}|4t`%`e)B`zJ$ z!)B*L9@X37J)_-+qs1Pw1R>6Hng~{kx$m?=`6N)KE|)1VltPe0s#(DW5capq z)LD%|g^VXyhM9%a9cEGWOI0DiFKGeGd_%jn6Ls*TiqCNc>Au``wSt3>RF zd|0HP@3*$90d`|wR@?Oa44v7>YPi?5I`1ZiF1+(=MMcgPM(kV|$ZGnHZ(=K%-@d!< zoReTNn<(@7(UM9CZhC^=zw&vi&K6=IO>WiqycYe8_rVbO9Q2Oh^DVp-{Pa^aSzdhx zbuO9Jc0QlcdQ2*v3fjGIwXm*?cLX@wR4&mQ2p9osu|FBn)m&( zCH)W&&(l;^p$XK-$spC*w%G$Xs^aW<0-0LGzYX8cyiO6Udo7LSF_b^OkzVG$J})4@ zSl^k-#<@B0U5`yKArac0m(~gzEu0is2(Q*fn(##B4YaWnD7-HZ``=KA$lV-{7{A{` z`}296b|g>7;h(ekWRpB7U8bWBFuX}97SHo-0Q*6Wh6 z+I6S+313o9&KPmIDr*c~oujj3ctv`>K9O_xcN5a>vGCp38`LVg=3#vN^sbhz67EVX zmJe+OZ#$&JYdeTm3O%mC2m8nHD$ljsWAm9Jk7jAr8x$+BXQ2$7_@;a9%d8wfb!5i- zQxeh>XQna1$IaO0dpkyp*kb(wjLLI`CGQm;v_^t2Sjbxz`1|6wlI*b1 zR-`0(xd_#u)yH zgPB6Djlvh=29!WUR=@FY@GXhM%a*rpJ~1hN*VAkoh{L96TjnpuUrZBoP?joomHs$o zEK{=LOlj#wl_iE?o9qZ8vOn%Fvpr&7q8;kJCJUxV_iou$zPlhid`=s#-Uj?vu`!u` zYw+mb6dvJ!C_EQeV|z1WXESC7*8hR(_#YgvYDs5y>}Jh?bgi1)W@dZ{*`z4lE{JYC z?TrNDUo@W1KQ!K`du#-Mv7Pw{WQGDv3Ty})J)&KKbVgEGlWP{xxRlL~B6Melnv6b3 zjwM9y^sCI-$JF!1FAe0*x8%&XM4QX!o-OVp-oNIvxj@i%U;u}b7&Lt_E;gOuZD0KP z$sMm~wqYmJ~V7#Z6tOa?){=ZP`*RiJq4S zw(-zg9PIl0h@`ib@{)m>#w6C0~Vy;rE#v?trgcgo-DTXDhHCmq>h zzhWXx0ayoECjXMa7nA3)P6)l~g=y&TY`#?F%1zWlm{PtKvwP~6 zN9?8|wlU#Cx%5OPtOR0{y2#E1Swjt;>};~Qm6s-FJW_SXx0Tcc;_bf*?TwNd#j$_TOQAGoT98+D%0DTqS}GLTq`FQ1-w~27l*0nQj3l{q=UYJ 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 E1C|9o0ssI2 diff --git a/artifacts/ReadLine.1.2.1.nupkg b/artifacts/ReadLine.1.2.1.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..69eac557a0c37e9afa0a3ea0da737355092eb5b4 GIT binary patch literal 18932 zcmb5!b8uxryf6ApCbn(c=EQa;nV37aZQFJxwr$(CZTn@;J@1`+?yGm}-Cea;?Nz(G zS9jO1)*qk#%1iwOfdcyX8H?bQGH`IOzW4zI^zRD|gaf2w2e7cGr~7v$$io1l$U*s! zrvK~Zs;!HM-^J2`zzJYyZ)$DDOTEO1GqAS&&%wUu^*tOT13d#fy``R& zsS&{5frvm^&(0X&z)M802+%W>HnjrKSvlI<01Su-Bn)|p6b)GPIQ0w-m{~YE8Ccl# z*@+0~|NlJy|7b<@mH-DmLp=vQdIM`a0IiMPcW*lfQ-J;dG`s(MKkNZ^PNoI``~S~A z^sG#5Mht8$>>NybEG+Cy40_D^Oa=@9R#rwPPEHnPeL5R^OG5*j|6HHGK0829U(bLY z!2I1>&+tFi_q`YY(}wfOe^(3&5HJwLe^d;ik41wsFc44_7!VNrcg6fK`}V)9nu*^N zR#=P(ox~5g<-Fk7Ci5zZ&ctD}rARvnao`M()y+4nmEK6lWe?M0r_}S%(2R(t=~<(C zfvMJ=FNf)BcXw~_ZZ%dYt>8xmGXTbZe_-E3QE{zg5ty;hw%t6ph5V!&Zk3;sHWy?1 zsD7SuAxG3EDMOL_lP+~IDd|Dy)uFx-V10;~?Sx!z&^T2c6iAqo_^ZEk{XiEpo4Ov`x5dMLo-t%xYs28@+Pl<2kXZPcDVgnF5HVCMCjOuqN zDk{|u8KWEu^qGQ5w*CoHiSvK7Ia6L(-HFFW9rq(?0_I@) z;AzR2pr;%WXEHk*N8jGDE}_ z70otk`Z%kkQoOD7q`|Sru4jSUSvi0;#W&H{+?}$IHl)niBR!=sBNaHts%&OJo^6J+w z(>Jh;3}jxKnPqnqw9|f!Y(cgVM;#+dc{J5vZf7PPM&odAte5Q4^K(~5cG4+laS5lV zxyvo!Ql0-^zp(}%I70v4YBWGVXy5f~VX9AW1#n1#uVlPuS zGPNrHHq^UeuGB6K_nPxAx~UDau^j_62-XDSEFmrS7tBatwJ$7;oB(4{5rmpi`!L`r z`z~m3@Al{#x0r*?H27E3&=4K=DibwNtn+g*! z{ji?>5YeDSJAb6*K)@D!Vk1E7|KwPj%jrtvD+;x=Y!)O%RXX{|j{E@6hJU9ic!K3% zkD*-vj)@_1@vjgEeqNbih(4>W#x5KHih}rL=Lfwvf6|Ge_{gT41LfzNZ$k~(%;r3F zVhT>v0Gj+lVwB)F$sPjZ4Pjrgp~$_I(ru|)zcnwZ<`x>bjM2kFthNxsUfH=b8r2H; z5(>gvAnsMk!kGQdDOE{2H=d-TV6{s}$Ds*2tpO90NcbdLC;xVoCHdkLAc~e9OSKeU z>fuu;v29U)0?VN>k5{Kx){0a{`mr2j#^5&D%M5p)o3jY1s{VRFaH?EdAjx^0Gs-k$ zFX|1=!ZfX_r|_FksGLwKBG6FJTH=cYH4(cMg|iqz2j)c&AW#8Awd%v5^GU_V>CXpb zZ8~f$bce07JiYTmVYTBL(&5FSr0K(h8$XRbE~e=uWjE?f{u>PfKJ4Q2 zF>_(7v+iZh_>MjNBQdZ`by$F&Qb<eA&*4qC^MqUqH$6c2q&#Sn^8d495G+vn;>g(X%xtQH~uuYHGO5enz5Yr8Cz zev-%2GUFFDRwL-JCA4^p+#q6lw_{QZ>^jh)+^KBVAaWO3HDW&W4%9@8 zFT$FLJIj`F*Fhnd0T;zf#|sxfF(KxoAE`P-ObwMc=?wy&S+s) z(^%`?f~-?h1v-+>T{6xJLRlHJ*=8w1Z?-Q!;b<0Gfiz|mXGpcONu)XSe;uX}PbMGl z|1R=3L92DZ6sTyX%+8VD8$#t&wewL=vGuyO*u+hs5SElTO|T5A`65grK8~<2&Dtqw z#(TxV(d9|UkV8Xokhzv25<_uk#Pg)Jq;Rx*j034q!z4tE8KX!#+d~3|TE?|$mM>u* z?Rp-Ks?QFStTHv8*m@>Mb+1y>c{!hAylIzRG0)#XxcU7(9js1{K)Jd7Kf-j;0o7Y+ z=^rJ!=*HD`1)M7YzYYTb4#8@4qv~|fHX8p8e~W_%I{~maJHieVF!$MsHBC2M%K9b_ zGSo>dbW28&#ycxp6^NxjkX4NA;kryzUejZyOA1tGc2j+b9wmr2cWRQMEqaTw{l?Hn zh|Q)v=FsV`Zj4GLA33+1sU7B$=iEHn7*xa6zxt|dY$3uGs$lpXBN26a1Bj zUzuu)5_%#YXZ`u8&_;qifG6v=+fSY~VLin9JJ>@$#@%r8iT(%-*~20&V$zUr-S{ZL z9mF{H9H0bIeF+FcSx$xx-1&!?SoNg~%wGW@xhfMZoDt|9H&1cElUZfOoPM*JJD)8K z+o&dinJ-7`ila~qD@Y9xz5K#U^`M)~E9S`P;W9Ig^OR>tStX`Z#wdq05Bv|LE?}*gETK9EEaY-YMbV zaM{mO@+fXw4S~~v;>hL|?JsHF5oEKOKf}K`76Aw22%|GhmkJXZdqNP?JS<5 z#&xB#deC(ASEY0r;gftOgUdB1jZn9Ev2ry@lO^=oj`>#!#MdH?5qP9O61Rjl{xaE) zd57bqMyvo0P5@_(cn^UhL9Ee|hd8TVtn$!_+h+bNr915jb8>XKH@tF1=GA$IAFEW- z?(-mf0Qg%lj_(-%uE#-n&{tQfBwnJ*cQ08*Y#FyHikSyH8-IOuY&rhGHS1$1c?uQd ztl9_m!kf^tE@+N%Q8SH7CkRe6KX7bKbDt-C>;=v1Z_Kb-FP!tjlxqg9b*vqB91`d? z61Qm&%0+;vZj!5gxnz>tG07vW01ZnNw<8PvTS=wI!1O+L-^Zop*Hf-6xrb4%Lh3ZD z6zD5j{t)dwL4G@wuY;%o+H1GW_gI_y_kn?xfDzYs*-u9~{@0^`K;VgNyAJ_7L7f;x zx)6&M*e?W>4>Y|)_ib`CGr)appeP2dCf&49L@DM5%NKeja>%6dJ*~@RCcS&khG5Y; zsU4bwy2+>~@RCXP@lnfQ1I8MdaQYFQDrp{K*@Z%h#G~N288=;pK>gILBJqO|Tl2Fu zWY-8+X?c+5aE*LPxV&$ml>-u0!?bCVrXuC;ErpRd9Zl1;?TH{K`f1?b`oR^lH{FWB zO|b;~sYrVgugCwVu8h%1U2qAaiP zEO|3iz8{SIW%Jw6j1!FL_WZ zn{J{xO0LME7Ic)0@f=p%0k;>ol$hjh>7Yt<>zqF2eBdSMTiZpNuJS_;taC<%xYG21 z)hU+od%{cigp&mXCCS*$Lv0wW{tT%d&}Jz}B3wnR*iYKQH!~Bv3jeBZ_P>$WQ%U1X zndz}g2bV@KUghi@!8KmlOhIo)wnredG*4#p68RpW{V>QKkSBWO**2RI4xx8=`|sLB zm{^R#0K4t_dx*<<{uu9&`;a%azYVvL^WORQN){E#+Jch`2PCtK=rh=v!g9>Uk#{Jw zPqCdotDD=M`~l9}Tu*JoFIjH}e?o}4Nbs-L_#$wAL8t~%1v8Kvh@*Euh>zLoKnkF) zN7w(*7HUm0rEU+sM=G`rxQ?vEKRKXy;Sttdz9Ca8ss}%*Lt5~jP>u_|bVA_mzlWGJ zPPueq%059XoPvl7=ajZ}2IZOvpI$V=@G0Adb3w@R+0soCPl;x_RFQ4hm{#i?^JFwS zMO;GrJ0%uyt7E9*umaDfKP`h0nY!f;#9vDPILLi6}7_`04;DBN*ilWhk!; zA3$8uk1II%XF^ClawT*nOnI;wmB3QC48TJu6~m^tm}Wz}i7cjZ!sCdSx1KcT97$xF zdQsJLzb~%lag)QyyL;95^CxepjbJznwx~-UaUrQ2`L0=XqmGuUDl~ck5#+`neh!A| zX%-(FPea`t8Ros2YhiO1i!?uT^iuz*$3J$`tiApUj?TCaW=6o_m`o4Tg(664c+l9$ zZD+Z^qf_0KD}sH+OO23&VMqQLI`>J#Mou@^c9;S@Jv}Y^UdqtSW<+tXw zn@T$i8oVBY5*sEQWh$t5{3c%InMx~zp<7`rc{1d=2X_@5r6XgP+{$HS0vd{2@CL_2 ztb`i`j#C+sPyZDEju!phI16K`Y*3mjlA{3&FK{=Fa4LB8bUKJYrMh&5iD3dM_PCvB z?_Vfd)4-WJt>K6j{Avv~6qHxWC}mN{SJ_AgtHi!)P|Sv>T64_MM3O&KF&L#loBP<` zhlpAnKhl86%BYKvIW8?4ynSw<|3{?hnLW*f}-jktbmE_Fobby(I|OpObNk$Ls3?+c`*e7G5;hItiZ zje^Xza4*N4l_O02Pq%qtDLa=xtR{8h6`*M8P^*f9oBhIaYzX$N3i) zD}+HeaM$PdQ=9`N*JWAR{1%kSf`alC4xP7~+Yy?H&V7uuTTIL5^~`DG7lA z5?_*wd14u=he~6t2v^I72z~L{S{+#|Y_OfSTWxYlOGJW|i5sW_py$qdd-XKHG}eI6 z((L=NYLtH0vj0A!MWRHXQ;x&zOV3~i4zHvLRV-F&Gjy&ASCfXHDM$nQnO-J>_rBC#n^14Kcbe3`L<=e zNV45v+FI3)*OD1RYxNGLeUNK>0}Nd8OBIn3WEPwa5`e*C3L0eY2F8imviu(i?9-6} z8`xRG>%20k;e?JH84+Y$`ZtEaE~}i55Nb6S1yzg^_^M#f8Zzz{T>3(%d>Gw1yF4-w z!sJzGQM-z}fb>y@D3-)IHK z?jgCD_WNzjDMJ+&ov;d9$)U z^GN=Bta{`q_Ma+h&cw?e+I3B7n*P17L#_}Fe7!CH8F)$L-FANG+zeb>Z_|lw`U6FL zetrjX*zU(ZsyJNJ{)pgO*t@~ec}x;ymrR-vyq z()7lhCb;ZPaM3$C9)HVMoa^e*Z?_%iRc`u?ml?S(wdZMSb9|1cxu>yct@<3&C#EYI zu`cF^Zt)SJtB$+Hy#Z(Mhk?szr-t{rXX1Qr$;;R*x)0Z@SwAsrZ2I3XU-Txn!DW-w%?Rr^keJNFd;7EoWPKaiOvYR9sFR|&YG_dT@2xG z>%6maxN!U;+nC{RIkTyqEvCMMTW>q3f2(|cpN!7-x-VTUQ7yx}Y<&sR0ezK|?Iuv&mEzS3{CkQe3(V9WeZUom zziG$GRpS)=*J3<7vi@$;^@;iBxpws6l2lBn!#Hy#SU>bJnppB=zXy=g6|pY*OIS-~%LUZ=#J ziN%@za_}Ec#n$Y<)*s(Wn)4A)oQ{2e{JoftY=B!1BOeD!(zqr;+1lnm@VJWjkm38S zZE}*!{u+@jB7iMrF?2WZix(?99@hmAcF$CJO7U_byh3k3Z5eOyPJEA9iYJ;=Cy$@mW>O$1SN~D6-DlWuwP#-0TVf&w9Sl zcVxGGTM=}Fu*Xn7uqK#th054&KK-0tL!upbMc=FMw)hJzDme^#LtHw6B=ZLIM*3yd z^hHvRm7=k8?Z&^!K_i>%z6Ouqkw=zp)X4@%f-Yz^k8O(SA(*35-xHM6;24d)w}XPq z_I^}+Yp|clYKO5=-D3ia7@%`575RJW=6F|Q3PF_GZ}s9Pn;NbGCpguUDPJ#o;KjvE zB1MAiQ%T{DAWFvG;gOGUa^&mQKKA+3s(7a>fB!4{t8B^}_`j2+tt+Lq&VQ05-hYwg zztaFc8yhA%hW`Vagtft0_@>Fs|3QPqPPCmLpqYIPe-7Jc?u+I%Xd!#2%p;VK+ZV zvA^@utFCO}A5NB)wf@7&jw+oluZ@pSHzRcWBwS zotp@BG(N(Hj_PXnY&~#;Bu*34z8*eWEY`gqZC;Z|VSiDU<@p&@9JaRy8>hyq{+XHv z%p4iJo@oBp9e>DeBduO#7< zFX2?0=M&)$T!Q=0Zq|-?wLcy$KXebsLnLkm-r6ar!<$J#gZEy2Ig*USaJwV}HcY7= zgJ{=Ie-5$L$Kq=7s9j3F<2T-itdLtAgc522l=iV^C)x`X5@^>4V8zCMSWSTsi^o%& zA((xwE0N(ROb@?@E3UXHB*M?KKxTxp)}fInuI5uNm(UHF_0U-ev10H74n@#kV^j;e z9izNB1GpBTN~Gahife`MGv>E`IKqrmS5weuk*K884GPv)H|Z{MpaQVReslgs`qs&} z+IA{Thx#9SmG77qih^E1I(p05env}lQUYSe`OW^u1dpKG`d)aq(wYIC@^o>vV{CKx zu~*rWuXN-ds>MvIE-~4sSCeC}ZFhE`m(n-v{{MI~J5GpCF(@PBo`VKeibfSKS8?HB zY>H+|iPs2dVlu8{KjM^fIrT(A#$ibHj(R5?W}>&;#-k`O1yt%meS`D0g)t8-lou zaweCC@$HzQn8^cB|A6u=zL8{c@v9MaiexF-UQ>5Dq15@{-4s}=e&bs@Nz5v(}IMsk0S;x-F9t-6^FNXFLd;IYs67D~!8iB!{w zIw-vi;`4a(s@#jb)}fyyxM_0K0(euz+gL~Wq7fA5@`J7{?mui@-j)T*lhi3N_~4m{K_DBShDN`WI8)iN>n;@oWAxq6G2PJdB|W24F6O=IZ4>x zq?1}0>>hAuOkf`%pw_kooKqSylyqFjWQV=n>UH@r<8T-d@rn7^3-h=OEl*YUFiHv) zIPj_x>1F2X-{R6^JlLSAp{q;kQNZI6{hi$@=V}KE2{Bsg#1#DCOUgNuoVX8QD7pJ> z*wS3CteJX{TE1bRLeQtAf>CP7E~uwKgDirIdUxQ@X?RPNA);VQnQLZd8Y6^?!Vk}6 z7Q#q{f%@rzzO}=)3D=1;GH{tV;T(7xAjroXS1@e*36x>KyFQajw3~I{!^77DH#?#f zdvSf-Seh_;=mjT4kl2|Z)qa2iKEr1l27m%9M5Q)yHM*8QBBjJXt?Ol0l<%3eqx6m= zh&-2w%`qP*pPW$s-A_@WjCPbvojnB7#Kaw_LpLFP(p@guYO#{)!*Pz?T4@$T(FPJb z6ulT&*4yyAVWBK!F9_mbhr{cJ(5I`v7ODZod4QIf%Ot)Z86yzGiGFht6otiYigL5Q zq5*O&F~nJ4J`9`4$a9YXyzVaHp1nriy>A+L?if$RyX08t>_O2H-4}RRy zCTJLUc@dL{+@N!Re&B4JIqX_Iu*<&0g=a*_{Xn%K&q(6kcgv3 z;bMIGj%=VwQ99+>&6qNOLEO9P;&qfmmJY4=2%q>nJ@{nn(&$)=7f7ZCHS*|g^Fg;v zwVGBG0OC?8gVwr`7{QE_rb}SbPT0Jg^xzk1K2RQygz$xW3gnr1*{h6%AJPU1P2Fz@)WEjaH8MUiq&IwmZ)NmTMQBshS%bw9`bj~!T7{MIh7 z-zTL!$@Dq-pRw{8t;7pv#NItL@P(V+gQZmgEJfweWee zYm}y}c|W6)kWA4H{nERno*f6vPN{~2XuxUhkw@*Pe?sL7f&*M3XlambIYX&Qu#>os z6Y2#fgRlrG9VujL@fSIUFRbG1b0!4n^?8AoIEyhA@csZok4u|%`tPLK)YyE7YaxY` zWC&_$Lf2U~L5MVN<3mKVGlf}Rahmx6_kzu-Gcp+Dg7x8B_HxrA?NxUGE@*W36Xo{M z7pauZL&DV@h_ra(9xOT8D43)r2y?>lkncx}o-W9f&_#iXOyNKiC3H*(uny_pB2`%%snadZ@&$oO}GgBvXR))awR z`X27DSk0%>K~-#}{H4fb6-it!V%;AyXzgUYp7>Xh7ns>2o-Kh@8vgLtFF~&G3aNtR zn7dLpxDzJ!8E}+5HM~6BQFHN)%O&|w*eCktD@+$`yodJij3wT$A0ixi(AJP#O&=JX zJ`9&IT5x-55k#5L*+S|t&V;nV@#5w?Acz{KN^a>S5nr zYL+C?jAqJGfjUHUNcLW|N3EP!x^(*cMQ|bbTIohRtIj?XjFQKhW#00;&7v%VJLn!Q zU!}b-W>h}Rm2*==9MF!=?9<6VDy$wv9uQHJ=35V}O1>#44v5geo8_ukAH=Q&I)Tz` zU|WxH-6f86$fgQ5wHzDqFi5IT>VnOBhGLaUoBCzTMAb7lU(y~9Gt5@?+}cu9L|r)$ z+37YmJE)#7+U`zM=#05^c2-)ZYuQY1rGDn_?q;TXPoTNAG&g6sTob~!h%sZKVWSjS zn%lt1#Z<1LZY{i}0c#nAJER{c4aa z`2L~VsSFTdX4~P&fi@HTK;ddBnttDGBz*ob&1y9Cuw#>t8G3AyfxG!v%yFzcvB3O8 zerqe5YWnD-a3PxO;X#O(7gl`>!RRkGEU#b11F>!049UZMmq_@dn1gxPGMc@zHBODi zoLN-f>L2N$yag-#P+_ie+_#A4P1Lzpha6e9C9nq{cPDe(+o@G48#jEegKeWWcaLeM) zxcPkL=;XMM>NoA*jO`InPe*QdTU!ivCpOp+46SBf?PZ#I&~$7%*L zuF<1c7Q==-BowL2e%g`?)u{384R@J!);t``5-8Uxcm{t9{4Eu!NhTUjpS1?5?;{rC zPQzAnlS~uQ=@;+S+27x5tju0*-U!zKUF(sGa>>KiR>vyE*3 z2U_a&huoj3=&M4YlRXCdHzc5*<6xDWukHn8rgef2$tsU*3TIBq{MFR`h5X5mxvD!~ ze{`Vtyp|*8P`&H|KmTyw|Aff~Ptt29CoRZ3k$z}XlvU<1Np3+N z6VeVrCn`5@Lt)U}O&XsP0U2aq9F7;tdEu#!!*(0wAGLXAlar8YHV3{-DTdxRY^Ytt z*i4^QJFf0vbdDTopr6iY!Qm#u0;G@DiYWIGbc7nMp)r)FgFh`wbhBt;K?2u~jYjIJd9u?LS2$S6x>|+rgBQUpyOHwCK?qwN#2Ni+zdvtpTZyyACRe6zZ@t7I zhmT8iNg#ZhWO5gzJ2Inq)-|noE;pl?Tsp^taF0N_hvTDztqRrw!-wNg9qp4@kH4`| zms8rC^PWWr<(1LXR9F_}8!r87Pcp!yO}H4L@d7;K9ScS*GkQ%$v9TBouKWqdll3+G zV(ZdlM6Z#_6BdgAP(`r1gKX!XFR@L#95U-jAIORqN*rs2Hf(Y`=iTCt`3D`#vw?^V z9C>iTn;nnvhYjOz%`eg`mAcLQ(C7k?l5tC@AS029>zaOE1H=bb3VtzVh%0^-UgN?a zA|h7NV^@y35#g=VLxD6^OVOD>%Zhuhe*4?$CN7EKzI!d?yL@N|9|5#u-Bolmg?Vqg z!-+w|csTE7?DMI z2@V#==*A5ZNB^R&AD*NCdH8uL{xZGI{I%uy^Q%9nuB;Oav~(a=Nm0OKX2ZvJPxzD={47`KW4-pFDRN- zU!8WsH%MJ|x{l6Lsq2rdATppcE+Ob#Z};cEyyWgIi`d`y53#>4N{zn&o3oXb+xe=v z8g?*vEgc67MsNO$TU+)Mla4)mQ=_Fz1z;*AR70}`hl}pN$;0Rz@tA;_Z}ukSk!43q zBNPQP7*h+EQ6XCYc1vGoBJ6<5N8cnI>J|H}c_@b+O6MGha}BB%9@o*O>YqQf3T{8S z#_!V64-XSHo+oB(*^d`3JC40@)6gzjiKfHfpJYTjT-A+#H0~#6ILBC=$BcvJs`%M> z+9O74opphsW`3A@oszxbzMg7#fZY>b6~V9P+iJ(Jj|2AlUj7q)2nt;`F;rr@b^ znD({Kq}iaV?`5Zsk7TIEIt9o_U1@HlXo9qjhXf^C1Cm#wA*a&Vq=E814SHxjEmw!P z`RaqT{k#2J;wx7;YM)2h?u;LX?KHnsrzAjdRHS&zNSkP6^OCa8JT(1qiq8?ALBRiwnQM0U8ao?AOx_Iq* zYQGipzJay9z2#aZrqQAx1&=5~Y;P%H%VAKAbcMaBEI2@#Hm-r(Hv%I9VQy<gjO>9eJEca3p{ahxzz~bR{+$6;P1l+Ia#gA&gK)3;?HSJ%I$yKum zh3i6mue%b(p8O2`89(ZduC%p}d;lf}@A;DTSVv)^A9~?}|EG9p+r0wyD*8t|?=j_$ z_QrB4;nJWJ>=nHK6~+xuX}hrZ`>*ulNyZp{j>tl>KZR5;Rd84M5kDe!X~d_8o47X4 z9PDTCbx&>M*mAAca*#e2Z0Eh^#aA6Ia#!VR7snRW7=ltn>wJuwaETWpSCJbCqV;d8 zqJSP~B%-hlwitMO?3PWhjNoC<7Y3e+51&;=nzL)b%&(o6IN(F{t$yuU_r$pnXIMjo zpQyoNa%dCLB?v52NN^d%@1|ZiOxz@9LCGtpuJ#=|ws{U>7VYgkCdVoZ+N(*dOYn+N z!8enO{Bp1@-sOuB9?rGe8~Eu<5h{`-Swt^;Vm}u z#s8(6{RQ&h*>V%o7*^sx*%JT1*wWrX&&p8G&hY=tE&qF@G7g~ORY5zZEw!jl4;@fb zqumG?qpx@uCWuxccAYje=B+cQ!SQtkjY9w)icQ#2eD?9<;DO@^CPqQ<0D%Fq<17Bv ziwg;YM2-#&NoE{H{M`DMohVApnQQl3)%iF3?X{aMRa-xJc07Jq|Cn#*RIq4}ITizQ$^=cKR=#5pDd-L)XL+I;Atv5MX=M5SsuW%Hvnl(} z*rR(N3gU;AZrFrY=)mR60z#DugSC{^NZg{%to_}<208yICq*KcjiDJ3sx5O{9zmd@ zmQkZ}mj6ehQbeHv25Z%)TK*H5t)=e=khdwx_OH3KB(7=LIfeB>C4@KsYc&bPTNurN zPaDFxu)6;+OZ4bhI%5xKB|zbIPXEbORNZUap2g>-&2xI+=VXOGvB4?V)%gytaY!-Q}vlhD0Sn?{{9d7S}bLuyaIO> zDEd3^^k!kr%5=f)4`HihM$`i|DEcCCJHvbLD?u?a{c;embBSYPqM+6C61tWqTYpiNEdP=;5_wu z=A!@wA+_ij$2yuH257WTJT>bpStdqb_H8k&M)~uz&`fSl5WFkE$JAF-VRez!igb8- z%p&4cX1L6ewkiaE_5q$y6$kZNC{yAwfBWoBNQa3TJp*;~ILDS^L2nvF|u%O}!?Sh+gVvF~S0qKI*CsgOCD=pRu*It8OdD)=A z(@#+L;A#xeaMLSgXQ{X@$GT|6~(ZE3w?7;Rbc+&;A$R{;dXi7I#Uh}RDqfu+Q_ zGgt$~Bb~UT-P+NM(TZ`vg|-1CQ#)$G4wVxz4&s2Kg0d2$7@zzvvZ*086x3vHO(EI| zI~T}-sqhGO{d439QeUKRwM5&5`vm@0%irU+foFl=YAGreyXOJ?|EQ(0Khd{ZPLI@) zY#q*6{wDoB{!SJ2i;7=CydCgQEuF#+{;4HwJ&(OhVYukGS}GAM;h3yONtPI9e5<9S z_%!Pw`ca`0D&uI`Iz)hKg>5#tXQFAG7$8@1Z9S<#U$cWJvP! zK$dZ=Qo(nsQf8D|+?d&WTI!a)+gy>*W9tq~@$@&uSwS{YMVwb4lknN!p>6i#3+*Yn z*d$78@pPg6jl^j>ZyzS~RTI#B0qhbyL2wHcz&$K>2N7cHn&{LvE{(tmkFU{aK+9Z>Rnv@O1}!=dOPH(#-HmqSG2Z-1 zkenq81#+vI@2_AC+=dy?2&hp@4Gh?oV`BQ;KDJlXd}g-RDAJ;9?iX~=jpJ-=BS@By zfFpwuSnl44ZqlPs?Pu9P_v!xBTi{b`#ep-F*su&~4S#ZoBa#?eU0=$xRDf*uW2W&V=bHUGe zX^a7zlJENkeCY;anl=x^}g z_np)TMczzNG!d33nC2ly2TG-$1M6TY!o@B-uYm*K)fv(ExzdOj`M&m{9ANc|G%Oi^ z&JP$;vK-ALQc=9@S4DyXr?YnF_d-Ge3S2R<=(GlYl!z_*UN}y>L|%V1(k00f92MVU&930( zH8qE38BRhyVT;QVdj4qW81T&Y(dkodzal(RxDsQ47ITpJ!PoTj+bbb1VPvAV)1(P9 zA$3I5!F0sbA)SdU{PBskChI{r1zPbWwGch>H6rf?6Fk855ga@E=4oMxc*zt#EDPhL z9h$x`6e8i(qE*%@$5t=BHl{P0EevLWA=4n@4gIU(ueX2rb~=jjUaW>KR(JqcH?8D ze?pW8-5J4;uf$r!sjmaN6T?^hVWeyvcRvFDMJov_#L8^hyIKCiHk;8lgWdIS&^lzd z!q2WIiP=Y%q)118{WQyRz$M3HDU^H1Y$+m7Q&e&*A7NS8c?`%p#ga8s_+YXWkzvii z4=sSP2UyF=X$isiCe~zSscc9NF6<;Vo2mJop_KYQHVV6mGcRm5H@1OsIZy`Scj6&2P$<{D~Z&m!$N#F{K9 zmf|(32s$iFnhM3D5#uc_b5PfcN|_Ym`OC^&_!oBaDf{y2n5B3YD`{{p&&`z&f-%l% zR+!sbSV|T}p!v@$eKnZn(O0G-_p@QV)hE@PVj5`xFObD!p+V9D3ab6h9tGMO7;&Sm znVPOnJgxi`It#YB$UoW^SiJ1ZUNzH|6nrnrFb66FWCJVzj z%NAyD4#bw6mcj?eLmY7C*h4GD7x+`ULOwZBzK1KlFBj&LdaqmQvNItaC%!+_Lk-%= z#%6=u_WHEkMn^6cWneDMlyGMm;{1^hRQE8}Smt_DGnbdMj@icvwdKv;%M~%Uy*vpl zYuEb^RVKnx-RwN_ucO=@%xoR`m&!vk+0&cH4N7W)Ca7L})7_Yag5u12XLRYo4~y=# zc`J)>Dzpx-v1kX7A>UG*%!Hab2ucgm<~}~sB#uOkz*ky{oG@%Q!b6eh0n>nGR3oc- zx&}R#4f9YeTH9Qww$0?#pUF(5R>4Ua-DXClqOZHQhfRCU?TG)Pm1LU(`6{L#kDX*? z1GSqLf4J<=6T7tcLIbh{+5}qzO_E~+P`s9plXy!aD)cX{sfss`JfDYmtjKP3o|m zCg$Rz;dwZ7cT;qC2nR>fYZxTU4Ly`;XmJTJh9QlCtP3FtlAM>X+N|1p9TxVA(8F#} z2`9gJOiA-wXm8V1x+3KWjxs%&epQOH57YDDsZzpUj<+i>X~1HB4C!U75yGFf>;S_8 zl0e=N=j_;#=%1ULtv;T6U2x!8$PzD9>YkgF3XZ{DqkAQbzqc(2?pk&jEaaUjx(LRD zp_-hl{^js;YKGHHwI{B`*(jMS)S$R-s^qPtpCbFzAQ;c#!VKhWStuE7TqsL! zQ<%l*JLjMAQy!N19@ks}++-S_ay(l4-MG78xfN}U@U?Mj4Gi+QFCib46EcA)lw;J$ zK8+Fbq<`EI=rLj`k+jJTxCqwLWRQj%%s*w1q$P;>sEH_Yk6eVJY-$xU1I~w1qvmNv zY%^l7-cD*)PTVr1dxgul&I{O>TeK9K_G%!BLiE>B$SRJ9wmSG7|GVBv>zPIyzgpK< zOH(&)97#4cNE|qIU?9j(t19K@9$Y`c#9=TCSlvgA6xOjlM^F#C1X~64*XEdmJJ4$T z>R2pbK2j2JY)`sV1PBW4Ci?9Vz*fIB7+Yv9;2@}#gJ`;0H|^)M^7HY`5}gLW$d^HZf`^XAP|~Fm|FhjqEIw_Q^XJJ{B5$Xek^Lv# z*9835({0DkxhRk8GaVe-mqYZ=lDm143Hr-6@2N*qXYnoS54|P7Ja9PPn6(@}Z;|VU z?Y(rt@T~T?w=UlK$HXD}=NnelOikzahn4XBnQ5UjD=i1=b?>>=?0PkCldtRPN?dBe zCfsDyY$-@Ks_$TB0Sem-3U?SCfQ`v-;Q8i&0+SpdB3gnlnIf%p4i%)SSe@c-EbQ`w zMUSUo1%qmvjXyDu6P@BUFX|?d^0i#55aZ3Gk^$tsQ^7VF-p~+H<5A+#n&D9XymdeB zqA+dUgk<$`h-H$u^)Y3zAZb7ToITj%oFVN^AQL3Ea5^ngqbvknOq-$-9_fUYF%w=7 z4<*dP;!ItVWL`gId5GS(h)fZ?r>PGN(nwxvUe+mjS*m%NF%&wY1o`W8nZd<%(3lFBi53j+M6>d?MEw=UTt?ZwVUQgtxIJ9c={f zwVT&gj~2S;TlWil=WFlOWmuxzQWx}W&;-gH z^|d`OUgVOo*R=sZ=pG^6?V`yE``Fj=^+~YI)2GbFh$jV*3yPq|Li@Sfur?Y zMLib0h|&q)2E>BOQpQ|l3&BRbinGybD=jk{Sj47O>jjV__a?Uuuqc3Nq*MFPDwC0< z`(cr2JkOX$286YI9V^~e&aNhm8lxrt|HV4mdza>^79WUFWy?l-+KdT3ur~Bz zvPd0FV$6&+$?2{UGHg0c|5qz#^WroRhVdwhf;aad-iBot1x-R$6fGg3we(=ORJsc* zDob`UZD%)|)O>8W=v4&$13WHX#M65AvMUHy@gyR6>Qzxe(94QKeP_~q(v(F?Ng(O_ zJnzh8rlFI`ulMHDqoZDMUw?S;{^662=HF9~isyU!y{+%9i};SzUpl@$b8JAL zy*SZ(dZ}=C>*({hyL&fgcXq#R|M_wH_u%v3>o5MUcTBfvtbXY)0;_;+*I|Zo;uM8( zuZi!Uk--*v)*|Xd0LdsAIHFp#eaGZf3c=}4V(+!!z$io7&msdFNSNG&#ri^w5J`|p*Vt~w z(VZ>=oCuPtr3IPoP!ZagTP5YpjvCOMv_XlZg(wRimpHEuDJPmD%}I(XhllDK>2_?# za5bn=P=coABMh_?+a$^c$TGVA$|`~XkyXD;JX8xvC#ba9Hld6TPacM- z90?Nl4bI|-`}eXi^Xes#Ti7-Q{rhIowxIpIWd=oYZ%d5OG7*Xk_xn$J3p58SljyNB z0lnoaY3RP`L51OT0FPm~nQ6F0JTL&dz`|#fVvc>0H!LH=h!KY)SxTW{&Om)Rz+^;< zkm{0~#Ks;09t_}JMyP=ZF{XTDr6F!5H}RO-Wq2@A{bYVUpfemeC<<|RNW*-x%$@|= zClKZ_U6R5%_~i_T#gL4X6{mq3N%7A^LJnRd>ycgopY*tYGV;h-51;i)KbA^*sZ!*X y_mClk2T7XsuLzUBpJdag2Y535PDvOw+-uhk1D8h-j=*OMuHCybJNgH@ToRxF literal 0 HcmV?d00001 diff --git a/src/ReadLine.Demo/ReadLine.Demo.csproj b/src/ReadLine.Demo/ReadLine.Demo.csproj index de7d7b5..ea2bcbb 100755 --- a/src/ReadLine.Demo/ReadLine.Demo.csproj +++ b/src/ReadLine.Demo/ReadLine.Demo.csproj @@ -6,7 +6,6 @@ ReadLine.Demo Exe ReadLine.Demo - $(PackageTargetFallback);dnxcore50 diff --git a/src/ReadLine/ReadLine.csproj b/src/ReadLine/ReadLine.csproj index 1b75189..56295ee 100755 --- a/src/ReadLine/ReadLine.csproj +++ b/src/ReadLine/ReadLine.csproj @@ -3,10 +3,10 @@ A GNU-Readline like library for .NET/.NET Core ReadLine - 1.2.0 Toni Solarin-Sodara;Latency McLaughlin - netcoreapp2.0;net47 - portable + Toni Solarin-Sodara + net47;netcoreapp2.0;netstandard2.0 + 1.2.1 ReadLine ReadLine readline;gnu;console;shell;cui @@ -14,7 +14,6 @@ https://github.com/tsolarin/readline/blob/master/LICENSE git https://github.com/tsolarin/readline - 1.6.1 false false false @@ -23,13 +22,21 @@ true snKey.snk true + Updated to support .NET Core 2.0. +Updated to support .NET Standard v2.0. +Updated to support .NET Framework v4.7. +Consolidated redundant code and expressions. +Repacked for multi-frameworks. +Updated versioning. +Updated test projects. + - + - + @@ -38,4 +45,15 @@ + + + + + + + + + + + diff --git a/test/ReadLine.Tests/ReadLine.Tests.csproj b/test/ReadLine.Tests/ReadLine.Tests.csproj index a0e11ab..c22ae78 100755 --- a/test/ReadLine.Tests/ReadLine.Tests.csproj +++ b/test/ReadLine.Tests/ReadLine.Tests.csproj @@ -6,7 +6,6 @@ ReadLine.Tests ReadLine.Tests true - $(PackageTargetFallback);dotnet5.4;portable-net451+win8 From 292257b4b0e4011c58c18e0e021ecc9e7bead314 Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Sat, 7 Oct 2017 15:29:05 -0700 Subject: [PATCH 06/21] Code formatted Allman style. --- src/ReadLine.Demo/Program.cs | 15 +- src/ReadLine/Abstractions/Console2.cs | 15 +- src/ReadLine/Abstractions/IConsole.cs | 6 +- src/ReadLine/KeyHandler.cs | 246 +++++++------ src/ReadLine/Properties/AssemblyInfo.cs | 12 +- src/ReadLine/ReadLine.cs | 23 +- test/ReadLine.Tests/Abstractions/Console2.cs | 56 +-- test/ReadLine.Tests/KeyHandlerTests.cs | 361 ++++++++++--------- test/ReadLine.Tests/ReadLineTests.cs | 46 ++- 9 files changed, 438 insertions(+), 342 deletions(-) diff --git a/src/ReadLine.Demo/Program.cs b/src/ReadLine.Demo/Program.cs index dda85d6..de8b59d 100755 --- a/src/ReadLine.Demo/Program.cs +++ b/src/ReadLine.Demo/Program.cs @@ -1,13 +1,17 @@ using System; -namespace ReadLine.Demo { - public class Program { - public static void Main(string[] args) { +namespace ReadLine.Demo +{ + public class Program + { + public static void Main(string[] args) + { Console.WriteLine("ReadLine Library Demo"); Console.WriteLine("---------------------"); Console.WriteLine(); - string[] history = { + string[] history = + { "ls -a", "dotnet run", "git init" @@ -15,7 +19,8 @@ public static void Main(string[] args) { ReadLine.AddHistory(history); ReadLine.AutoCompletionHandler = (t, s) => t.StartsWith("git ") - ? new[] { + ? new[] + { "init", "clone", "pull", diff --git a/src/ReadLine/Abstractions/Console2.cs b/src/ReadLine/Abstractions/Console2.cs index f7188d2..b2052fb 100644 --- a/src/ReadLine/Abstractions/Console2.cs +++ b/src/ReadLine/Abstractions/Console2.cs @@ -1,7 +1,10 @@ using System; -namespace ReadLine.Abstractions { - internal class Console2 : IConsole { +namespace ReadLine.Abstractions +{ + internal class Console2 : IConsole + { + public bool PasswordMode { get; set; } public int CursorLeft => Console.CursorLeft; public int CursorTop => Console.CursorTop; @@ -10,16 +13,16 @@ internal class Console2 : IConsole { public int BufferHeight => Console.BufferHeight; - public bool PasswordMode { get; set; } - public void SetBufferSize(int width, int height) => Console.SetBufferSize(width, height); - public void SetCursorPosition(int left, int top) { + public void SetCursorPosition(int left, int top) + { if (!PasswordMode) Console.SetCursorPosition(left, top); } - public void Write(string value) { + public void Write(string value) + { if (PasswordMode) value = new string(default(char), value.Length); diff --git a/src/ReadLine/Abstractions/IConsole.cs b/src/ReadLine/Abstractions/IConsole.cs index 6b764bc..65dfff9 100644 --- a/src/ReadLine/Abstractions/IConsole.cs +++ b/src/ReadLine/Abstractions/IConsole.cs @@ -1,5 +1,7 @@ -namespace ReadLine.Abstractions { - public interface IConsole { +namespace ReadLine.Abstractions +{ + public interface IConsole + { int CursorLeft { get; } int CursorTop { get; } int BufferWidth { get; } diff --git a/src/ReadLine/KeyHandler.cs b/src/ReadLine/KeyHandler.cs index 5a2a225..50070cf 100644 --- a/src/ReadLine/KeyHandler.cs +++ b/src/ReadLine/KeyHandler.cs @@ -3,19 +3,104 @@ using System.Text; using ReadLine.Abstractions; -namespace ReadLine { - public class KeyHandler { - private int _cursorPos; - private int _cursorLimit; - private readonly StringBuilder _text; +namespace ReadLine +{ + public class KeyHandler + { + private readonly IConsole _console2; private readonly List _history; - private int _historyIndex; - private ConsoleKeyInfo _keyInfo; private readonly Dictionary _keyActions; + private readonly StringBuilder _text; private string[] _completions; - private int _completionStart; private int _completionsIndex; - private readonly IConsole _console2; + private int _completionStart; + private int _cursorLimit; + private int _cursorPos; + private int _historyIndex; + private ConsoleKeyInfo _keyInfo; + + public KeyHandler(IConsole console, List history, Func autoCompleteHandler) + { + _console2 = console; + + _historyIndex = history.Count; + _history = history; + _text = new StringBuilder(); + _keyActions = new Dictionary + { + ["LeftArrow"] = MoveCursorLeft, + ["Home"] = MoveCursorHome, + ["End"] = MoveCursorEnd, + ["ControlA"] = MoveCursorHome, + ["ControlB"] = MoveCursorLeft, + ["RightArrow"] = MoveCursorRight, + ["ControlF"] = MoveCursorRight, + ["ControlE"] = MoveCursorEnd, + ["Backspace"] = Backspace, + ["Delete"] = Delete, + ["ControlH"] = Backspace, + ["ControlL"] = ClearLine, + ["UpArrow"] = PrevHistory, + ["ControlP"] = PrevHistory, + ["DownArrow"] = NextHistory, + ["ControlN"] = NextHistory, + ["ControlU"] = () => + { + while (!IsStartOfLine()) + Backspace(); + }, + ["ControlK"] = () => + { + var pos = _cursorPos; + MoveCursorEnd(); + while (_cursorPos > pos) + Backspace(); + }, + ["ControlW"] = () => + { + while (!IsStartOfLine() && _text[_cursorPos - 1] != ' ') + Backspace(); + }, + ["Tab"] = () => + { + if (IsInAutoCompleteMode()) + NextAutoComplete(); + else + { + if (autoCompleteHandler == null || !IsEndOfLine()) + return; + + var anyOf = new[] + { + ' ', + '.', + '/', + '\\', + ':' + }; + var text = _text.ToString(); + + _completionStart = text.LastIndexOfAny(anyOf); + _completionStart = _completionStart == -1 ? 0 : _completionStart + 1; + + _completions = autoCompleteHandler.Invoke(text, _completionStart); + _completions = _completions?.Length == 0 ? null : _completions; + + if (_completions == null) + return; + + StartAutoComplete(); + } + }, + ["ShiftTab"] = () => + { + if (IsInAutoCompleteMode()) + PreviousAutoComplete(); + } + }; + } + + public string Text => _text.ToString(); private bool IsStartOfLine() => _cursorPos == 0; @@ -26,7 +111,8 @@ public class KeyHandler { private bool IsEndOfBuffer() => _console2.CursorLeft == _console2.BufferWidth - 1; private bool IsInAutoCompleteMode() => _completions != null; - private void MoveCursorLeft() { + private void MoveCursorLeft() + { if (IsStartOfLine()) return; @@ -38,16 +124,19 @@ private void MoveCursorLeft() { _cursorPos--; } - private void MoveCursorHome() { + private void MoveCursorHome() + { while (!IsStartOfLine()) MoveCursorLeft(); } - private string BuildKeyInput() { - return (_keyInfo.Modifiers != ConsoleModifiers.Control && _keyInfo.Modifiers != ConsoleModifiers.Shift) ? _keyInfo.Key.ToString() : _keyInfo.Modifiers + _keyInfo.Key.ToString(); + private string BuildKeyInput() + { + return _keyInfo.Modifiers != ConsoleModifiers.Control && _keyInfo.Modifiers != ConsoleModifiers.Shift ? _keyInfo.Key.ToString() : _keyInfo.Modifiers + _keyInfo.Key.ToString(); } - private void MoveCursorRight() { + private void MoveCursorRight() + { if (IsEndOfLine()) return; @@ -59,36 +148,43 @@ private void MoveCursorRight() { _cursorPos++; } - private void MoveCursorEnd() { + private void MoveCursorEnd() + { while (!IsEndOfLine()) MoveCursorRight(); } - private void ClearLine() { + private void ClearLine() + { MoveCursorEnd(); while (!IsStartOfLine()) Backspace(); } - private void WriteNewString(string str) { + private void WriteNewString(string str) + { ClearLine(); foreach (var character in str) WriteChar(character); } - private void WriteString(string str) { + private void WriteString(string str) + { foreach (var character in str) WriteChar(character); } private void WriteChar() => WriteChar(_keyInfo.KeyChar); - private void WriteChar(char c) { - if (IsEndOfLine()) { + private void WriteChar(char c) + { + if (IsEndOfLine()) + { _text.Append(c); _console2.Write(c.ToString()); _cursorPos++; - } else { + } else + { var left = _console2.CursorLeft; var top = _console2.CursorTop; var str = _text.ToString().Substring(_cursorPos); @@ -101,7 +197,8 @@ private void WriteChar(char c) { _cursorLimit++; } - private void Backspace() { + private void Backspace() + { if (IsStartOfLine()) return; @@ -116,7 +213,8 @@ private void Backspace() { _cursorLimit--; } - private void Delete() { + private void Delete() + { if (IsEndOfLine()) return; @@ -130,7 +228,8 @@ private void Delete() { _cursorLimit--; } - private void StartAutoComplete() { + private void StartAutoComplete() + { while (_cursorPos > _completionStart) Backspace(); @@ -139,7 +238,8 @@ private void StartAutoComplete() { WriteString(_completions[_completionsIndex]); } - private void NextAutoComplete() { + private void NextAutoComplete() + { while (_cursorPos > _completionStart) Backspace(); @@ -151,7 +251,8 @@ private void NextAutoComplete() { WriteString(_completions[_completionsIndex]); } - private void PreviousAutoComplete() { + private void PreviousAutoComplete() + { while (_cursorPos > _completionStart) Backspace(); @@ -163,15 +264,19 @@ private void PreviousAutoComplete() { WriteString(_completions[_completionsIndex]); } - private void PrevHistory() { - if (_historyIndex > 0) { + private void PrevHistory() + { + if (_historyIndex > 0) + { _historyIndex--; WriteNewString(_history[_historyIndex]); } } - private void NextHistory() { - if (_historyIndex < _history.Count) { + private void NextHistory() + { + if (_historyIndex < _history.Count) + { _historyIndex++; if (_historyIndex == _history.Count) ClearLine(); @@ -180,87 +285,14 @@ private void NextHistory() { } } - private void ResetAutoComplete() { + private void ResetAutoComplete() + { _completions = null; _completionsIndex = 0; } - public string Text => _text.ToString(); - - public KeyHandler(IConsole console, List history, Func autoCompleteHandler) { - _console2 = console; - - _historyIndex = history.Count; - _history = history; - _text = new StringBuilder(); - _keyActions = new Dictionary { - ["LeftArrow"] = MoveCursorLeft, - ["Home"] = MoveCursorHome, - ["End"] = MoveCursorEnd, - ["ControlA"] = MoveCursorHome, - ["ControlB"] = MoveCursorLeft, - ["RightArrow"] = MoveCursorRight, - ["ControlF"] = MoveCursorRight, - ["ControlE"] = MoveCursorEnd, - ["Backspace"] = Backspace, - ["Delete"] = Delete, - ["ControlH"] = Backspace, - ["ControlL"] = ClearLine, - ["UpArrow"] = PrevHistory, - ["ControlP"] = PrevHistory, - ["DownArrow"] = NextHistory, - ["ControlN"] = NextHistory, - ["ControlU"] = () => { - while (!IsStartOfLine()) - Backspace(); - }, - ["ControlK"] = () => { - var pos = _cursorPos; - MoveCursorEnd(); - while (_cursorPos > pos) - Backspace(); - }, - ["ControlW"] = () => { - while (!IsStartOfLine() && _text[_cursorPos - 1] != ' ') - Backspace(); - }, - ["Tab"] = () => { - if (IsInAutoCompleteMode()) { - NextAutoComplete(); - } else { - if (autoCompleteHandler == null || !IsEndOfLine()) - return; - - var anyOf = new[] { - ' ', - '.', - '/', - '\\', - ':' - }; - var text = _text.ToString(); - - _completionStart = text.LastIndexOfAny(anyOf); - _completionStart = _completionStart == -1 ? 0 : _completionStart + 1; - - _completions = autoCompleteHandler.Invoke(text, _completionStart); - _completions = _completions?.Length == 0 ? null : _completions; - - if (_completions == null) - return; - - StartAutoComplete(); - } - }, - ["ShiftTab"] = () => { - if (IsInAutoCompleteMode()) { - PreviousAutoComplete(); - } - } - }; - } - - public void Handle(ConsoleKeyInfo keyInfo) { + public void Handle(ConsoleKeyInfo keyInfo) + { _keyInfo = keyInfo; // If in auto complete mode and Tab wasn't pressed diff --git a/src/ReadLine/Properties/AssemblyInfo.cs b/src/ReadLine/Properties/AssemblyInfo.cs index 9d08c04..ba9f49b 100644 --- a/src/ReadLine/Properties/AssemblyInfo.cs +++ b/src/ReadLine/Properties/AssemblyInfo.cs @@ -1,5 +1,7 @@ -[assembly: System.Reflection.AssemblyTitle("ReadLine")] -[assembly: System.Reflection.AssemblyDescription("A GNU-Readline like library for .NET/.NET Core")] -[assembly: System.Reflection.AssemblyFileVersion("1.2.1")] -[assembly: System.Reflection.AssemblyVersion("1.2.1")] -[assembly: System.Reflection.AssemblyInformationalVersion("1.2.1")] \ No newline at end of file +using System.Reflection; + +[assembly: AssemblyTitle("ReadLine")] +[assembly: AssemblyDescription("A GNU-Readline like library for .NET/.NET Core")] +[assembly: AssemblyFileVersion("1.2.1")] +[assembly: AssemblyVersion("1.2.1")] +[assembly: AssemblyInformationalVersion("1.2.1")] \ No newline at end of file diff --git a/src/ReadLine/ReadLine.cs b/src/ReadLine/ReadLine.cs index 67d7a81..5581f2b 100755 --- a/src/ReadLine/ReadLine.cs +++ b/src/ReadLine/ReadLine.cs @@ -2,30 +2,37 @@ using System.Collections.Generic; using ReadLine.Abstractions; -namespace ReadLine { - public static class ReadLine { +namespace ReadLine +{ + public static class ReadLine + { private static KeyHandler _keyHandler; private static List _history; - static ReadLine() { + static ReadLine() + { _history = new List(); } + public static Func AutoCompletionHandler { private get; set; } + public static bool PasswordMode { private get; set; } + public static void AddHistory(params string[] text) => _history.AddRange(text); public static List GetHistory() => _history; public static void ClearHistory() => _history = new List(); - public static Func AutoCompletionHandler { private get; set; } - public static bool PasswordMode { private get; set; } - public static string Read(string prompt = "", string defaultInput = "") { + public static string Read(string prompt = "", string defaultInput = "") + { Console.Write(prompt); - _keyHandler = new KeyHandler(new Console2() { + _keyHandler = new KeyHandler(new Console2 + { PasswordMode = PasswordMode }, _history, AutoCompletionHandler); var keyInfo = Console.ReadKey(true); - while (keyInfo.Key != ConsoleKey.Enter) { + while (keyInfo.Key != ConsoleKey.Enter) + { _keyHandler.Handle(keyInfo); keyInfo = Console.ReadKey(true); } diff --git a/test/ReadLine.Tests/Abstractions/Console2.cs b/test/ReadLine.Tests/Abstractions/Console2.cs index c84ce25..2239f50 100644 --- a/test/ReadLine.Tests/Abstractions/Console2.cs +++ b/test/ReadLine.Tests/Abstractions/Console2.cs @@ -1,43 +1,45 @@ using ReadLine.Abstractions; -namespace ReadLine.Tests.Abstractions { - internal class Console2 : IConsole { - public int CursorLeft => _cursorLeft; - - public int CursorTop => _cursorTop; +namespace ReadLine.Tests.Abstractions +{ + internal class Console2 : IConsole + { + public Console2() + { + CursorLeft = 0; + CursorTop = 0; + BufferWidth = 100; + BufferHeight = 100; + } - public int BufferWidth => _bufferWidth; + public int CursorLeft { get; private set; } - public int BufferHeight => _bufferHeight; + public int CursorTop { get; private set; } - private int _cursorLeft; - private int _cursorTop; - private int _bufferWidth; - private int _bufferHeight; + public int BufferWidth { get; private set; } - public Console2() { - _cursorLeft = 0; - _cursorTop = 0; - _bufferWidth = 100; - _bufferHeight = 100; - } + public int BufferHeight { get; private set; } - public void SetBufferSize(int width, int height) { - _bufferWidth = width; - _bufferHeight = height; + public void SetBufferSize(int width, int height) + { + BufferWidth = width; + BufferHeight = height; } - public void SetCursorPosition(int left, int top) { - _cursorLeft = left; - _cursorTop = top; + public void SetCursorPosition(int left, int top) + { + CursorLeft = left; + CursorTop = top; } - public void Write(string value) { - _cursorLeft += value.Length; + public void Write(string value) + { + CursorLeft += value.Length; } - public void WriteLine(string value) { - _cursorLeft += value.Length; + public void WriteLine(string value) + { + CursorLeft += value.Length; } } } \ No newline at end of file diff --git a/test/ReadLine.Tests/KeyHandlerTests.cs b/test/ReadLine.Tests/KeyHandlerTests.cs index 259b3f4..a8306f5 100644 --- a/test/ReadLine.Tests/KeyHandlerTests.cs +++ b/test/ReadLine.Tests/KeyHandlerTests.cs @@ -1,23 +1,22 @@ using System; using System.Collections.Generic; -using Xunit; using ReadLine.Tests.Abstractions; +using Xunit; namespace ReadLine.Tests { - public class KeyHandlerTests { - private KeyHandler _keyHandler; - private ConsoleKeyInfo _keyInfo; - private readonly List _history; - private readonly string[] _completions; - - public KeyHandlerTests() { - _completions = new[] { + public class KeyHandlerTests + { + public KeyHandlerTests() + { + _completions = new[] + { "World", "Angel", "Love" }; - _history = new List(new[] { + _history = new List(new[] + { "dotnet run", "git init", "clear" @@ -40,33 +39,14 @@ public KeyHandlerTests() { _keyHandler.Handle(_keyInfo); } - [Fact] - public void TestWriteChar() { - Assert.Equal("Hello", _keyHandler.Text); - - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("Hello World", _keyHandler.Text); - } + private KeyHandler _keyHandler; + private ConsoleKeyInfo _keyInfo; + private readonly List _history; + private readonly string[] _completions; [Fact] - public void TestBackspace() { + public void TestBackspace() + { _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); _keyHandler.Handle(_keyInfo); @@ -74,44 +54,41 @@ public void TestBackspace() { } [Fact] - public void TestDelete() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("Hell", _keyHandler.Text); - } - - [Fact] - public void TestDelete_EndOfLine() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); + public void TestBackwardsTab() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); _keyHandler.Handle(_keyInfo); + // Nothing happens when no auto complete handler is set Assert.Equal("Hello", _keyHandler.Text); - } - [Fact] - public void TestControlH() { - _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, true); + _keyHandler = new KeyHandler(new Console2(), _history, (t, s) => _completions); + + _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); _keyHandler.Handle(_keyInfo); - Assert.Equal("Hell", _keyHandler.Text); - } + _keyInfo = new ConsoleKeyInfo('i', ConsoleKey.I, false, false, false); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestHome() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('S', ConsoleKey.S, false, false, false); + // Bring up the first Autocomplete + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); _keyHandler.Handle(_keyInfo); - Assert.Equal("SHello", _keyHandler.Text); + for (var i = _completions.Length - 1; i >= 0; i--) + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, true, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal($"Hi {_completions[i]}", _keyHandler.Text); + } } [Fact] - public void TestControlA() { + public void TestControlA() + { _keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, true); _keyHandler.Handle(_keyInfo); @@ -122,21 +99,23 @@ public void TestControlA() { } [Fact] - public void TestEnd() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); + public void TestControlB() + { + _keyInfo = new ConsoleKeyInfo('B', ConsoleKey.B, false, false, true); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.Equal("Hell No", _keyHandler.Text); } [Fact] - public void TestControlE() { + public void TestControlE() + { _keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, true); _keyHandler.Handle(_keyInfo); @@ -150,63 +129,52 @@ public void TestControlE() { } [Fact] - public void TestLeftArrow() { + public void TestControlF() + { _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyInfo = new ConsoleKeyInfo('F', ConsoleKey.F, false, false, true); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); _keyHandler.Handle(_keyInfo); - Assert.Equal("Hell No", _keyHandler.Text); + Assert.Equal("Hello!", _keyHandler.Text); } [Fact] - public void TestControlB() { - _keyInfo = new ConsoleKeyInfo('B', ConsoleKey.B, false, false, true); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); + public void TestControlH() + { + _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, true); _keyHandler.Handle(_keyInfo); - Assert.Equal("Hell No", _keyHandler.Text); + Assert.Equal("Hell", _keyHandler.Text); } [Fact] - public void TestRightArrow() { + public void TestControlK() + { _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.RightArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello!", _keyHandler.Text); - } - - [Fact] - public void TestControlF() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal("Hell", _keyHandler.Text); - _keyInfo = new ConsoleKeyInfo('F', ConsoleKey.F, false, false, true); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.Equal(string.Empty, _keyHandler.Text); } [Fact] - public void TestControlL() { + public void TestControlL() + { _keyInfo = new ConsoleKeyInfo('L', ConsoleKey.L, false, false, true); _keyHandler.Handle(_keyInfo); @@ -214,57 +182,38 @@ public void TestControlL() { } [Fact] - public void TestUpArrow() { - for (int i = _history.Count - 1; i >= 0; i--) { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal(_history[i], _keyHandler.Text); - } - } - - [Fact] - public void TestControlP() { - for (int i = _history.Count - 1; i >= 0; i--) { - _keyInfo = new ConsoleKeyInfo('P', ConsoleKey.P, false, false, true); - _keyHandler.Handle(_keyInfo); - - Assert.Equal(_history[i], _keyHandler.Text); - } - } - - [Fact] - public void TestDownArrow() { - for (int i = _history.Count - 1; i >= 0; i--) { + public void TestControlN() + { + for (var i = _history.Count - 1; i >= 0; i--) + { _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); _keyHandler.Handle(_keyInfo); } - foreach (var t in _history) { + foreach (var t in _history) + { Assert.Equal(t, _keyHandler.Text); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.DownArrow, false, false, false); + _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, true); _keyHandler.Handle(_keyInfo); } } [Fact] - public void TestControlN() { - for (int i = _history.Count - 1; i >= 0; i--) { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); + public void TestControlP() + { + for (var i = _history.Count - 1; i >= 0; i--) + { + _keyInfo = new ConsoleKeyInfo('P', ConsoleKey.P, false, false, true); _keyHandler.Handle(_keyInfo); - } - - foreach (var t in _history) { - Assert.Equal(t, _keyHandler.Text); - _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, true); - _keyHandler.Handle(_keyInfo); + Assert.Equal(_history[i], _keyHandler.Text); } } [Fact] - public void TestControlU() { + public void TestControlU() + { _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); _keyHandler.Handle(_keyInfo); @@ -283,60 +232,138 @@ public void TestControlU() { } [Fact] - public void TestControlK() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + public void TestControlW() + { + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); _keyHandler.Handle(_keyInfo); - Assert.Equal("Hell", _keyHandler.Text); + _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); + _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); + _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hello ", _keyHandler.Text); + + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); _keyHandler.Handle(_keyInfo); Assert.Equal(string.Empty, _keyHandler.Text); } [Fact] - public void TestControlW() { - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + public void TestDelete() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); + Assert.Equal("Hell", _keyHandler.Text); + } + + [Fact] + public void TestDelete_EndOfLine() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); + Assert.Equal("Hello", _keyHandler.Text); + } + + [Fact] + public void TestDownArrow() + { + for (var i = _history.Count - 1; i >= 0; i--) + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + } + + foreach (var t in _history) + { + Assert.Equal(t, _keyHandler.Text); + + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.DownArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + } + } + + [Fact] + public void TestEnd() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); + Assert.Equal("Hello!", _keyHandler.Text); + } + + [Fact] + public void TestHome() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); + _keyInfo = new ConsoleKeyInfo('S', ConsoleKey.S, false, false, false); _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello ", _keyHandler.Text); + Assert.Equal("SHello", _keyHandler.Text); + } - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); + [Fact] + public void TestLeftArrow() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); _keyHandler.Handle(_keyInfo); - Assert.Equal(string.Empty, _keyHandler.Text); + _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hell No", _keyHandler.Text); + } + + [Fact] + public void TestRightArrow() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.RightArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hello!", _keyHandler.Text); } [Fact] - public void TestTab() { + public void TestTab() + { _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); _keyHandler.Handle(_keyInfo); @@ -354,7 +381,8 @@ public void TestTab() { _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); _keyHandler.Handle(_keyInfo); - foreach (var t in _completions) { + foreach (var t in _completions) + { _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); _keyHandler.Handle(_keyInfo); @@ -363,34 +391,41 @@ public void TestTab() { } [Fact] - public void TestBackwardsTab() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); - _keyHandler.Handle(_keyInfo); + public void TestUpArrow() + { + for (var i = _history.Count - 1; i >= 0; i--) + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - // Nothing happens when no auto complete handler is set + Assert.Equal(_history[i], _keyHandler.Text); + } + } + + [Fact] + public void TestWriteChar() + { Assert.Equal("Hello", _keyHandler.Text); - _keyHandler = new KeyHandler(new Console2(), _history, (t, s) => _completions); + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('i', ConsoleKey.I, false, false, false); + _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); _keyHandler.Handle(_keyInfo); - // Bring up the first Autocomplete - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); _keyHandler.Handle(_keyInfo); - for (var i = _completions.Length - 1; i >= 0; i--) { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, true, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal($"Hi {_completions[i]}", _keyHandler.Text); - } + Assert.Equal("Hello World", _keyHandler.Text); } } } \ No newline at end of file diff --git a/test/ReadLine.Tests/ReadLineTests.cs b/test/ReadLine.Tests/ReadLineTests.cs index fdcd3a2..7fa28c7 100755 --- a/test/ReadLine.Tests/ReadLineTests.cs +++ b/test/ReadLine.Tests/ReadLineTests.cs @@ -2,10 +2,14 @@ using System.Linq; using Xunit; -namespace ReadLine.Tests { - public class ReadLineTests : IDisposable { - public ReadLineTests() { - string[] history = { +namespace ReadLine.Tests +{ + public class ReadLineTests : IDisposable + { + public ReadLineTests() + { + string[] history = + { "ls -a", "dotnet run", "git init" @@ -13,29 +17,33 @@ public ReadLineTests() { ReadLine.AddHistory(history); } - [Fact] - public void TestNoInitialHistory() { - Assert.Equal(3, ReadLine.GetHistory().Count); - } - - [Fact] - public void TestUpdatesHistory() { - ReadLine.AddHistory("mkdir"); - Assert.Equal(4, ReadLine.GetHistory().Count); - Assert.Equal("mkdir", ReadLine.GetHistory().Last()); + public void Dispose() + { + // If all above tests pass + // clear history works + ReadLine.ClearHistory(); } [Fact] - public void TestGetCorrectHistory() { + public void TestGetCorrectHistory() + { Assert.Equal("ls -a", ReadLine.GetHistory()[0]); Assert.Equal("dotnet run", ReadLine.GetHistory()[1]); Assert.Equal("git init", ReadLine.GetHistory()[2]); } - public void Dispose() { - // If all above tests pass - // clear history works - ReadLine.ClearHistory(); + [Fact] + public void TestNoInitialHistory() + { + Assert.Equal(3, ReadLine.GetHistory().Count); + } + + [Fact] + public void TestUpdatesHistory() + { + ReadLine.AddHistory("mkdir"); + Assert.Equal(4, ReadLine.GetHistory().Count); + Assert.Equal("mkdir", ReadLine.GetHistory().Last()); } } } \ No newline at end of file From 69c677eb6e4cdc24d6b35d01dccfa291bd0f1b2e Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Sun, 8 Oct 2017 03:25:08 -0700 Subject: [PATCH 07/21] Change indent from 2 to 4 spaces. Updated tag in manifest. --- artifacts/ReadLine.1.2.1.nupkg | Bin 18932 -> 17985 bytes src/ReadLine.Demo/Program.cs | 50 +- src/ReadLine/Abstractions/Console2.cs | 42 +- src/ReadLine/Abstractions/IConsole.cs | 22 +- src/ReadLine/KeyHandler.cs | 510 +++++++------- src/ReadLine/ReadLine.cs | 84 +-- src/ReadLine/ReadLine.csproj | 4 +- test/ReadLine.Tests/Abstractions/Console2.cs | 76 +- test/ReadLine.Tests/KeyHandlerTests.cs | 688 +++++++++---------- test/ReadLine.Tests/ReadLine.Tests.csproj | 3 - test/ReadLine.Tests/ReadLineTests.cs | 72 +- 11 files changed, 774 insertions(+), 777 deletions(-) diff --git a/artifacts/ReadLine.1.2.1.nupkg b/artifacts/ReadLine.1.2.1.nupkg index 69eac557a0c37e9afa0a3ea0da737355092eb5b4..8e18dcd2f5e14f0ab8f6dc38b87040c756272c1d 100644 GIT binary patch literal 17985 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 FcmV(FwbK9q literal 18932 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 diff --git a/src/ReadLine.Demo/Program.cs b/src/ReadLine.Demo/Program.cs index de8b59d..8961e55 100755 --- a/src/ReadLine.Demo/Program.cs +++ b/src/ReadLine.Demo/Program.cs @@ -2,34 +2,34 @@ namespace ReadLine.Demo { - public class Program - { - public static void Main(string[] args) + public class Program { - Console.WriteLine("ReadLine Library Demo"); - Console.WriteLine("---------------------"); - Console.WriteLine(); + public static void Main(string[] args) + { + Console.WriteLine("ReadLine Library Demo"); + Console.WriteLine("---------------------"); + Console.WriteLine(); - string[] history = - { - "ls -a", - "dotnet run", - "git init" - }; - ReadLine.AddHistory(history); + string[] history = + { + "ls -a", + "dotnet run", + "git init" + }; + ReadLine.AddHistory(history); - ReadLine.AutoCompletionHandler = (t, s) => t.StartsWith("git ") - ? new[] - { - "init", - "clone", - "pull", - "push" - } - : null; + ReadLine.AutoCompletionHandler = (t, s) => t.StartsWith("git ") + ? new[] + { + "init", + "clone", + "pull", + "push" + } + : null; - var input = ReadLine.Read("(prompt)> "); - Console.Write(input); + var input = ReadLine.Read("(prompt)> "); + Console.Write(input); + } } - } } \ No newline at end of file diff --git a/src/ReadLine/Abstractions/Console2.cs b/src/ReadLine/Abstractions/Console2.cs index b2052fb..d4d2aa0 100644 --- a/src/ReadLine/Abstractions/Console2.cs +++ b/src/ReadLine/Abstractions/Console2.cs @@ -2,33 +2,33 @@ namespace ReadLine.Abstractions { - internal class Console2 : IConsole - { - public bool PasswordMode { get; set; } - public int CursorLeft => Console.CursorLeft; + internal class Console2 : IConsole + { + public bool PasswordMode { get; set; } + public int CursorLeft => Console.CursorLeft; - public int CursorTop => Console.CursorTop; + public int CursorTop => Console.CursorTop; - public int BufferWidth => Console.BufferWidth; + public int BufferWidth => Console.BufferWidth; - public int BufferHeight => Console.BufferHeight; + public int BufferHeight => Console.BufferHeight; - public void SetBufferSize(int width, int height) => Console.SetBufferSize(width, height); + public void SetBufferSize(int width, int height) => Console.SetBufferSize(width, height); - public void SetCursorPosition(int left, int top) - { - if (!PasswordMode) - Console.SetCursorPosition(left, top); - } + public void SetCursorPosition(int left, int top) + { + if (!PasswordMode) + Console.SetCursorPosition(left, top); + } - public void Write(string value) - { - if (PasswordMode) - value = new string(default(char), value.Length); + public void Write(string value) + { + if (PasswordMode) + value = new string(default(char), value.Length); - Console.Write(value); - } + Console.Write(value); + } - public void WriteLine(string value) => Console.WriteLine(value); - } + public void WriteLine(string value) => Console.WriteLine(value); + } } \ No newline at end of file diff --git a/src/ReadLine/Abstractions/IConsole.cs b/src/ReadLine/Abstractions/IConsole.cs index 65dfff9..c128a00 100644 --- a/src/ReadLine/Abstractions/IConsole.cs +++ b/src/ReadLine/Abstractions/IConsole.cs @@ -1,14 +1,14 @@ namespace ReadLine.Abstractions { - public interface IConsole - { - int CursorLeft { get; } - int CursorTop { get; } - int BufferWidth { get; } - int BufferHeight { get; } - void SetCursorPosition(int left, int top); - void SetBufferSize(int width, int height); - void Write(string value); - void WriteLine(string value); - } + public interface IConsole + { + int CursorLeft { get; } + int CursorTop { get; } + int BufferWidth { get; } + int BufferHeight { get; } + void SetCursorPosition(int left, int top); + void SetBufferSize(int width, int height); + void Write(string value); + void WriteLine(string value); + } } \ No newline at end of file diff --git a/src/ReadLine/KeyHandler.cs b/src/ReadLine/KeyHandler.cs index 50070cf..fdb40c0 100644 --- a/src/ReadLine/KeyHandler.cs +++ b/src/ReadLine/KeyHandler.cs @@ -5,303 +5,303 @@ namespace ReadLine { - public class KeyHandler - { - private readonly IConsole _console2; - private readonly List _history; - private readonly Dictionary _keyActions; - private readonly StringBuilder _text; - private string[] _completions; - private int _completionsIndex; - private int _completionStart; - private int _cursorLimit; - private int _cursorPos; - private int _historyIndex; - private ConsoleKeyInfo _keyInfo; - - public KeyHandler(IConsole console, List history, Func autoCompleteHandler) + public class KeyHandler { - _console2 = console; - - _historyIndex = history.Count; - _history = history; - _text = new StringBuilder(); - _keyActions = new Dictionary - { - ["LeftArrow"] = MoveCursorLeft, - ["Home"] = MoveCursorHome, - ["End"] = MoveCursorEnd, - ["ControlA"] = MoveCursorHome, - ["ControlB"] = MoveCursorLeft, - ["RightArrow"] = MoveCursorRight, - ["ControlF"] = MoveCursorRight, - ["ControlE"] = MoveCursorEnd, - ["Backspace"] = Backspace, - ["Delete"] = Delete, - ["ControlH"] = Backspace, - ["ControlL"] = ClearLine, - ["UpArrow"] = PrevHistory, - ["ControlP"] = PrevHistory, - ["DownArrow"] = NextHistory, - ["ControlN"] = NextHistory, - ["ControlU"] = () => + private readonly IConsole _console2; + private readonly List _history; + private readonly Dictionary _keyActions; + private readonly StringBuilder _text; + private string[] _completions; + private int _completionsIndex; + private int _completionStart; + private int _cursorLimit; + private int _cursorPos; + private int _historyIndex; + private ConsoleKeyInfo _keyInfo; + + public KeyHandler(IConsole console, List history, Func autoCompleteHandler) { - while (!IsStartOfLine()) - Backspace(); - }, - ["ControlK"] = () => - { - var pos = _cursorPos; - MoveCursorEnd(); - while (_cursorPos > pos) - Backspace(); - }, - ["ControlW"] = () => - { - while (!IsStartOfLine() && _text[_cursorPos - 1] != ' ') - Backspace(); - }, - ["Tab"] = () => - { - if (IsInAutoCompleteMode()) - NextAutoComplete(); - else - { - if (autoCompleteHandler == null || !IsEndOfLine()) - return; - - var anyOf = new[] + _console2 = console; + + _historyIndex = history.Count; + _history = history; + _text = new StringBuilder(); + _keyActions = new Dictionary { - ' ', - '.', - '/', - '\\', - ':' + ["LeftArrow"] = MoveCursorLeft, + ["Home"] = MoveCursorHome, + ["End"] = MoveCursorEnd, + ["ControlA"] = MoveCursorHome, + ["ControlB"] = MoveCursorLeft, + ["RightArrow"] = MoveCursorRight, + ["ControlF"] = MoveCursorRight, + ["ControlE"] = MoveCursorEnd, + ["Backspace"] = Backspace, + ["Delete"] = Delete, + ["ControlH"] = Backspace, + ["ControlL"] = ClearLine, + ["UpArrow"] = PrevHistory, + ["ControlP"] = PrevHistory, + ["DownArrow"] = NextHistory, + ["ControlN"] = NextHistory, + ["ControlU"] = () => + { + while (!IsStartOfLine()) + Backspace(); + }, + ["ControlK"] = () => + { + var pos = _cursorPos; + MoveCursorEnd(); + while (_cursorPos > pos) + Backspace(); + }, + ["ControlW"] = () => + { + while (!IsStartOfLine() && _text[_cursorPos - 1] != ' ') + Backspace(); + }, + ["Tab"] = () => + { + if (IsInAutoCompleteMode()) + NextAutoComplete(); + else + { + if (autoCompleteHandler == null || !IsEndOfLine()) + return; + + var anyOf = new[] + { + ' ', + '.', + '/', + '\\', + ':' + }; + var text = _text.ToString(); + + _completionStart = text.LastIndexOfAny(anyOf); + _completionStart = _completionStart == -1 ? 0 : _completionStart + 1; + + _completions = autoCompleteHandler.Invoke(text, _completionStart); + _completions = _completions?.Length == 0 ? null : _completions; + + if (_completions == null) + return; + + StartAutoComplete(); + } + }, + ["ShiftTab"] = () => + { + if (IsInAutoCompleteMode()) + PreviousAutoComplete(); + } }; - var text = _text.ToString(); - - _completionStart = text.LastIndexOfAny(anyOf); - _completionStart = _completionStart == -1 ? 0 : _completionStart + 1; - - _completions = autoCompleteHandler.Invoke(text, _completionStart); - _completions = _completions?.Length == 0 ? null : _completions; - - if (_completions == null) - return; - - StartAutoComplete(); - } - }, - ["ShiftTab"] = () => - { - if (IsInAutoCompleteMode()) - PreviousAutoComplete(); } - }; - } - public string Text => _text.ToString(); + public string Text => _text.ToString(); - private bool IsStartOfLine() => _cursorPos == 0; + private bool IsStartOfLine() => _cursorPos == 0; - private bool IsEndOfLine() => _cursorPos == _cursorLimit; + private bool IsEndOfLine() => _cursorPos == _cursorLimit; - private bool IsStartOfBuffer() => _console2.CursorLeft == 0; + private bool IsStartOfBuffer() => _console2.CursorLeft == 0; - private bool IsEndOfBuffer() => _console2.CursorLeft == _console2.BufferWidth - 1; - private bool IsInAutoCompleteMode() => _completions != null; + private bool IsEndOfBuffer() => _console2.CursorLeft == _console2.BufferWidth - 1; + private bool IsInAutoCompleteMode() => _completions != null; - private void MoveCursorLeft() - { - if (IsStartOfLine()) - return; + private void MoveCursorLeft() + { + if (IsStartOfLine()) + return; - if (IsStartOfBuffer()) - _console2.SetCursorPosition(_console2.BufferWidth - 1, _console2.CursorTop - 1); - else - _console2.SetCursorPosition(_console2.CursorLeft - 1, _console2.CursorTop); + if (IsStartOfBuffer()) + _console2.SetCursorPosition(_console2.BufferWidth - 1, _console2.CursorTop - 1); + else + _console2.SetCursorPosition(_console2.CursorLeft - 1, _console2.CursorTop); - _cursorPos--; - } + _cursorPos--; + } - private void MoveCursorHome() - { - while (!IsStartOfLine()) - MoveCursorLeft(); - } + private void MoveCursorHome() + { + while (!IsStartOfLine()) + MoveCursorLeft(); + } - private string BuildKeyInput() - { - return _keyInfo.Modifiers != ConsoleModifiers.Control && _keyInfo.Modifiers != ConsoleModifiers.Shift ? _keyInfo.Key.ToString() : _keyInfo.Modifiers + _keyInfo.Key.ToString(); - } + private string BuildKeyInput() + { + return _keyInfo.Modifiers != ConsoleModifiers.Control && _keyInfo.Modifiers != ConsoleModifiers.Shift ? _keyInfo.Key.ToString() : _keyInfo.Modifiers + _keyInfo.Key.ToString(); + } - private void MoveCursorRight() - { - if (IsEndOfLine()) - return; + private void MoveCursorRight() + { + if (IsEndOfLine()) + return; - if (IsEndOfBuffer()) - _console2.SetCursorPosition(0, _console2.CursorTop + 1); - else - _console2.SetCursorPosition(_console2.CursorLeft + 1, _console2.CursorTop); + if (IsEndOfBuffer()) + _console2.SetCursorPosition(0, _console2.CursorTop + 1); + else + _console2.SetCursorPosition(_console2.CursorLeft + 1, _console2.CursorTop); - _cursorPos++; - } + _cursorPos++; + } - private void MoveCursorEnd() - { - while (!IsEndOfLine()) - MoveCursorRight(); - } + private void MoveCursorEnd() + { + while (!IsEndOfLine()) + MoveCursorRight(); + } - private void ClearLine() - { - MoveCursorEnd(); - while (!IsStartOfLine()) - Backspace(); - } + private void ClearLine() + { + MoveCursorEnd(); + while (!IsStartOfLine()) + Backspace(); + } - private void WriteNewString(string str) - { - ClearLine(); - foreach (var character in str) - WriteChar(character); - } + private void WriteNewString(string str) + { + ClearLine(); + foreach (var character in str) + WriteChar(character); + } - private void WriteString(string str) - { - foreach (var character in str) - WriteChar(character); - } + private void WriteString(string str) + { + foreach (var character in str) + WriteChar(character); + } - private void WriteChar() => WriteChar(_keyInfo.KeyChar); + private void WriteChar() => WriteChar(_keyInfo.KeyChar); - private void WriteChar(char c) - { - if (IsEndOfLine()) - { - _text.Append(c); - _console2.Write(c.ToString()); - _cursorPos++; - } else - { - var left = _console2.CursorLeft; - var top = _console2.CursorTop; - var str = _text.ToString().Substring(_cursorPos); - _text.Insert(_cursorPos, c); - _console2.Write(c + str); - _console2.SetCursorPosition(left, top); - MoveCursorRight(); - } - - _cursorLimit++; - } + private void WriteChar(char c) + { + if (IsEndOfLine()) + { + _text.Append(c); + _console2.Write(c.ToString()); + _cursorPos++; + } else + { + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + var str = _text.ToString().Substring(_cursorPos); + _text.Insert(_cursorPos, c); + _console2.Write(c + str); + _console2.SetCursorPosition(left, top); + MoveCursorRight(); + } + + _cursorLimit++; + } - private void Backspace() - { - if (IsStartOfLine()) - return; - - MoveCursorLeft(); - var index = _cursorPos; - _text.Remove(index, 1); - var replacement = _text.ToString().Substring(index); - var left = _console2.CursorLeft; - var top = _console2.CursorTop; - _console2.Write($"{replacement} "); - _console2.SetCursorPosition(left, top); - _cursorLimit--; - } + private void Backspace() + { + if (IsStartOfLine()) + return; + + MoveCursorLeft(); + var index = _cursorPos; + _text.Remove(index, 1); + var replacement = _text.ToString().Substring(index); + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + _console2.Write($"{replacement} "); + _console2.SetCursorPosition(left, top); + _cursorLimit--; + } - private void Delete() - { - if (IsEndOfLine()) - return; - - var index = _cursorPos; - _text.Remove(index, 1); - var replacement = _text.ToString().Substring(index); - var left = _console2.CursorLeft; - var top = _console2.CursorTop; - _console2.Write($"{replacement} "); - _console2.SetCursorPosition(left, top); - _cursorLimit--; - } + private void Delete() + { + if (IsEndOfLine()) + return; + + var index = _cursorPos; + _text.Remove(index, 1); + var replacement = _text.ToString().Substring(index); + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + _console2.Write($"{replacement} "); + _console2.SetCursorPosition(left, top); + _cursorLimit--; + } - private void StartAutoComplete() - { - while (_cursorPos > _completionStart) - Backspace(); + private void StartAutoComplete() + { + while (_cursorPos > _completionStart) + Backspace(); - _completionsIndex = 0; + _completionsIndex = 0; - WriteString(_completions[_completionsIndex]); - } + WriteString(_completions[_completionsIndex]); + } - private void NextAutoComplete() - { - while (_cursorPos > _completionStart) - Backspace(); + private void NextAutoComplete() + { + while (_cursorPos > _completionStart) + Backspace(); - _completionsIndex++; + _completionsIndex++; - if (_completionsIndex == _completions.Length) - _completionsIndex = 0; + if (_completionsIndex == _completions.Length) + _completionsIndex = 0; - WriteString(_completions[_completionsIndex]); - } + WriteString(_completions[_completionsIndex]); + } - private void PreviousAutoComplete() - { - while (_cursorPos > _completionStart) - Backspace(); + private void PreviousAutoComplete() + { + while (_cursorPos > _completionStart) + Backspace(); - _completionsIndex--; + _completionsIndex--; - if (_completionsIndex == -1) - _completionsIndex = _completions.Length - 1; + if (_completionsIndex == -1) + _completionsIndex = _completions.Length - 1; - WriteString(_completions[_completionsIndex]); - } + WriteString(_completions[_completionsIndex]); + } - private void PrevHistory() - { - if (_historyIndex > 0) - { - _historyIndex--; - WriteNewString(_history[_historyIndex]); - } - } + private void PrevHistory() + { + if (_historyIndex > 0) + { + _historyIndex--; + WriteNewString(_history[_historyIndex]); + } + } - private void NextHistory() - { - if (_historyIndex < _history.Count) - { - _historyIndex++; - if (_historyIndex == _history.Count) - ClearLine(); - else - WriteNewString(_history[_historyIndex]); - } - } + private void NextHistory() + { + if (_historyIndex < _history.Count) + { + _historyIndex++; + if (_historyIndex == _history.Count) + ClearLine(); + else + WriteNewString(_history[_historyIndex]); + } + } - private void ResetAutoComplete() - { - _completions = null; - _completionsIndex = 0; - } + private void ResetAutoComplete() + { + _completions = null; + _completionsIndex = 0; + } - public void Handle(ConsoleKeyInfo keyInfo) - { - _keyInfo = keyInfo; + public void Handle(ConsoleKeyInfo keyInfo) + { + _keyInfo = keyInfo; - // If in auto complete mode and Tab wasn't pressed - if (IsInAutoCompleteMode() && _keyInfo.Key != ConsoleKey.Tab) - ResetAutoComplete(); + // If in auto complete mode and Tab wasn't pressed + if (IsInAutoCompleteMode() && _keyInfo.Key != ConsoleKey.Tab) + ResetAutoComplete(); - _keyActions.TryGetValue(BuildKeyInput(), out var action); - action = action ?? WriteChar; - action.Invoke(); + _keyActions.TryGetValue(BuildKeyInput(), out var action); + action = action ?? WriteChar; + action.Invoke(); + } } - } } \ No newline at end of file diff --git a/src/ReadLine/ReadLine.cs b/src/ReadLine/ReadLine.cs index 5581f2b..a67f7e3 100755 --- a/src/ReadLine/ReadLine.cs +++ b/src/ReadLine/ReadLine.cs @@ -4,48 +4,48 @@ namespace ReadLine { - public static class ReadLine - { - private static KeyHandler _keyHandler; - private static List _history; - - static ReadLine() - { - _history = new List(); - } - - public static Func AutoCompletionHandler { private get; set; } - public static bool PasswordMode { private get; set; } - - public static void AddHistory(params string[] text) => _history.AddRange(text); - public static List GetHistory() => _history; - public static void ClearHistory() => _history = new List(); - - public static string Read(string prompt = "", string defaultInput = "") + public static class ReadLine { - Console.Write(prompt); - - _keyHandler = new KeyHandler(new Console2 - { - PasswordMode = PasswordMode - }, _history, AutoCompletionHandler); - var keyInfo = Console.ReadKey(true); - - while (keyInfo.Key != ConsoleKey.Enter) - { - _keyHandler.Handle(keyInfo); - keyInfo = Console.ReadKey(true); - } - - Console.WriteLine(); - - var text = _keyHandler.Text; - if (string.IsNullOrWhiteSpace(text) && !string.IsNullOrWhiteSpace(defaultInput)) - text = defaultInput; - else - _history.Add(text); - - return text; + private static KeyHandler _keyHandler; + private static List _history; + + static ReadLine() + { + _history = new List(); + } + + public static Func AutoCompletionHandler { private get; set; } + public static bool PasswordMode { private get; set; } + + public static void AddHistory(params string[] text) => _history.AddRange(text); + public static List GetHistory() => _history; + public static void ClearHistory() => _history = new List(); + + public static string Read(string prompt = "", string defaultInput = "") + { + Console.Write(prompt); + + _keyHandler = new KeyHandler(new Console2 + { + PasswordMode = PasswordMode + }, _history, AutoCompletionHandler); + var keyInfo = Console.ReadKey(true); + + while (keyInfo.Key != ConsoleKey.Enter) + { + _keyHandler.Handle(keyInfo); + keyInfo = Console.ReadKey(true); + } + + Console.WriteLine(); + + var text = _keyHandler.Text; + if (string.IsNullOrWhiteSpace(text) && !string.IsNullOrWhiteSpace(defaultInput)) + text = defaultInput; + else + _history.Add(text); + + return text; + } } - } } \ No newline at end of file diff --git a/src/ReadLine/ReadLine.csproj b/src/ReadLine/ReadLine.csproj index 56295ee..615ffac 100755 --- a/src/ReadLine/ReadLine.csproj +++ b/src/ReadLine/ReadLine.csproj @@ -3,7 +3,7 @@ A GNU-Readline like library for .NET/.NET Core ReadLine - Toni Solarin-Sodara;Latency McLaughlin + Toni Solarin-Sodara Toni Solarin-Sodara net47;netcoreapp2.0;netstandard2.0 1.2.1 @@ -29,7 +29,7 @@ Consolidated redundant code and expressions. Repacked for multi-frameworks. Updated versioning. Updated test projects. - + Toni Solarin-Sodara diff --git a/test/ReadLine.Tests/Abstractions/Console2.cs b/test/ReadLine.Tests/Abstractions/Console2.cs index 2239f50..338e874 100644 --- a/test/ReadLine.Tests/Abstractions/Console2.cs +++ b/test/ReadLine.Tests/Abstractions/Console2.cs @@ -2,44 +2,44 @@ namespace ReadLine.Tests.Abstractions { - internal class Console2 : IConsole - { - public Console2() + internal class Console2 : IConsole { - CursorLeft = 0; - CursorTop = 0; - BufferWidth = 100; - BufferHeight = 100; + public Console2() + { + CursorLeft = 0; + CursorTop = 0; + BufferWidth = 100; + BufferHeight = 100; + } + + public int CursorLeft { get; private set; } + + public int CursorTop { get; private set; } + + public int BufferWidth { get; private set; } + + public int BufferHeight { get; private set; } + + public void SetBufferSize(int width, int height) + { + BufferWidth = width; + BufferHeight = height; + } + + public void SetCursorPosition(int left, int top) + { + CursorLeft = left; + CursorTop = top; + } + + public void Write(string value) + { + CursorLeft += value.Length; + } + + public void WriteLine(string value) + { + CursorLeft += value.Length; + } } - - public int CursorLeft { get; private set; } - - public int CursorTop { get; private set; } - - public int BufferWidth { get; private set; } - - public int BufferHeight { get; private set; } - - public void SetBufferSize(int width, int height) - { - BufferWidth = width; - BufferHeight = height; - } - - public void SetCursorPosition(int left, int top) - { - CursorLeft = left; - CursorTop = top; - } - - public void Write(string value) - { - CursorLeft += value.Length; - } - - public void WriteLine(string value) - { - CursorLeft += value.Length; - } - } } \ No newline at end of file diff --git a/test/ReadLine.Tests/KeyHandlerTests.cs b/test/ReadLine.Tests/KeyHandlerTests.cs index a8306f5..90b470f 100644 --- a/test/ReadLine.Tests/KeyHandlerTests.cs +++ b/test/ReadLine.Tests/KeyHandlerTests.cs @@ -5,427 +5,427 @@ namespace ReadLine.Tests { - public class KeyHandlerTests - { - public KeyHandlerTests() + public class KeyHandlerTests { - _completions = new[] - { - "World", - "Angel", - "Love" - }; - _history = new List(new[] - { - "dotnet run", - "git init", - "clear" - }); - _keyHandler = new KeyHandler(new Console2(), _history, null); - - _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('e', ConsoleKey.E, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); - _keyHandler.Handle(_keyInfo); - } - - private KeyHandler _keyHandler; - private ConsoleKeyInfo _keyInfo; - private readonly List _history; - private readonly string[] _completions; - - [Fact] - public void TestBackspace() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("Hell", _keyHandler.Text); - } - - [Fact] - public void TestBackwardsTab() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); - _keyHandler.Handle(_keyInfo); - - // Nothing happens when no auto complete handler is set - Assert.Equal("Hello", _keyHandler.Text); - - _keyHandler = new KeyHandler(new Console2(), _history, (t, s) => _completions); - - _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('i', ConsoleKey.I, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); - - // Bring up the first Autocomplete - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); - _keyHandler.Handle(_keyInfo); - - for (var i = _completions.Length - 1; i >= 0; i--) - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, true, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal($"Hi {_completions[i]}", _keyHandler.Text); - } - } - - [Fact] - public void TestControlA() - { - _keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, true); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('S', ConsoleKey.S, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("SHello", _keyHandler.Text); - } - - [Fact] - public void TestControlB() - { - _keyInfo = new ConsoleKeyInfo('B', ConsoleKey.B, false, false, true); - _keyHandler.Handle(_keyInfo); + public KeyHandlerTests() + { + _completions = new[] + { + "World", + "Angel", + "Love" + }; + _history = new List(new[] + { + "dotnet run", + "git init", + "clear" + }); + _keyHandler = new KeyHandler(new Console2(), _history, null); + + _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('e', ConsoleKey.E, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); + _keyHandler.Handle(_keyInfo); + } + + private KeyHandler _keyHandler; + private ConsoleKeyInfo _keyInfo; + private readonly List _history; + private readonly string[] _completions; + + [Fact] + public void TestBackspace() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hell", _keyHandler.Text); + } + + [Fact] + public void TestBackwardsTab() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + _keyHandler.Handle(_keyInfo); + + // Nothing happens when no auto complete handler is set + Assert.Equal("Hello", _keyHandler.Text); + + _keyHandler = new KeyHandler(new Console2(), _history, (t, s) => _completions); + + _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('i', ConsoleKey.I, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); - _keyHandler.Handle(_keyInfo); + // Bring up the first Autocomplete + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + _keyHandler.Handle(_keyInfo); + + for (var i = _completions.Length - 1; i >= 0; i--) + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, true, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hell No", _keyHandler.Text); - } - - [Fact] - public void TestControlE() - { - _keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, true); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('E', ConsoleKey.E, false, false, true); - _keyHandler.Handle(_keyInfo); + Assert.Equal($"Hi {_completions[i]}", _keyHandler.Text); + } + } + + [Fact] + public void TestControlA() + { + _keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, true); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('S', ConsoleKey.S, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("SHello", _keyHandler.Text); + } + + [Fact] + public void TestControlB() + { + _keyInfo = new ConsoleKeyInfo('B', ConsoleKey.B, false, false, true); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hell No", _keyHandler.Text); + } + + [Fact] + public void TestControlE() + { + _keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, true); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('E', ConsoleKey.E, false, false, true); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello!", _keyHandler.Text); - } + Assert.Equal("Hello!", _keyHandler.Text); + } - [Fact] - public void TestControlF() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestControlF() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('F', ConsoleKey.F, false, false, true); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('F', ConsoleKey.F, false, false, true); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello!", _keyHandler.Text); - } + Assert.Equal("Hello!", _keyHandler.Text); + } - [Fact] - public void TestControlH() - { - _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, true); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestControlH() + { + _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, true); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hell", _keyHandler.Text); - } + Assert.Equal("Hell", _keyHandler.Text); + } - [Fact] - public void TestControlK() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestControlK() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hell", _keyHandler.Text); + Assert.Equal("Hell", _keyHandler.Text); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); + _keyHandler.Handle(_keyInfo); - Assert.Equal(string.Empty, _keyHandler.Text); - } + Assert.Equal(string.Empty, _keyHandler.Text); + } - [Fact] - public void TestControlL() - { - _keyInfo = new ConsoleKeyInfo('L', ConsoleKey.L, false, false, true); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestControlL() + { + _keyInfo = new ConsoleKeyInfo('L', ConsoleKey.L, false, false, true); + _keyHandler.Handle(_keyInfo); - Assert.Equal(string.Empty, _keyHandler.Text); - } + Assert.Equal(string.Empty, _keyHandler.Text); + } - [Fact] - public void TestControlN() - { - for (var i = _history.Count - 1; i >= 0; i--) - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - } - - foreach (var t in _history) - { - Assert.Equal(t, _keyHandler.Text); - - _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, true); - _keyHandler.Handle(_keyInfo); - } - } + [Fact] + public void TestControlN() + { + for (var i = _history.Count - 1; i >= 0; i--) + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + } - [Fact] - public void TestControlP() - { - for (var i = _history.Count - 1; i >= 0; i--) - { - _keyInfo = new ConsoleKeyInfo('P', ConsoleKey.P, false, false, true); - _keyHandler.Handle(_keyInfo); + foreach (var t in _history) + { + Assert.Equal(t, _keyHandler.Text); - Assert.Equal(_history[i], _keyHandler.Text); - } - } + _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, true); + _keyHandler.Handle(_keyInfo); + } + } - [Fact] - public void TestControlU() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestControlP() + { + for (var i = _history.Count - 1; i >= 0; i--) + { + _keyInfo = new ConsoleKeyInfo('P', ConsoleKey.P, false, false, true); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('U', ConsoleKey.U, false, false, true); - _keyHandler.Handle(_keyInfo); + Assert.Equal(_history[i], _keyHandler.Text); + } + } + + [Fact] + public void TestControlU() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("o", _keyHandler.Text); + _keyInfo = new ConsoleKeyInfo('U', ConsoleKey.U, false, false, true); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal("o", _keyHandler.Text); - _keyInfo = new ConsoleKeyInfo('U', ConsoleKey.U, false, false, true); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal(string.Empty, _keyHandler.Text); - } + _keyInfo = new ConsoleKeyInfo('U', ConsoleKey.U, false, false, true); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestControlW() - { - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal(string.Empty, _keyHandler.Text); + } - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestControlW() + { + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello ", _keyHandler.Text); + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal("Hello ", _keyHandler.Text); - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal(string.Empty, _keyHandler.Text); - } + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestDelete() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal(string.Empty, _keyHandler.Text); + } + + [Fact] + public void TestDelete() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hell", _keyHandler.Text); + } - Assert.Equal("Hell", _keyHandler.Text); - } + [Fact] + public void TestDelete_EndOfLine() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestDelete_EndOfLine() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal("Hello", _keyHandler.Text); + } - Assert.Equal("Hello", _keyHandler.Text); - } + [Fact] + public void TestDownArrow() + { + for (var i = _history.Count - 1; i >= 0; i--) + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + } - [Fact] - public void TestDownArrow() - { - for (var i = _history.Count - 1; i >= 0; i--) - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - } - - foreach (var t in _history) - { - Assert.Equal(t, _keyHandler.Text); - - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.DownArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - } - } + foreach (var t in _history) + { + Assert.Equal(t, _keyHandler.Text); - [Fact] - public void TestEnd() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.DownArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + } + } - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestEnd() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello!", _keyHandler.Text); - } + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestHome() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal("Hello!", _keyHandler.Text); + } - _keyInfo = new ConsoleKeyInfo('S', ConsoleKey.S, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestHome() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("SHello", _keyHandler.Text); - } + _keyInfo = new ConsoleKeyInfo('S', ConsoleKey.S, false, false, false); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestLeftArrow() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal("SHello", _keyHandler.Text); + } - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestLeftArrow() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hell No", _keyHandler.Text); - } + _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestRightArrow() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal("Hell No", _keyHandler.Text); + } - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.RightArrow, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestRightArrow() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.RightArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello!", _keyHandler.Text); - } + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestTab() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal("Hello!", _keyHandler.Text); + } - // Nothing happens when no auto complete handler is set - Assert.Equal("Hello", _keyHandler.Text); + [Fact] + public void TestTab() + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + _keyHandler.Handle(_keyInfo); + + // Nothing happens when no auto complete handler is set + Assert.Equal("Hello", _keyHandler.Text); - _keyHandler = new KeyHandler(new Console2(), _history, (t, s) => _completions); + _keyHandler = new KeyHandler(new Console2(), _history, (t, s) => _completions); - _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('i', ConsoleKey.I, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('i', ConsoleKey.I, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); - foreach (var t in _completions) - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); - _keyHandler.Handle(_keyInfo); + foreach (var t in _completions) + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal($"Hi {t}", _keyHandler.Text); - } - } + Assert.Equal($"Hi {t}", _keyHandler.Text); + } + } - [Fact] - public void TestUpArrow() - { - for (var i = _history.Count - 1; i >= 0; i--) - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestUpArrow() + { + for (var i = _history.Count - 1; i >= 0; i--) + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal(_history[i], _keyHandler.Text); - } - } + Assert.Equal(_history[i], _keyHandler.Text); + } + } - [Fact] - public void TestWriteChar() - { - Assert.Equal("Hello", _keyHandler.Text); + [Fact] + public void TestWriteChar() + { + Assert.Equal("Hello", _keyHandler.Text); - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello World", _keyHandler.Text); + Assert.Equal("Hello World", _keyHandler.Text); + } } - } } \ No newline at end of file diff --git a/test/ReadLine.Tests/ReadLine.Tests.csproj b/test/ReadLine.Tests/ReadLine.Tests.csproj index c22ae78..bf74bf8 100755 --- a/test/ReadLine.Tests/ReadLine.Tests.csproj +++ b/test/ReadLine.Tests/ReadLine.Tests.csproj @@ -10,9 +10,6 @@ - - - diff --git a/test/ReadLine.Tests/ReadLineTests.cs b/test/ReadLine.Tests/ReadLineTests.cs index 7fa28c7..9634a64 100755 --- a/test/ReadLine.Tests/ReadLineTests.cs +++ b/test/ReadLine.Tests/ReadLineTests.cs @@ -4,46 +4,46 @@ namespace ReadLine.Tests { - public class ReadLineTests : IDisposable - { - public ReadLineTests() + public class ReadLineTests : IDisposable { - string[] history = - { - "ls -a", - "dotnet run", - "git init" - }; - ReadLine.AddHistory(history); - } + public ReadLineTests() + { + string[] history = + { + "ls -a", + "dotnet run", + "git init" + }; + ReadLine.AddHistory(history); + } - public void Dispose() - { - // If all above tests pass - // clear history works - ReadLine.ClearHistory(); - } + public void Dispose() + { + // If all above tests pass + // clear history works + ReadLine.ClearHistory(); + } - [Fact] - public void TestGetCorrectHistory() - { - Assert.Equal("ls -a", ReadLine.GetHistory()[0]); - Assert.Equal("dotnet run", ReadLine.GetHistory()[1]); - Assert.Equal("git init", ReadLine.GetHistory()[2]); - } + [Fact] + public void TestGetCorrectHistory() + { + Assert.Equal("ls -a", ReadLine.GetHistory()[0]); + Assert.Equal("dotnet run", ReadLine.GetHistory()[1]); + Assert.Equal("git init", ReadLine.GetHistory()[2]); + } - [Fact] - public void TestNoInitialHistory() - { - Assert.Equal(3, ReadLine.GetHistory().Count); - } + [Fact] + public void TestNoInitialHistory() + { + Assert.Equal(3, ReadLine.GetHistory().Count); + } - [Fact] - public void TestUpdatesHistory() - { - ReadLine.AddHistory("mkdir"); - Assert.Equal(4, ReadLine.GetHistory().Count); - Assert.Equal("mkdir", ReadLine.GetHistory().Last()); + [Fact] + public void TestUpdatesHistory() + { + ReadLine.AddHistory("mkdir"); + Assert.Equal(4, ReadLine.GetHistory().Count); + Assert.Equal("mkdir", ReadLine.GetHistory().Last()); + } } - } } \ No newline at end of file From 9c160c7b79cf2601e462cb697dc37ab491b5bd02 Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Sun, 8 Oct 2017 03:34:45 -0700 Subject: [PATCH 08/21] Updated ReadLine.csproj --- artifacts/ReadLine.1.2.1.nupkg | Bin 17985 -> 17988 bytes src/ReadLine/ReadLine.csproj | 7 ++++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/artifacts/ReadLine.1.2.1.nupkg b/artifacts/ReadLine.1.2.1.nupkg index 8e18dcd2f5e14f0ab8f6dc38b87040c756272c1d..5d39d6031fb2bfefe21456db047cecc362202818 100644 GIT binary patch delta 16882 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%0A<&kZTg}E^etv#- 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 DoD%~^ delta 16888 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�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 a&P_=!2=HbFI-7xk9SDViCm2Y$fOr5@!xhv3 diff --git a/src/ReadLine/ReadLine.csproj b/src/ReadLine/ReadLine.csproj index 615ffac..c4eaff0 100755 --- a/src/ReadLine/ReadLine.csproj +++ b/src/ReadLine/ReadLine.csproj @@ -10,10 +10,10 @@ ReadLine ReadLine readline;gnu;console;shell;cui - https://github.com/tsolarin/readline - https://github.com/tsolarin/readline/blob/master/LICENSE + https://github.com/tonerdo/readline + https://github.com/tonerdo/readline/blob/master/LICENSE git - https://github.com/tsolarin/readline + https://github.com/tonerdo/readline false false false @@ -56,4 +56,5 @@ Updated test projects. + From 97661fd4034bd15509114018cb840b72c53bc090 Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Sat, 30 Dec 2017 21:25:55 -0700 Subject: [PATCH 09/21] Updated target .NET Framework 4.7 to 4.7.1 Changed version. --- artifacts/ReadLine.1.2.1.nupkg | Bin 17988 -> 17972 bytes src/ReadLine/ReadLine.csproj | 9 +++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/artifacts/ReadLine.1.2.1.nupkg b/artifacts/ReadLine.1.2.1.nupkg index 5d39d6031fb2bfefe21456db047cecc362202818..e7dc205ae7da27e2331eee4819daa96f89115dd9 100644 GIT binary patch delta 17466 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 literal 17988 zcmZVGV{|1^qp0hoqmJ2eRywwA+qP}nwr$(C*|BYOR@||Zlke_*&bj;EA62tP{j4!- zj;gnwQSwq?;AkKqAU{FC9mS=zpIWYAK|w$szc<+LvwDsu)=qS^|JkP`Oj-`nBZ)kP zdb(obi%v@G%z=c6hS4TZ1mOTQxGQ$cHx@N?CY9t^=+bd=u3}wMXdZP z1JAjiXg4W5sb&M)z6Rirg5~~B%WBSy7Z1?R1ZFz9n^OPzMN>QhR-dt^2ObWYQtQ__959D3d8 z;ax09n3S`nEvxNF-z!l5DLJR@s9sd2a7yAT<963A!!pQ*UybOR&0xMRxa-?*u6gqR z89)Mm@?>wwv@w+fd_pkeaK7ImPA* z;xO7oG%&@w!+$`{9ju!Q#8dNzua-N337#Rb)|v{M?0GV5fuVPQZ*HdJ`}{sBXI5hZ zxtw*ebxe!A(?QQRepaNJpbr`T!F4!I zc+_ICh9CuZVa(2HGSnt5X4f#Ys%tC^DbI}Az87Fe6j@SU8y_WA(V&l3d`w)8eN6UJ zuKz}F;sHl>=e1fES=vslZJDJ5Y?yyr7r@gj8 z)Badud%(L=t!p?&N##6|EGw0<`oQ~KhQ2wCet0mXaIvw2(Mc2l>3nfJd1T1hMXnx4 z)SzkBYk;Rau2~P@W%zmDlEm5!8M}XXZ)%@1mw#mQmcez!T2GH~dpg2m#YfK&yY||W zBLmYhRsjvH!jYO51|9H^TfxT2uL@1_PRGZ`3!EC~whZ#`Ds#xgwfnczuGP*pxr=OX z*vuw*HHRQVjE(1SiV;8#y1G(ecQS(d3bR>3Z0yxdTKO9)il^w>CQCFrw5<-p$N#8& zb`u$x!}EgtyrAawWl%vxVF5w-{EHI8B^hEfkQ1!th7q%o+nPER>wzf>`#3j*)aC|R-_%c_=@@8_L3(n41=--32g(01-i8C`B-T#@g#@5!CnqKZW%PD+JiK30xRIL~65qJC%cSyeE z--pBm(7vNT#vG_mM3UGWnOn&cSgxY85s_U{Xp1rK$;c#7nUdVe3SE3j0pI{#qs4(ad-5-Lof{&jrp37jDs+2RFRyEa9;&# z#QbYcF<=FLzP~O!}N_mKd3nst^(p}*vaDR0PhFS~{G{V~$hhfMicm4bdgJY=}3#s8|D6Vo$)OM=P zC_q$+i?T1VAfm97fcKD&B3)G1m^Pi-&42QUJ zd)82Ej`$XmBrQKnD&O>JI;%c=q8cALS{$XHkvaUl;(M)o%o9Hvy@FauXXZ7=jh0fZ z%?f~~H9H?(%6IS9?}D9e>&|j@bcsx_Oz=wPeww`EVx}6~gc?ioD^$iWa3;CE{tMe= z3ptk&rYn4Huo}GnX|>b9b;|oAnEbkKUaDD^LF^9a=xHE(%5E>i>rAZ2ln9&;LPl!&FD7S6_2@v8BjfSmsI(_}0uFWGkhn;XTY^0QMe1>r zXBd>k2NGi&jv(ls5pQh>Z?Rz()M0d{Xd`ME+I*W|ZXzLG5MW1Kq&<%1{?)L#at7tM zdII9}lNLhg+YJi$dEQ@*y+OR5q1YgvRfNGNs}hg`>m$Q2?6v$g*` zUgAF_ai8qH!2%z7`U(0)lIKckKQ7=5SX7bLiA5;xJMxS^Rg(Tv@PIg_{U-%;Ve*=p z#6Dg7U<+Z4v3w0#_|y@>OSBkX$64O1MC!?5)t=~8WBLMEIow~#LQDLzx_XPahv_ry z{lhE%UiTB=LX(i@@ImQp8zEipf2az+%3st7H~HH;=aHx*p_RYo+RV-l(6N0>4= zOZ0pAzlmw&P0*5h?7u@X|I(T9dENY=EJ|*<7kr@uWNHW79Kz+w(9*8 z%(A>lX0BH;bs#Pqsk!!TVQY-woxm`Fje$_#S&e-JQD`=25@fA zb*kqRWX#1;->Zn`X#jaewbFhTGrhKk@H(P;t_s>QX=0!O>w#lHO>LwX#>b|OzXdt~ z_W?ngXx`Sj-$fiJu+Dr%mZD;2pKC5Z<{^G~)Vltf1gK8}t8zDWoRDgoHUP{-3He^C47+n(>o+O_VGE;A?{@bFYN#${X64ocY{3j>PJ^0E;{ia|`xMY9% zlyOzyxd=BOb@BWdatv>*`MrblDD7$C%_#D^VyX!9>lAh2yx9QgCh*ukeVzrAOt3jJ z%6Q{trqhB?x+C0aLbS@gFKR*wecO)>5u`U%d!|oD)LN zs3c(5R7NIUk?aBve+^2m32il9zmELicsqrh12uFL9pZTkCLflON_aE&H4@`!E2agH zsB$P|v*swOBjkeU)P|#a_|xzXI;UJt78zF$xHQF#j%qwOS2?nnnH!1q<`z;QBA4N*2rs0^t%QS77xp-> z?5*}83=cn7UtQy%!H!#7)2AGHmORIYTTbqSVc zS*fy6lu#VD6u%N-KBs%kz#T^r)e*wIE_=4o9Fk|_{7v~M%hz&?Hsq8dd{p*on;&ITJ=TOl@SuU% zkZEQ=$=K$TN4xyK%riwV@bPeqnQ>28GD`VvyyO#DnPd}|5`_q%u_N6W@w65qHeQ~l(qe6RSJeCio<07dnP8WfJ zRSIN@m@cb#3aVn#uZ{>uurUIcYhakVmVD5oV;{2$MJZ^PZ0Au<3D(Av+jA@}k*YGJ z;YboC{)*Xa>;BY6cI8K{+p1PM^KVK0W0|nB-C4mfHt{Z{oGT98G*S_7L%LiR`yGSN z+G#>=YLDZ(*J)qip)5tJOw>df410J!ILM#{skQmzJkxPVzpT`Dpn*xHkxl7@2899x zb1wR;M$?+UB&&Tgs{=JfgI{5Jt!hMNQIi#jY=cK?`vULdb4oCM6d+o7p(X25K81-AVq#dvTCL&f!VDq`=S*bt6iSBdCZ{w)Sb#7rnsh2|Y0M1I zeVNS}T)pRN9FTgQ_91dpe)z}_ex*RF82men4}g(;y`iJIBkq6mN{`l9Ws-i z@mCfHGE?!*!tEL1U#1nrVGjBHLgPyhoFf+@k#A= zv~h1ZKy5~%Y#fAL_oh(`q!0DE1Q$pOM4MOk1ztK3@OOAgzCI5al5eJ5+)Lk9iwc~4 z*hM3x0UiLZdY`-MP_|k==WO2}{Hq&U{-3Py?@9i-=1O?%Blx+I_&!I=U}@5eymbpw zed{Y74sT<0+wz`Ye$}0B17F_iH%B5(S+H~u0H5b9vTM9-hcBo;_qT*bE?U2ilS8~| zzKys3xl}ASiP_{YtLwo;s5qYVT}-ci$*-zUGB)s3ZkO4oUA~paG`U)zkAKU2eb2*I zPP1{MV2C>2=ZRYT0YrFwHcWn~FAoh;ZM6tnu7d^7QolmX#*5S!gSuJ67+1-t0AY%_ z0>D2?jItAv(Nq3>d-3ljTXc(oPQ;7VT~ zGLEbrI)D$HJQ#CvasMWY;swMRe|#DOMrze)Hw}kHJMWb@O&n6{06jvXy|c;Oi4SfQ zf*0{UuL3>b1*QF+wK6QjQiOEzOOHsWZ2u_n`>o`EFDHVu zsPff+x2u-z_AF&4+G*$gb#ZXLb>A{T_vQ5r)wW|V25g}FGIn~iwfQ*RzncG}E&-T%UmNp`Bo&mtT`?cf!#nTzEKrhh)5WsuIqv*g z8qZrv+0=S?ChzG>-(<7;Yfg<7UMhx~3HZ6XLbDsICcsHLeVJjgX^Va1kpFbOV+&#K zB`L#3JvwAhMb!vYQ@;WTUs(~l}u@CcJQ)IxTJ{Yk3=1E zS?_2W;x`&M?8M}>Am=mOhSH++@3deS!Dc(8>9c(-RoOdt#{Z5od(nx@9}J43Drj3 zG;(LO@b-*2Avp1Q$0;GtGsV7zDw}goH?eH`!v1GGgsHDfC*ljcivb+vHzV``T?|g@ zL-5%IX93nl7Lm#mS*SIHSb8kf*Tg$<5*-6Hv-{~Es;(@`l+Pg z#1|{$Xh*OS=;p~$FTOr=Vv?n1^Pd0qDb7r499=hM8N;8iAHvgCInOkGq`0yUn!7ge_szLycvWH89&?9P{uG%*aTKPHV8yg!n}S?$&%MaT6d@ z)hX5(gWLc{49h@$fr27#6N1#ZC#eVlZ3+$DMVti!jgz=dOdNnVLPRY4TZB~?hB77n zW2S>=!JL@vUBc4OdeiCZV}|Ex%jtVJU$pM~fOkYh$j5u#CwI?YVaD`vd;-p!Ae9?F zR|K)!b?;Df=au#dXx;*b8zFK;?3*(t$Zlqs_hGq+E-Fyr*<7AQAZ&t}cDJ*4uPrt- z#gr@E%~$*R0$-|k)XWW<<*SGc350Gw3m}LiXF&r<6jxKWg_B6O%bsC(NS<3>Owo_O zl8%K5W<`OQge6a)yHm301T!*>o``a(vCBmlpN)oU#M{ zEr%RpkJbTE2j^4ej_GH7x2fbD<<^Pe`r0!K$LSYSPMS*VG+Izj6(MII5(R-=?Q)HZ z4=Fj1907;u8swDDa|Ry+B6?lOrU&(4a%F`V}yHioYkditS3Mcke9nJu)_yCRK< zO9a>-Q14i$QKzL(^8SyLdJ#R}H`$ zV1#zoh>yMLUhP*Gd)!C1q1thSUS`IJ)<|yB*h(|j`f;R>1Hdc7aCXwDPUYgo;{u^R z=592U`%y*Ga{%p;-EmWIJ0Jf^MHh2k6nJ%m1cJG*7clxXG^KRk_-_(F{lW@E%0=dwprIDlxR5_j~f zX6)LcCsfE3GK0UW4$^h%InLi&POd8)Z_z2XZbgdYNKN)%&hMCDL~i!6} zUri%#83Ws(NSA@uv@%}$)y`h_c@*{-66t6uJ*P=dM-fTPnl^FmSs2{Y0dgaXT`QWT zWkkwBGuc=UmU!B5XSP*(Q_@(j|Fz(E+)2sKl8#uq=(eBQE?DDR(`bs(NbwT6M_r66PVK^%;hr;y-Ze^!Wf}WIWwS+m@vH1~u3r4gb_@^w zR^uIqUXfbzNB8c@CCg=u-B2WRDPQ@C?qyu4W!{ciG)li(*@0S*ash*HOy9Ln;2 z1MO3DIgIwvK7f;NWJTkQ8@>1M^78rAqVI8nfZiiksDRVE^zODztN?$6L)Y=IH-!Y8j-LC1OVy>^y%<5kC12SKD?lE99BNS~G^ zxxo&2&LYAHE$D6W&FE!vqkD}#LmwQwfF*K+7kKunfR!XUssc>`6aIEbsioQin9e}j z5~X{(jgn^KdzLwwQ8ocPc;2vc&(UXIAl?9eASA5_e0P4z0&D<=fQAr- z&7v-3&GJlPibc^Q`#U3Ww0|Zzhb?06?uGgPtKD90)e|!Dre0( z7y-8#4jgw#AY+JN9$fMn!3Ht#YK|ztgI}ws6{J0fXaw-u zou?2J78w|gjkeJFUgH_O;zf>RzARO~C^TE7D;mbV1gR`5>%yu9Uybp=tus|5M+opi zxdA4Hi{Y3+FxMb7~P}Z)cx1Hof<|t?WM{Eqt6_I&L+v__}HGSASr;0$N`Q z=jeC3bzzg`d*)mOvw~fJ_DBMG3!n?iO0J0nX$nM?afiIw zl6~?=Io&XAIRT@ImT(mTCa8{a^>uk(zE!5jgTy&H^GEyW+$jE?AVvY#jDmR=Bj=S6aZD-*}{9%!h5-2>uKncF1|0c&7rJSgB}I#kAxh?ueQ~MX}>DcD5|r#YQpGHp)8^akfk;?365So+mj7D0~?i z)@vF5bd6JHjK=Q72{RV|O0}P{s&*wcGO|~6Pu5hKh)^Yr1iPjUh@l?7^Vj@W=rrPO|VU=H1Px8BW1N##N!50@_<;hEl0Y2 zF+5&zt+qL!MG>qtN$1x@$RC&eePLNhudGmDrUMspnW^o-+B)TCR?TEDG$q83%!j^Z zNw^Xl46VK_K81CNB_mEF)dlAs6Ra+7n+-7Yo@sQ=5>|oN|w&1ax-nv`f zyp|jR)?3Q<@Z3rRa;rJP31c#&#QpVk+fvc)M`J=EE#m6kJmoC`!nSc%f{ z)`mwT#c5yE6R*V!WPT*mF*0JF{oIm1;Y_7h>4M&ZS`lcfY1K#83ljf2vZb}pq}#Dh zmsr-4c}K?tx)zEb52*VEXH-4-rdK?aW>%U=|M?VjCrM)$!`aRue6BkOm*?Xh(|_fV zt%+J-_m`AFWHT456GE(e%QDq6Y`3!^&JR>{-X66|A2tt!nr&lVEOmJNt=LoFjZec9?oWdJzz#81 z5j%Q}cr1L4Uh}aw>(}UZC&uObYI!^4#G1%gX+fZu+zdilQUXWxnXk%9N8e?ggDxON z&fawa!=t!@7JjzT%^@)7NVz&U7+9jVuT#uCa73xCMs)WVBCuC{97=?DJp9bWh5#Q{j8JqAKQfqGSKR&Xx0WmcYas>N@`EGgfVlvTGRUTB8hjB0(vlPx zVS9unvUai*movU?qd#X{kSqU6i2zacL&$HwU5o)56)G-OPK1m(Z#{F@byrMIzCeZv zmq+sZf2F;MX`k%gFA;CgWDwpmy;09ywuyO|&QHwCNqRmBDz9rrblPn;sSjn?T?eo> zIck@DPg^y=%KW-N2STntZRb(5=xk|wIlWJa^qzNugjC9QKOb=7R6iFVcCUHeWbWL? zdfn~imd%>|vfjL}4{qtU?@9()BFy--9|hM@b>>avc>mSx?kqmukgym|Ag-SHB+-!bzR)d(>dhYNwT^X#{}!@48tM83r; z!SgTpL3Cbh3)B~#Eaa`J7JN0)q8H=PZd0H_fm9c`Rjfj-o}bwK&&u` z=Mw8ceiWrZjGGC(fK5O^_Y)+Te&ZSY5vxel>FYm8#kfOijVg;pNNHhfds zp;^SSH3;7hsQXt7uNKWRe6BB3Y|l?`LaO?8n?HF=aE0qZ$!RW z0SSYIY2Og@#rM%IkMkkcw$1MfSmD?GcK>j~`!bn3%j0r1ul6a#muy~ExO8o&;d)Z) zL}whh?X$wc@(zlk)3Y=kp+KdK01NbGvC8}2Z;3Y;eE}IwqS%}HJQ^NR+^s{DAA{cWH(^Rwwon!YU_=G9? z3uG}kViRW9Re|Q6h2ac@xzQDsMw^RU;T+=}mlJZTh+~+k7cAi{CWJgnzY_hwG84#1&+nrqh*2nB9*Lsa&RlV08DEoSear@x*+;V|(!cly#l z3&ZI6dNm4#0nFxosP6&I^TaB{Y{WysPn8nVq8vN${&0v$(}ZI91Kz6!FG2U{3I556 z`b5;SmT3}A8)xTXWPB;*m*0R*4B$EjF!C3Li#SHy_+A69x!GDuo;I( z_)s(77+7aNLf(c+RzJ^XO&^}Ry0E{{gFe3Q{4QVg{%3R)_-PV{@!!!A|NlluCuaj& zV*^Ly|9^G#vDf;xjMoyLi6&YN$93_;!VyM=YYm24GhqS2&r}U4W3JREQSj`uw@r5_ z8nfMGS?mKyFv$hpXprQnuC77>0gU}{myqb>7bu#UKPD4HY3Ahf;kw|d>(Ru+5Eesu zPPWK2Qgc%MS{L~qNjRTA|95me)Yx#oso4VoA@lA1#NLxYn$>)soE3O~{>yh6M8r`? z?XGy{ZX$4PyA2baJ{n(v0A*-NXh011q1lfs1AZ@@-$I3r$qLyl@7wE^P*cr&a z%v+?-{0o-FBZkoQn=Z`g7mLA&~*znKisP8#;HFukD;dG|4xoVt|@rues#64vWsabIqD`6F0|D+?dbjPuuMF^I1#`;~IxK$=x z_3+E>@e1Cf3L_n-!91?H69Tx(8k8!31Ta+4qiU7V*75@a8c?FnA}I{_tr^f0Lk3K^ zNXyGL)oR8CB@mO3!KGIDRX!*v+BX{Z%>j3y^I3+VxTWY0H<@x5@NAZQ_?RxGQ!1y9WN?t?95H z+&piT9h_nWZ)aiajBvyzziWqk9d#Iw-yzLr)`e=6W4!W9?mw8(wa;$OD9BpO6yX~) zR*8p!eM(rDg|rq-3jg4QoASQ)7@X8lvRg!5g&rA$gfSgw}z-oxf8|{EX4g^hZH8F{BS9(k_KLmOjEOy z^n7|t)0nl&ZuSGpN!%P2SWn?_W=7+w9~N4Q9S^Im2WF@5jZd&_3mb9A3(z6?YtTnv z;8zGUh19>hx)e|LrgB2KMRg?H&?9ZsuQBf z)})aWCBA-5K#vL2?t*M3W0PRLExl(WjsC@rjR_Kwr^^ixg)oUy)JXCJj1EP0#6v&!+vX??7+_KplL%nx zba#SYj`p&te3Y}P@b977CquPY^dtlu8`7(DhV&)v81U7=c99*X!5c;@#~3JsU@f#p zbQJb=2S8q8CF*deh|UA0$l;bhsh}xFaW~>2W)TSsU-qAZ%6BJGLZxvMxx&*puNSzX z(pY50Y+Y!r+;F54_C=cz(c(2=9ZK67$^Kh2lKw|Ca{j+G)q_<%|nBPCFXgfHTERX`TOdHoKcMADY8#lK`~Y4rr$c?R1+*^W>7aij&B#I~Rmnj#!c=8}OkxfNdQ>w4+l{ZO9LGtxwcPwxl!Un9nA9RM~PA!s`esz@N;N4iuEaEQxr6SHfhvNVZ zKw%$u*enG)B5`l?!m~*P1<*&yoU`n4^l_z`>#CY@*WT7HYYpc79- zK|gw5oWyQZYuomN_8T)o6e4y-@X{@Y_c_Yzq(tbBVE2yntTcKfp8q*s(fXCxm-OaK z(KA|?dfkAC@d=pN=ueG7q1ij5VwQW#3TUy7CfM!8@@5R-m-@oG@aft4@9 z*PK8%tC8L(#vm}f7R3Nen|&H=V2j3VoHt~EU^qVg=05WI=OTQfyO3eoR7QMVm)gyf zV0>)~utjv%%){n8C;tGlRuem4nR)E3>*G(fu`I!LO zuFLXfw0YHlJqWj)i;(n~9oM>KCxf_{*seGM+KZ-nLJK}ZwUqIQF?-fKf?ZLuk|?AU z##fseWD*cw@-~Hzs5wHM?JHtsn<6D@4Z8T|jdjYmy&pI}0p%c^*7tDVlyOYdKv+ay zwWLvH;DInV?|AV$F^c91GrtmZrciuSM$&J}m?_Hqdcj;cKO69YRWuu5g{2eZKqy?* zE?$}=cRT0no)N`vXEqnoy&%;dJEoh7&%D8j3uulqH#m+*_OCRb5iA!BmDSr8dZMDw)KSdjAZNV7oAPE zRb~K)1;%@K+r7~{f)Hq9W#SHIOaIP+Wh1Kbzb2>&eM<=4mnp`ew+VPkunp$;4`v(^ z|3V<~`@x`o?w)5+)r@hf5OH?RkYZfeg)5B6*b{c@Bt0O(-0w`Ys3Scv;$4ce7lZv2 zh4SB+ar+;b`ww3!jz}!Z!bO7d3v3IPFI=W2dB+u$U z%*!|8f^v_sapnp>eXX6f=(KPniJ={(eRXxUwTSzf>Uw%rwlTxYH>vHG8i839|DlY- zzp*BpAF+Bj2PVQX7rtJTuoRBkIY;m~gXgNYeqWwkeG ztAwwVr1>4ZYT>P*Z#Tr7EhSXqw9!z^5<-1_Iw*gOKZ9v=G9Y8+;78}BpM}fR^iu`i5YJ7m$^Y^G<}89QZsZtmH#^} zVxvRTSdcUXSt9TcpW()gbxqlHJrtwkDHvhL|A?{@(rlz#gsE@DLZ(U_uNO8V)!Z#2 z4XtNkFuhpLH)Bp%3S(&%$Am%l0`%vGzzJ=}7{nCK6_7EnnHK73N2vn^SMznoxEYgJ zEhDTd|FqOtdMg)Y2dc(Q1=uR#EXF8MEs83~`bzKDw^C%w+UzPr;`{)2fn%OUpSk8& zLaF=uD3ZW#@N+f~XLLwhHP+a$_w(*nlQV7fQb85!no$m8i9Xsny*;;&uF166pOUqU zCWeG}N=KE9$y0#=<1R;x$)slM=}>7hEahcvQE(sQ@oaAIjI&y~pV=lY^`PchpQ|aP z>n{IKTojfuW?nn(e=pvt8+$MowW{Oj)s?yx9>iP(*kC4s6>2tmINQrJS@en5{MJ$% zM*#cVlTLo42-y>=V_;h5+5ulw^pRSw5DD9|c^`0O+n!C~z|}mAq^gvGi5)(cfj{8j zL0~Vk1}f7Xxu|Lp^w>#SC8FtulRAUTb;oAOoiNw7S{rXmuwfO=kHTl|JZZap#Cp;1 zvM+d74#1zATB<~%m9B-wslvjtwnMJA8l4Wx$?Sj_lU4b%qnzU=QLL@cuk_h=b|ybq zZ(r2bNJiP>Uzo{JI>tPy`~O%*^sCoz%lK!za|A4+UNb3aPWY~LLwjpbDHKIKM07N1Kv|AbSUldQ?kj21y+cV{ z-`Z5P3^7CgWe_hM<;-F`zw`5%C2krD-KKJ=Lvcm+lp;{RhS=>4+gdVu@oI;bIUvq;Dw9-FEaTOfY5KwA=9Y@3d0~9&a4jFAniKu!6Beq03KJ!&h!e{>L^CT;hv6 z3fr==lLimK-)W(B!hi9|GP(ZL7y_WNe^a?R%(Wu?FmZHjJLnIber!ahZ4QQC^ly?0 zW{eKF1{X^S#+cU(1>GKhTSk78FZX@$3HJ%ST$C?T=H{(1BeXw92`9SwbAv$V^ZJtG<5+S%T*T<{xNMWPVSf~TNi=8vw-(BUu?royweeZS zdj6C!i>TA>UgfOC4P0lR@7|8`3wQwXm=2g4nN*aI{kcmlfP*5>4f_?f6-C{WP zDZ|brNH<;Wfrsx|Nmi0zkngmj>7G&SFphrLmH$Z@i~lcW{DM5xj?}5s?wnQ@`fnai`&^Qb?6}RAby)Bz~?Hy_C-qly@aN|+ffqg?r;Qg@TyDrL8^NK=8gyx%(>~A zh78?|N&0vrxmO9h9QN-=|Tizdr6_ zCZE5^c2W-9c6aRGg=LN3GbeR7zKUYfaMcsv-iWSAwAAq23BHEaSakZxHSR2TigrZo zxUV$due4HbMi=F5yxTH+AA_=oTF3-8mSh;ZVffzcmA2Ae1L8i=q(jn|YUaDI0cRci z4M{Rz?kd#}vFE$Xe@a&F+*+|46g*$i6%0cUGe6J<@7Z>mG?{tQ<{=~?#}>B)W0yY>IB1R9By4w7#Rh8_cQ zOY)8HwlNm7;KnF6lNg|?!)0Rn#0 z_c~J5>!yIB$-n21m=td)yXMuNv0`ky7LfXAMhV#{s~HFKlMd+{WL(%84eB9e3Bg!~ z`+V>$Pls#FPiEJs2ik9Zek+mJ*PMfXF$14pFIrxo82_^=?s&^|&wjVW`R{)opni{9 zLUy*!CbrIc${zM6PCB&iHr6=_47Nk`a3W7XdV=y>>W`htBL`(eiP^>>z%yDyCeR2L z1RUS!CCYxtM8yvOul@eNzwzxe6ZPVjLx#!e;ibvE2`6fgY~0+_O|aIu3nGypOW-p(H+^1|I=3O)7fg4FF8-?V>jEHLi?1L*hLz%vX2f&MQ@OwLYB zPt`9@Eh@`QPA%5YO)W`GNi0d!2d(YYEhx$_NG&SK1WF{Pq^6{pr6ifBrJ0(TCz&TE zCYmG}CmEWXn46g-C7S3J6z8TS7vu)r&%b3LP&a?e|A$l3H%w*=aCKg__13QqO&1p2 zjq9y#5Ix>^?p)Bn-!nOs%-$ZI^!M+M_vgZG>aMWWDObLIqjWN27DLp_DcjmzFSY&s zVOObRU$3=9Ic9S9geEusz|_AnCtZtp7S1fbwU+SoOD_ z)z-+seve#4?DdU$?<>nQXMK!6eZAKvN%z>TUkYoEbY}(pko%_NwpH+^^(xm7d!3b2 zRQW2(W_^@u4p8E#dzW*EXRYeS=mw{gJ5@vu2JS2kJA6#i@m8O?AEyxO{)6jlTH_|= zIn7D=$r=}y|5#pQ%0;n*FJ9HW@wmX5q>`|DeRQ4O1Iuae-{w6H_g?!*=4+ht)b#b& zUtBHDzgPY0Df8)`yBpU$xSrh~TJcIoGyan4*@N2@=6*e=@IzUOdDB%^`HsD3IOL}l z@+S#?Ezt^p%gy%fO4i~VVLwi7E}ip? zHe-Dg=WMY*^D7FSf8N)Q`UhO^%g7|c02*z_emDqF0tp};6@so2{e%pJE)!t7gC9Ns zIWGfUGy16o2+enyah+j+ZU*{VWrP{p5^ytctXxJn3w;U#Vb%iRxeCxT6>v>Rpc{r> q_8<)V;()azLN@?C^CB7GNQ0~#;LQp=<%EHO9SDVi<%P5hhz9@;v!w_C diff --git a/src/ReadLine/ReadLine.csproj b/src/ReadLine/ReadLine.csproj index c4eaff0..d57c8a9 100755 --- a/src/ReadLine/ReadLine.csproj +++ b/src/ReadLine/ReadLine.csproj @@ -5,7 +5,7 @@ ReadLine Toni Solarin-Sodara Toni Solarin-Sodara - net47;netcoreapp2.0;netstandard2.0 + net471;netcoreapp2.0;netstandard2.0 1.2.1 ReadLine ReadLine @@ -24,7 +24,7 @@ true Updated to support .NET Core 2.0. Updated to support .NET Standard v2.0. -Updated to support .NET Framework v4.7. +Updated to support .NET Framework v4.7.1 Consolidated redundant code and expressions. Repacked for multi-frameworks. Updated versioning. @@ -32,6 +32,11 @@ Updated test projects. Toni Solarin-Sodara + + bin\Release\ + TRACE;RELEASE + + From 179c27e8f33bfb69e0deb47dd86520c99b8b4a19 Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Tue, 27 Feb 2018 00:24:38 -0500 Subject: [PATCH 10/21] Fixed compilation errors. Added framework support for Standard v1.3 and .NET 4.5 / 4.6.2 --- ReadLine.sln | 2 +- artifacts/ReadLine.1.2.1.nupkg | Bin 17972 -> 0 bytes artifacts/ReadLine.2.0.1.nupkg | Bin 0 -> 34244 bytes src/ReadLine/Properties/AssemblyInfo.cs | 0 src/ReadLine/ReadLine.cs | 4 +-- src/ReadLine/ReadLine.csproj | 32 ++++------------------ test/ReadLine.Tests/KeyHandlerTests.cs | 4 +-- test/ReadLine.Tests/ReadLine.Tests.csproj | 2 +- 8 files changed, 11 insertions(+), 33 deletions(-) delete mode 100644 artifacts/ReadLine.1.2.1.nupkg create mode 100644 artifacts/ReadLine.2.0.1.nupkg delete mode 100644 src/ReadLine/Properties/AssemblyInfo.cs diff --git a/ReadLine.sln b/ReadLine.sln index 2feb5f2..d0fa19b 100755 --- a/ReadLine.sln +++ b/ReadLine.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26730.16 +VisualStudioVersion = 15.0.27130.2036 MinimumVisualStudioVersion = 15.0.26124.0 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{06FC0E85-E73C-4DC1-B6FD-A583B7B1DFE4}" EndProject diff --git a/artifacts/ReadLine.1.2.1.nupkg b/artifacts/ReadLine.1.2.1.nupkg deleted file mode 100644 index e7dc205ae7da27e2331eee4819daa96f89115dd9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17972 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�O*~BzEG}C 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 b|36%u AutoCompletionHandler { private get; set; } - public static bool PasswordMode { private get; set; } public static void AddHistory(params string[] text) => _history.AddRange(text); public static List GetHistory() => _history; @@ -32,8 +31,7 @@ public static string Read(string prompt = "", string @default = "") } else { - if (HistoryEnabled) - _history.Add(text); + _history.Add(text); } return text; diff --git a/src/ReadLine/ReadLine.csproj b/src/ReadLine/ReadLine.csproj index 91f5d90..296b677 100755 --- a/src/ReadLine/ReadLine.csproj +++ b/src/ReadLine/ReadLine.csproj @@ -4,52 +4,32 @@ ReadLine Toni Solarin-Sodara Toni Solarin-Sodara - net471;netcoreapp2.0;netstandard2.0 - 1.2.1 + Toni Solarin-Sodara + net45;net462;net471;netcoreapp2.0;netstandard1.3;netstandard2.0 ReadLine ReadLine - $(AssemblyVersion) readline;gnu;console;shell;cui https://github.com/tonerdo/readline https://github.com/tonerdo/readline/blob/master/LICENSE git https://github.com/tonerdo/readline - false - false - false - false - false true snKey.snk true - Updated to support .NET Core 2.0. -Updated to support .NET Standard v2.0. -Updated to support .NET Framework v4.7.1 -Consolidated redundant code and expressions. -Repacked for multi-frameworks. -Updated versioning. -Updated test projects. - Toni Solarin-Sodara - - - - bin\Release\ - TRACE;RELEASE + Updated to support .NET Standard v1.3 Framework v4.5 / v4.6.2 + 2.0.1 + A GNU-Readline like library for .NET - + - - - - diff --git a/test/ReadLine.Tests/KeyHandlerTests.cs b/test/ReadLine.Tests/KeyHandlerTests.cs index ea3034d..3fdde53 100644 --- a/test/ReadLine.Tests/KeyHandlerTests.cs +++ b/test/ReadLine.Tests/KeyHandlerTests.cs @@ -371,7 +371,7 @@ public void TestTab() // Nothing happens when no auto complete handler is set Assert.Equal("Hello", _keyHandler.Text); - _keyHandler = new KeyHandler(new Console2(), _history, _autoCompleteHandler); + _keyHandler = new KeyHandler(new Console2(), _history, (t, s) => _completions); _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); _keyHandler.Handle(_keyInfo); @@ -384,7 +384,7 @@ public void TestTab() foreach (var t in _completions) { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + _keyInfo = new ConsoleKeyInfo('\t', ConsoleKey.Tab, false, false, false); _keyHandler.Handle(_keyInfo); Assert.Equal($"Hi {t}", _keyHandler.Text); diff --git a/test/ReadLine.Tests/ReadLine.Tests.csproj b/test/ReadLine.Tests/ReadLine.Tests.csproj index bf74bf8..66019b4 100755 --- a/test/ReadLine.Tests/ReadLine.Tests.csproj +++ b/test/ReadLine.Tests/ReadLine.Tests.csproj @@ -10,7 +10,7 @@ - + From ae9fa2d245c06ccc5267b7cb7ea6188299139684 Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Mon, 7 May 2018 13:35:35 -0700 Subject: [PATCH 11/21] Code format. Merge from rubberduck203 (pull request #41) --- artifacts/ReadLine.2.0.1.nupkg | Bin 34244 -> 34768 bytes src/ReadLine.Demo/AutoCompleteHandler.cs | 28 + src/ReadLine.Demo/Program.cs | 64 +-- src/ReadLine/Abstractions/Console2.cs | 10 + src/ReadLine/IAutoCompleteHandler.cs | 2 +- src/ReadLine/KeyHandler.cs | 312 +++++----- src/ReadLine/ReadLine.cs | 45 +- test/ReadLine.Tests/Abstractions/Console2.cs | 6 + test/ReadLine.Tests/AutoCompleteHandler.cs | 25 +- test/ReadLine.Tests/CharExtensions.cs | 112 ++++ .../ConsoleKeyInfoExtensions.cs | 38 ++ test/ReadLine.Tests/KeyHandlerTests.cs | 536 +++++++----------- test/ReadLine.Tests/ReadLineTests.cs | 5 + 13 files changed, 667 insertions(+), 516 deletions(-) create mode 100644 src/ReadLine.Demo/AutoCompleteHandler.cs create mode 100644 test/ReadLine.Tests/CharExtensions.cs create mode 100644 test/ReadLine.Tests/ConsoleKeyInfoExtensions.cs diff --git a/artifacts/ReadLine.2.0.1.nupkg b/artifacts/ReadLine.2.0.1.nupkg index 2ddd9166b5b62fe52d387799459451f2a90527be..3e9ef8a2f2760c9c413474c43c2c06c176e8b9ed 100644 GIT binary patch delta 33036 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 diff --git a/src/ReadLine.Demo/AutoCompleteHandler.cs b/src/ReadLine.Demo/AutoCompleteHandler.cs new file mode 100644 index 0000000..44e188b --- /dev/null +++ b/src/ReadLine.Demo/AutoCompleteHandler.cs @@ -0,0 +1,28 @@ +namespace ReadLine.Demo +{ + internal class AutoCompletionHandler : IAutoCompleteHandler + { + public char[] Separators { get; set; } = + { + ' ', + '.', + '/', + '\\', + ':' + }; + + + public string[] GetSuggestions(string text, int index) + { + return text.StartsWith("git ") + ? new[] + { + "init", + "clone", + "pull", + "push" + } + : null; + } + } +} diff --git a/src/ReadLine.Demo/Program.cs b/src/ReadLine.Demo/Program.cs index 8961e55..896f066 100755 --- a/src/ReadLine.Demo/Program.cs +++ b/src/ReadLine.Demo/Program.cs @@ -1,35 +1,31 @@ -using System; - -namespace ReadLine.Demo -{ - public class Program - { - public static void Main(string[] args) - { - Console.WriteLine("ReadLine Library Demo"); - Console.WriteLine("---------------------"); - Console.WriteLine(); - - string[] history = - { - "ls -a", - "dotnet run", - "git init" - }; - ReadLine.AddHistory(history); - - ReadLine.AutoCompletionHandler = (t, s) => t.StartsWith("git ") - ? new[] - { - "init", - "clone", - "pull", - "push" - } - : null; - - var input = ReadLine.Read("(prompt)> "); - Console.Write(input); - } - } +using System; + + +namespace ReadLine.Demo +{ + public class Program + { + public static void Main(string[] args) + { + Console.WriteLine("ReadLine Library Demo"); + Console.WriteLine("---------------------"); + Console.WriteLine(); + + string[] history = + { + "ls -a", + "dotnet run", + "git init" + }; + ReadLine.AddHistory(history); + + ReadLine.AutoCompletionHandler = new AutoCompletionHandler(); + + var input = ReadLine.Read("(prompt)> "); + Console.WriteLine(input); + + input = ReadLine.ReadPassword("Enter Password> "); + Console.WriteLine(input); + } + } } \ No newline at end of file diff --git a/src/ReadLine/Abstractions/Console2.cs b/src/ReadLine/Abstractions/Console2.cs index d4d2aa0..9ebbfe4 100644 --- a/src/ReadLine/Abstractions/Console2.cs +++ b/src/ReadLine/Abstractions/Console2.cs @@ -1,26 +1,35 @@ using System; + namespace ReadLine.Abstractions { internal class Console2 : IConsole { public bool PasswordMode { get; set; } + + public int CursorLeft => Console.CursorLeft; + public int CursorTop => Console.CursorTop; + public int BufferWidth => Console.BufferWidth; + public int BufferHeight => Console.BufferHeight; + public void SetBufferSize(int width, int height) => Console.SetBufferSize(width, height); + public void SetCursorPosition(int left, int top) { if (!PasswordMode) Console.SetCursorPosition(left, top); } + public void Write(string value) { if (PasswordMode) @@ -29,6 +38,7 @@ public void Write(string value) Console.Write(value); } + public void WriteLine(string value) => Console.WriteLine(value); } } \ No newline at end of file diff --git a/src/ReadLine/IAutoCompleteHandler.cs b/src/ReadLine/IAutoCompleteHandler.cs index 20b84c5..aa19dd0 100644 --- a/src/ReadLine/IAutoCompleteHandler.cs +++ b/src/ReadLine/IAutoCompleteHandler.cs @@ -1,4 +1,4 @@ -namespace System +namespace ReadLine { public interface IAutoCompleteHandler { diff --git a/src/ReadLine/KeyHandler.cs b/src/ReadLine/KeyHandler.cs index 046d11d..8e34ded 100644 --- a/src/ReadLine/KeyHandler.cs +++ b/src/ReadLine/KeyHandler.cs @@ -1,58 +1,145 @@ -using Internal.ReadLine.Abstractions; - using System; using System.Collections.Generic; using System.Text; +using ReadLine.Abstractions; + -namespace Internal.ReadLine +namespace ReadLine { internal class KeyHandler { - private int _cursorPos; + private readonly IConsole _console2; + private readonly List _history; + private readonly Dictionary _keyActions; + private readonly StringBuilder _text; + private string[] _completions; + private int _completionsIndex; + private int _completionStart; private int _cursorLimit; - private StringBuilder _text; - private List _history; + private int _cursorPos; private int _historyIndex; private ConsoleKeyInfo _keyInfo; - private Dictionary _keyActions; - private string[] _completions; - private int _completionStart; - private int _completionsIndex; - private IConsole Console2; + + + public KeyHandler(IConsole console, List history, IAutoCompleteHandler autoCompleteHandler) + { + _console2 = console; + + _history = history ?? new List(); + _historyIndex = _history.Count; + _text = new StringBuilder(); + _keyActions = new Dictionary + { + ["LeftArrow"] = MoveCursorLeft, + ["Home"] = MoveCursorHome, + ["End"] = MoveCursorEnd, + ["ControlA"] = MoveCursorHome, + ["ControlB"] = MoveCursorLeft, + ["RightArrow"] = MoveCursorRight, + ["ControlF"] = MoveCursorRight, + ["ControlE"] = MoveCursorEnd, + ["Backspace"] = Backspace, + ["Delete"] = Delete, + ["ControlD"] = Delete, + ["ControlH"] = Backspace, + ["ControlL"] = ClearLine, + ["Escape"] = ClearLine, + ["UpArrow"] = PrevHistory, + ["ControlP"] = PrevHistory, + ["DownArrow"] = NextHistory, + ["ControlN"] = NextHistory, + ["ControlU"] = () => + { + while (!IsStartOfLine()) + Backspace(); + }, + ["ControlK"] = () => + { + var pos = _cursorPos; + MoveCursorEnd(); + while (_cursorPos > pos) + Backspace(); + }, + ["ControlW"] = () => + { + while (!IsStartOfLine() && _text[_cursorPos - 1] != ' ') + Backspace(); + }, + ["ControlT"] = TransposeChars, + ["Tab"] = () => + { + if (IsInAutoCompleteMode()) + { + NextAutoComplete(); + } else + { + if (autoCompleteHandler == null || !IsEndOfLine()) + return; + + var text = _text.ToString(); + + _completionStart = text.LastIndexOfAny(autoCompleteHandler.Separators); + _completionStart = _completionStart == -1 ? 0 : _completionStart + 1; + + _completions = autoCompleteHandler.GetSuggestions(text, _completionStart); + _completions = _completions?.Length == 0 ? null : _completions; + + if (_completions == null) + return; + + StartAutoComplete(); + } + }, + ["ShiftTab"] = () => + { + if (IsInAutoCompleteMode()) + PreviousAutoComplete(); + } + }; + } + + + public string Text => _text.ToString(); + private bool IsStartOfLine() => _cursorPos == 0; + private bool IsEndOfLine() => _cursorPos == _cursorLimit; - private bool IsStartOfBuffer() => Console2.CursorLeft == 0; - private bool IsEndOfBuffer() => Console2.CursorLeft == Console2.BufferWidth - 1; + private bool IsStartOfBuffer() => _console2.CursorLeft == 0; + + + private bool IsEndOfBuffer() => _console2.CursorLeft == _console2.BufferWidth - 1; + + private bool IsInAutoCompleteMode() => _completions != null; + private void MoveCursorLeft() { if (IsStartOfLine()) return; if (IsStartOfBuffer()) - Console2.SetCursorPosition(Console2.BufferWidth - 1, Console2.CursorTop - 1); + _console2.SetCursorPosition(_console2.BufferWidth - 1, _console2.CursorTop - 1); else - Console2.SetCursorPosition(Console2.CursorLeft - 1, Console2.CursorTop); + _console2.SetCursorPosition(_console2.CursorLeft - 1, _console2.CursorTop); _cursorPos--; } + private void MoveCursorHome() { while (!IsStartOfLine()) MoveCursorLeft(); } - private string BuildKeyInput() - { - return (_keyInfo.Modifiers != ConsoleModifiers.Control && _keyInfo.Modifiers != ConsoleModifiers.Shift) ? - _keyInfo.Key.ToString() : _keyInfo.Modifiers.ToString() + _keyInfo.Key.ToString(); - } + + private string BuildKeyInput() => _keyInfo.Modifiers != ConsoleModifiers.Control && _keyInfo.Modifiers != ConsoleModifiers.Shift ? _keyInfo.Key.ToString() : _keyInfo.Modifiers + _keyInfo.Key.ToString(); + private void MoveCursorRight() { @@ -60,19 +147,21 @@ private void MoveCursorRight() return; if (IsEndOfBuffer()) - Console2.SetCursorPosition(0, Console2.CursorTop + 1); + _console2.SetCursorPosition(0, _console2.CursorTop + 1); else - Console2.SetCursorPosition(Console2.CursorLeft + 1, Console2.CursorTop); + _console2.SetCursorPosition(_console2.CursorLeft + 1, _console2.CursorTop); _cursorPos++; } + private void MoveCursorEnd() { while (!IsEndOfLine()) MoveCursorRight(); } + private void ClearLine() { MoveCursorEnd(); @@ -80,101 +169,120 @@ private void ClearLine() Backspace(); } + private void WriteNewString(string str) { ClearLine(); - foreach (char character in str) + foreach (var character in str) WriteChar(character); } + private void WriteString(string str) { - foreach (char character in str) + foreach (var character in str) WriteChar(character); } + private void WriteChar() => WriteChar(_keyInfo.KeyChar); + private void WriteChar(char c) { if (IsEndOfLine()) { _text.Append(c); - Console2.Write(c.ToString()); + _console2.Write(c.ToString()); _cursorPos++; - } - else + } else { - int left = Console2.CursorLeft; - int top = Console2.CursorTop; - string str = _text.ToString().Substring(_cursorPos); + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + var str = _text.ToString().Substring(_cursorPos); _text.Insert(_cursorPos, c); - Console2.Write(c.ToString() + str); - Console2.SetCursorPosition(left, top); + _console2.Write(c + str); + _console2.SetCursorPosition(left, top); MoveCursorRight(); } _cursorLimit++; } + private void Backspace() { if (IsStartOfLine()) return; MoveCursorLeft(); - int index = _cursorPos; + var index = _cursorPos; _text.Remove(index, 1); - string replacement = _text.ToString().Substring(index); - int left = Console2.CursorLeft; - int top = Console2.CursorTop; - Console2.Write(string.Format("{0} ", replacement)); - Console2.SetCursorPosition(left, top); + var replacement = _text.ToString().Substring(index); + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + _console2.Write($"{replacement} "); + _console2.SetCursorPosition(left, top); _cursorLimit--; } + private void Delete() { if (IsEndOfLine()) return; - int index = _cursorPos; + var index = _cursorPos; _text.Remove(index, 1); - string replacement = _text.ToString().Substring(index); - int left = Console2.CursorLeft; - int top = Console2.CursorTop; - Console2.Write(string.Format("{0} ", replacement)); - Console2.SetCursorPosition(left, top); + var replacement = _text.ToString().Substring(index); + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + _console2.Write($"{replacement} "); + _console2.SetCursorPosition(left, top); _cursorLimit--; } + private void TransposeChars() { // local helper functions - bool almostEndOfLine() => (_cursorLimit - _cursorPos) == 1; - int incrementIf(Func expression, int index) => expression() ? index + 1 : index; - int decrementIf(Func expression, int index) => expression() ? index - 1 : index; + bool AlmostEndOfLine() + { + return _cursorLimit - _cursorPos == 1; + } + + int IncrementIf(Func expression, int index) + { + return expression() ? index + 1 : index; + } - if (IsStartOfLine()) { return; } + int DecrementIf(Func expression, int index) + { + return expression() ? index - 1 : index; + } - var firstIdx = decrementIf(IsEndOfLine, _cursorPos - 1); - var secondIdx = decrementIf(IsEndOfLine, _cursorPos); + if (IsStartOfLine()) + return; + + var firstIdx = DecrementIf(IsEndOfLine, _cursorPos - 1); + var secondIdx = DecrementIf(IsEndOfLine, _cursorPos); var secondChar = _text[secondIdx]; _text[secondIdx] = _text[firstIdx]; _text[firstIdx] = secondChar; - var left = incrementIf(almostEndOfLine, Console2.CursorLeft); - var cursorPosition = incrementIf(almostEndOfLine, _cursorPos); + var left = IncrementIf(AlmostEndOfLine, _console2.CursorLeft); + var cursorPosition = IncrementIf(AlmostEndOfLine, _cursorPos); WriteNewString(_text.ToString()); - Console2.SetCursorPosition(left, Console2.CursorTop); + _console2.SetCursorPosition(left, _console2.CursorTop); _cursorPos = cursorPosition; MoveCursorRight(); } + private void StartAutoComplete() { while (_cursorPos > _completionStart) @@ -185,6 +293,7 @@ private void StartAutoComplete() WriteString(_completions[_completionsIndex]); } + private void NextAutoComplete() { while (_cursorPos > _completionStart) @@ -198,6 +307,7 @@ private void NextAutoComplete() WriteString(_completions[_completionsIndex]); } + private void PreviousAutoComplete() { while (_cursorPos > _completionStart) @@ -211,6 +321,7 @@ private void PreviousAutoComplete() WriteString(_completions[_completionsIndex]); } + private void PrevHistory() { if (_historyIndex > 0) @@ -220,6 +331,7 @@ private void PrevHistory() } } + private void NextHistory() { if (_historyIndex < _history.Count) @@ -232,100 +344,13 @@ private void NextHistory() } } + private void ResetAutoComplete() { _completions = null; _completionsIndex = 0; } - public string Text - { - get - { - return _text.ToString(); - } - } - - public KeyHandler(IConsole console, List history, IAutoCompleteHandler autoCompleteHandler) - { - Console2 = console; - - _history = history ?? new List(); - _historyIndex = _history.Count; - _text = new StringBuilder(); - _keyActions = new Dictionary(); - - _keyActions["LeftArrow"] = MoveCursorLeft; - _keyActions["Home"] = MoveCursorHome; - _keyActions["End"] = MoveCursorEnd; - _keyActions["ControlA"] = MoveCursorHome; - _keyActions["ControlB"] = MoveCursorLeft; - _keyActions["RightArrow"] = MoveCursorRight; - _keyActions["ControlF"] = MoveCursorRight; - _keyActions["ControlE"] = MoveCursorEnd; - _keyActions["Backspace"] = Backspace; - _keyActions["Delete"] = Delete; - _keyActions["ControlD"] = Delete; - _keyActions["ControlH"] = Backspace; - _keyActions["ControlL"] = ClearLine; - _keyActions["Escape"] = ClearLine; - _keyActions["UpArrow"] = PrevHistory; - _keyActions["ControlP"] = PrevHistory; - _keyActions["DownArrow"] = NextHistory; - _keyActions["ControlN"] = NextHistory; - _keyActions["ControlU"] = () => - { - while (!IsStartOfLine()) - Backspace(); - }; - _keyActions["ControlK"] = () => - { - int pos = _cursorPos; - MoveCursorEnd(); - while (_cursorPos > pos) - Backspace(); - }; - _keyActions["ControlW"] = () => - { - while (!IsStartOfLine() && _text[_cursorPos - 1] != ' ') - Backspace(); - }; - _keyActions["ControlT"] = TransposeChars; - - _keyActions["Tab"] = () => - { - if (IsInAutoCompleteMode()) - { - NextAutoComplete(); - } - else - { - if (autoCompleteHandler == null || !IsEndOfLine()) - return; - - string text = _text.ToString(); - - _completionStart = text.LastIndexOfAny(autoCompleteHandler.Separators); - _completionStart = _completionStart == -1 ? 0 : _completionStart + 1; - - _completions = autoCompleteHandler.GetSuggestions(text, _completionStart); - _completions = _completions?.Length == 0 ? null : _completions; - - if (_completions == null) - return; - - StartAutoComplete(); - } - }; - - _keyActions["ShiftTab"] = () => - { - if (IsInAutoCompleteMode()) - { - PreviousAutoComplete(); - } - }; - } public void Handle(ConsoleKeyInfo keyInfo) { @@ -335,10 +360,9 @@ public void Handle(ConsoleKeyInfo keyInfo) if (IsInAutoCompleteMode() && _keyInfo.Key != ConsoleKey.Tab) ResetAutoComplete(); - Action action; - _keyActions.TryGetValue(BuildKeyInput(), out action); + _keyActions.TryGetValue(BuildKeyInput(), out var action); action = action ?? WriteChar; action.Invoke(); } } -} +} \ No newline at end of file diff --git a/src/ReadLine/ReadLine.cs b/src/ReadLine/ReadLine.cs index 4576027..66dc0ae 100755 --- a/src/ReadLine/ReadLine.cs +++ b/src/ReadLine/ReadLine.cs @@ -2,51 +2,70 @@ using System.Collections.Generic; using ReadLine.Abstractions; + namespace ReadLine { public static class ReadLine { private static List _history; + static ReadLine() { _history = new List(); } - public static Func AutoCompletionHandler { private get; set; } - public static void AddHistory(params string[] text) => _history.AddRange(text); - public static List GetHistory() => _history; - public static void ClearHistory() => _history = new List(); + public static IAutoCompleteHandler AutoCompletionHandler { private get; set; } + + + public static void AddHistory(params string[] text) + { + _history.AddRange(text); + } + + + public static List GetHistory() + { + return _history; + } + + + public static void ClearHistory() + { + _history = new List(); + } + public static string Read(string prompt = "", string @default = "") { Console.Write(prompt); - KeyHandler keyHandler = new KeyHandler(new Console2(), _history, AutoCompletionHandler); - string text = GetText(keyHandler); + var keyHandler = new KeyHandler(new Console2(), _history, AutoCompletionHandler); + var text = GetText(keyHandler); - if (String.IsNullOrWhiteSpace(text) && !String.IsNullOrWhiteSpace(@default)) - { + if (string.IsNullOrWhiteSpace(text) && !string.IsNullOrWhiteSpace(@default)) text = @default; - } else - { _history.Add(text); - } return text; } + public static string ReadPassword(string prompt = "") { Console.Write(prompt); - KeyHandler keyHandler = new KeyHandler(new Console2() { PasswordMode = true }, null, null); + var keyHandler = new KeyHandler(new Console2 + { + PasswordMode = true + }, null, null); return GetText(keyHandler); } + private static string GetText(KeyHandler keyHandler) { - ConsoleKeyInfo keyInfo = Console.ReadKey(true); + var keyInfo = Console.ReadKey(true); while (keyInfo.Key != ConsoleKey.Enter) { keyHandler.Handle(keyInfo); diff --git a/test/ReadLine.Tests/Abstractions/Console2.cs b/test/ReadLine.Tests/Abstractions/Console2.cs index 338e874..8548360 100644 --- a/test/ReadLine.Tests/Abstractions/Console2.cs +++ b/test/ReadLine.Tests/Abstractions/Console2.cs @@ -1,5 +1,6 @@ using ReadLine.Abstractions; + namespace ReadLine.Tests.Abstractions { internal class Console2 : IConsole @@ -12,6 +13,7 @@ public Console2() BufferHeight = 100; } + public int CursorLeft { get; private set; } public int CursorTop { get; private set; } @@ -20,23 +22,27 @@ public Console2() public int BufferHeight { get; private set; } + public void SetBufferSize(int width, int height) { BufferWidth = width; BufferHeight = height; } + public void SetCursorPosition(int left, int top) { CursorLeft = left; CursorTop = top; } + public void Write(string value) { CursorLeft += value.Length; } + public void WriteLine(string value) { CursorLeft += value.Length; diff --git a/test/ReadLine.Tests/AutoCompleteHandler.cs b/test/ReadLine.Tests/AutoCompleteHandler.cs index 3d65e89..6332dff 100644 --- a/test/ReadLine.Tests/AutoCompleteHandler.cs +++ b/test/ReadLine.Tests/AutoCompleteHandler.cs @@ -1,10 +1,25 @@ -using System; - namespace ReadLine.Tests { - class AutoCompleteHandler : IAutoCompleteHandler + internal class AutoCompleteHandler : IAutoCompleteHandler { - public char[] Separators { get; set; } = new char[] { ' ', '.', '/', '\\', ':' }; - public string[] GetSuggestions(string text, int index) => new string[] { "World", "Angel", "Love" }; + public char[] Separators { get; set; } = + { + ' ', + '.', + '/', + '\\', + ':' + }; + + + public string[] GetSuggestions(string text, int index) + { + return new[] + { + "World", + "Angel", + "Love" + }; + } } } \ No newline at end of file diff --git a/test/ReadLine.Tests/CharExtensions.cs b/test/ReadLine.Tests/CharExtensions.cs new file mode 100644 index 0000000..2f4cbc2 --- /dev/null +++ b/test/ReadLine.Tests/CharExtensions.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; + + +namespace ReadLine.Tests +{ + public static class CharExtensions + { + public const char ExclamationPoint = '!'; + public const char Space = ' '; + + public const char CtrlA = '\u0001'; + public const char CtrlB = '\u0002'; + public const char CtrlD = '\u0004'; + public const char CtrlE = '\u0005'; + public const char CtrlF = '\u0006'; + public const char CtrlH = '\u0008'; + public const char CtrlK = '\u000B'; + public const char CtrlL = '\u000C'; + public const char CtrlN = '\u000E'; + public const char CtrlP = '\u0010'; + public const char CtrlT = '\u0014'; + public const char CtrlU = '\u0015'; + public const char CtrlW = '\u0017'; + + private static readonly Dictionary> specialKeyCharMap = new Dictionary> + { + { + ExclamationPoint, Tuple.Create(ConsoleKey.D0, NoModifiers()) + }, + { + Space, Tuple.Create(ConsoleKey.Spacebar, NoModifiers()) + }, + { + CtrlA, Tuple.Create(ConsoleKey.A, ConsoleModifiers.Control) + }, + { + CtrlB, Tuple.Create(ConsoleKey.B, ConsoleModifiers.Control) + }, + { + CtrlD, Tuple.Create(ConsoleKey.D, ConsoleModifiers.Control) + }, + { + CtrlE, Tuple.Create(ConsoleKey.E, ConsoleModifiers.Control) + }, + { + CtrlF, Tuple.Create(ConsoleKey.F, ConsoleModifiers.Control) + }, + { + CtrlH, Tuple.Create(ConsoleKey.H, ConsoleModifiers.Control) + }, + { + CtrlK, Tuple.Create(ConsoleKey.K, ConsoleModifiers.Control) + }, + { + CtrlL, Tuple.Create(ConsoleKey.L, ConsoleModifiers.Control) + }, + { + CtrlN, Tuple.Create(ConsoleKey.N, ConsoleModifiers.Control) + }, + { + CtrlP, Tuple.Create(ConsoleKey.P, ConsoleModifiers.Control) + }, + { + CtrlT, Tuple.Create(ConsoleKey.T, ConsoleModifiers.Control) + }, + { + CtrlU, Tuple.Create(ConsoleKey.U, ConsoleModifiers.Control) + }, + { + CtrlW, Tuple.Create(ConsoleKey.W, ConsoleModifiers.Control) + } + }; + + + public static ConsoleKeyInfo ToConsoleKeyInfo(this char c) + { + var (key, modifiers) = c.ParseKeyInfo(); + + var ctrl = modifiers.HasFlag(ConsoleModifiers.Control); + var shift = modifiers.HasFlag(ConsoleModifiers.Shift); + var alt = modifiers.HasFlag(ConsoleModifiers.Alt); + + return new ConsoleKeyInfo(c, key, shift, alt, ctrl); + } + + + private static Tuple ParseKeyInfo(this char c) + { + { + var success = Enum.TryParse(c.ToString().ToUpper(), out ConsoleKey result); + if (success) + return Tuple.Create(result, NoModifiers()); + } + + { + var success = specialKeyCharMap.TryGetValue(c, out var result); + if (success) + return result; + } + + //if all else fails, return whatever the default is + return Tuple.Create(default(ConsoleKey), NoModifiers()); + } + + + private static ConsoleModifiers NoModifiers() + { + return 0; + } + } +} \ No newline at end of file diff --git a/test/ReadLine.Tests/ConsoleKeyInfoExtensions.cs b/test/ReadLine.Tests/ConsoleKeyInfoExtensions.cs new file mode 100644 index 0000000..e604a17 --- /dev/null +++ b/test/ReadLine.Tests/ConsoleKeyInfoExtensions.cs @@ -0,0 +1,38 @@ +using System; + + +namespace ReadLine.Tests +{ + public static class ConsoleKeyInfoExtensions + { + public static readonly ConsoleKeyInfo Backspace = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); + public static readonly ConsoleKeyInfo Delete = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); + + public static readonly ConsoleKeyInfo Home = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); + public static readonly ConsoleKeyInfo End = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); + + public static readonly ConsoleKeyInfo LeftArrow = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + public static readonly ConsoleKeyInfo RightArrow = new ConsoleKeyInfo('\0', ConsoleKey.RightArrow, false, false, false); + public static readonly ConsoleKeyInfo UpArrow = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); + public static readonly ConsoleKeyInfo DownArrow = new ConsoleKeyInfo('\0', ConsoleKey.DownArrow, false, false, false); + + public static readonly ConsoleKeyInfo Tab = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + public static readonly ConsoleKeyInfo ShiftTab = new ConsoleKeyInfo('\0', ConsoleKey.Tab, true, false, false); + + public static readonly ConsoleKeyInfo ExclamationPoint = CharExtensions.ExclamationPoint.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo Space = CharExtensions.Space.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlA = CharExtensions.CtrlA.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlB = CharExtensions.CtrlB.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlD = CharExtensions.CtrlD.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlE = CharExtensions.CtrlE.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlF = CharExtensions.CtrlF.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlH = CharExtensions.CtrlH.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlK = CharExtensions.CtrlK.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlL = CharExtensions.CtrlL.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlN = CharExtensions.CtrlN.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlP = CharExtensions.CtrlP.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlT = CharExtensions.CtrlT.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlU = CharExtensions.CtrlU.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlW = CharExtensions.CtrlW.ToConsoleKeyInfo(); + } +} \ No newline at end of file diff --git a/test/ReadLine.Tests/KeyHandlerTests.cs b/test/ReadLine.Tests/KeyHandlerTests.cs index f949a92..917050f 100644 --- a/test/ReadLine.Tests/KeyHandlerTests.cs +++ b/test/ReadLine.Tests/KeyHandlerTests.cs @@ -1,503 +1,401 @@ using System; using System.Collections.Generic; using System.Linq; - +using ReadLine.Tests.Abstractions; using Xunit; +using static ReadLine.Tests.ConsoleKeyInfoExtensions; -using ReadLine.Tests.Abstractions; -using Internal.ReadLine; namespace ReadLine.Tests { public class KeyHandlerTests { - private KeyHandler _keyHandler; - private ConsoleKeyInfo _keyInfo; - private List _history; - private AutoCompleteHandler _autoCompleteHandler; - private string[] _completions; - private Internal.ReadLine.Abstractions.IConsole _console; - public KeyHandlerTests() { _autoCompleteHandler = new AutoCompleteHandler(); _completions = _autoCompleteHandler.GetSuggestions("", 0); - _history = new List(new string[] { "dotnet run", "git init", "clear" }); + _history = new List(new[] + { + "dotnet run", + "git init", + "clear" + }); _console = new Console2(); _keyHandler = new KeyHandler(_console, _history, null); - _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('e', ConsoleKey.E, false, false, false); - _keyHandler.Handle(_keyInfo); + "Hello".Select(c => c.ToConsoleKeyInfo()).ToList().ForEach(_keyHandler.Handle); + } - _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); - _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); - _keyHandler.Handle(_keyInfo); + private KeyHandler _keyHandler; + private readonly List _history; + private readonly AutoCompleteHandler _autoCompleteHandler; + private readonly string[] _completions; + private readonly Internal.ReadLine.Abstractions.IConsole _console; - _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); - _keyHandler.Handle(_keyInfo); - } [Fact] - public void TestWriteChar() + public void MoveCursorThenPreviousHistory() { - Assert.Equal("Hello", _keyHandler.Text); - - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyHandler.Handle(LeftArrow); + _keyHandler.Handle(UpArrow); - _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("Hello World", _keyHandler.Text); + Assert.Equal("clear", _keyHandler.Text); } + [Fact] public void TestBackspace() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); - _keyHandler.Handle(_keyInfo); - + _keyHandler.Handle(Backspace); Assert.Equal("Hell", _keyHandler.Text); } - [Fact] - public void TestDelete() - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("Hell", _keyHandler.Text); - } [Fact] - public void TestDelete_EndOfLine() + public void TestBackwardsTab() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyHandler.Handle(Tab); + // Nothing happens when no auto complete handler is set Assert.Equal("Hello", _keyHandler.Text); - } - [Fact] - public void TestControlH() - { - _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, true); - _keyHandler.Handle(_keyInfo); + _keyHandler = new KeyHandler(new Console2(), _history, _autoCompleteHandler); - Assert.Equal("Hell", _keyHandler.Text); + "Hi ".Select(c => c.ToConsoleKeyInfo()).ToList().ForEach(_keyHandler.Handle); + + // Bring up the first Autocomplete + _keyHandler.Handle(Tab); + + _completions.Reverse().ToList().ForEach(completion => + { + _keyHandler.Handle(ShiftTab); + Assert.Equal($"Hi {completion}", _keyHandler.Text); + }); } + [Fact] - public void TestControlT() + public void TestControlA() { - var initialCursorCol = _console.CursorLeft; - var ctrlT = new ConsoleKeyInfo('\u0014', ConsoleKey.T, false, false, true); - _keyHandler.Handle(ctrlT); + new List + { + CtrlA, + 'S'.ToConsoleKeyInfo() + }.ForEach(_keyHandler.Handle); - Assert.Equal("Helol", _keyHandler.Text); - Assert.Equal(initialCursorCol, _console.CursorLeft); + Assert.Equal("SHello", _keyHandler.Text); } + [Fact] - public void TestControlT_LeftOnce_CursorMovesToEnd() + public void TestControlB() { - var initialCursorCol = _console.CursorLeft; - var leftArrow = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(leftArrow); + " N".Select(c => c.ToConsoleKeyInfo()).Prepend(CtrlB).ToList().ForEach(_keyHandler.Handle); - var ctrlT = new ConsoleKeyInfo('\u0014', ConsoleKey.T, false, false, true); - _keyHandler.Handle(ctrlT); - - Assert.Equal("Helol", _keyHandler.Text); - Assert.Equal(initialCursorCol, _console.CursorLeft); + Assert.Equal("Hell No", _keyHandler.Text); } + [Fact] - public void TestControlT_CursorInMiddleOfLine() + public void TestControlD() { - var leftArrow = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - Enumerable - .Repeat(leftArrow, 3) - .ToList() - .ForEach(_keyHandler.Handle); - - var initialCursorCol = _console.CursorLeft; - - var ctrlT = new ConsoleKeyInfo('\u0014', ConsoleKey.T, false, false, true); - _keyHandler.Handle(ctrlT); + Enumerable.Repeat(LeftArrow, 4).Append(CtrlD).ToList().ForEach(_keyHandler.Handle); - Assert.Equal("Hlelo", _keyHandler.Text); - Assert.Equal(initialCursorCol + 1, _console.CursorLeft); + Assert.Equal("Hllo", _keyHandler.Text); } + [Fact] - public void TestControlT_CursorAtBeginningOfLine_HasNoEffect() + public void TestControlE() { - var ctrlA = new ConsoleKeyInfo('\u0001', ConsoleKey.A, false, false, true); - _keyHandler.Handle(ctrlA); - - var initialCursorCol = _console.CursorLeft; - - var ctrlT = new ConsoleKeyInfo('\u0014', ConsoleKey.T, false, false, true); - _keyHandler.Handle(ctrlT); + new List + { + CtrlA, + CtrlE, + ExclamationPoint + }.ForEach(_keyHandler.Handle); - Assert.Equal("Hello", _keyHandler.Text); - Assert.Equal(initialCursorCol, _console.CursorLeft); + Assert.Equal("Hello!", _keyHandler.Text); } + [Fact] - public void TestHome() + public void TestControlF() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('S', ConsoleKey.S, false, false, false); - _keyHandler.Handle(_keyInfo); + new List + { + LeftArrow, + CtrlF, + ExclamationPoint + }.ForEach(_keyHandler.Handle); - Assert.Equal("SHello", _keyHandler.Text); + Assert.Equal("Hello!", _keyHandler.Text); } + [Fact] - public void TestControlA() + public void TestControlH() { - _keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, true); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('S', ConsoleKey.S, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("SHello", _keyHandler.Text); + _keyHandler.Handle(CtrlH); + Assert.Equal("Hell", _keyHandler.Text); } + [Fact] - public void TestEnd() + public void TestControlK() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyHandler.Handle(LeftArrow); + _keyHandler.Handle(CtrlK); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); - _keyHandler.Handle(_keyInfo); + Assert.Equal("Hell", _keyHandler.Text); - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyHandler.Handle(Home); + _keyHandler.Handle(CtrlK); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.Equal(string.Empty, _keyHandler.Text); } + [Fact] - public void TestControlE() + public void TestControlL() { - _keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, true); - _keyHandler.Handle(_keyInfo); + _keyHandler.Handle(CtrlL); + Assert.Equal(string.Empty, _keyHandler.Text); + } - _keyInfo = new ConsoleKeyInfo('E', ConsoleKey.E, false, false, true); - _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestControlN() + { + Enumerable.Repeat(UpArrow, _history.Count).ToList().ForEach(_keyHandler.Handle); - Assert.Equal("Hello!", _keyHandler.Text); + _history.ForEach(history => + { + Assert.Equal(history, _keyHandler.Text); + _keyHandler.Handle(CtrlN); + }); } + [Fact] - public void TestLeftArrow() + public void TestControlP() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); + _history.AsEnumerable().Reverse().ToList().ForEach(history => + { + _keyHandler.Handle(CtrlP); + Assert.Equal(history, _keyHandler.Text); + }); + } - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); - _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); - _keyHandler.Handle(_keyInfo); + [Fact] + public void TestControlT() + { + var initialCursorCol = _console.CursorLeft; + _keyHandler.Handle(CtrlT); - Assert.Equal("Hell No", _keyHandler.Text); + Assert.Equal("Helol", _keyHandler.Text); + Assert.Equal(initialCursorCol, _console.CursorLeft); } + [Fact] - public void TestControlB() + public void TestControlT_CursorAtBeginningOfLine_HasNoEffect() { - _keyInfo = new ConsoleKeyInfo('B', ConsoleKey.B, false, false, true); - _keyHandler.Handle(_keyInfo); + _keyHandler.Handle(CtrlA); - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); + var initialCursorCol = _console.CursorLeft; - _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyHandler.Handle(CtrlT); - Assert.Equal("Hell No", _keyHandler.Text); + Assert.Equal("Hello", _keyHandler.Text); + Assert.Equal(initialCursorCol, _console.CursorLeft); } + [Fact] - public void TestRightArrow() + public void TestControlT_CursorInMiddleOfLine() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); + Enumerable.Repeat(LeftArrow, 3).ToList().ForEach(_keyHandler.Handle); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.RightArrow, false, false, false); - _keyHandler.Handle(_keyInfo); + var initialCursorCol = _console.CursorLeft; - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyHandler.Handle(CtrlT); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.Equal("Hlelo", _keyHandler.Text); + Assert.Equal(initialCursorCol + 1, _console.CursorLeft); } + [Fact] - public void TestControlD() + public void TestControlT_LeftOnce_CursorMovesToEnd() { - for (var i = 0; i < 4; i++) - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - } + var initialCursorCol = _console.CursorLeft; - _keyInfo = new ConsoleKeyInfo('\u0004', ConsoleKey.D, false, false, true); - _keyHandler.Handle(_keyInfo); + new List + { + LeftArrow, + CtrlT + }.ForEach(_keyHandler.Handle); - Assert.Equal("Hllo", _keyHandler.Text); + Assert.Equal("Helol", _keyHandler.Text); + Assert.Equal(initialCursorCol, _console.CursorLeft); } + [Fact] - public void TestControlF() + public void TestControlU() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyHandler.Handle(LeftArrow); + _keyHandler.Handle(CtrlU); - _keyInfo = new ConsoleKeyInfo('F', ConsoleKey.F, false, false, true); - _keyHandler.Handle(_keyInfo); + Assert.Equal("o", _keyHandler.Text); - _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); - _keyHandler.Handle(_keyInfo); + _keyHandler.Handle(End); + _keyHandler.Handle(CtrlU); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.Equal(string.Empty, _keyHandler.Text); } + [Fact] - public void TestControlL() + public void TestControlW() { - _keyInfo = new ConsoleKeyInfo('L', ConsoleKey.L, false, false, true); - _keyHandler.Handle(_keyInfo); + " World".Select(c => c.ToConsoleKeyInfo()).Append(CtrlW).ToList().ForEach(_keyHandler.Handle); + + Assert.Equal("Hello ", _keyHandler.Text); + + _keyHandler.Handle(Backspace); + _keyHandler.Handle(CtrlW); Assert.Equal(string.Empty, _keyHandler.Text); } + [Fact] - public void TestUpArrow() + public void TestDelete() { - for (int i = _history.Count - 1; i >= 0 ; i--) + new List { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); - _keyHandler.Handle(_keyInfo); + LeftArrow, + Delete + }.ForEach(_keyHandler.Handle); - Assert.Equal(_history[i], _keyHandler.Text); - } + Assert.Equal("Hell", _keyHandler.Text); } + [Fact] - public void TestControlP() + public void TestDelete_EndOfLine() { - for (int i = _history.Count - 1; i >= 0 ; i--) - { - _keyInfo = new ConsoleKeyInfo('P', ConsoleKey.P, false, false, true); - _keyHandler.Handle(_keyInfo); - - Assert.Equal(_history[i], _keyHandler.Text); - } + _keyHandler.Handle(Delete); + Assert.Equal("Hello", _keyHandler.Text); } + [Fact] public void TestDownArrow() { - for (int i = _history.Count - 1; i >= 0 ; i--) - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - } + Enumerable.Repeat(UpArrow, _history.Count).ToList().ForEach(_keyHandler.Handle); - for (int i = 0; i < _history.Count; i++) + _history.ForEach(history => { - Assert.Equal(_history[i], _keyHandler.Text); - - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.DownArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - } + Assert.Equal(history, _keyHandler.Text); + _keyHandler.Handle(DownArrow); + }); } + [Fact] - public void TestControlN() + public void TestEnd() { - for (int i = _history.Count - 1; i >= 0 ; i--) + new List { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - } + Home, + End, + ExclamationPoint + }.ForEach(_keyHandler.Handle); - for (int i = 0; i < _history.Count; i++) - { - Assert.Equal(_history[i], _keyHandler.Text); - - _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, true); - _keyHandler.Handle(_keyInfo); - } + Assert.Equal("Hello!", _keyHandler.Text); } + [Fact] - public void TestControlU() + public void TestHome() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('U', ConsoleKey.U, false, false, true); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("o", _keyHandler.Text); - - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('U', ConsoleKey.U, false, false, true); - _keyHandler.Handle(_keyInfo); + new List + { + Home, + 'S'.ToConsoleKeyInfo() + }.ForEach(_keyHandler.Handle); - Assert.Equal(string.Empty, _keyHandler.Text); + Assert.Equal("SHello", _keyHandler.Text); } + [Fact] - public void TestControlK() + public void TestLeftArrow() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("Hell", _keyHandler.Text); + " N".Select(c => c.ToConsoleKeyInfo()).Prepend(LeftArrow).ToList().ForEach(_keyHandler.Handle); - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); - _keyHandler.Handle(_keyInfo); - - Assert.Equal(string.Empty, _keyHandler.Text); + Assert.Equal("Hell No", _keyHandler.Text); } + [Fact] - public void TestControlW() + public void TestRightArrow() { - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); - _keyHandler.Handle(_keyInfo); - - Assert.Equal("Hello ", _keyHandler.Text); - - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); - _keyHandler.Handle(_keyInfo); + new List + { + LeftArrow, + RightArrow, + ExclamationPoint + }.ForEach(_keyHandler.Handle); - Assert.Equal(string.Empty, _keyHandler.Text); + Assert.Equal("Hello!", _keyHandler.Text); } + [Fact] public void TestTab() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); - _keyHandler.Handle(_keyInfo); - + _keyHandler.Handle(Tab); // Nothing happens when no auto complete handler is set Assert.Equal("Hello", _keyHandler.Text); _keyHandler = new KeyHandler(new Console2(), _history, _autoCompleteHandler); - _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); - _keyHandler.Handle(_keyInfo); + "Hi ".Select(c => c.ToConsoleKeyInfo()).ToList().ForEach(_keyHandler.Handle); - _keyInfo = new ConsoleKeyInfo('i', ConsoleKey.I, false, false, false); - _keyHandler.Handle(_keyInfo); + _completions.ToList().ForEach(completion => + { + _keyHandler.Handle(Tab); + Assert.Equal($"Hi {completion}", _keyHandler.Text); + }); + } - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); - for (int i = 0; i < _completions.Length; i++) + [Fact] + public void TestUpArrow() + { + _history.AsEnumerable().Reverse().ToList().ForEach(history => { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal($"Hi {_completions[i]}", _keyHandler.Text); - } + _keyHandler.Handle(UpArrow); + Assert.Equal(history, _keyHandler.Text); + }); } + [Fact] - public void TestBackwardsTab() + public void TestWriteChar() { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); - _keyHandler.Handle(_keyInfo); - - // Nothing happens when no auto complete handler is set Assert.Equal("Hello", _keyHandler.Text); - _keyHandler = new KeyHandler(new Console2(), _history, _autoCompleteHandler); - - _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); - _keyHandler.Handle(_keyInfo); + " World".Select(c => c.ToConsoleKeyInfo()).ToList().ForEach(_keyHandler.Handle); - _keyInfo = new ConsoleKeyInfo('i', ConsoleKey.I, false, false, false); - _keyHandler.Handle(_keyInfo); - - _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); - _keyHandler.Handle(_keyInfo); - - // Bring up the first Autocomplete - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); - _keyHandler.Handle(_keyInfo); - - for (int i = _completions.Length - 1; i >= 0; i--) - { - _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, true, false, false); - _keyHandler.Handle(_keyInfo); - - Assert.Equal($"Hi {_completions[i]}", _keyHandler.Text); - } + Assert.Equal("Hello World", _keyHandler.Text); } } -} +} \ No newline at end of file diff --git a/test/ReadLine.Tests/ReadLineTests.cs b/test/ReadLine.Tests/ReadLineTests.cs index 9634a64..3de99c6 100755 --- a/test/ReadLine.Tests/ReadLineTests.cs +++ b/test/ReadLine.Tests/ReadLineTests.cs @@ -2,6 +2,7 @@ using System.Linq; using Xunit; + namespace ReadLine.Tests { public class ReadLineTests : IDisposable @@ -17,6 +18,7 @@ public ReadLineTests() ReadLine.AddHistory(history); } + public void Dispose() { // If all above tests pass @@ -24,6 +26,7 @@ public void Dispose() ReadLine.ClearHistory(); } + [Fact] public void TestGetCorrectHistory() { @@ -32,12 +35,14 @@ public void TestGetCorrectHistory() Assert.Equal("git init", ReadLine.GetHistory()[2]); } + [Fact] public void TestNoInitialHistory() { Assert.Equal(3, ReadLine.GetHistory().Count); } + [Fact] public void TestUpdatesHistory() { From bc34e00a30351e98e5687d16345085fe2efa230e Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Mon, 7 May 2018 13:51:59 -0700 Subject: [PATCH 12/21] Add build support for .NET 4.7.2 --- src/ReadLine/ReadLine.csproj | 6 +++--- test/ReadLine.Tests/KeyHandlerTests.cs | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ReadLine/ReadLine.csproj b/src/ReadLine/ReadLine.csproj index 296b677..c023ad9 100755 --- a/src/ReadLine/ReadLine.csproj +++ b/src/ReadLine/ReadLine.csproj @@ -5,7 +5,7 @@ Toni Solarin-Sodara Toni Solarin-Sodara Toni Solarin-Sodara - net45;net462;net471;netcoreapp2.0;netstandard1.3;netstandard2.0 + net45;net462;net471;net472;netcoreapp2.0;netstandard1.3;netstandard2.0 ReadLine ReadLine readline;gnu;console;shell;cui @@ -16,8 +16,8 @@ true snKey.snk true - Updated to support .NET Standard v1.3 Framework v4.5 / v4.6.2 - 2.0.1 + Updated to support .NET Standard v1.3 Framework v4.5 / v4.6.2 / v7.2 + 2.0.2 A GNU-Readline like library for .NET diff --git a/test/ReadLine.Tests/KeyHandlerTests.cs b/test/ReadLine.Tests/KeyHandlerTests.cs index 917050f..1e332cb 100644 --- a/test/ReadLine.Tests/KeyHandlerTests.cs +++ b/test/ReadLine.Tests/KeyHandlerTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using ReadLine.Abstractions; using ReadLine.Tests.Abstractions; using Xunit; using static ReadLine.Tests.ConsoleKeyInfoExtensions; @@ -32,7 +33,7 @@ public KeyHandlerTests() private readonly List _history; private readonly AutoCompleteHandler _autoCompleteHandler; private readonly string[] _completions; - private readonly Internal.ReadLine.Abstractions.IConsole _console; + private readonly IConsole _console; [Fact] From 4edea46e001eb98fdeaa597c56227d43a6a1789e Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Mon, 7 May 2018 14:35:16 -0700 Subject: [PATCH 13/21] Revert expression body format style after code analyzing. Change internal modifier for unit test domain assemblies. TODO: Revert & consider using friend assemblies (InternalsVisibleTo) w/ SNK. --- src/ReadLine/KeyHandler.cs | 2 +- src/ReadLine/ReadLine.cs | 20 ++++---------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/ReadLine/KeyHandler.cs b/src/ReadLine/KeyHandler.cs index 8e34ded..56e4dae 100644 --- a/src/ReadLine/KeyHandler.cs +++ b/src/ReadLine/KeyHandler.cs @@ -6,7 +6,7 @@ namespace ReadLine { - internal class KeyHandler + public class KeyHandler { private readonly IConsole _console2; private readonly List _history; diff --git a/src/ReadLine/ReadLine.cs b/src/ReadLine/ReadLine.cs index 66dc0ae..0bb765e 100755 --- a/src/ReadLine/ReadLine.cs +++ b/src/ReadLine/ReadLine.cs @@ -10,31 +10,19 @@ public static class ReadLine private static List _history; - static ReadLine() - { - _history = new List(); - } + static ReadLine() => _history = new List(); public static IAutoCompleteHandler AutoCompletionHandler { private get; set; } - public static void AddHistory(params string[] text) - { - _history.AddRange(text); - } + public static void AddHistory(params string[] text) => _history.AddRange(text); - public static List GetHistory() - { - return _history; - } + public static List GetHistory() => _history; - public static void ClearHistory() - { - _history = new List(); - } + public static void ClearHistory() => _history = new List(); public static string Read(string prompt = "", string @default = "") From b6f5bc47f2253b6e36c3f43533e657ef11c3af7c Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Mon, 7 May 2018 15:40:40 -0700 Subject: [PATCH 14/21] Refresh unit test files from merge @ PR#41 (77c1761072df4cce910c676e1874ef38cdfb0ccb) --- test/ReadLine.Tests/Abstractions/Console2.cs | 20 +- test/ReadLine.Tests/AutoCompleteHandler.cs | 23 +- test/ReadLine.Tests/KeyHandlerTests.cs | 536 +++++++++++-------- test/ReadLine.Tests/ReadLineTests.cs | 46 +- 4 files changed, 346 insertions(+), 279 deletions(-) diff --git a/test/ReadLine.Tests/Abstractions/Console2.cs b/test/ReadLine.Tests/Abstractions/Console2.cs index 8548360..1b0a56e 100644 --- a/test/ReadLine.Tests/Abstractions/Console2.cs +++ b/test/ReadLine.Tests/Abstractions/Console2.cs @@ -5,15 +5,6 @@ namespace ReadLine.Tests.Abstractions { internal class Console2 : IConsole { - public Console2() - { - CursorLeft = 0; - CursorTop = 0; - BufferWidth = 100; - BufferHeight = 100; - } - - public int CursorLeft { get; private set; } public int CursorTop { get; private set; } @@ -23,26 +14,31 @@ public Console2() public int BufferHeight { get; private set; } + public Console2() + { + CursorLeft = 0; + CursorTop = 0; + BufferWidth = 100; + BufferHeight = 100; + } + public void SetBufferSize(int width, int height) { BufferWidth = width; BufferHeight = height; } - public void SetCursorPosition(int left, int top) { CursorLeft = left; CursorTop = top; } - public void Write(string value) { CursorLeft += value.Length; } - public void WriteLine(string value) { CursorLeft += value.Length; diff --git a/test/ReadLine.Tests/AutoCompleteHandler.cs b/test/ReadLine.Tests/AutoCompleteHandler.cs index 6332dff..6d38439 100644 --- a/test/ReadLine.Tests/AutoCompleteHandler.cs +++ b/test/ReadLine.Tests/AutoCompleteHandler.cs @@ -1,25 +1,8 @@ namespace ReadLine.Tests { - internal class AutoCompleteHandler : IAutoCompleteHandler + class AutoCompleteHandler : IAutoCompleteHandler { - public char[] Separators { get; set; } = - { - ' ', - '.', - '/', - '\\', - ':' - }; - - - public string[] GetSuggestions(string text, int index) - { - return new[] - { - "World", - "Angel", - "Love" - }; - } + public char[] Separators { get; set; } = { ' ', '.', '/', '\\', ':' }; + public string[] GetSuggestions(string text, int index) => new[] { "World", "Angel", "Love" }; } } \ No newline at end of file diff --git a/test/ReadLine.Tests/KeyHandlerTests.cs b/test/ReadLine.Tests/KeyHandlerTests.cs index 1e332cb..f10d3aa 100644 --- a/test/ReadLine.Tests/KeyHandlerTests.cs +++ b/test/ReadLine.Tests/KeyHandlerTests.cs @@ -4,399 +4,495 @@ using ReadLine.Abstractions; using ReadLine.Tests.Abstractions; using Xunit; -using static ReadLine.Tests.ConsoleKeyInfoExtensions; - namespace ReadLine.Tests { public class KeyHandlerTests { + private KeyHandler _keyHandler; + private ConsoleKeyInfo _keyInfo; + private readonly List _history; + private readonly AutoCompleteHandler _autoCompleteHandler; + private readonly string[] _completions; + private readonly IConsole _console; + public KeyHandlerTests() { _autoCompleteHandler = new AutoCompleteHandler(); _completions = _autoCompleteHandler.GetSuggestions("", 0); - _history = new List(new[] - { - "dotnet run", - "git init", - "clear" - }); + _history = new List(new[] { "dotnet run", "git init", "clear" }); _console = new Console2(); _keyHandler = new KeyHandler(_console, _history, null); - "Hello".Select(c => c.ToConsoleKeyInfo()).ToList().ForEach(_keyHandler.Handle); - } - + _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); + _keyHandler.Handle(_keyInfo); - private KeyHandler _keyHandler; - private readonly List _history; - private readonly AutoCompleteHandler _autoCompleteHandler; - private readonly string[] _completions; - private readonly IConsole _console; + _keyInfo = new ConsoleKeyInfo('e', ConsoleKey.E, false, false, false); + _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); + _keyHandler.Handle(_keyInfo); - [Fact] - public void MoveCursorThenPreviousHistory() - { - _keyHandler.Handle(LeftArrow); - _keyHandler.Handle(UpArrow); + _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("clear", _keyHandler.Text); + _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); + _keyHandler.Handle(_keyInfo); } - [Fact] - public void TestBackspace() + public void TestWriteChar() { - _keyHandler.Handle(Backspace); - Assert.Equal("Hell", _keyHandler.Text); - } + Assert.Equal("Hello", _keyHandler.Text); + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestBackwardsTab() - { - _keyHandler.Handle(Tab); + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); + _keyHandler.Handle(_keyInfo); - // Nothing happens when no auto complete handler is set - Assert.Equal("Hello", _keyHandler.Text); + _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyHandler = new KeyHandler(new Console2(), _history, _autoCompleteHandler); + _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); + _keyHandler.Handle(_keyInfo); - "Hi ".Select(c => c.ToConsoleKeyInfo()).ToList().ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); + _keyHandler.Handle(_keyInfo); - // Bring up the first Autocomplete - _keyHandler.Handle(Tab); + _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); + _keyHandler.Handle(_keyInfo); - _completions.Reverse().ToList().ForEach(completion => - { - _keyHandler.Handle(ShiftTab); - Assert.Equal($"Hi {completion}", _keyHandler.Text); - }); + Assert.Equal("Hello World", _keyHandler.Text); } - [Fact] - public void TestControlA() + public void TestBackspace() { - new List - { - CtrlA, - 'S'.ToConsoleKeyInfo() - }.ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("SHello", _keyHandler.Text); + Assert.Equal("Hell", _keyHandler.Text); } - [Fact] - public void TestControlB() + public void TestDelete() { - " N".Select(c => c.ToConsoleKeyInfo()).Prepend(CtrlB).ToList().ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hell No", _keyHandler.Text); + Assert.Equal("Hell", _keyHandler.Text); } - [Fact] - public void TestControlD() + public void TestDelete_EndOfLine() { - Enumerable.Repeat(LeftArrow, 4).Append(CtrlD).ToList().ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Delete, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hllo", _keyHandler.Text); + Assert.Equal("Hello", _keyHandler.Text); } - [Fact] - public void TestControlE() + public void TestControlH() { - new List - { - CtrlA, - CtrlE, - ExclamationPoint - }.ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, true); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.Equal("Hell", _keyHandler.Text); } - [Fact] - public void TestControlF() + public void TestControlT() { - new List - { - LeftArrow, - CtrlF, - ExclamationPoint - }.ForEach(_keyHandler.Handle); + var initialCursorCol = _console.CursorLeft; + var ctrlT = new ConsoleKeyInfo('\u0014', ConsoleKey.T, false, false, true); + _keyHandler.Handle(ctrlT); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.Equal("Helol", _keyHandler.Text); + Assert.Equal(initialCursorCol, _console.CursorLeft); } - [Fact] - public void TestControlH() + public void TestControlT_LeftOnce_CursorMovesToEnd() { - _keyHandler.Handle(CtrlH); - Assert.Equal("Hell", _keyHandler.Text); - } + var initialCursorCol = _console.CursorLeft; + var leftArrow = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(leftArrow); + var ctrlT = new ConsoleKeyInfo('\u0014', ConsoleKey.T, false, false, true); + _keyHandler.Handle(ctrlT); + + Assert.Equal("Helol", _keyHandler.Text); + Assert.Equal(initialCursorCol, _console.CursorLeft); + } [Fact] - public void TestControlK() + public void TestControlT_CursorInMiddleOfLine() { - _keyHandler.Handle(LeftArrow); - _keyHandler.Handle(CtrlK); + var leftArrow = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + Enumerable + .Repeat(leftArrow, 3) + .ToList() + .ForEach(_keyHandler.Handle); - Assert.Equal("Hell", _keyHandler.Text); + var initialCursorCol = _console.CursorLeft; - _keyHandler.Handle(Home); - _keyHandler.Handle(CtrlK); + var ctrlT = new ConsoleKeyInfo('\u0014', ConsoleKey.T, false, false, true); + _keyHandler.Handle(ctrlT); - Assert.Equal(string.Empty, _keyHandler.Text); + Assert.Equal("Hlelo", _keyHandler.Text); + Assert.Equal(initialCursorCol + 1, _console.CursorLeft); } - [Fact] - public void TestControlL() + public void TestControlT_CursorAtBeginningOfLine_HasNoEffect() { - _keyHandler.Handle(CtrlL); - Assert.Equal(string.Empty, _keyHandler.Text); - } + var ctrlA = new ConsoleKeyInfo('\u0001', ConsoleKey.A, false, false, true); + _keyHandler.Handle(ctrlA); + var initialCursorCol = _console.CursorLeft; - [Fact] - public void TestControlN() - { - Enumerable.Repeat(UpArrow, _history.Count).ToList().ForEach(_keyHandler.Handle); + var ctrlT = new ConsoleKeyInfo('\u0014', ConsoleKey.T, false, false, true); + _keyHandler.Handle(ctrlT); - _history.ForEach(history => - { - Assert.Equal(history, _keyHandler.Text); - _keyHandler.Handle(CtrlN); - }); + Assert.Equal("Hello", _keyHandler.Text); + Assert.Equal(initialCursorCol, _console.CursorLeft); } - [Fact] - public void TestControlP() + public void TestHome() { - _history.AsEnumerable().Reverse().ToList().ForEach(history => - { - _keyHandler.Handle(CtrlP); - Assert.Equal(history, _keyHandler.Text); - }); - } + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); + _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('S', ConsoleKey.S, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("SHello", _keyHandler.Text); + } [Fact] - public void TestControlT() + public void TestControlA() { - var initialCursorCol = _console.CursorLeft; - _keyHandler.Handle(CtrlT); + _keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, true); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Helol", _keyHandler.Text); - Assert.Equal(initialCursorCol, _console.CursorLeft); - } + _keyInfo = new ConsoleKeyInfo('S', ConsoleKey.S, false, false, false); + _keyHandler.Handle(_keyInfo); + Assert.Equal("SHello", _keyHandler.Text); + } [Fact] - public void TestControlT_CursorAtBeginningOfLine_HasNoEffect() + public void TestEnd() { - _keyHandler.Handle(CtrlA); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); + _keyHandler.Handle(_keyInfo); - var initialCursorCol = _console.CursorLeft; + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyHandler.Handle(CtrlT); + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello", _keyHandler.Text); - Assert.Equal(initialCursorCol, _console.CursorLeft); + Assert.Equal("Hello!", _keyHandler.Text); } - [Fact] - public void TestControlT_CursorInMiddleOfLine() + public void TestControlE() { - Enumerable.Repeat(LeftArrow, 3).ToList().ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo('A', ConsoleKey.A, false, false, true); + _keyHandler.Handle(_keyInfo); - var initialCursorCol = _console.CursorLeft; + _keyInfo = new ConsoleKeyInfo('E', ConsoleKey.E, false, false, true); + _keyHandler.Handle(_keyInfo); - _keyHandler.Handle(CtrlT); + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hlelo", _keyHandler.Text); - Assert.Equal(initialCursorCol + 1, _console.CursorLeft); + Assert.Equal("Hello!", _keyHandler.Text); } - [Fact] - public void TestControlT_LeftOnce_CursorMovesToEnd() + public void TestLeftArrow() { - var initialCursorCol = _console.CursorLeft; + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - new List - { - LeftArrow, - CtrlT - }.ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Helol", _keyHandler.Text); - Assert.Equal(initialCursorCol, _console.CursorLeft); - } + _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); + _keyHandler.Handle(_keyInfo); + Assert.Equal("Hell No", _keyHandler.Text); + } [Fact] - public void TestControlU() + public void TestControlB() { - _keyHandler.Handle(LeftArrow); - _keyHandler.Handle(CtrlU); + _keyInfo = new ConsoleKeyInfo('B', ConsoleKey.B, false, false, true); + _keyHandler.Handle(_keyInfo); - Assert.Equal("o", _keyHandler.Text); + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyHandler.Handle(End); - _keyHandler.Handle(CtrlU); + _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal(string.Empty, _keyHandler.Text); + Assert.Equal("Hell No", _keyHandler.Text); } - [Fact] - public void TestControlW() + public void TestRightArrow() { - " World".Select(c => c.ToConsoleKeyInfo()).Append(CtrlW).ToList().ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello ", _keyHandler.Text); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.RightArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - _keyHandler.Handle(Backspace); - _keyHandler.Handle(CtrlW); + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal(string.Empty, _keyHandler.Text); + Assert.Equal("Hello!", _keyHandler.Text); } - [Fact] - public void TestDelete() + public void TestControlD() { - new List + for (var i = 0; i < 4; i++) { - LeftArrow, - Delete - }.ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + } - Assert.Equal("Hell", _keyHandler.Text); - } + _keyInfo = new ConsoleKeyInfo('\u0004', ConsoleKey.D, false, false, true); + _keyHandler.Handle(_keyInfo); + Assert.Equal("Hllo", _keyHandler.Text); + } [Fact] - public void TestDelete_EndOfLine() + public void TestControlF() { - _keyHandler.Handle(Delete); - Assert.Equal("Hello", _keyHandler.Text); - } + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('F', ConsoleKey.F, false, false, true); + _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo('!', ConsoleKey.D0, false, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hello!", _keyHandler.Text); + } [Fact] - public void TestDownArrow() + public void TestControlL() { - Enumerable.Repeat(UpArrow, _history.Count).ToList().ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo('L', ConsoleKey.L, false, false, true); + _keyHandler.Handle(_keyInfo); - _history.ForEach(history => - { - Assert.Equal(history, _keyHandler.Text); - _keyHandler.Handle(DownArrow); - }); + Assert.Equal(string.Empty, _keyHandler.Text); } - [Fact] - public void TestEnd() + public void TestUpArrow() { - new List + for (var i = _history.Count - 1; i >= 0 ; i--) { - Home, - End, - ExclamationPoint - }.ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.Equal(_history[i], _keyHandler.Text); + } } + [Fact] + public void TestControlP() + { + for (var i = _history.Count - 1; i >= 0 ; i--) + { + _keyInfo = new ConsoleKeyInfo('P', ConsoleKey.P, false, false, true); + _keyHandler.Handle(_keyInfo); + + Assert.Equal(_history[i], _keyHandler.Text); + } + } [Fact] - public void TestHome() + public void TestDownArrow() { - new List + for (var i = _history.Count - 1; i >= 0 ; i--) { - Home, - 'S'.ToConsoleKeyInfo() - }.ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + } - Assert.Equal("SHello", _keyHandler.Text); + foreach (string t in _history) { + Assert.Equal(t, _keyHandler.Text); + + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.DownArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + } } + [Fact] + public void TestControlN() + { + for (var i = _history.Count - 1; i >= 0 ; i--) + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.UpArrow, false, false, false); + _keyHandler.Handle(_keyInfo); + } + + foreach (var t in _history) { + Assert.Equal(t, _keyHandler.Text); + + _keyInfo = new ConsoleKeyInfo('N', ConsoleKey.N, false, false, true); + _keyHandler.Handle(_keyInfo); + } + } [Fact] - public void TestLeftArrow() + public void TestControlU() { - " N".Select(c => c.ToConsoleKeyInfo()).Prepend(LeftArrow).ToList().ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hell No", _keyHandler.Text); - } + _keyInfo = new ConsoleKeyInfo('U', ConsoleKey.U, false, false, true); + _keyHandler.Handle(_keyInfo); + Assert.Equal("o", _keyHandler.Text); + + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.End, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('U', ConsoleKey.U, false, false, true); + _keyHandler.Handle(_keyInfo); + + Assert.Equal(string.Empty, _keyHandler.Text); + } [Fact] - public void TestRightArrow() + public void TestControlK() { - new List - { - LeftArrow, - RightArrow, - ExclamationPoint - }.ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.LeftArrow, false, false, false); + _keyHandler.Handle(_keyInfo); - Assert.Equal("Hello!", _keyHandler.Text); + _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hell", _keyHandler.Text); + + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Home, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('K', ConsoleKey.K, false, false, true); + _keyHandler.Handle(_keyInfo); + + Assert.Equal(string.Empty, _keyHandler.Text); } + [Fact] + public void TestControlW() + { + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('o', ConsoleKey.O, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('r', ConsoleKey.R, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('l', ConsoleKey.L, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('d', ConsoleKey.D, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); + _keyHandler.Handle(_keyInfo); + + Assert.Equal("Hello ", _keyHandler.Text); + + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Backspace, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('W', ConsoleKey.W, false, false, true); + _keyHandler.Handle(_keyInfo); + + Assert.Equal(string.Empty, _keyHandler.Text); + } [Fact] public void TestTab() { - _keyHandler.Handle(Tab); + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + _keyHandler.Handle(_keyInfo); + // Nothing happens when no auto complete handler is set Assert.Equal("Hello", _keyHandler.Text); _keyHandler = new KeyHandler(new Console2(), _history, _autoCompleteHandler); - "Hi ".Select(c => c.ToConsoleKeyInfo()).ToList().ForEach(_keyHandler.Handle); + _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); + _keyHandler.Handle(_keyInfo); - _completions.ToList().ForEach(completion => - { - _keyHandler.Handle(Tab); - Assert.Equal($"Hi {completion}", _keyHandler.Text); - }); - } + _keyInfo = new ConsoleKeyInfo('i', ConsoleKey.I, false, false, false); + _keyHandler.Handle(_keyInfo); + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); - [Fact] - public void TestUpArrow() - { - _history.AsEnumerable().Reverse().ToList().ForEach(history => - { - _keyHandler.Handle(UpArrow); - Assert.Equal(history, _keyHandler.Text); - }); - } + foreach (var t in _completions) { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + _keyHandler.Handle(_keyInfo); + Assert.Equal($"Hi {t}", _keyHandler.Text); + } + } [Fact] - public void TestWriteChar() + public void TestBackwardsTab() { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + _keyHandler.Handle(_keyInfo); + + // Nothing happens when no auto complete handler is set Assert.Equal("Hello", _keyHandler.Text); - " World".Select(c => c.ToConsoleKeyInfo()).ToList().ForEach(_keyHandler.Handle); + _keyHandler = new KeyHandler(new Console2(), _history, _autoCompleteHandler); - Assert.Equal("Hello World", _keyHandler.Text); + _keyInfo = new ConsoleKeyInfo('H', ConsoleKey.H, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo('i', ConsoleKey.I, false, false, false); + _keyHandler.Handle(_keyInfo); + + _keyInfo = new ConsoleKeyInfo(' ', ConsoleKey.Spacebar, false, false, false); + _keyHandler.Handle(_keyInfo); + + // Bring up the first Autocomplete + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, false, false, false); + _keyHandler.Handle(_keyInfo); + + for (var i = _completions.Length - 1; i >= 0; i--) + { + _keyInfo = new ConsoleKeyInfo('\0', ConsoleKey.Tab, true, false, false); + _keyHandler.Handle(_keyInfo); + + Assert.Equal($"Hi {_completions[i]}", _keyHandler.Text); + } } } -} \ No newline at end of file +} diff --git a/test/ReadLine.Tests/ReadLineTests.cs b/test/ReadLine.Tests/ReadLineTests.cs index 3de99c6..2b8cfdc 100755 --- a/test/ReadLine.Tests/ReadLineTests.cs +++ b/test/ReadLine.Tests/ReadLineTests.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using Xunit; +using static ReadLine.ReadLine; namespace ReadLine.Tests @@ -9,46 +10,37 @@ public class ReadLineTests : IDisposable { public ReadLineTests() { - string[] history = - { - "ls -a", - "dotnet run", - "git init" - }; - ReadLine.AddHistory(history); + string[] history = { "ls -a", "dotnet run", "git init" }; + AddHistory(history); } - - public void Dispose() + [Fact] + public void TestNoInitialHistory() { - // If all above tests pass - // clear history works - ReadLine.ClearHistory(); + Assert.Equal(3, GetHistory().Count); } - [Fact] - public void TestGetCorrectHistory() + public void TestUpdatesHistory() { - Assert.Equal("ls -a", ReadLine.GetHistory()[0]); - Assert.Equal("dotnet run", ReadLine.GetHistory()[1]); - Assert.Equal("git init", ReadLine.GetHistory()[2]); + AddHistory("mkdir"); + Assert.Equal(4, GetHistory().Count); + Assert.Equal("mkdir", GetHistory().Last()); } - [Fact] - public void TestNoInitialHistory() + public void TestGetCorrectHistory() { - Assert.Equal(3, ReadLine.GetHistory().Count); + Assert.Equal("ls -a", GetHistory()[0]); + Assert.Equal("dotnet run", GetHistory()[1]); + Assert.Equal("git init", GetHistory()[2]); } - - [Fact] - public void TestUpdatesHistory() + public void Dispose() { - ReadLine.AddHistory("mkdir"); - Assert.Equal(4, ReadLine.GetHistory().Count); - Assert.Equal("mkdir", ReadLine.GetHistory().Last()); + // If all above tests pass + // clear history works + ClearHistory(); } } -} \ No newline at end of file +} From dadba03ba79c534c9216445b00b3e818b49d0b6f Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Sun, 9 Sep 2018 17:31:13 -0700 Subject: [PATCH 15/21] Update build configurations supporting newer .NET frameworks. --- artifacts/ReadLine.1.0.0.nupkg | Bin 0 -> 29053 bytes artifacts/ReadLine.2.0.2.nupkg | Bin 40640 -> 29531 bytes src/ReadLine.Demo/ReadLine.Demo.csproj | 30 +++++++++++----------- src/ReadLine/ReadLine.csproj | 6 ++--- test/ReadLine.Tests/ReadLine.Tests.csproj | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) create mode 100644 artifacts/ReadLine.1.0.0.nupkg diff --git a/artifacts/ReadLine.1.0.0.nupkg b/artifacts/ReadLine.1.0.0.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..7ca71ffbc7f4f3e146232325738b1656d18c11f1 GIT binary patch literal 29053 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 OJ~Khb)UeI#PyY`I{lmTh literal 0 HcmV?d00001 diff --git a/artifacts/ReadLine.2.0.2.nupkg b/artifacts/ReadLine.2.0.2.nupkg index 0ab6877812133bce42e1c7eabd30d54364d3ade7..a20c5d92599d99a488c9d7d9ca01c606bc3f79d7 100644 GIT binary patch literal 29531 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 z≫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 literal 40640 zcmb5#V{|54qp0mT9jjv}9ouHdPRGU*+qRvKZQHhO+qRvYUTeL3zi01#&KckLqpHTJ zpL5I_HS4Zx%1MHPeFp*p`UW%~P$czS*|iP}3qD70>cP=&bR_GVsQ07|UJjht&)vl^+iXZWUZ8%1gJK9F89cw5px>AE} zDT}B@U>WzL&4z_Xwk}7 zpri43_V|_Wv;%Gy1;P`4bJ1~lfW7NAh=^phPbSXbq4eA|CQe@}v3r{%knc#r=m@Evh6=GB9c~4wd8I9{hfMX`#Be4;paT@ubknXT$ z&}&EZZ($bh+n&!O1*e{&^|O}>-1AtQFR;QDcS4U)VpigE;DaY=hIG1{B`E9Qk~uwf zUXaQCmqBZdDws0^0RjSt1Oh_%GibjI^$es;tqf_c9PMok0Ub&cRwxXJoy0friBpjo z`QG1Lo1o?S#R!87U4e!&Eu=acYdS3Z%51k|T)^8$jM~5xgurdZot!#TUJlc0o`#yP z&QEjZkKsM!77bkZUom`T?q=1 zHzC@>gqCA3t0_QnA0dnCy=A0PalYLm{*W0#)F%<5b=}vXT9G(h>ON4!)Mdt;I15tc z{o%=I;9$+Ftv%52K-g6ylGC!VPBoXNF~Vc)aAi^bxY=z#J-9@`<53bHT!O3%5)lA| z-h%YIsu@0XqwbSb`w9o9>Q24jw*jT1rpj0a>rA2gY$3Jg={${=SzEq%-?vN|z9_P~ zmw*|WDAKaKN2U-L17#7eXHx$Ff_A$aG@Ah4akP#zh{*cZ3h%_sH#l{*=wS=HJ`=WF zR8dd_`Z^@RP8-tz0{MD!#Yr{%CSQ}xd$Cao2R4GDGa zXi5%xMqJ>9T5)R_YpP(PC-DBpEZC)uMkBLJhN&3_@lbRjt=OLM+^EV1d_61zE6~Z2@rh)_eGiA`z1%y3O$JfBtc`dglLcHmvh#;& z4*3#{n-|i-3z!@mn|5Ex3);b7GG)9)T^H0E7b}s1K6WKp<#$z+aJv(I)EtcOB^{GP zcPvlv_}U*R4!Si63+qsKO9>dBmG&ZB__&K6`2=53|8-i*TE;Ry{`F|n0|BA^xmcL$ z(^(lhFtgD8=L9vdu((inb-+1@sp2gxa*TA8>>Nsrz8S`HSRTXxl+R&NP5ah z-vz5vdUzPG7qRQr8CiRpeVl*#I4!H{EPXxYa%0A(Z3X@gBzJSSVhj}R=d##~?_Jq1 zt9uCmW>>ynZx=1-JUV>1V$IN9Z4|k9R;5RhEhv|=8UD7qSCX9q?PM7SK2)wp{7YH6 zy?ddi1v^{z*Y-}|;DuU8RnNO_=sYZ}XS5#yt z^x|dI8eA^mN=p-BE}TsACbTb63u04}fC_Ggd@4rq%Dn0E6Q11j16p1&)|?7QAYpL3 z6xy7}Xda~rES#Pi5+7(|xJk*HL#_Z|l><4TY}GgfY2s|0*kUE%68b zimC_w>{wZO6U_N1T9 zpr(=q)i|>ywW{}N(`(?yOx4PIGt2Y>7Q#6gFeAOIt+>I(-=3Jw>_UFcu~{)3N4 zivr?ScwqxB>KP6Eun9~O0Cx%Q!z8zHIuyq@BhB5<>E2M%6X6w$nSoPXz;GfcheoaI zOHrd>dGr@Q*E@>7ojP%Nx^T-$@fuRqN@ur zxaF9j+PqvNySFhCx4Ag0mwvP&LE;8+%Z7ay$Ju*%CU8!X9FXTh2B}9O(&F$!u!p|! ztlin~_a%y>_@5-)vIFsMESVi1R`Or~rZhlawHW3iRS)!B=`>q^RqL%h6x87K1yCl!wDAb}Mel&9w_cZpQS< z1TtRR89tZU%}zx1(sZKss=rxDC*&#e`aIfTGXgIpB~fY96bqVb0>D|yQk0#Zt3~^I zIT_{4DkrHB?|$4VVg6K-M>iuZ!UnB1n#kD`-tBOZ-_|-7Wm0b(;6#Z(+uRhq}kT}Mn z9YEz&Da5jM&t9ufJJvkNIGmt=3n=7=%8Hqf-vCvMuqsk;FvhHSF?jZ8I?iOT#r8i*T~cNl#5V%N7ibGme{JxY5XAIMy0BLcx&=xo}0m0l>S7tq%AF`5!;4< zihp|)bn$L_DrsgLd;c5ei>%VT*}D`uZx(Nb}MvpvTb>OcZfu|wazq58Pz zXC7i`!NhXvqwhOe4%_6dgMroI)QEy|Byfd|Di+D5elG))$Mb3GqKYHVZ{S_r; zu5*vVFYNhScg*qcN61e@=1kk-eeX)UGQ#@tY!3K(TtzJ&BX_{fqNoKBIw}$@aJ+i2 ze(#~ySkwiIzFQ;aig4Nr+QO|FC)$MzQX0v;z4ve_$5#zSF`GcBu@F=Ao@yjA^Ui5H zpaY^02p>XU0);j3APZSaA-p4=Lu#GjBvtxwt?$g&D<5~R_Ig0V4Zy(s2#WcY{%yxWT9yua6s=#52leVf+CU7FxVBCZg{@NcD`5UXz zFl=-FH;5fz#*rp%t8{)*GU$s$u zgNnwqr#BNdeU6nbI=F8Q>$fBrE#Q$`8$YGDiejP34w+`ZCcB`G-ix0KEyq4W$I0QZ zEjnX@zJv32Lgre`K4Oq#!j`;n&hc~ya{RP@mBJuAA)Mhm;OJVEC|Ii0(^^xQHJZTH!Di5`$iPGs?k5KcUjcj?b#`3W;00 zg|~zhA-FI$RKKvdD8})A5_~x6_;bU>Ms()zox%`~egiXf6QT_!rd2Pdi=)~eqb*&M z6#!q~&n=jh7y3HMtr9Ogpj@wa0dtw&qE+cj6^TLF8d@p$#Y6uPQV%vk$@`-G^)9du z-q>PN7(Gow+p0{$e4dL+-6Bd*qIMByPPmu*gtXAdLhFXelML*gmLSB8a%nkkR0dIJ z=PI3dgcO-6%It<$aV_y`(#}n!ak!5di8tOvmlprQ7^PeNsexdDl6eefTyy7%@g?$S=gBK*SJmo!F2CE zPT_@Ao)n!ytG{XbNyhpUVIk?fMl22_&Z1*PN)1k(&Lou{W> zg==g}&{1!gqfd%>oNl+ct6$|hRViYj-o)ugl7wGlv%Jsfi`U;ZbN;MOSw73u`sB;$ z+ zrlXzE?6+TheKW1|fG*kPi*zWAK5n3#K^-?$HatOf$uea!XTP9J0GWP%11<9_miL90Svn#k*Tysa?ym@qQtm^KqLyJMCKr5-jwgc1dp@C7Z}1Li)W2)Rw2 zU^N2^pXvNrZkB)Em=lw_aC*T|YI@;xW&v8uhzOuw(%j*#Lgk=NF(iRiL7zOlcw1|k z`O2u;(SwC2i)F4mF0Se{i{rQKMFxlv=BzN7)y`0L^u1Sa}YuKK%}fMyv= z06s;WY0vbc>8Xl|acy_R7W9#ELq9@Kf`5G2AtE{g!)csb*8n}djA}OsSV2=N-X+Q3 zYpjCaKF_uV2C(-ts#u;8reSSjXWXheox=7lVxC;N?gbrFhBO6#z?S2nh3FgzptH(~ z!w9_UdT|KLEV8~J1s~GBX~98izdo;HeVyLBjn^dD_ie_D3J&w#MjwXGL_;6ye9&=6 zVW>F;hxPn?7m@cMNfgc9esu$%fEPR(BH4~jZ>h*iz`u5Z=Y{ghRjj4E*qC_Ea8OjC zxhf5+$cDA9jM`|~eIj6|*&L=LKcl}V4zRMVYt(dNGc44d@h;Ucw?C*wd)cqXh1)$I zmP6Dx(r9?}Ga#MS<56~=G!u;4Z!e9QlvKm%@)p)C3e!{*>bO{L&zC$i#5g-xh1LSA z6*jJyY07g@Y_RT*K}u%dl0nqjnEPeboF33buBq}m&cFoPHz?-8eRA4FU;Mj~0UFbq zo}JEy&Iy*9-IX0~ZZGBB;(l&xLL6L$-a!-oHfyd!KC&<<(vv=9&NuTCec0gCh++yh z;l(4kvpG(0MwXi>cQvAE|EM9Skime4t_(79mFR(SvjOQHBseT8b~O6`P+D0)-=r_cPLczQ(~ z`x%*SqwMZIz~XJDme3+pZ(J%9G)ch$@hUp_IpbPmpySND?W0C|E77a^HQ@|D)CVj6 zhZdCIexHOec#qF%5~cBr8Rb+A$a3zRIptIwXu?HjHuXg56LEzfC6tC(wLWNPjH0HX z0jRbqXq{1sm)erJ@=T1z%EcWOu$I68bYvdE`~y&w@{07hPbK)lsFhaEq_5AR%7f44 zt;6BO?VD$7RK|2}MXXe+JZFf=v4Ke&Ui{5KSGz>-OlkHv+~N}E8l{^&G6IGeQ~v#! z9(jC%m>YQNo#4UWaveH?X(XPFx!zaZla_Ny9Znkw&f6WSRSRsuo(vISH;Jn5FvYtt z4PoBgkF&lHbK|nu6{qfPZ?x+#JF?Nr-bY7An@nHco8~SS7voX2;bGPu$D2o&m=$l6 zZPp*BsuxXF&nt-tbSKXvn{Q6mRd3iQBbZZ9bj7V-i*J(3{od~bqe+zbYu`2B`#1R9 zjutPgxSc-7bXrgM!KdEe&Pi%iuiMbq+n-K6(i zXIY$Me=k*-)PdF(QmG4n&!IJEL@U6^T=~vs+UU2Ff&1;aKtQ;({OB`*nT>IRH(XKZ zhDGSeim>HPN2v5F5e`N)E^O zX0H~fHe6Zj`d=Gw$Pin;ug+_W2k;#^AvzGkB*{oC%Ntp3c{GmJ7)KXcXlhZEAPX&| zPpC%3y%MJ=;|*Z)joN;tUhOGh0A3S8?o9{5B6Ffpe79I`Xb|dM;T7{by#q7cOfCiACF}5##Xb&$(x4i%!C!;51(OU|S z+WQq6Pez-qC3B^pJBx79@1OHA(N$P4dT$LsGu|>k%E+>~-aq}PvRrOj=X0G2aCw~W zpLZm;d>!eu-JQbY5<@;pbZE z-gG}C%dUTx?=3s6&xy#s2!%*yQ?Z_1qpX5%h_Z5D%SuP;a36iH!VWmixOd%_yhLojQ# z?AJhU(Oc(YFr3Q7!dzs2R2gKLd-I3QP!hbELuLhu-U;iql=>J5 zH)?~G{T&MsFqbqi*0J4}hvlP?F{eZ66r2o-M`D}T}fwFgx@}hz8 zz;DX^`95)aWOaM~v{LQ+^Ip*cUt@Im3)YP7e9OqSnowQtLQroUUMbrb|y zc>odx6_xh+>GCWnJpsjain9b?+JZYW8n|S>kq;t>^fjkj4A@OwxE{xnp&r}*0MO<4 zcP;~{k5xyO(Ah7K6sqSJj;JoofKBX#lnm;D-3}|CoM@!Db^pf`ykg?ZyKS-6<)pz{ z_mVRev1P4neU*NvbN1%OoXB$$Fb&@4C1#7;ZLSXK!L zzfM&#s&;Kuc|*i27BgdeadRp0`%z1wrA|y5^5D&6U8^;;A{Sb5mxIhahKqR%0?JaA zn&&6nIRdzTHwr?J5oS=133X9)XxX5Fn!}+*!YTBx!VIX2p)D?6unP${H_6BSjL*IN zZJmS5h@n5CGMog6!|Ls)$i#(mk@H+j!Mj(3t=!iyM?+WXEm4oi?5}}dQ0SIf!#Q-U z>?PsY`cT^nFJ=^Vkvn^Eey;z7&zjuQi|zt`T*`V-@s-_ehJH!A(&RQ=EWV0D?zwFX z!=(P!s%8t(x;tJNp_XPoE?x^(8Ms?uN3-S&ZYb#ziIWRXLPfY9%^cQ%X*o@PKHPdsu}{D^PLwd*N06*<&U0)B~ESA($c&+5^||c^H3ZKcyFBK)su^ z+OjTRj^6kp9)m^3MU(C^Aiuv3NC?54aBa|{N4{KmZgBc1oWh=;jICzBP)MM^zrE11 z7biAzBVQA|gx#GS_2ArT`G9_Lx;)mJ!Y)JCJisfZc#Ulb`6)P2ibb4m)F_-*84~+v zBhK(j?8F#f1FF8~JND{M7IK^dmfAk`gtX{J)U;q`ohi+@^U;(w&Dd1xmZQI`atIgw zPxS5hMuIAeBSdK`H^zdPU_vj{jP@3j07|<}RB4Sg)KXQr^lv*wrk0EQhibebGQ|^J z{SCRHd+S4*AWcR~;Y61j&*_DAzlY9e?J@#$&&FB5@Z~04U3P|MJNok43M(`xPp4SN zvp>XN2sXsbG!ln%gK7s}xWc#9#_DcR-19+Z&hbVrGT$arjtn1QVR!;Tj;XGgcjh9e z303fKLo>w3Dt_MT6s0S`CtP!*Dx5C3Jl=u}BSlPbM@9A$8LC!+QAw2vYRoD&exJ*y zbWh*iHOc4cQZZ<5t6AI;Zx(4()|HGa4@hX;DX|e{?_FvoE-+X*?=w^!Pl~qr&sNHm zO!U9E(kj9K+Dbz&s3iVpD~>~=?ce$)5>|3poha*n zeJ>N5kr^QR(@KRCX#b;?O8?bLiT?Li`XX^`@jqLsvECz;v@bF*aS25mWG%*qjPda# zqx#+1PLoVgn`sUe1^jPKvi9j|uX=)IC%-FUYr`X1hXZPA#~#e|1;~>MUE!3myp5_* zr_*%1&2UY37D7w$OI}5f;VkUU3&DugVQPd@Y^!*)qHl>XN*quycRDEM!)0L@lBx3r z4UwmgF1Qwych}ejX0nh*2jhk2acFpVt?7}w7G@`5nOh_?X-FYY^&M2i6ETg4jfr)> zvR^-D7clCB`hcEvIRaoR2~!&<=9_;aU+vU(q5RcKdnf*GrG1ND9xVP{Khyc0v07sn zO`N8BVAdYNozYQe+O{G8)k=~6-AY;h-AaxBX{9QET4|QTpH{kQ{M!EBX^mE%t>}wz z0I%d9H(Dmv#I!M1pK1y-SHybndEcp~`nR?{&>9*PCum z71H-~id?8`z>|r3Ya&*q8bZq}wTtLE#IoRcE6{MTNeWG@m%Kg11a(o7J&cwn4l1FS zC~CT^H*l5m8$a>W-59#r_h=`%e7mSVN+Dc~9+hn^o!&{5&DP*T1#!b_BppGGS$Q2%_sLiJ-E9g72VSo$;Rq!HYG>#_SRgisphhiuF)!Y*y~gs{Cw0Ikyu z3uR6~_^O&+H2<$UPJ$)DRpBlHMFf?$W4(J_)^|%~pxM_!J=)PqOvTdc@94Oiv{4$zut2gl`@DMB(xq(7t%a%=@`Zm~gC6_pHRL zN?3}y(XXbEUIVfZb}6SHoELdR9{sLMKl_kpC@cBO4&7bP)G`hZkfjI`c8Ho}-c>wY zQ>N^z;Kp@^S*f4up-&Io59%0si-#H>nX&>}gl0HEDU8@>?M(FCSm$I4KmLiO5hq&f zPi0clg$1;cd+l0d4`zj;F_qn~C}va=r1LDv6*>!x#2+PH2$_C5rr7eItm$t>a&{PJ z(w&mkUKvJ2B%g3Lm2`pcvXXDxI;wpNHZ5)#94c>B25>{wothsYi(3m;L*+S0Rfcd& zy%VcT)1`Z-c_u$IUM=g7JVP08Jx?(A|Gd$G==%C@%a{}IvFz0I*?!-_d~u1T9U%Os z{8SJ-dJfUfL$)-QsiTyn>$6T~tqW54{6zu8lS}~|fin}yud|TYZN&kibS<85zwMR} zX9F`U;(|-Dc@Y0C9n?^4sZULe&c`ZWemUZvD4#EoU9)_h1j#e3gz`$j?N<(Gv5>!% zGXoFNDQ_iHMNb@cn7ReG|CKM<4%xN&^o>-G^{gQ`E^0ecarTXKAKwB5Ls8e^R@6Pd zCpw|0%xYl$VitdEx9EMcgae$t(ILzRvYE>Bnlb)#6NT44wFqV2m9VOguVN5s1mecr z*ze5Hw?f#7^D*h$f1 z{B^poC8vH-kydGAM$EM?UQGM+#KagQRW5^}Uz7O<7-!By7DWILgM20qJ&u!1Mg6;F zpA<$~Ye0(_x8(|M9x>C?iR^$SpjWKmZAh$hfOrd}BSq0e1?K)KpAjVp7h4)D1VV}| zasalqHIkxLou^ejXDy;gnhLe<>B=ndL3y+$R)i{|zpkO(BCV(sdC{sKIVFDv7)55i zHtvvI=!we|KvcUaK?=8cBE*V8(Z{++Z_7|`Q1 zQ{LxlZPHbdfv6k(t7jAjZQW3G&0HKsSpuk=ZfHsb+v8MD7 zhV&yHj3*;aWJS&}^)Sbn$T#hu8GmLcQOI06VIS-_vHSX+@>mfpI7Hedgw~}Ly z%escadGExdFA?K))^x4rg9($70aMZy3xcVnoGGU8m{)=_w!UNJwV(u(<3=3Vt6{#s9SxkwOVa=4a_HKPA?fbK8#GeVE@1EB zyc$>K3BlwP-s@=ColZaZn|@F~CBJN|H@i1KQeMp6zsJ?ry#}D$Gty_uo+55+3<&wO zlA&z&%h|IF_)5QwH1np^JNHLQhrf5|;wM#LlXNvI9zWuO?N4V8x57JEh(mUX2t)(5uBpzu<5aH6zlBB}kdsd55Ym!|2R zrs=@*GyYh6#kR2yz=k@h{zlaHq9gb^2r>a1Zj@)0Q` z_S<%0@Vg&3zn?KjYUAjvS}(7=CkoiK?hm=%E+JUR#aofVMuHQ{M>kf!`5SKJ34~w+VLL5#iebiRQmFE&S)ear0 zfVBFBp<;;&6rTa(RMZA118c#ICh)WhW`F`uRGk8E9Gr}&ojtud;Bw^%YmlTc=Q$uo zPLE8>@R09?d%GqCX+?`%JSR7p6ZspK2%p&jHDSP5`zjE2|?DE>{ieB2=u&}pTL3#2x^0q#C83!D7I4q!6WqI!o-6e|V^@vV( znXX7*cRzU2J+WUsb~%ob1x>+ix(Uuup0Pw8i7%~-3u;H_PQVPOR+^xGd~;Nbt05n_ z9?xqQzxxh*)y~gP2S@qKkmso?za_@>Q7u0gU+1SoR8!QXvVQyz@o86J56?qhj3s^` zHQ-sA7N)#1LL3n&J-g#&1S&=^2ah{MKBQDxU+h@(rnQ<8Y2{L5o%L<5>1nIA*6|#+ z?>A%Fk;vnb7N?k_8#BtyY!UWPl@ax#>hj{*oJ+@@{T70%(j9&+i3E~Ml5#8oO>w&O z5`)*(R$=O)7$2ntiXeQO^%2SbRBjxd;f@e&7OSg5Z-&USwYszGKMm#wm%<4)U;Xm6 z9Lyt`MXy2SsC}b>FA`Q4mc%L^q*o@%UZS_ya*2=89?wwV* zT{jk+GP^21K8T0#Iu9G^yq{;WzZ^^TZbZ92Y-Z^Eui&m)+#iXfwH^}KGTZo^j?kSu z+^_eOsP7iMzM`YMoLwPTreCHNWc})GVZhOy2{E#_a%sl8uwx69o(UJ5YA)6?S=~m9 z1T`TxW?F)?rtwZWT5oc^&CK5CR}dzNaW~AJoHTA=JIXk?no?v)6JbT>QUXlDHPSRD zS3}WNI9)O_R>&_L&Ry_S^O7zdiU7u=VpSH_6Ai+oD9=HQODnCVxa%=GBT-VDo`w4+ zPuHKTWe7uj-;^H@X|!TKSTufJp z1ev1qX)jlN@|{%4!}wVO3aN&v_Fu}o9l!t|2dLYnyN^gK8;8AYzG=r@{bip{%Rtim zrEYnY;+T5uWx)oXmQ`{M<36u`=F~_-u(!wNF2)Q0({+rvbI47Wntg0ychSw{WvWr< zjN~&>lsz!O`lue9w}0Y8tvb9w0BYg8C$W+tiNgEvBbLsxcTo@YLo@hL? zGUn)$J+~NZAXXe+8O%_KjYq$>pD58|f%`4{6VVjeKg|?d89lmYp_#HV{C{Ys<$Y`-jenA9wMTZ0WeUdrjFhAmcdBx$aYSTI52DNV zb?r6sx8DKMs!oKy{P0&nze)OG5Nd%1Ypvq~4P0IDe`u!J(5OWXSSWe&Fjd5)?^o>~ zbky@acy_)10j8y$uTgjti!jz;;6RG+9`6j@{sftk*TGp-Hz>(ZazHX@JUm|lC0{2m z{%_J`?0OmiCkt+j=z?F$ob38w7gCfag??IVc|EpNdP1Y4Vd$-#P7a{=lF-y$nw?~2 zPt4Tc62&Hf2*Faf8=eTDc8&4->?+54t%k#aJ=Ct_AhLDd{*#wh?L4mu9Dk%UcKqR` z?MvYF&!YW5p0Yh#Ax}fxdDvrF;R|Zc)zAOMOVR)EQuu%IQtBq8zj^6E;6J=nxUz0~ zyyZW6X%weVE=bEyEx`+Xx6)J=_9%cP5ULE<-@G*JKX_^MBtbS#!XIABVj7P7hnE)o z;ibg?jh7k#x}aVnl>JIGDECzt#w(G|XF(phdoty_wHZ6^S5F+Rk^bVPtUPNeUjO2y zX@B$5%*>CClLT&xU1?6`Dp_-~j(-Ar9PNs-7ynI;e&(27vVcifC9YUQbX|r!AMJ`4^wgnz6 z$9Rq*{ZP44*W+kmHfMy9+!W@XH0An{=1lhTwEPnciP|NtL1gNOMs1C zQ5w1(xMDD=z*_4o&T{Dh6wq6i_~s+_^JkE48N>pT{dyrM$MB-y!x6h#Lz84`Ydz z)?G6a%h8=&6=yKRd1}@^hY}Ap1`fen^k|G+@yk<%DU8So#v&a8&)97a2}Oi~gggqV z{%~M5vGBISjo&}aQH>~CP=gte(o$?0l8^G#{Lohr4Kl}fP&iyf&qdTzCRWTMUkEJH5s z3wtSyG|C>|9%?;Pi!Q9$ddEI-QV_3Ba?BAej2F=O;vH=^*$4AUzTwW@YQ8#pQ2uGr z$GqA_hoAEoFD3dnFE#y#m!|&1OVv6F%Z$a2DZcaTxE4WWSq3<@ycWxzOQ~Do#(r@g zq}$a89F-*hsv4|InxYERwK%k~_>M-==SHHcr;fUsTUa}gOscf9_Z?l7_~M0!sBa^( z0baJ(v9&3Z$h{Y-b5To8B5{ISS!6)-MS@l%8cC%wRqRR%BCdY~p&ex! z_xqAeK;ub*2|Uc~U_J+>p+mBDQqIA0XSw1|t+-Mcwxp_DU8<>JaI`Bkbty4Q!|7=| z2!kx6P6C4>s$&kCT`L2D`JyIgCRimHQd@0f($9)|7ixUROe%b+-vco8>zXN;W`H6= zDxsP`(X?1KyEtb-@g)8y#;=Nz=m?g6c5;j{kOpY{?;ey1lF%A>nPmZsb`+Jz63-F&h39y~`VL$fg5ZjBz+{+xc5zxud9=60?}xllvpH>W)VF4A{yNv0sTt(4-iJd`OGm|e0?WcQyunRGD= zpgqW&%CORvwfS4qP6YnerCw<#l8iH7b9ka|#EN2A+&%Yd3GAMoYadwTyro@xWUtYT zk&a-+pYekCNSA4PFSLp6VJyeDd+(?{Ll#uRUsS3_9+C#WKO%a&2-QPbP^0oBB@F}% zs(py>uWWo9kwK=1Ki+S_u?7IB~6 zZ{Blnc+=Dq)` z^m?|t;iN?`vXN?HvE$WO6%TxIO71S7m`{XHNA|rc22OY$yPET0XRZ3Em?{B+KGEVq z;Wo^M=Hn#foCn&{evX^ICQU^;6t{6d>)nNH-X9gH^a!5cnN|4MDS`uy70>UqK@8iQ^ zMI@7;>$S=1mxL!GI*)S4g!n|3b_L5~YjjlW7j{nMK#mw+sV#i%5i_oGr-&*2c_OSz zzbdXk|K_Fee|RZqY=qSe{(T@~0k|I{4^dK|EjrDt$}p-;M)>IiLN*BRQLf=El+f2f zZdc6Wm{POp&9`fxuAh}bkALyffq!_Z*lL6cSDp?!#V5ffNSh|}nCLMPx>gyoM6(I1 zBp#xeney9#x>(yWjnIQlWH=r_f>H05AqmoipF4KlN@>rzruN*itI$8fw5&ar7mF@> zII)F8C=c?^GUTwYi6@WF=Zc{fixnuxSj&K+RD*Q-2?MV6*iZyi8lKY_y=cFbMsBzInx!jMUE; z*rqp~wP;V=v(Fl;daGIrj|8;B*FB`IlIGLBy6=2{S6&Od)#-2H3yl4#YJIB}@i1jV z`fGO!?C9m!aF+}x*w-kQOwYk7!@lNTS1L<-_v^2RJ5_I$Hqg2tk@id$O@t=1Ex|IG zQiNPM$3NM0>J8a&|7})b*jwS1f*TTHm~L8iR&v-hMq7CD?DI=tmD<}!@g_@vb4>JJ zJ>i)0kh!e(9;bbvK7}RyCP@PLcu)#TcR$1m{I#?Z>~RdK*iV)y1DuV>(r4{AYwwuY z4Q-LowkG+{Rw!lS4G=A{ylUJNvfrKGY@5Yi!i4U>D=6{$+}8^_%7sFtTmsw*ir<mg)o$<1nRU^`(t5xN4{_=lK;d&?7U92Bobvi%0P;JS+8bY;B%d`g}0z47|q56$xa z@ugt1uDrQqin(XWOguWriE?edTfA>RozgeN#)Q8xJ?VO18S@#L^#YDFwSycuF4Gv9 z0ZyYXXexwSa4cd=+m}=Tt4x2c3BhKBd8z^Q9mZxheACb)YlwSA2~PYRFPpA+oh>|k zyi3N6P=oX9LW6Nzb@iY$y^m~MNe+}mfW<0)UB+Y0&Q8>R^Fe-_Lg+=_htX(rd*lJp zO}$}LG_34a5glq%q%Cp6B{s=FzSQ8?jVI0YQpRWmwv)vVQ-V{r3}&>s<5Nb`6SIe7 zvp`y=Ox6m;ao+YSR93Zrd@0VU3w<^$Zzd2A1Wu20&?lX!FLIpbZC??)3L{~Hz%k&|jQ~jS&x<)5iHO2+nQ0sS zH(o067cWh-ErH2PK@y!OPYGPzFe2)}r!|yV_abHqTCn&OMjrWb_hzFh<68NRtDBu! z4;wxO2)EtI9s(=x(u@>RNc*Z9CyvAF)SAIXM(^22Bj?Y|&1L~M{ja>#cu0gZMkE_DJ_TIn7KWs7F55*JNcy_m;$fRw%as>I z!Xmh=50r)xGT`v-=fmRAk;IHPZvWK0!9NQn2gTwW{_oL4v(tT4=#9~ue&RbRM_vHt zi61p^aOS&8xg9n^{EOAk-`afGp9t$pUh9W`L$-i@3oO+W6@EWFkfSh61}k z#+pFA1(-%I22jV+1j@%NkU-qNbA$A?&@8hmZ}m%Gv6M#v;?k0n4?OU2t9f~Cu&f=Y+SC(0Lt zu_-gw```;3T?^)ATg_98)zL<0lXaWTar^d#EV;U2N8t_kNh+84@R@Qw2e8^4YDF%> zfA~_4KfW~Tk1s{}AHMW{$2?^6W^rakA|mz&6epQa)zmuV9@aMkD*jdyXCnuefIf0U zDR|sBJ>kLVC~Lf3GC_L^8-KeCD=yZW2?-sQf@f{khYQC?asgkhg)S=>=cRc)TI7{lp{0mzW2;+>o{cJPN4!E3w5X_Ai~ zVN2%yBTR4p2vfo*to}uezl7<|zl5or^+DH{(92)K)B;P|^lxG6`?oL^9^UGIVr%W0 ziS+;EU-AvtV|r~wNuAaK6_w8ZN0`Fzn-TvJrosPRm`YXSyDas`T1TAYx&rj8$hREz zEAgcxP$F!pf*t>-FunShFs1$P!gOoshG6BpnUq^OEe>(-4U#()Ug&bttfwg#X>cMd(bJ#x)oqxDfJ-_Xt0xVx~5?O#*7ek`(;rS9mrZBt0#1O)BS$5?5JDj z|7(wZOFZ+e?g@$EJ&q51V9SNA^3@*pbLnX61>mF6+<#Q!V|!3R9NY!B&zj zz}S$>4>(Q_y}yNNgaLN6#aNU8-bDSM?f9kz?t{x1T&znlKcWMZ5cRbMqb7n3TLgP) z!4iL1{4ci7!l|l;?Ykl&NJ=--eUR>w6zT4e?(P!lE|G4eyFZt?|rq^jf_wxA;=UsG+1YB56)Wc}?qjt397~ z)1u>fKBc0h<0%$tWU_LQ@#1qxy7MxG3w~D>+{2YUDt~*o4Ak0K%yv8v2$8SV;3{L+ zFW17nBSIzs^^e2+fL~8oRH{_qPltSCcRChR@^BMZSKY)SeKCf%jGVSbES-m@lx5~} z7DbwxmwsC_jl-w+ZZ8xd!);Ek!()G9i7W6G7v!2mJjj1O5lu=Z9! zAU1M@I0HXEUpBtZgcg4TDq=!&;DnK;`1L2KpfyE#rA;#o<@kkJYYD!xxGb|gTux=g zDs$+j;-F^L@@@1Am0^(QpZ!J#tbN@#+%iJpDQP))T#p6ca$A+wjm!w+}+5@~4r zAtV1WDO>tdFbjX!leyOly%4&H~Z_%gPh?*qOv9K8ZJ{JI{TrkrxbV;~*!6o#VPr$VG zk^>{Ug+dBR0Sruio`ET~PN0+-HX7wS2HdlZfQV3@oqKG}{%%!7sKQkb0#TV?s{VLX zx>yzw$6P9Fg+GoSQjW+K6B&5&Pj9&G1ii&T8%IICD{pW2My`w6ntU#t&+0}w-&q0^ z(`EVRi78Tp8Y7mL?Ur1R#ZUGva~~v zT+?e}_%Nv<>rYM$4fZ#us2)`k`%Kk^cVx0u`luL@eM;@dE`5Hh=TBs^EQ?He>=OeCb?H+r|b z7NfHdcU)9MBSHcIFVz_Al63|1Qt-UA_s&kP?x+jkr3~p-G1@VM|L{^a>yIFY$3-wN z6#{rEJ;gRFz)PdkBW{}4$a##J|MF6`glAs*?unPWTG|RKEI;v5buceA<8nP6gH_pT zrcJD1qg4X)Qj(F;`Qo9GDi4HIS&c`ue|c%D#xpPVdFG|gm?2io+;`prtlMiC-Z6*G zgiAF97OY zBuz=sa@%!e>$&nK=1)zcqX)UhTo;CA78WDdMNdcxs#Rf*{UNi#2%3#^PC=}j_*LOC z=^E`pCyvR`ZDVh!UGJOvx(u@$SFZT`r-H128M*HoNc!S6nEXuBXzS&=EU)&^`KYcG z3!~6$c`C)>bbfxXf4@EGfM$j4knDt(TJ&S$j;@0*lUjDbn2dGvLI5*+VV7=6P1Kwh z&vpHMqsF)Tm|rjYojc$W55z)+2u4ntcfuF%f=g5U4M7QmYMx=suagF~09;BB;L^DN z!liAt-d-+s@Qh~J_B{DsIUfp>DO8CSH_7RKdP@}(m(hHpvzAktWG$#$b1eV9*l8VO z#zT-0$DUj&rEajeX9o&7&Hv6_TceT1PKt758mJ8#r@vxJCLsE-v{CEaez89B;S(B@f5{bF( z3zDt$tp~}FLtkl*xf>LwR>Mx1#(5=?nM?HMd(P}7b>e~_$}SMb7c%9?SJiSE^1E=3 zmkwqG{>a@+@sD|bH7(W`IJX8CrhT4ObSs@PGgZLCG@zBlB@kGcdcPbjw*F2Rjq2rBf zT6Uq76M5ZA`r%!sC-Sbs16H(Af|b6TujrYEX4%QTYT-sp97^o)TjTIEnt88aC(PZF z7G{#sW6A5f8XXCcz**&m8^kr!{G&M2KJ1&uhBf1sm5($(s=r1*m_EX!{Ly*G1?_1k zaM7s&ns4iyp^91~Rou(s4V%|IBMlxE#Zp>Jxmv3NnMJ{Qc8eTs|Cwe$GlBl-H7+tE z;Ya8=_U_VL12meW?qd=gDvGkJ+mPRxw-#ZiPYAt<`sV;HD^Sk(Maw}}k->XXTIib` z(R}88^&U$FP-Ea2J9uJRBaso#m3a>`Gd#-)EycLUUJ8RRQSb43Go~DwCq%8;u>)zt z`BS8NO2nC%Ca^i|(Bvxa2;V4@ILa%sOfC(QT9jy<=+gg}Doh+kWWnqBWu88Apnmy_Gvn%8?0>-g@!6WMy)9=$mTR@hA)v04LAJM&G zoqd)-Nk^m(-$SjG;mEbBzmX%uk<}FX+7TFNo|y|H+QfzuiXv~duWXUM84A2jwgY(S z7Y~4!LJMbOp@eG-m^TBwwCr==HxYoK2EMio`qsA1lg;2yiL>+~9wHM<6X2!Rm^&Xt zJ3(B7CdQ!x)=XJi-{r_}>eHQ8iuu3SW*f*aeV)4ss>Ru*eeiO@_4X z_a$F7A=2dzTq_@B^K_9SLM0+Gyx&s{*}T>tzeZbsToHKK8+Tq6aZ&Y3?1|A9kxo9d z-?$rpToKpUv=_&Cbj>;S6t-3lE;W=c0w$&%Wr?+w0jCd4)UeG7)PlgolsKcz?BiMn zzQ36Z`}nmD_qZrWcs1NGNq18Us{h9f{9Pl}z%#oYL0sPh@fH6w4Dq(O0ZOtg8D^zT zA@LC^#aD4ALAwySlp;&Lj=421G2ODE;l{^#tMJF9E{G013S>Xkab(1xt)Xa4?v{>e z=cRw{j@(?ny*FNIit)oFWnXWtWM9Bv_jWjxWxHpcq2uTD^hEtO*w2C{i~KS!^( zR~{xyaH3zAF|?FWKdICyveapZ5e;WTqW2*C)x2I+oKx}FF{JEZ&62kZYXxNi;X=wx z$xK{&1!Ny?*DljX!J(YluPshzD*sr+i$Qi-N`HhRq!sy5TT79_S ze${#`OwazPKxEh;7NK6UI<3;4I+70701$_L7L~6jtC#a3IVq|Js zFDQlxOgvwzQ?~}KY`Tj z>(BQGgv^PYuru$-4>O|E+RQ+YS^bJ3*N_~bJRTK40$u#XO2k0P&miq4SIBT%XVzFq zk}_x2h<<$ba|U(*n4U#F0n>6;=>O&8J5NiJBXZXPz|?;;y7L*Bj&x*07=eN58~{u; z&t)_J0@H@RvxGmvEC4X=piUcFqzT2j&|}v7FJQ{cmBeZC1WfbZDQK}Y*n)xSFc_GA z0)VNVWy8O~boUvU)&syax#^{El70{RKfqL`i+Qvc3{17c!N62dpJyEarn$MNPDyC5 znA1EC*b{7J(MxH4w{jAFau^9may9QUVK8zn!ru4bAq>MWh7v%+OA|_W7FbZQ<8_`n z+sn6OAP~f7-)%csE4~{4unrsc%ON9A44NsiQEh-($dGtN@77{|$_*6((tTE| z_&I)?oW0U~w7ui}wEg*Fn@3(gArxc}vG1iJ-lLigqQD3KZ?R|2+};d1#Bj0=IGmf5$CTPxQ^uf&&?@iHC)t;>+FcCwp%X$1fS&NgR#mo^uvbvwxj?*)Xlx?U#i`tox z$ny%6w}HJ(6nV0 zqw4EVp@(H9jfzOhj@R!it25dot8oj-Er{C(h=GmikC;9bZBt)(%=~|V>D1mSt>C{t z{@V!UsgFN1O8qwqwE-W$Jp=IZGr&GR{qbL5s`Ug+{lGqcJYfvr<7cS@K7J+?L4FC- z|M2l4|36^*Uc`HU{=R9ul+S*!KXM)H;}bn^Oj9dL*<`!1%;Fx;b}q}BJtD4eDT=lp zmfLABTCW#NST8+~V%*~&w$6Jf*@lilD_HgG(YNWX&RGvFGhPowk<*@Mjn)Sqrvry& zL|&__X*ZD{bW$#d)(oeR)4a+ZEboer3U0in&=!Pf({CnK9`+oLZqw@b{qf59o6hHm z=rl1x{rRfShvS?(AnPt$XZL=v9{22elEw!ddMS?;;6Po^4c z?V$6imbf@mJJaK1(04qte8QfE4^&3qf4QjEbrl<=cumPu_z+pEi!QcfG{0WyZhWs% zdtjD%&*V?3MrBAy!eq3*Cjx8jNjwf}tO4HQuOMK>|MJq-Ctlh`I$)|aXtl_Ac9ZLC z`B0QzzuB@qthnTuo*jJQIH8?J#B^zf_;sXms5|y43*B^K(Cj+bu;syVVT3E+wVHokGo>YM5K6)gl;$RZxIhNR)2w@e9tthXiyKXx(tF=9ScldsEUXH!b%Tdak%G_Ueby z3s&=Xg6r>#eH%-+5;Esu_$5ud!oM{03(Is(?GI-hs(3^VI{U3T(g9|_A47r zJ}!LOUI~v6XzNX1g71RWSPWHjSs$%gm+{`gh{uz9Gq0@dz=*LU-9Tz#fdc4v7Cw2v)}mChUC!OfpM zW`di%s^3X7^_1YV9kZKouI#jIAG3QqqbDdB&le0^&>Lp>WCCeXY8y)$*eS9!{q0^~GC zRK+8Lo=CqxX{Vf^*A{)RdZSN_YSA@L{*_!W$ZyQ%zKslXS zi{FyKNrlDR@&Ex2R8@OF4z+J>9ZC9X@85G&nj07WKL2?ZX0Xa|6aW6mRA3V(yVH83JccCqId4je5$K#9_xE36e?vEU%qzQ>kv{rZPNxZ~fe=P9 z`QrTP#Ru%xSJ=w7T9{6d=n_{Mt7WC%M$3k*DW1Wpw{rF}!P~PIjl_li*L3rv!(;r! z6xYb}dF~kzE~CELYU?(bgWSrEULt-=y8C#~1n8P7{#x#|ldvqR=>`?WqTQ^UDi^-n}ju) zbXDTYTiMxfx4$%J_}#bKSJ9FiG0^ETq$V!~TO53GQi5yJDQAx_zl3#ih6Ch$Jc-#} zKL;7OTc`Fz`cFi?fS>8y*GuI{7p9WYpvD&f$oV=^Nln5^d;x!_rjfwZ^Z=NeLMr23 z=sitMFTRZ9n<=cp08>*~E5&)-0=0-8MK$sp41k;(A{2+KR~D*5eLQ) zBz+QoCc0yw2lPQyJIcov^%k7uNmvSLT`!g$!SK|0x6uX0`k2rPT-eDre>bq4AHpKv z2AW^|xu@yBciM7m-x4op=yRO0ymz!5dee0I>EZDF3eUj%p3@tn{!On^-^%-Kfw5w_ z70=Bto6Z=_s;Ev?zfc{z6J>C!s8;m7P95}E zc)-ms{wX8Y+0rMUR;Bjr=9kd?e0KBwp4|K|wK*BoM_@N!ezLCeuLG%n8QyPh@U;tc+#`BMMuN{feJ z2^!2n%7%RoLCrZc^5#<<^x#+`7s?E7s?t;{%Za^Fe9WBi5B7=!J4P*9qM+^zR*cv2 zC55Oa)W(8CX4!E|9soKOfdtU$H0HnP)GDYtc7h&^PA33#iWoGjb0wTCuM;U`KrKcsJVC|WYNeQtQo&$Ut}dkA)0lK#bu6zL@3f9K;j}(>>eVaCcR1#h*!o9$?!0?LiUO^mLcQi@*1&{CMQ2lDsC$$Ah8Lqpq z0KBnR748$I*mq=PY5K{v`?wuq%vS`z^c?aEC=J86FYteqAE=#VRx-I^dT9OjbMpfE zLjM;#mHQ7nXgbQu~OslMp@WXk_$gS__j=LOU$IDa>owz50N<`JgpC@+@ z`nIx7>V{_q`(D;7S_kn*d#(H#QP&A*g#w&3wLu!=DlV|0ZLI!4p$IX^@qQ%$&XNEs z)Bjd!01eoj@>0oT^y(30fx=cVS3j6i8=L`UfT@ephbr-vku#Ku zK-R3*%^RAP){j$*b-1+>48#CMB|Y=Xb3)pMY>5}nSo;{)I^hLscoDtwXa{km(?y-=vD$S?JkLSe^{0Yd#wbv5)DlIWw-^e^OfQ27GTWqm)>u;WRS34mSWerlf_ zFGtnVz~WGrmGVVcYo{@Vopz6_rWCR)=wq9YAPrX4gb{Px=FcW)FSEwrcihTyB711x zRvOw8j_s_y$IJSDoM3!rcx)Gj%9g&}hUEJNRsB+n=1us!$3U}8pldpzrbOQEDQ;N51b|cw0Ho?28ZvqZ zS?-)XtNQj#d?sBrPRmam6(ksf6H)zoK2dwPI(Zjm!aU(nAJ_Qi?d3g(LaeDjF!pe5 ziruS`v=(WE*;`TMmOTk-d{cE^JRMrCN#r*nd$ba8Le$&9A0FdgvAo_yxR*XDnbXyZ zCF)_iu|h%+P*xr=VN>Szl9T9kWf=Fc!!7Nt7E1jb<6Oa{ z6Zah6WMmK+o(_&P_wiGv`cxf%z4P3^1?`IU1&i~GNQ*zRj(c4@=FmUDi!XQxujHXN zr*YmF(xpNViB+ew7EjV1YyR$)g!=?6Pa)luG>~3xQu(cl=D@EK=1AGRHih?qG^Muc(u2_+QnH(j`ETNKQm4hvAmVm7?6>~9`Uh3WJC-3t zoP*H=JMK8sGjHQEF-V0k&m?lONR@4TE)y=s`m(RC zvrUrAHiIDGW`cPlfPhE_Cn!LQGPE1N@g|H!i-1szVAPnRGB++_K@7=3pzH~$Lg+ss z)!l+Jf2oDy4atEv56)i(;kzbfaS}Mi1Ho2|;{lcwx?Mq(ncRtfQrwI@>}pP^+&Eea z`ue70o0K=OFy%$9_VoA1#s{`*u<*2nKs(-#b(2>k0~OeC>>? z@}!8H*8`)}a8-)5cb{1}G?Q5>^|hJXs0|S~g-j!Ir?5)S%IdF5RZOyJ}OoQrMS1!mU}O2`RkjyhH2v{wekrz zq{L~!+s9DK;upc6mg}0c!Uq{09}A3j1)WxRSBX|~heqPBGppg+dKlToFcr7$IpOQO z@i-bx{&btmw#5_T(e2Gc4BMHsxQ2L!s@+w1f#Yc3cnP)@CAAb^XY=Su56{xEH#Lla zBd63>=*zZ|Z%8rtf3g}oZKtwPIFM+V%;JdYG+J_d8GwXxng3MhwWpeF84uYq8yfMJ zWM4$ni#j>;uKe%fRk3$M?- z4%AHx;cMJ~8eF_x?D|^YDe8t=)NmI{p+LQbyjK6?Z9PyoUAO50*G(H;4Yv_lC>Cp^ z!F5wpaNRV{rl#HgwZ4Ltf54lpY-O0rtIaM@*JDi=_lNuxxRM)`Fq!v-j5=%< zYy7px`PNr$E1fLp+(#Wa3`ka`^>Q0c?bbog7ik~4orWD=y_@@#zW@fR)TmVguOOS~ z%(^LILNh*W`2}CcCl7;xswfQBs~gay%i9pjUuxK^-3Z)0)&jRY3j7w52E56{or;Xs zT`4>X=Q+n2?P0!IHd;7rc|&w$;lWpu15?&|Da88v=#|U5HifHO2iU4Me6~hLMwJaz z5#uXs&wbN~Kk3`eas(2T;hpaSnElcS-vE763XlwDoIm-CPFu>sEN+U%39%g(9Q1pU zi|rQ?Nk!unsYMgg=|$TxTTNmn*a!)q>6Tl;eN(9yhQ6xO6Dtt+_fY|40*(xJ<5VK3 z)Na}89lH?ucLVfFIWRaIo(B45K8Po@ms$39Dt+9X1&yiW78(yUw ze)oGvEF5k!ftcXbNzc`G&?$?+b1~)tQhveM)@kUMCU0n!F{UxPK6l8saQ%-6`bH=C z^(mG5E=0V;BMHVx{MQeV+bd1i%oW!69!uLTI?!gS08d2#cSc-mH+4&1 ztu~HDeUq&cz9fI2+SU_G)aA~lGqHkrmW2cND_Yf=JO3B7);T4S_uCaPo<%7=q z&Y6Ahb93h@uQP5Hp6dNN26o;GS3#N08XtH5hvO<_DK?L@c>eo8>*qxE*Lb95+B2t9 zLXr536UU#=8m@JSv(OznnnK_OjDk=PsaYVE|{i@2zuae1IGS;XzCk$(O})bG}Ted z&fBg!;UzoG%u&U9;(>DGqfN)E`PdEsQ~RSG`aNH$Qwr)kxIdbd8REHQYp-i_mhw!# zu@r)CpTF}Q_8gsyK*1%44gb|mhF>Lb%af-8^i8E(0}7(rBID^u4_61Y!bfbD*60_U zYsOm=I)vy_nDTDXQ z<9|%lc|3+RPE)vv06mEIH9SVU_w){q+_BU*HWDEnH*Ey+p)?`pSaMSbQ69U$vI=xA z9^j`rQP78N?TUG|bNNR0tbisU;n1^UA~v|S^{ic~Gq0BKI?dYq!Io%uXQ94zMB?XY zRdSVg-R{pWg*8^AE5zHS-Pv@uO1P8_7Yg6@ zp-^Gwe%l~KC+A`f7+wbLvNLVWn=TM}!>;z^UvMrax zKruVjH<(5Kfd@2BdH!jfQUHxp<(>~c_2iwRUcTQ>!w-#-TGyE6ir6VQ-2=7UeYQ0& z&z8b?$@7&SVl4i_hW^7XC2zCP|YcelOg zAF!`~F=F(GeK~gT5!Ltc{51aIe=ktsavI7o{^C@k|KL=62R$nTJv#$N5cB`fQ>Xsn zsg0Wpz!LRcB@96=V+5&2CD}(&aO@NzViPd;4_#R38^wBhuov+AVVpSmN;$Biq~4#{ zdZ65Gl9mgklncOa+`J4HI`QA9*o(5@Q$+5%vis9rsLmCyh&9Uk)rz+%bgs5*+47H}@UJctrA<0&d-ktfsK7i`(xeM^ zE_OF65y{aq+`k9lsq_rUbWV;IdoVlk=n1WdYvz@1I{qS=@&!0=!vxTN6uCwD9aqKc zL4#YT0xf<`(5;7589IAqq<`;1y_syn@LOK^x|>SZnT2zJ??J@a&ufx?=)?6(8#%%# z%om5QOzZaz2Bs5M!7N_QKWCwEslRGOK4#ZOSE6<(r(us{q>{|2S!|^d%3XkIYSN3w zrx_~YZ&b6#X@#ZYc3XUnm-!C!wl^=6j$nb*X{X@l&lE(7f&!c*a+x60@o!vxaQK;k zx8JF#iqQp&(pivGI50(1463MD@$*oo6`7J|wJXLontAP{_Qu^ucZBK_L$dZw$F8Fe z*=#$BlZRU^^L^9|oRj67TR+_yjEbYwwEOejI1jOM+K^fP^t5~K_B4gAhn3yAP1LGw z%nB^&5i6luCuI$lu0zcIbCLbjFH3S=Z2pHgBo}(bOKM#$qUG%9<&mp)a-=0EdJ+Wi z>li`88=VQ0W=m?+G?Rh{rpQi3MHT9;@C&lx$T+OVapI0uuZbK_ zwUO3EzthK)*s10XFpZUE)WL&vbxYc_Dl!Eulq#OiLfvSID>8%Uvw<_dX_Vp6gUet8+*Exe%|ay zWAFFMQQJFkc=u?u;f~}36%x8i)YCcc^|uwJpSps5Lm_H_x1Y>p zWckS|;9DOqrz8MVJDy-F3;Y4l%)q5n*suL=*vxXLGstmS)2@AH z_eut_`=X9~{)zLX=pUg81qt|0#5i1A$^|Mg%i$~*5UBA7)HHyrP_~hK5HjKtyzl~N z<(QS0KQZyU)maP?co$`{u^d9yNhsda;p3-}c3e!%WmMcZILam^2Y$wuDXPN^&9oCW zwU7Zj`;ph1Syn3%fV`|NZvxCv|JC+Mp0xdC@C;P}fT<|4RewXL_oc@`=#=_@g-#Qm zU~2Kdp;P%$0H(GkNiS=%bi{EUN#qs}NhlS=Nc;6MSF@ShpVASDQci9?_WTn%O&=(I zf~lNh#>A0x-#5A7Mc9)pA6m1LPLF?Ges_--bGFp*Pnk-$Oc1?|Jpu0COxDmviy#_8 zK7~%V4c93z#GyaU@y0ChUM8Q;0HISj-tMQ+X|#R#C};-%&wqtZBfg&SKvSKY@w#7s ziJ|H-BJ35_i?%CP@xjPc%A_}?(Frk?Pvw=iwPhJkTOnmyTvFZpL#9cpF<9~agEEQ4 zy)5w}M(|0^p(>6V+ijs8&DLOVy+w1#^HC^fDilioV`%|rSxs)a`COGOPC9YC*sc7p zV{clt0!Df-HVt3LO93pE&JbX!xp4#y1KD~Xo@S^U82>dxjhYAtSn3v-rGjUub*XT5 z<4-KL#e)Nwp>_Z))u}!ln4zL{OUM;xeTvQsV91cj!|#bQlkzesrs#oaS0yY~cw(vV z0hZe5LGD2u|Lb)s?L>Gz@2KUxltbx>^l36I_$UYCuWP`JF7kFLLLTx|Kf zN7jmfAB8~`IUlstXY!YW0Bhe4Z0-N~$J&pUd$RU(zYWjkN(V283H-<-P<>+=QOjCa zqY3MAlNWW^ox!RJef;v9%CG06P`q2m+_+Z4&ia=D2aH!zH7=2sv-Qo$Izy`?LAPV6 z0mENeW0vfXJ8JFQw?9hkXdM$2ApX8;M%W6n558Tm!8y*+d%(5LBVioCYm6*UW!7xj zpoVym0w0A^#x%o)Qp#%m=6m&fLa^W^hJ@tQD*a}pxPqj$t{dS5VeSayeW;{E#Ulpm z3wB=+^r~78?wz(L^tHRk%GoQu+#?KDSbK+GJV5R=(C2rnVvx6J_RTq6D_|g-O``Z^ z+`aZ@JthQShk7-*=V@*T_V;mwX)AI&Y#mHXfITXvt)CZE_Phk_d(unVcrn(HUK-h) z*Abl(!Ux#x>78if?-NF4h?|Aok#-sG_@l_`Ke)r~mfhz?dj$X>=+abpW$T7%Wh6)9 zPy;SGM_Z3ea`5V|pNfkN{PHXBRR0XqA17>%j`ZT=vOSTwR}hhi*ptasJ2;6IC0 zkD##Rn-15DSMgeFic%qp?K8*W*+x(47b58)Vt))}K|iDq~*X5N~b$)TX4s zSAQtV86)b@(hUqv^7P~Tl_gW;7XzB_jJbu5X`J$EKw<)od)%K$)(?xwWWTCf)2WIH z+G_I*pR<_KwE~ryp7CUjod$`HWb0bGbu1>D&KSD~yh4c;hF#Q-*t>N{`H2aZm+=ysQrbzhmU7kkV_lb<_Ag8K;?`}A0AD5mdsYBrEX$K$Y z>nR(YaZVfNaTpGt>NhQs)ri_cH^f(H5*zIBKfL6DD{I?x2^dIt^V%pVWHL~3{V3q$J!HZJ|M`*d z4dlvq@kg!s(CQ_Cqjrd$f#P;x?Q^&PkLD@4s!qf|&C}?#$bXxsQ$UJU{crQscul$r z`|#Cy!WD@o%;gqoiK91jzU}1~8dE;+J?S3;5zgPgZ3;#>e~VP-ujfZCwv+*c_{3ph z8ZQ$ennMnH`p%(pr_qSKRJcJ#w*Alr>D$?38!@v*JEo=Gjp;EjW=qYv9=kE&p2`KW zfV`uLcpJ|Hk@4ZavPHf4yu^VjH)W-M`7 zw)N9qIISJ`pgrD(3(mmLbR^{^4zDk^9;iB{9Lr@6Vz%rFA zw%iFXVA~E@rc!2mJ|5c`^HdNq)bN6rsS*8QHSM_R;y9D7>}kNKxQEOd?R~D$8wcX2 zLU06VXn*6UoEj7g1tk~5o<==EQe9{;Q80n#`l3d&<}e)HVSITE2aMgi6iNIjGLd@b zH=k=(Ug&8pnHnZ=gc`9jOXEjZ~TX z=w^-ZUP+pd|CtY=8B2eOv`4jS!H9(Ud^D=db^aF)>0ETXNMnQ_wctx2HPYy3wNbU$ztd!G7v^dN<-Hkc~gvoSGq`^36C8jfq{rsBv zry6NKkPSDH;Ll_Z#H$1(>~)}l%FL7+o1G0Fs8UHM<>SF->%x_b{(*f>#GiJ>98b9Ft#H1ZbG+%3#hLsEx-j-Ulk{yfI6wQ z2QHvmf(xixa9B7zdGCI#l#IT6?=YJ58NrLA!XK+zr2@)nz45rfejGec{V$*2897Mi z$>%r!>+?H$w+!GB|Ks!jsbI0Xc$%jIK0nR{#6R=YblYPNHNfYeGyX51-!`7xapXGz zw|OIEf(7HGCC6OtK6SBktMr@zS`j^stR#d3njA`X{9{)97eU zKfbtGmktoAi*U+89y1-My$RhPd5O=e@m-2bBQKRtV+84^bL4NYce?0IE|0Z;(xKxa zzn*>Klx~H*X(C4a@Oc2S??X2FhnyX}DH3T)frA&zb-lVenWZERY1H^Xnw6b@(ep#x zw)?;V2ctH%#1+5?qkd1Y`cH8CPeeW+jFOIu05TXnb%qP05g@A%j~E5?3LFc0HlU=A zIZl7(pb7%vLD6#Z07hn4Bu(jly&sW;YtBE9hSiUITUk7__l9G)cJq{f)V-OEBHNXK zB_mR%p@oA{YE@*NQPFVBMDM~}($P5A<5ZnmgYO?-O!Uf`lBL&!hf}udVNV%|M41ay z*;rj{DAbvDj8SsfPJ;Nj=eK!mNj-P|AT#uExcck&D`_6tMw*AkvBLNw!UbIQi!Q9Rhx_0| zJVK4jSo1Qzs@*xF5pD)dc;4#W3&Xn3d-lt;L#O56?x$VkLPSWOztu#Fk_t?DWE!`m zQBN8%EVX5)9Yl)uh4KfJ!bETaj0wA?lJaz2wxNC9)Wo9;jqDz2lJF9Z(nV-)k84Dq z?nPld-HXENnz04ni-L*9AbY+S)uZ?I-9PuDX2>sPBDNG(VKy66ojg8;#vSq{yt`6o zsUN8YIg@GGJ&v2iK~-gGG`_Npm!w>GvTJbPzB=~#W&&&grZ+$ihsnd3e(w~%{1*I? z==VvP=IK~e$Fl8bCb&D7L8f0wprzAe@>0@j+rbNpd29uj5P$hCFA`F=7Hhxb9;~c( z;8v80Jv#ptDg{tKwSwM}IV?r^wYSySXC3*2$3bc(_M;9LvvvQa*G0`bgV%k#ap_}x zCWF?)+*T4NCEs~}Xma5Q{*Q}3TIv2>JZmkdiFs~qPg%FykeT^I*R6I2XRTr{tNV(x ztKImPtCBfd%(}_TKw2*slZD~lNWOBA=iH;F^V}ovZRpMvcVYSu2c7HoON#q~()jd7 z_v1q?c9~-SGfe!JHAkd{=Jaqa#PKal^sely2F$un^Z3mbjQ&xxJCu*@Lke(0?Fw?R zj7v?Q@_JBpcplRX?&>r{_`;$E|v$H+)!6#+D8(_NDP~dQ%Nj=2IjcNH||sEJsYo6}8o@`WHj*e82k> zf~Ml-c-gEa*6Vds;*<8HyI@~uUFvjy_YVnA;z6mR8BinXtdA|X5YpuCK3ztgl*fhqVVo&iKPB#(tRv|;9LZBO)`t~>sSY3zvIAD$eq z81Kj6KXX=3PXF`OD4%Vfo)^2Q8`i70m`n9L0Rlh)RhP+Hc%@bd?Z$jH|HGvCJfcPB z{DY>YUrE&($|u~R9;Oh_rX`?&>YucTjRq7@5rG0K;d24C$2qnhTtFq$UyS~zfNK1o z0_sK6#d84_lK-l9efQr2DyL`NPr&JCF_UyH1`(1D08T#yp&sD$*Zk}B-z!>h08YR1 zU#GvdtU{fWV&O_T-tR-0Snk`}3E*nfcpk^!t5IC#z||<*lq2+!^9JzMD1aUPVqexT z;tOhj{NpkD{}oVQ9GyoW|8@HR52E`2FI3%K@TVO4PiN=GB-HolTbpa|RF%iG0xd1{ zEk1rT=>Mjpehn?XF=a-EsC^KW7-!iX-A)`OAn_8B*mj;JYCIAZR_7Bex$OJJ+^Dbh z5U3_^zh}ZBW>%9!yuX62a35}{YO12;?APhPJRh8OKfF(MKWx}eaX-{oZn{5776dk` z{M#dtJW#*ppjvMmVEEfbkYBC&WL1R{#kh@t4vAP(N9!%aXa7{llB5CWqee5{R8qD&WQugG5MZ|->)<_V#|UwNp=P}Q z(u)REE3CW7{g-Fv6OLpOkM@SOtJ~1{-juM-bu`S}YVX+`Uz|M>GWPR5GgT|(h}>{} zQ#uup^Zjf1CU`~skokzz7c*?t(FEZegO(lOg{u1Bg{pL{IRgvxEct-d;V)kU(l!m& z7b4Jhfn0v`E9Z)ArZ%X(-(C!)B64^_46*wIEmRwnw;BBkRj^bFs2IO1MJ*eAQ`*pn zzS9xqb3UT6&vA3(>1L^N zU+Dd-pBBbj#ARsvzh7QZx0h1uuCOxSnlsb7%9jtmo@E&R=_OUZjZyB+%iN^+>EiC? z#jnJ2+$>YR@EUCPYqar!au(ocXI@`y@m!z-Db#TiqC9X4)kj>I zF9O)7ro@uq0sGX5zx&kie^aRD$j>R%-zlgC7V>Knz&`bzm7=;YdUPk3l5&ujD{wpt z4$_!|<9o?R68L z8UHo=X;w86pUi$^g*MPE{u*#R>b9!ombnE>&M@sbqi65v0sf}x@%_W$(gwDl$6!6H=7}kSaKZ8V{sUYZ+<5Db$yPo4C(NmFvHdDpv)4JgraCuN#SH zq}un4R1XoXPV5Yd0HjL%7pWeKJtNf$FjB1mkSZO3RMnHQvTqolkZQ;?QmuMM zs!Wy$yqfVu{|8c?bCgXW`A_@f1CZBmU7Yx(_pio ztPFfRiahnloQdCH)zj^$&8OQ@(Y>aY%ErJxH9|UH>OcEbzGSukVfH%#B~+{08}CqH zpSsi^}g^ehd-7?B@WR{hyj&KAHV$`nz_L zu>(KBW`Ekn9q7sI52ak=nlo$rCJLDSHMgg0K47zd=4+Ipz06nn3fY!`!Eb0?aV4VT z-0^~G9M?Y1FB^S-%?FROHNPIx6P!UBRV0Owhv2sO(Hz)e3l*~7L{|i0i$P@*t7abyw&%$w=9F(n`%Adc zgOMt|!ufw8)v70?$_PfPbC7CbR(Z@|q`Di|hle%3R6iSs{z|+SP20qTUme}d6MQ?$ zVC(62lx;iy@bC3AdKE8KFOHBKbMzE z(@m6(i~A2!Etb>LRw(nrFY^umPUzLFxVhU_Ts-GsIZo249nUP6@{#_aqU7Lj2(^-F z9^KN?%u@TG5b9Lwi+Z#{FHIZA3Lu0k3WQK!#or&yHe1Oc@F`F)>+jX>@3yNjUukqT z??`L8kK_K_2b=wMJMbbRXP~Rn$=9rR+AybG4PEzt<`G=R-+8CjD@0>&A})!|4y%E5 zPCQ<;f;nQmPrFOA#?+K7c)7j7rsSJW#V_i{Iq@O4MpA{zGisNXY3y{q zE_xZEF{d3((mNkDZ|0J-6(%Y2xAko>AK8Rzug~ulrJx7MOWvLn05b{|XR1E1d9&K2 zfsaS|Y%=NygO5k?ggzaQ3I>T7yeBXBBR%unnNb!*`Q4x+a5zInSR@!dz=2eRV%Y}U z0vjn2s+a5qV_J7XpM!jx{*A0&-W_w7{cePmcff&tVvjXz#HM-v(psMLl0L8moRy5y z7F}RBDSO-8e;ETDkJ7&3JzxcnM|l*U z-?d_=`Vn%zy5^Jc8b+A7z;V*P~LL#&{A(f!h;sgw{jy zKA=zi4D~xS!K09%`QH1acsQ2QZ^ZK(S+roc-=s#SlVGz`4gG6qhJJ%U9^m$;*~w{A zRD1gicxS(vM{%NGueHTmYTw}o;Tk%OiM+I&gd=c}qslVsF@u9;K8Ylhd-M?~23{Q@+>Za+NW_BY!h=4hQ^X3YVORq5Hc zsuvpoQUPpg4}jFnnkSGdWH8u42Y}QDHsR1UuaTXPt8YYSIz-=|K>{Gv3=hi9Pp&mo zTW@lPYBV{_L`AI>)w4^6`}m_*p~`^b(Ud7sbH7-MGmk@saCN|*OhE(CLKQVu!)f;a z8rOg91(4Ku56(n|MRVHI_)0{?G-bhNk1`L@o>x^s40Y=%hH4-6DS(vT*C^LKv6k^b z4+#50>4?*QD}g(+2G4N?DKn%6{|J8QgQAw{4-*Iy!YDt!h>or%m%sn&AwA?Gp(KT}bZgJoiwbV3o zWoBvyWm-0zxzYqQRJ7C_lzSAKqT)zXbMbz$-n#j|zxTfv4sd|;eE2@+Jm)!_&+{3g zGu1m`s4O|?zsDVpLt=c&JesG}JI5Y<$m`R5uwaVm$VdP1+J+yZUC;oB6}lmi$hnLK~Nb&aL`k+*Pn} z1+p_m5G{>{L~@i+1dqb>j%0})wG_2XCJ1jo{SdFQWkuHlqBV-O*DC@zs3P=z-I7`l z)t;V_gLSl_bM16!d!sgHS=UvY%mr@%&i=&Gkt-MC^cc>575q6R@5W{dC#yjYv2wpSbWDX4sEh}az8thxTIbvo?1>+zw>U#+rKzrc%vXWw@MkW4l)DkqZ$&@_P;3* zDQWjhDr*>r6M*`t4GK^n^)@9{P@tUHGx5qd2?x|i#RBzFhTL{5w)entp{IfRs8S6@ zr}ClY&pbrKzRw|%jQXf$!PYeeMt#)$3xx4 zYP=u$T3N#B?_sDBpDn@;q$o-vOVWfIJf!Fkb%8L{@SkC*sz^o{s&`#VIhzo1?#)gZ z>WlATs7iphf2@?@?RO)n@calvb#>;PZ4Uf+ej_$pL~*taP@_)V(Pv|*QIGwl#R{lV z{al@TT>&+!;(KDvQJ-*wn))ZMhkKlw^(|jk=5QAHswzE~ap}`1_E zChE1r$lukd$j1Y2fEx9X8YKzC;8>Cyv#t1IGSt zo_xd2d`|vlYF0B9+e|$R!7z;dBtudmlws_*chhID&W}tar?}sP_NWg&_FFNfEW^Au zx?Y_2N^oj3!Lnwa4-lD8J-=zTw(f7-zx-*)`#xHp<~bVpnD-}Z`sVEpYpO76V_#;y zBSS5IX~JV&0oeMLqpC#RB`+BD=|oQqE+*%1Mx3dlWT>h~;ioeLF>roJ4L?SUz(?l4 zP}r%ySI3_BlN&##5j6deLGcuse_90O5oyIcEo<&Nf+ma>%=B>{9}sWN7ks1(q;SPm zQN;uuHs2lvSW~_momZ##{?3|G7_8~lf3c==7R&P@B`2e*7Mq59hf-EO@YbVymz(7I z8Y9Z8To|_g30|#*A@-_v#i;W>R>M90uQtYV%tvekSIaX;D#vY3m4t`%)U9;CWvxa} zV9SG($s=3q&*|T^+b4l~BD~sY@AfqT_FoxiJ|4N*ObuX(()Ow<~_IaNEpea1~}Pq9OB zzblCpZ2PnW#u+20y_HuLNMkF;K!3*5PK8cOeSL0@t1Jmv%?sX~_4|fb zosrsTUFz+H;OIGo6Og0*k^Rql9o7a?r$v{nFoYE_>s8d7Q-%fDZ`0LMmvQ6$)#K;& z=-s5xkTB%*v%$8`IgA?J%b$|dOk1s6s_)0S>PtI>>xQF!W}>gQBC3%`BZAuBW~x?1 z(x=EJ^cRGOfuzb~F6rFftC(*m3Z5l6o1EfB+TF5{Z;Q!>_dHmU! z=M(L=na!l5lmR!IR(p-aN!LiI8WBAEf6M)(%%H--L=31oBTw_px-f)W&qp z@B#C!Mu(!iE@M5q1jtYnhhy?2z~JA`Fj&;V;>DY7qz3b1eQWmCh@Jotc&Q2 zTOj(DbaU_?@HcTKH=}Zs^DCo9b!v{Fo3gswE_gy0cM4KunY~u^l89YrHMH~kwvhVt zJ`V{RTa^XPw@S6;L%)1NmR@;TlJlt9s?FnJiwp?t-d260)EzVoKHnk?4sTj31_y7s z!A~{{1c%s?Mjs&1c^g>b=mOy36i!dV;fitfOGV-9b4|Q>>Cp9x2Ti7H`z4dDZhV1? z@ZK`bZO$i6zgBoCB3f2GmUcaYiaq%n*Rtfd+}|-0+{E^w12!A*?Xjj_b2E8f#hQx* zKQzi0@5n+)>qz`r7bUwRKUHPOPeD6%Q6Cxd(*@V`HDRBg=~K;PQDNJC@950GyZJ}Z zrgiTC*=ZLu6B8JCwbS)M1|X0D4i`dw5h#1v5N|I`ngWt24?4Tbf{S@jSvnDL?JB?sv1A^RRq*lEMX!B^r4vzc!`}iXK1Kfcx;4o(mRk$-kT|wSO*-1%5 z1Fo*5rY5hf09RI2bb_nN`l7tyFkf#=g(!rzY|4}ioRaF;@rCZ=Tdvf7gFz=`co1m7<&mpW3cuyO!rEu!QE2P5y{l1 zN%NY3SWkZy%g!mWXNC8V)fl9Rkx?BpaUfK{n32D-Z7w&~Rfb~tj@uxEZqX?QU3x!* zeP4CllLYa({aBFx3fD@w&G^pXN)s{a4zO@a7wvDM{*yM#F;+W1(L? z*TB~l2M!C^V^blVCr&5*;q}#fFnj1mvEDyTR4PvIXa|p6S1x6wE|~nbnqU0Ri*p?% zy*$Sj$tNuF4?N>yytPlvU`{XSE3?7#P$OW??EP9YlzGzOY3hZ-yRM+wr(JqwMGKEy zXVi(zn|PVFSW_6Sl?ksZr5wwZX!@5ETPZR~@2zOaKrJ85`5tYB@``HmWYH^{LM2)n z`;X9AH@mEBJ`g>)E(#65=%3ogKH{C+-w@2l-;9=QwA6??BsV8Xk5WifvoL06Il#m? zLEvB_#}=5Z6%&R)z#3Tr9$dhuzuz4E5nd=cS;q73fwd`*dOU!IwTGRFiTAfrDgcxv z!U=BTjzq{J15v&R*zUpR-nSH2ejH;Q{B3X>D-)BKyR#e;5umK{n>u_q#yXsJg#H8L z&~F$k0>3a+e-As}4YIpY?ibEc*L`sH?m><(J~1!AlFFOdKHN_Iz&`~pd|{R#3P zf=G5>&~DxRFRTIYpIHA%g})nY_mR^tFqxSD0k-=9YB$*KE%_JN#jO8zgWe6Wdr$ip bK=%K`4rgJ!hmG+QT) - - - netcoreapp2.0 - portable - ReadLine.Demo - Exe - ReadLine.Demo - - - - - - - + + + + netcoreapp2.1 + portable + ReadLine.Demo + Exe + ReadLine.Demo + + + + + + + diff --git a/src/ReadLine/ReadLine.csproj b/src/ReadLine/ReadLine.csproj index c023ad9..5d39c87 100755 --- a/src/ReadLine/ReadLine.csproj +++ b/src/ReadLine/ReadLine.csproj @@ -5,7 +5,7 @@ Toni Solarin-Sodara Toni Solarin-Sodara Toni Solarin-Sodara - net45;net462;net471;net472;netcoreapp2.0;netstandard1.3;netstandard2.0 + net45;net462;net472;netcoreapp2.1;netstandard2.0 ReadLine ReadLine readline;gnu;console;shell;cui @@ -16,12 +16,12 @@ true snKey.snk true - Updated to support .NET Standard v1.3 Framework v4.5 / v4.6.2 / v7.2 + Updated to support .NET Standard v2.0 / Core 2.1 / Framework v4.5 / v4.6.2 / v4.7.2 2.0.2 A GNU-Readline like library for .NET - + diff --git a/test/ReadLine.Tests/ReadLine.Tests.csproj b/test/ReadLine.Tests/ReadLine.Tests.csproj index 66019b4..b8cbee7 100755 --- a/test/ReadLine.Tests/ReadLine.Tests.csproj +++ b/test/ReadLine.Tests/ReadLine.Tests.csproj @@ -1,7 +1,7 @@  - netcoreapp2.0 + netcoreapp2.1 portable ReadLine.Tests ReadLine.Tests From beb2e967832061a96d773d21f5c533129367601b Mon Sep 17 00:00:00 2001 From: cobbr Date: Thu, 4 Apr 2019 20:54:13 -0400 Subject: [PATCH 16/21] Faster tab completion --- src/ReadLine/KeyHandler.cs | 51 +++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/src/ReadLine/KeyHandler.cs b/src/ReadLine/KeyHandler.cs index 046d11d..8cbc8e6 100644 --- a/src/ReadLine/KeyHandler.cs +++ b/src/ReadLine/KeyHandler.cs @@ -31,15 +31,20 @@ internal class KeyHandler private void MoveCursorLeft() { - if (IsStartOfLine()) - return; + MoveCursorLeft(1); + } + + private void MoveCursorLeft(int count) + { + if (count > _cursorPos) + count = _cursorPos; - if (IsStartOfBuffer()) + if (count > Console2.CursorLeft) Console2.SetCursorPosition(Console2.BufferWidth - 1, Console2.CursorTop - 1); else - Console2.SetCursorPosition(Console2.CursorLeft - 1, Console2.CursorTop); + Console2.SetCursorPosition(Console2.CursorLeft - count, Console2.CursorTop); - _cursorPos--; + _cursorPos -= count; } private void MoveCursorHome() @@ -76,8 +81,7 @@ private void MoveCursorEnd() private void ClearLine() { MoveCursorEnd(); - while (!IsStartOfLine()) - Backspace(); + Backspace(_cursorPos); } private void WriteNewString(string str) @@ -119,18 +123,24 @@ private void WriteChar(char c) private void Backspace() { - if (IsStartOfLine()) - return; + Backspace(1); + } - MoveCursorLeft(); + private void Backspace(int count) + { + if (count > _cursorPos) + count = _cursorPos; + + MoveCursorLeft(count); int index = _cursorPos; - _text.Remove(index, 1); + _text.Remove(index, count); string replacement = _text.ToString().Substring(index); int left = Console2.CursorLeft; int top = Console2.CursorTop; - Console2.Write(string.Format("{0} ", replacement)); + string spaces = new string(' ', count); + Console2.Write(string.Format("{0}{1}", replacement, spaces)); Console2.SetCursorPosition(left, top); - _cursorLimit--; + _cursorLimit -= count; } private void Delete() @@ -177,8 +187,7 @@ private void TransposeChars() private void StartAutoComplete() { - while (_cursorPos > _completionStart) - Backspace(); + Backspace(_cursorPos - _completionStart); _completionsIndex = 0; @@ -187,8 +196,7 @@ private void StartAutoComplete() private void NextAutoComplete() { - while (_cursorPos > _completionStart) - Backspace(); + Backspace(_cursorPos - _completionStart); _completionsIndex++; @@ -200,8 +208,7 @@ private void NextAutoComplete() private void PreviousAutoComplete() { - while (_cursorPos > _completionStart) - Backspace(); + Backspace(_cursorPos - _completionStart); _completionsIndex--; @@ -275,15 +282,13 @@ public KeyHandler(IConsole console, List history, IAutoCompleteHandler a _keyActions["ControlN"] = NextHistory; _keyActions["ControlU"] = () => { - while (!IsStartOfLine()) - Backspace(); + Backspace(_cursorPos); }; _keyActions["ControlK"] = () => { int pos = _cursorPos; MoveCursorEnd(); - while (_cursorPos > pos) - Backspace(); + Backspace(_cursorPos - pos); }; _keyActions["ControlW"] = () => { From 4e28c483a20ae9c109f1bc82b07c3e2520293588 Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Mon, 8 Apr 2019 12:09:24 -0700 Subject: [PATCH 17/21] Updated target frameworks to support VS2019. --- artifacts/ReadLine.2.0.2.nupkg | Bin 29531 -> 0 bytes artifacts/ReadLine.2.0.3.nupkg | Bin 0 -> 36593 bytes src/ReadLine/ReadLine.csproj | 6 +++--- 3 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 artifacts/ReadLine.2.0.2.nupkg create mode 100644 artifacts/ReadLine.2.0.3.nupkg diff --git a/artifacts/ReadLine.2.0.2.nupkg b/artifacts/ReadLine.2.0.2.nupkg deleted file mode 100644 index a20c5d92599d99a488c9d7d9ca01c606bc3f79d7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29531 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 z≫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 diff --git a/artifacts/ReadLine.2.0.3.nupkg b/artifacts/ReadLine.2.0.3.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..8f196ec9f720b427aa3738960d4b69dbe1ee9188 GIT binary patch literal 36593 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 A)&Kwi literal 0 HcmV?d00001 diff --git a/src/ReadLine/ReadLine.csproj b/src/ReadLine/ReadLine.csproj index 5d39c87..be3c5c1 100755 --- a/src/ReadLine/ReadLine.csproj +++ b/src/ReadLine/ReadLine.csproj @@ -5,7 +5,7 @@ Toni Solarin-Sodara Toni Solarin-Sodara Toni Solarin-Sodara - net45;net462;net472;netcoreapp2.1;netstandard2.0 + net45;net462;net472;netcoreapp2.2;netcoreapp3.0;netstandard2.0 ReadLine ReadLine readline;gnu;console;shell;cui @@ -16,8 +16,8 @@ true snKey.snk true - Updated to support .NET Standard v2.0 / Core 2.1 / Framework v4.5 / v4.6.2 / v4.7.2 - 2.0.2 + Updated to support .NET Standard v2.0 / Core 2.2 & 3.0 / Framework v4.5 / v4.6.2 / v4.7.2 + 2.0.3 A GNU-Readline like library for .NET From 7c9c2513c348978f0691e8ef98441a8e6bf5ffa0 Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Tue, 17 Mar 2020 19:29:01 -0700 Subject: [PATCH 18/21] Moved SRC and Test folders to root directory. Refactored static ReadLine class to a true singleton. Changed unit tests to use NUnit instead of XUnit. Fixed Ctrl+C issue #59 (Add option to return CTRL+C) Updated version. --- Artifacts/ReadLine.2.0.4.nupkg | Bin 0 -> 43580 bytes .../AutoCompleteHandler.cs | 56 +- .../Program.cs | 62 +- .../ReadLine.Demo.csproj | 30 +- .../Abstractions/Console2.cs | 0 .../AutoCompleteHandler.cs | 0 .../CharExtensions.cs | 2 + .../ConsoleKeyInfoExtensions.cs | 1 + .../KeyHandlerTests.cs | 156 ++-- ReadLine.Tests/ReadLine.Tests.csproj | 22 + ReadLine.Tests/ReadLineTests.cs | 51 ++ ReadLine.sln | 10 +- .../Abstractions/Console2.cs | 0 .../Abstractions/IConsole.cs | 0 .../IAutoCompleteHandler.cs | 0 ReadLine/IReadLine.cs | 12 + {src/ReadLine => ReadLine}/KeyHandler.cs | 709 +++++++++--------- {src/ReadLine => ReadLine}/ReadLine.cs | 24 +- {src/ReadLine => ReadLine}/ReadLine.csproj | 2 +- {src/ReadLine => ReadLine}/snKey.snk | Bin artifacts/ReadLine.2.0.3.nupkg | Bin 41824 -> 0 bytes test/ReadLine.Tests/ReadLine.Tests.csproj | 19 - test/ReadLine.Tests/ReadLineTests.cs | 46 -- 23 files changed, 618 insertions(+), 584 deletions(-) create mode 100644 Artifacts/ReadLine.2.0.4.nupkg rename {src/ReadLine.Demo => ReadLine.Demo}/AutoCompleteHandler.cs (95%) rename {src/ReadLine.Demo => ReadLine.Demo}/Program.cs (65%) mode change 100755 => 100644 rename {src/ReadLine.Demo => ReadLine.Demo}/ReadLine.Demo.csproj (96%) mode change 100755 => 100644 rename {test/ReadLine.Tests => ReadLine.Tests}/Abstractions/Console2.cs (100%) rename {test/ReadLine.Tests => ReadLine.Tests}/AutoCompleteHandler.cs (100%) rename {test/ReadLine.Tests => ReadLine.Tests}/CharExtensions.cs (96%) rename {test/ReadLine.Tests => ReadLine.Tests}/ConsoleKeyInfoExtensions.cs (96%) rename {test/ReadLine.Tests => ReadLine.Tests}/KeyHandlerTests.cs (69%) create mode 100644 ReadLine.Tests/ReadLine.Tests.csproj create mode 100644 ReadLine.Tests/ReadLineTests.cs rename {src/ReadLine => ReadLine}/Abstractions/Console2.cs (100%) rename {src/ReadLine => ReadLine}/Abstractions/IConsole.cs (100%) rename {src/ReadLine => ReadLine}/IAutoCompleteHandler.cs (100%) create mode 100644 ReadLine/IReadLine.cs rename {src/ReadLine => ReadLine}/KeyHandler.cs (96%) rename {src/ReadLine => ReadLine}/ReadLine.cs (61%) mode change 100755 => 100644 rename {src/ReadLine => ReadLine}/ReadLine.csproj (98%) mode change 100755 => 100644 rename {src/ReadLine => ReadLine}/snKey.snk (100%) delete mode 100644 artifacts/ReadLine.2.0.3.nupkg delete mode 100755 test/ReadLine.Tests/ReadLine.Tests.csproj delete mode 100755 test/ReadLine.Tests/ReadLineTests.cs diff --git a/Artifacts/ReadLine.2.0.4.nupkg b/Artifacts/ReadLine.2.0.4.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..250e9154d0416f1500cb1a840f7bc9fe95b7a59e GIT binary patch literal 43580 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

2jdX$!o>CM5txUWBBNL$csS} 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 literal 0 HcmV?d00001 diff --git a/src/ReadLine.Demo/AutoCompleteHandler.cs b/ReadLine.Demo/AutoCompleteHandler.cs similarity index 95% rename from src/ReadLine.Demo/AutoCompleteHandler.cs rename to ReadLine.Demo/AutoCompleteHandler.cs index 44e188b..8fa9a11 100644 --- a/src/ReadLine.Demo/AutoCompleteHandler.cs +++ b/ReadLine.Demo/AutoCompleteHandler.cs @@ -1,28 +1,28 @@ -namespace ReadLine.Demo -{ - internal class AutoCompletionHandler : IAutoCompleteHandler - { - public char[] Separators { get; set; } = - { - ' ', - '.', - '/', - '\\', - ':' - }; - - - public string[] GetSuggestions(string text, int index) - { - return text.StartsWith("git ") - ? new[] - { - "init", - "clone", - "pull", - "push" - } - : null; - } - } -} +namespace ReadLine.Demo +{ + internal class AutoCompletionHandler : IAutoCompleteHandler + { + public char[] Separators { get; set; } = + { + ' ', + '.', + '/', + '\\', + ':' + }; + + + public string[] GetSuggestions(string text, int index) + { + return text.StartsWith("git ") + ? new[] + { + "init", + "clone", + "pull", + "push" + } + : null; + } + } +} diff --git a/src/ReadLine.Demo/Program.cs b/ReadLine.Demo/Program.cs old mode 100755 new mode 100644 similarity index 65% rename from src/ReadLine.Demo/Program.cs rename to ReadLine.Demo/Program.cs index 896f066..5be4213 --- a/src/ReadLine.Demo/Program.cs +++ b/ReadLine.Demo/Program.cs @@ -1,31 +1,33 @@ -using System; - - -namespace ReadLine.Demo -{ - public class Program - { - public static void Main(string[] args) - { - Console.WriteLine("ReadLine Library Demo"); - Console.WriteLine("---------------------"); - Console.WriteLine(); - - string[] history = - { - "ls -a", - "dotnet run", - "git init" - }; - ReadLine.AddHistory(history); - - ReadLine.AutoCompletionHandler = new AutoCompletionHandler(); - - var input = ReadLine.Read("(prompt)> "); - Console.WriteLine(input); - - input = ReadLine.ReadPassword("Enter Password> "); - Console.WriteLine(input); - } - } +using System; + + +namespace ReadLine.Demo +{ + public class Program + { + public static void Main(string[] args) + { + Console.WriteLine("ReadLine Library Demo"); + Console.WriteLine("---------------------"); + Console.WriteLine(); + + string[] history = + { + "ls -a", + "dotnet run", + "git init" + }; + + IReadLine readLine = ReadLine.Instance; + readLine.AddHistory(history); + + readLine.AutoCompletionHandler = new AutoCompletionHandler(); + + var input = readLine.Read("(prompt)> "); + Console.WriteLine(input); + + input = readLine.ReadPassword("Enter Password> "); + Console.WriteLine(input); + } + } } \ No newline at end of file diff --git a/src/ReadLine.Demo/ReadLine.Demo.csproj b/ReadLine.Demo/ReadLine.Demo.csproj old mode 100755 new mode 100644 similarity index 96% rename from src/ReadLine.Demo/ReadLine.Demo.csproj rename to ReadLine.Demo/ReadLine.Demo.csproj index a1a89cb..039c0da --- a/src/ReadLine.Demo/ReadLine.Demo.csproj +++ b/ReadLine.Demo/ReadLine.Demo.csproj @@ -1,15 +1,15 @@ - - - - netcoreapp2.2 - portable - ReadLine.Demo - Exe - ReadLine.Demo - - - - - - - + + + + netcoreapp2.2 + portable + ReadLine.Demo + Exe + ReadLine.Demo + + + + + + + diff --git a/test/ReadLine.Tests/Abstractions/Console2.cs b/ReadLine.Tests/Abstractions/Console2.cs similarity index 100% rename from test/ReadLine.Tests/Abstractions/Console2.cs rename to ReadLine.Tests/Abstractions/Console2.cs diff --git a/test/ReadLine.Tests/AutoCompleteHandler.cs b/ReadLine.Tests/AutoCompleteHandler.cs similarity index 100% rename from test/ReadLine.Tests/AutoCompleteHandler.cs rename to ReadLine.Tests/AutoCompleteHandler.cs diff --git a/test/ReadLine.Tests/CharExtensions.cs b/ReadLine.Tests/CharExtensions.cs similarity index 96% rename from test/ReadLine.Tests/CharExtensions.cs rename to ReadLine.Tests/CharExtensions.cs index 7d0e892..2888008 100644 --- a/test/ReadLine.Tests/CharExtensions.cs +++ b/ReadLine.Tests/CharExtensions.cs @@ -11,6 +11,7 @@ public static class CharExtensions public const char CtrlA = '\u0001'; public const char CtrlB = '\u0002'; + public const char CtrlC = '\u0003'; public const char CtrlD = '\u0004'; public const char CtrlE = '\u0005'; public const char CtrlF = '\u0006'; @@ -29,6 +30,7 @@ public static class CharExtensions {Space, Tuple.Create(ConsoleKey.Spacebar, NoModifiers())}, {CtrlA, Tuple.Create(ConsoleKey.A, ConsoleModifiers.Control)}, {CtrlB, Tuple.Create(ConsoleKey.B, ConsoleModifiers.Control)}, + {CtrlC, Tuple.Create(ConsoleKey.C, ConsoleModifiers.Control)}, {CtrlD, Tuple.Create(ConsoleKey.D, ConsoleModifiers.Control)}, {CtrlE, Tuple.Create(ConsoleKey.E, ConsoleModifiers.Control)}, {CtrlF, Tuple.Create(ConsoleKey.F, ConsoleModifiers.Control)}, diff --git a/test/ReadLine.Tests/ConsoleKeyInfoExtensions.cs b/ReadLine.Tests/ConsoleKeyInfoExtensions.cs similarity index 96% rename from test/ReadLine.Tests/ConsoleKeyInfoExtensions.cs rename to ReadLine.Tests/ConsoleKeyInfoExtensions.cs index e604a17..e2497e9 100644 --- a/test/ReadLine.Tests/ConsoleKeyInfoExtensions.cs +++ b/ReadLine.Tests/ConsoleKeyInfoExtensions.cs @@ -23,6 +23,7 @@ public static class ConsoleKeyInfoExtensions public static readonly ConsoleKeyInfo Space = CharExtensions.Space.ToConsoleKeyInfo(); public static readonly ConsoleKeyInfo CtrlA = CharExtensions.CtrlA.ToConsoleKeyInfo(); public static readonly ConsoleKeyInfo CtrlB = CharExtensions.CtrlB.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlC = CharExtensions.CtrlC.ToConsoleKeyInfo(); public static readonly ConsoleKeyInfo CtrlD = CharExtensions.CtrlD.ToConsoleKeyInfo(); public static readonly ConsoleKeyInfo CtrlE = CharExtensions.CtrlE.ToConsoleKeyInfo(); public static readonly ConsoleKeyInfo CtrlF = CharExtensions.CtrlF.ToConsoleKeyInfo(); diff --git a/test/ReadLine.Tests/KeyHandlerTests.cs b/ReadLine.Tests/KeyHandlerTests.cs similarity index 69% rename from test/ReadLine.Tests/KeyHandlerTests.cs rename to ReadLine.Tests/KeyHandlerTests.cs index 30705e1..4a48dad 100644 --- a/test/ReadLine.Tests/KeyHandlerTests.cs +++ b/ReadLine.Tests/KeyHandlerTests.cs @@ -1,23 +1,25 @@ using System; using System.Collections.Generic; using System.Linq; +using NUnit.Framework; using ReadLine.Abstractions; using ReadLine.Tests.Abstractions; -using Xunit; using static ReadLine.Tests.ConsoleKeyInfoExtensions; namespace ReadLine.Tests { + [TestFixture] public class KeyHandlerTests { private KeyHandler _keyHandler; - private readonly List _history; - private readonly AutoCompleteHandler _autoCompleteHandler; - private readonly string[] _completions; - private readonly IConsole _console; + private List _history; + private AutoCompleteHandler _autoCompleteHandler; + private string[] _completions; + private IConsole _console; - public KeyHandlerTests() + [SetUp] + public void Initialize() { _autoCompleteHandler = new AutoCompleteHandler(); _completions = _autoCompleteHandler.GetSuggestions("", 0); @@ -31,59 +33,65 @@ public KeyHandlerTests() .ForEach(_keyHandler.Handle); } - [Fact] + [Test] public void TestWriteChar() { - Assert.Equal("Hello", _keyHandler.Text); + Assert.AreEqual("Hello", _keyHandler.Text); " World".Select(c => c.ToConsoleKeyInfo()) .ToList() .ForEach(_keyHandler.Handle); - Assert.Equal("Hello World", _keyHandler.Text); + Assert.AreEqual("Hello World", _keyHandler.Text); } - [Fact] + [Test] public void TestBackspace() { _keyHandler.Handle(Backspace); - Assert.Equal("Hell", _keyHandler.Text); + Assert.AreEqual("Hell", _keyHandler.Text); } - [Fact] + [Test] public void TestDelete() { new List() { LeftArrow, Delete } .ForEach(_keyHandler.Handle); - Assert.Equal("Hell", _keyHandler.Text); + Assert.AreEqual("Hell", _keyHandler.Text); } - [Fact] + [Test] public void TestDelete_EndOfLine() { _keyHandler.Handle(Delete); - Assert.Equal("Hello", _keyHandler.Text); + Assert.AreEqual("Hello", _keyHandler.Text); } - [Fact] + [Test] + public void TestControlC() { + //_keyHandler.Handle(CtrlC); + Assert.Ignore("Unable to test."); + } + + [Test] public void TestControlH() { _keyHandler.Handle(CtrlH); - Assert.Equal("Hell", _keyHandler.Text); + Assert.AreEqual("Hell", _keyHandler.Text); } - [Fact] + [Test] public void TestControlT() { var initialCursorCol = _console.CursorLeft; _keyHandler.Handle(CtrlT); - Assert.Equal("Helol", _keyHandler.Text); - Assert.Equal(initialCursorCol, _console.CursorLeft); + Assert.AreEqual("Helol", _keyHandler.Text); + Assert.AreEqual(initialCursorCol, _console.CursorLeft); } - [Fact] + [Test] public void TestControlT_LeftOnce_CursorMovesToEnd() { var initialCursorCol = _console.CursorLeft; @@ -91,11 +99,11 @@ public void TestControlT_LeftOnce_CursorMovesToEnd() new List() { LeftArrow, CtrlT } .ForEach(_keyHandler.Handle); - Assert.Equal("Helol", _keyHandler.Text); - Assert.Equal(initialCursorCol, _console.CursorLeft); + Assert.AreEqual("Helol", _keyHandler.Text); + Assert.AreEqual(initialCursorCol, _console.CursorLeft); } - [Fact] + [Test] public void TestControlT_CursorInMiddleOfLine() { Enumerable @@ -107,11 +115,11 @@ public void TestControlT_CursorInMiddleOfLine() _keyHandler.Handle(CtrlT); - Assert.Equal("Hlelo", _keyHandler.Text); - Assert.Equal(initialCursorCol + 1, _console.CursorLeft); + Assert.AreEqual("Hlelo", _keyHandler.Text); + Assert.AreEqual(initialCursorCol + 1, _console.CursorLeft); } - [Fact] + [Test] public void TestControlT_CursorAtBeginningOfLine_HasNoEffect() { _keyHandler.Handle(CtrlA); @@ -120,47 +128,47 @@ public void TestControlT_CursorAtBeginningOfLine_HasNoEffect() _keyHandler.Handle(CtrlT); - Assert.Equal("Hello", _keyHandler.Text); - Assert.Equal(initialCursorCol, _console.CursorLeft); + Assert.AreEqual("Hello", _keyHandler.Text); + Assert.AreEqual(initialCursorCol, _console.CursorLeft); } - [Fact] + [Test] public void TestHome() { new List() { Home, 'S'.ToConsoleKeyInfo() } .ForEach(_keyHandler.Handle); - Assert.Equal("SHello", _keyHandler.Text); + Assert.AreEqual("SHello", _keyHandler.Text); } - [Fact] + [Test] public void TestControlA() { new List() { CtrlA, 'S'.ToConsoleKeyInfo() } .ForEach(_keyHandler.Handle); - Assert.Equal("SHello", _keyHandler.Text); + Assert.AreEqual("SHello", _keyHandler.Text); } - [Fact] + [Test] public void TestEnd() { new List() { Home, End, ExclamationPoint } .ForEach(_keyHandler.Handle); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.AreEqual("Hello!", _keyHandler.Text); } - [Fact] + [Test] public void TestControlE() { new List() { CtrlA, CtrlE, ExclamationPoint } .ForEach(_keyHandler.Handle); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.AreEqual("Hello!", _keyHandler.Text); } - [Fact] + [Test] public void TestLeftArrow() { " N".Select(c => c.ToConsoleKeyInfo()) @@ -168,10 +176,10 @@ public void TestLeftArrow() .ToList() .ForEach(_keyHandler.Handle); - Assert.Equal("Hell No", _keyHandler.Text); + Assert.AreEqual("Hell No", _keyHandler.Text); } - [Fact] + [Test] public void TestControlB() { " N".Select(c => c.ToConsoleKeyInfo()) @@ -179,19 +187,19 @@ public void TestControlB() .ToList() .ForEach(_keyHandler.Handle); - Assert.Equal("Hell No", _keyHandler.Text); + Assert.AreEqual("Hell No", _keyHandler.Text); } - [Fact] + [Test] public void TestRightArrow() { new List() { LeftArrow, RightArrow, ExclamationPoint } .ForEach(_keyHandler.Handle); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.AreEqual("Hello!", _keyHandler.Text); } - [Fact] + [Test] public void TestControlD() { Enumerable.Repeat(LeftArrow, 4) @@ -199,44 +207,44 @@ public void TestControlD() .ToList() .ForEach(_keyHandler.Handle); - Assert.Equal("Hllo", _keyHandler.Text); + Assert.AreEqual("Hllo", _keyHandler.Text); } - [Fact] + [Test] public void TestControlF() { new List() { LeftArrow, CtrlF, ExclamationPoint } .ForEach(_keyHandler.Handle); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.AreEqual("Hello!", _keyHandler.Text); } - [Fact] + [Test] public void TestControlL() { _keyHandler.Handle(CtrlL); - Assert.Equal(string.Empty, _keyHandler.Text); + Assert.AreEqual(string.Empty, _keyHandler.Text); } - [Fact] + [Test] public void TestUpArrow() { _history.AsEnumerable().Reverse().ToList().ForEach((history) => { _keyHandler.Handle(UpArrow); - Assert.Equal(history, _keyHandler.Text); + Assert.AreEqual(history, _keyHandler.Text); }); } - [Fact] + [Test] public void TestControlP() { _history.AsEnumerable().Reverse().ToList().ForEach((history) => { _keyHandler.Handle(CtrlP); - Assert.Equal(history, _keyHandler.Text); + Assert.AreEqual(history, _keyHandler.Text); }); } - [Fact] + [Test] public void TestDownArrow() { Enumerable.Repeat(UpArrow, _history.Count) @@ -244,12 +252,12 @@ public void TestDownArrow() .ForEach(_keyHandler.Handle); _history.ForEach( history => { - Assert.Equal(history, _keyHandler.Text); + Assert.AreEqual(history, _keyHandler.Text); _keyHandler.Handle(DownArrow); }); } - [Fact] + [Test] public void TestControlN() { Enumerable.Repeat(UpArrow, _history.Count) @@ -257,40 +265,40 @@ public void TestControlN() .ForEach(_keyHandler.Handle); _history.ForEach( history => { - Assert.Equal(history, _keyHandler.Text); + Assert.AreEqual(history, _keyHandler.Text); _keyHandler.Handle(CtrlN); }); } - [Fact] + [Test] public void TestControlU() { _keyHandler.Handle(LeftArrow); _keyHandler.Handle(CtrlU); - Assert.Equal("o", _keyHandler.Text); + Assert.AreEqual("o", _keyHandler.Text); _keyHandler.Handle(End); _keyHandler.Handle(CtrlU); - Assert.Equal(string.Empty, _keyHandler.Text); + Assert.AreEqual(string.Empty, _keyHandler.Text); } - [Fact] + [Test] public void TestControlK() { _keyHandler.Handle(LeftArrow); _keyHandler.Handle(CtrlK); - Assert.Equal("Hell", _keyHandler.Text); + Assert.AreEqual("Hell", _keyHandler.Text); _keyHandler.Handle(Home); _keyHandler.Handle(CtrlK); - Assert.Equal(string.Empty, _keyHandler.Text); + Assert.AreEqual(string.Empty, _keyHandler.Text); } - [Fact] + [Test] public void TestControlW() { " World".Select(c => c.ToConsoleKeyInfo()) @@ -298,20 +306,20 @@ public void TestControlW() .ToList() .ForEach(_keyHandler.Handle); - Assert.Equal("Hello ", _keyHandler.Text); + Assert.AreEqual("Hello ", _keyHandler.Text); _keyHandler.Handle(Backspace); _keyHandler.Handle(CtrlW); - Assert.Equal(string.Empty, _keyHandler.Text); + Assert.AreEqual(string.Empty, _keyHandler.Text); } - [Fact] + [Test] public void TestTab() { _keyHandler.Handle(Tab); // Nothing happens when no auto complete handler is set - Assert.Equal("Hello", _keyHandler.Text); + Assert.AreEqual("Hello", _keyHandler.Text); _keyHandler = new KeyHandler(new Console2(), _history, _autoCompleteHandler); @@ -319,17 +327,17 @@ public void TestTab() _completions.ToList().ForEach(completion => { _keyHandler.Handle(Tab); - Assert.Equal($"Hi {completion}", _keyHandler.Text); + Assert.AreEqual($"Hi {completion}", _keyHandler.Text); }); } - [Fact] + [Test] public void TestBackwardsTab() { _keyHandler.Handle(Tab); // Nothing happens when no auto complete handler is set - Assert.Equal("Hello", _keyHandler.Text); + Assert.AreEqual("Hello", _keyHandler.Text); _keyHandler = new KeyHandler(new Console2(), _history, _autoCompleteHandler); @@ -340,17 +348,17 @@ public void TestBackwardsTab() _completions.Reverse().ToList().ForEach(completion => { _keyHandler.Handle(ShiftTab); - Assert.Equal($"Hi {completion}", _keyHandler.Text); + Assert.AreEqual($"Hi {completion}", _keyHandler.Text); }); } - [Fact] + [Test] public void MoveCursorThenPreviousHistory() { _keyHandler.Handle(LeftArrow); _keyHandler.Handle(UpArrow); - Assert.Equal("clear", _keyHandler.Text); + Assert.AreEqual("clear", _keyHandler.Text); } } } \ No newline at end of file diff --git a/ReadLine.Tests/ReadLine.Tests.csproj b/ReadLine.Tests/ReadLine.Tests.csproj new file mode 100644 index 0000000..568a4fb --- /dev/null +++ b/ReadLine.Tests/ReadLine.Tests.csproj @@ -0,0 +1,22 @@ + + + + net472 + ReadLine.Tests + ReadLine.Tests + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/ReadLine.Tests/ReadLineTests.cs b/ReadLine.Tests/ReadLineTests.cs new file mode 100644 index 0000000..f07e200 --- /dev/null +++ b/ReadLine.Tests/ReadLineTests.cs @@ -0,0 +1,51 @@ +using System.Linq; +using NUnit.Framework; + + +namespace ReadLine.Tests +{ + [TestFixture] + public class ReadLineTests + { + private readonly IReadLine _readLine = ReadLine.Instance; + private static readonly string[] History = { "ls -a", "dotnet run", "git init" }; + + [SetUp] + public void Initialize() { + _readLine.AddHistory(History); + } + + [TearDown] + public void Destruct() { + _readLine.ClearHistory(); + } + + [Test] + public void TestClearHistory() { + _readLine.ClearHistory(); + Assert.AreEqual(0, _readLine.GetHistory().Count); + } + + [Test] + public void TestNoInitialHistory() + { + Assert.AreEqual(3, _readLine.GetHistory().Count); + } + + [Test] + public void TestUpdatesHistory() + { + _readLine.AddHistory("mkdir"); + Assert.AreEqual(4, _readLine.GetHistory().Count); + Assert.AreEqual("mkdir", _readLine.GetHistory().Last()); + } + + [Test] + public void TestGetCorrectHistory() + { + Assert.AreEqual("ls -a", _readLine.GetHistory()[0]); + Assert.AreEqual("dotnet run", _readLine.GetHistory()[1]); + Assert.AreEqual("git init", _readLine.GetHistory()[2]); + } + } +} diff --git a/ReadLine.sln b/ReadLine.sln index d0fa19b..489bf7c 100755 --- a/ReadLine.sln +++ b/ReadLine.sln @@ -2,15 +2,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27130.2036 MinimumVisualStudioVersion = 15.0.26124.0 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{06FC0E85-E73C-4DC1-B6FD-A583B7B1DFE4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine", "ReadLine\ReadLine.csproj", "{9EB290C9-BB52-4B24-9779-5A816AC75E18}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine", "src\ReadLine\ReadLine.csproj", "{9EB290C9-BB52-4B24-9779-5A816AC75E18}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine.Demo", "ReadLine.Demo\ReadLine.Demo.csproj", "{4C512FD1-A0E8-4908-B0A4-B0D85947716A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine.Demo", "src\ReadLine.Demo\ReadLine.Demo.csproj", "{4C512FD1-A0E8-4908-B0A4-B0D85947716A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{38C56AEB-DB08-4CBF-AAC0-EBFC2B0EE045}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine.Tests", "test\ReadLine.Tests\ReadLine.Tests.csproj", "{631582D9-EEEA-4F9D-8069-71ECA24ED282}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine.Tests", "ReadLine.Tests\ReadLine.Tests.csproj", "{631582D9-EEEA-4F9D-8069-71ECA24ED282}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/ReadLine/Abstractions/Console2.cs b/ReadLine/Abstractions/Console2.cs similarity index 100% rename from src/ReadLine/Abstractions/Console2.cs rename to ReadLine/Abstractions/Console2.cs diff --git a/src/ReadLine/Abstractions/IConsole.cs b/ReadLine/Abstractions/IConsole.cs similarity index 100% rename from src/ReadLine/Abstractions/IConsole.cs rename to ReadLine/Abstractions/IConsole.cs diff --git a/src/ReadLine/IAutoCompleteHandler.cs b/ReadLine/IAutoCompleteHandler.cs similarity index 100% rename from src/ReadLine/IAutoCompleteHandler.cs rename to ReadLine/IAutoCompleteHandler.cs diff --git a/ReadLine/IReadLine.cs b/ReadLine/IReadLine.cs new file mode 100644 index 0000000..e7ab988 --- /dev/null +++ b/ReadLine/IReadLine.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace ReadLine { + public interface IReadLine { + IAutoCompleteHandler AutoCompletionHandler { get; set; } + void AddHistory(params string[] text); + List GetHistory(); + void ClearHistory(); + string Read(string prompt = "", string @default = ""); + string ReadPassword(string prompt = ""); + } +} diff --git a/src/ReadLine/KeyHandler.cs b/ReadLine/KeyHandler.cs similarity index 96% rename from src/ReadLine/KeyHandler.cs rename to ReadLine/KeyHandler.cs index 075700e..5fb3824 100644 --- a/src/ReadLine/KeyHandler.cs +++ b/ReadLine/KeyHandler.cs @@ -1,355 +1,356 @@ -using System; -using System.Collections.Generic; -using System.Text; -using ReadLine.Abstractions; - - -namespace ReadLine -{ - public class KeyHandler - { - private readonly IConsole _console2; - private readonly List _history; - private readonly Dictionary _keyActions; - private readonly StringBuilder _text; - private string[] _completions; - private int _completionsIndex; - private int _completionStart; - private int _cursorLimit; - private int _cursorPos; - private int _historyIndex; - private ConsoleKeyInfo _keyInfo; - - public KeyHandler(IConsole console, List history, IAutoCompleteHandler autoCompleteHandler) - { - _console2 = console; - - _history = history ?? new List(); - _historyIndex = _history.Count; - _text = new StringBuilder(); - _keyActions = new Dictionary - { - ["LeftArrow"] = MoveCursorLeft, - ["Home"] = MoveCursorHome, - ["End"] = MoveCursorEnd, - ["ControlA"] = MoveCursorHome, - ["ControlB"] = MoveCursorLeft, - ["RightArrow"] = MoveCursorRight, - ["ControlF"] = MoveCursorRight, - ["ControlE"] = MoveCursorEnd, - ["Backspace"] = Backspace, - ["Delete"] = Delete, - ["ControlD"] = Delete, - ["ControlH"] = Backspace, - ["ControlL"] = ClearLine, - ["Escape"] = ClearLine, - ["UpArrow"] = PrevHistory, - ["ControlP"] = PrevHistory, - ["DownArrow"] = NextHistory, - ["ControlN"] = NextHistory, - ["ControlU"] = () => { Backspace(_cursorPos); }, - ["ControlK"] = () => - { - var pos = _cursorPos; - MoveCursorEnd(); - Backspace(_cursorPos - pos); - }, - ["ControlW"] = () => - { - while (!IsStartOfLine() && _text[_cursorPos - 1] != ' ') - Backspace(); - }, - ["ControlT"] = TransposeChars, - ["Tab"] = () => - { - if (IsInAutoCompleteMode()) - { - NextAutoComplete(); - } - else - { - if (autoCompleteHandler == null || !IsEndOfLine()) - return; - - var text = _text.ToString(); - - _completionStart = text.LastIndexOfAny(autoCompleteHandler.Separators); - _completionStart = _completionStart == -1 ? 0 : _completionStart + 1; - - _completions = autoCompleteHandler.GetSuggestions(text, _completionStart); - _completions = _completions?.Length == 0 ? null : _completions; - - if (_completions == null) - return; - - StartAutoComplete(); - } - }, - ["ShiftTab"] = () => - { - if (IsInAutoCompleteMode()) - PreviousAutoComplete(); - } - }; - } - - - public string Text => _text.ToString(); - - - private bool IsStartOfLine() => _cursorPos == 0; - - - private bool IsEndOfLine() => _cursorPos == _cursorLimit; - - - private bool IsStartOfBuffer() => _console2.CursorLeft == 0; - - - private bool IsEndOfBuffer() => _console2.CursorLeft == _console2.BufferWidth - 1; - - - private bool IsInAutoCompleteMode() => _completions != null; - - - private void MoveCursorLeft() => MoveCursorLeft(1); - - private void MoveCursorLeft(int count) - { - if (count > _cursorPos) - count = _cursorPos; - - if (count > _console2.CursorLeft) - _console2.SetCursorPosition(_console2.BufferWidth - 1, _console2.CursorTop - 1); - else - _console2.SetCursorPosition(_console2.CursorLeft - 1, _console2.CursorTop); - - _cursorPos -= count; - } - - - private void MoveCursorHome() - { - while (!IsStartOfLine()) - MoveCursorLeft(); - } - - - private string BuildKeyInput() => _keyInfo.Modifiers != ConsoleModifiers.Control && _keyInfo.Modifiers != ConsoleModifiers.Shift ? _keyInfo.Key.ToString() : _keyInfo.Modifiers + _keyInfo.Key.ToString(); - - - private void MoveCursorRight() - { - if (IsEndOfLine()) - return; - - if (IsEndOfBuffer()) - _console2.SetCursorPosition(0, _console2.CursorTop + 1); - else - _console2.SetCursorPosition(_console2.CursorLeft + 1, _console2.CursorTop); - - _cursorPos++; - } - - - private void MoveCursorEnd() - { - while (!IsEndOfLine()) - MoveCursorRight(); - } - - - private void ClearLine() - { - MoveCursorEnd(); - Backspace(_cursorPos); - } - - - private void WriteNewString(string str) - { - ClearLine(); - WriteString(str); - } - - - private void WriteString(string str) - { - foreach (var character in str) - WriteChar(character); - } - - - private void WriteChar() => WriteChar(_keyInfo.KeyChar); - - - private void WriteChar(char c) - { - if (IsEndOfLine()) - { - _text.Append(c); - _console2.Write(c.ToString()); - _cursorPos++; - } - else - { - var left = _console2.CursorLeft; - var top = _console2.CursorTop; - var str = _text.ToString().Substring(_cursorPos); - _text.Insert(_cursorPos, c); - _console2.Write(c + str); - _console2.SetCursorPosition(left, top); - MoveCursorRight(); - } - - _cursorLimit++; - } - - - private void Backspace() => Backspace(1); - - private void Backspace(int count) - { - if (count > _cursorPos) - count = _cursorPos; - - MoveCursorLeft(count); - var index = _cursorPos; - _text.Remove(index, count); - var replacement = _text.ToString().Substring(index); - var left = _console2.CursorLeft; - var top = _console2.CursorTop; - var spaces = new string(' ', count); - _console2.Write($"{replacement}{spaces}"); - _console2.SetCursorPosition(left, top); - _cursorLimit -= count; - } - - - private void Delete() - { - if (IsEndOfLine()) - return; - - var index = _cursorPos; - _text.Remove(index, 1); - var replacement = _text.ToString().Substring(index); - var left = _console2.CursorLeft; - var top = _console2.CursorTop; - _console2.Write($"{replacement} "); - _console2.SetCursorPosition(left, top); - _cursorLimit--; - } - - - private void TransposeChars() - { - // local helper functions - bool AlmostEndOfLine() => _cursorLimit - _cursorPos == 1; - - int IncrementIf(Func expression, int index) => expression() ? index + 1 : index; - - int DecrementIf(Func expression, int index) => expression() ? index - 1 : index; - - if (IsStartOfLine()) - return; - - var firstIdx = DecrementIf(IsEndOfLine, _cursorPos - 1); - var secondIdx = DecrementIf(IsEndOfLine, _cursorPos); - - var secondChar = _text[secondIdx]; - _text[secondIdx] = _text[firstIdx]; - _text[firstIdx] = secondChar; - - var left = IncrementIf(AlmostEndOfLine, _console2.CursorLeft); - var cursorPosition = IncrementIf(AlmostEndOfLine, _cursorPos); - - WriteNewString(_text.ToString()); - - _console2.SetCursorPosition(left, _console2.CursorTop); - _cursorPos = cursorPosition; - - MoveCursorRight(); - } - - - private void StartAutoComplete() - { - Backspace(_cursorPos - _completionStart); - - _completionsIndex = 0; - - WriteString(_completions[_completionsIndex]); - } - - - private void NextAutoComplete() - { - Backspace(_cursorPos - _completionStart); - - _completionsIndex++; - - if (_completionsIndex == _completions.Length) - _completionsIndex = 0; - - WriteString(_completions[_completionsIndex]); - } - - - private void PreviousAutoComplete() - { - Backspace(_cursorPos - _completionStart); - - _completionsIndex--; - - if (_completionsIndex == -1) - _completionsIndex = _completions.Length - 1; - - WriteString(_completions[_completionsIndex]); - } - - - private void PrevHistory() - { - if (_historyIndex > 0) - { - _historyIndex--; - WriteNewString(_history[_historyIndex]); - } - } - - - private void NextHistory() - { - if (_historyIndex < _history.Count) - { - _historyIndex++; - if (_historyIndex == _history.Count) - ClearLine(); - else - WriteNewString(_history[_historyIndex]); - } - } - - - private void ResetAutoComplete() - { - _completions = null; - _completionsIndex = 0; - } - - - public void Handle(ConsoleKeyInfo keyInfo) - { - _keyInfo = keyInfo; - - // If in auto complete mode and Tab wasn't pressed - if (IsInAutoCompleteMode() && _keyInfo.Key != ConsoleKey.Tab) - ResetAutoComplete(); - - _keyActions.TryGetValue(BuildKeyInput(), out var action); - action = action ?? WriteChar; - action.Invoke(); - } - } +using System; +using System.Collections.Generic; +using System.Text; +using ReadLine.Abstractions; + + +namespace ReadLine +{ + public class KeyHandler + { + private readonly IConsole _console2; + private readonly List _history; + private readonly Dictionary _keyActions; + private readonly StringBuilder _text; + private string[] _completions; + private int _completionsIndex; + private int _completionStart; + private int _cursorLimit; + private int _cursorPos; + private int _historyIndex; + private ConsoleKeyInfo _keyInfo; + + public KeyHandler(IConsole console, List history, IAutoCompleteHandler autoCompleteHandler) + { + _console2 = console; + + _history = history ?? new List(); + _historyIndex = _history.Count; + _text = new StringBuilder(); + _keyActions = new Dictionary + { + ["LeftArrow"] = MoveCursorLeft, + ["Home"] = MoveCursorHome, + ["End"] = MoveCursorEnd, + ["ControlA"] = MoveCursorHome, + ["ControlB"] = MoveCursorLeft, + ["ControlC"] = () => Environment.Exit(0), + ["RightArrow"] = MoveCursorRight, + ["ControlF"] = MoveCursorRight, + ["ControlE"] = MoveCursorEnd, + ["Backspace"] = Backspace, + ["Delete"] = Delete, + ["ControlD"] = Delete, + ["ControlH"] = Backspace, + ["ControlL"] = ClearLine, + ["Escape"] = ClearLine, + ["UpArrow"] = PrevHistory, + ["ControlP"] = PrevHistory, + ["DownArrow"] = NextHistory, + ["ControlN"] = NextHistory, + ["ControlU"] = () => { Backspace(_cursorPos); }, + ["ControlK"] = () => + { + var pos = _cursorPos; + MoveCursorEnd(); + Backspace(_cursorPos - pos); + }, + ["ControlW"] = () => + { + while (!IsStartOfLine() && _text[_cursorPos - 1] != ' ') + Backspace(); + }, + ["ControlT"] = TransposeChars, + ["Tab"] = () => + { + if (IsInAutoCompleteMode()) + { + NextAutoComplete(); + } + else + { + if (autoCompleteHandler == null || !IsEndOfLine()) + return; + + var text = _text.ToString(); + + _completionStart = text.LastIndexOfAny(autoCompleteHandler.Separators); + _completionStart = _completionStart == -1 ? 0 : _completionStart + 1; + + _completions = autoCompleteHandler.GetSuggestions(text, _completionStart); + _completions = _completions?.Length == 0 ? null : _completions; + + if (_completions == null) + return; + + StartAutoComplete(); + } + }, + ["ShiftTab"] = () => + { + if (IsInAutoCompleteMode()) + PreviousAutoComplete(); + } + }; + } + + + public string Text => _text.ToString(); + + + private bool IsStartOfLine() => _cursorPos == 0; + + + private bool IsEndOfLine() => _cursorPos == _cursorLimit; + + + private bool IsStartOfBuffer() => _console2.CursorLeft == 0; + + + private bool IsEndOfBuffer() => _console2.CursorLeft == _console2.BufferWidth - 1; + + + private bool IsInAutoCompleteMode() => _completions != null; + + + private void MoveCursorLeft() => MoveCursorLeft(1); + + private void MoveCursorLeft(int count) + { + if (count > _cursorPos) + count = _cursorPos; + + if (count > _console2.CursorLeft) + _console2.SetCursorPosition(_console2.BufferWidth - 1, _console2.CursorTop - 1); + else + _console2.SetCursorPosition(_console2.CursorLeft - 1, _console2.CursorTop); + + _cursorPos -= count; + } + + + private void MoveCursorHome() + { + while (!IsStartOfLine()) + MoveCursorLeft(); + } + + + private string BuildKeyInput() => _keyInfo.Modifiers != ConsoleModifiers.Control && _keyInfo.Modifiers != ConsoleModifiers.Shift ? _keyInfo.Key.ToString() : _keyInfo.Modifiers + _keyInfo.Key.ToString(); + + + private void MoveCursorRight() + { + if (IsEndOfLine()) + return; + + if (IsEndOfBuffer()) + _console2.SetCursorPosition(0, _console2.CursorTop + 1); + else + _console2.SetCursorPosition(_console2.CursorLeft + 1, _console2.CursorTop); + + _cursorPos++; + } + + + private void MoveCursorEnd() + { + while (!IsEndOfLine()) + MoveCursorRight(); + } + + + private void ClearLine() + { + MoveCursorEnd(); + Backspace(_cursorPos); + } + + + private void WriteNewString(string str) + { + ClearLine(); + WriteString(str); + } + + + private void WriteString(string str) + { + foreach (var character in str) + WriteChar(character); + } + + + private void WriteChar() => WriteChar(_keyInfo.KeyChar); + + + private void WriteChar(char c) + { + if (IsEndOfLine()) + { + _text.Append(c); + _console2.Write(c.ToString()); + _cursorPos++; + } + else + { + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + var str = _text.ToString().Substring(_cursorPos); + _text.Insert(_cursorPos, c); + _console2.Write(c + str); + _console2.SetCursorPosition(left, top); + MoveCursorRight(); + } + + _cursorLimit++; + } + + + private void Backspace() => Backspace(1); + + private void Backspace(int count) + { + if (count > _cursorPos) + count = _cursorPos; + + MoveCursorLeft(count); + var index = _cursorPos; + _text.Remove(index, count); + var replacement = _text.ToString().Substring(index); + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + var spaces = new string(' ', count); + _console2.Write($"{replacement}{spaces}"); + _console2.SetCursorPosition(left, top); + _cursorLimit -= count; + } + + + private void Delete() + { + if (IsEndOfLine()) + return; + + var index = _cursorPos; + _text.Remove(index, 1); + var replacement = _text.ToString().Substring(index); + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + _console2.Write($"{replacement} "); + _console2.SetCursorPosition(left, top); + _cursorLimit--; + } + + + private void TransposeChars() + { + // local helper functions + bool AlmostEndOfLine() => _cursorLimit - _cursorPos == 1; + + int IncrementIf(Func expression, int index) => expression() ? index + 1 : index; + + int DecrementIf(Func expression, int index) => expression() ? index - 1 : index; + + if (IsStartOfLine()) + return; + + var firstIdx = DecrementIf(IsEndOfLine, _cursorPos - 1); + var secondIdx = DecrementIf(IsEndOfLine, _cursorPos); + + var secondChar = _text[secondIdx]; + _text[secondIdx] = _text[firstIdx]; + _text[firstIdx] = secondChar; + + var left = IncrementIf(AlmostEndOfLine, _console2.CursorLeft); + var cursorPosition = IncrementIf(AlmostEndOfLine, _cursorPos); + + WriteNewString(_text.ToString()); + + _console2.SetCursorPosition(left, _console2.CursorTop); + _cursorPos = cursorPosition; + + MoveCursorRight(); + } + + + private void StartAutoComplete() + { + Backspace(_cursorPos - _completionStart); + + _completionsIndex = 0; + + WriteString(_completions[_completionsIndex]); + } + + + private void NextAutoComplete() + { + Backspace(_cursorPos - _completionStart); + + _completionsIndex++; + + if (_completionsIndex == _completions.Length) + _completionsIndex = 0; + + WriteString(_completions[_completionsIndex]); + } + + + private void PreviousAutoComplete() + { + Backspace(_cursorPos - _completionStart); + + _completionsIndex--; + + if (_completionsIndex == -1) + _completionsIndex = _completions.Length - 1; + + WriteString(_completions[_completionsIndex]); + } + + + private void PrevHistory() + { + if (_historyIndex > 0) + { + _historyIndex--; + WriteNewString(_history[_historyIndex]); + } + } + + + private void NextHistory() + { + if (_historyIndex < _history.Count) + { + _historyIndex++; + if (_historyIndex == _history.Count) + ClearLine(); + else + WriteNewString(_history[_historyIndex]); + } + } + + + private void ResetAutoComplete() + { + _completions = null; + _completionsIndex = 0; + } + + + public void Handle(ConsoleKeyInfo keyInfo) + { + _keyInfo = keyInfo; + + // If in auto complete mode and Tab wasn't pressed + if (IsInAutoCompleteMode() && _keyInfo.Key != ConsoleKey.Tab) + ResetAutoComplete(); + + _keyActions.TryGetValue(BuildKeyInput(), out var action); + action = action ?? WriteChar; + action.Invoke(); + } + } } \ No newline at end of file diff --git a/src/ReadLine/ReadLine.cs b/ReadLine/ReadLine.cs old mode 100755 new mode 100644 similarity index 61% rename from src/ReadLine/ReadLine.cs rename to ReadLine/ReadLine.cs index 0bb765e..434744a --- a/src/ReadLine/ReadLine.cs +++ b/ReadLine/ReadLine.cs @@ -5,27 +5,29 @@ namespace ReadLine { - public static class ReadLine + public class ReadLine : IReadLine { - private static List _history; + private List _history; + private ReadLine() { + _history = new List(); + } - static ReadLine() => _history = new List(); - + public static ReadLine Instance = new ReadLine(); // Singleton implementation - public static IAutoCompleteHandler AutoCompletionHandler { private get; set; } + public IAutoCompleteHandler AutoCompletionHandler { get; set; } - public static void AddHistory(params string[] text) => _history.AddRange(text); + public void AddHistory(params string[] text) => _history.AddRange(text); - public static List GetHistory() => _history; + public List GetHistory() => _history; - public static void ClearHistory() => _history = new List(); + public void ClearHistory() => _history = new List(); - public static string Read(string prompt = "", string @default = "") + public string Read(string prompt = "", string @default = "") { Console.Write(prompt); var keyHandler = new KeyHandler(new Console2(), _history, AutoCompletionHandler); @@ -40,7 +42,7 @@ public static string Read(string prompt = "", string @default = "") } - public static string ReadPassword(string prompt = "") + public string ReadPassword(string prompt = "") { Console.Write(prompt); var keyHandler = new KeyHandler(new Console2 @@ -53,6 +55,8 @@ public static string ReadPassword(string prompt = "") private static string GetText(KeyHandler keyHandler) { + Console.TreatControlCAsInput = true; + var keyInfo = Console.ReadKey(true); while (keyInfo.Key != ConsoleKey.Enter) { diff --git a/src/ReadLine/ReadLine.csproj b/ReadLine/ReadLine.csproj old mode 100755 new mode 100644 similarity index 98% rename from src/ReadLine/ReadLine.csproj rename to ReadLine/ReadLine.csproj index 88d7801..6694755 --- a/src/ReadLine/ReadLine.csproj +++ b/ReadLine/ReadLine.csproj @@ -13,7 +13,7 @@ snKey.snk true Updated to support .NET Standard v2.0 / Core 2.2 & 3.0 / Framework v4.5 - v4.8 - 2.0.3 + 2.0.4 A GNU-Readline like library for .NET artifacts MIT diff --git a/src/ReadLine/snKey.snk b/ReadLine/snKey.snk similarity index 100% rename from src/ReadLine/snKey.snk rename to ReadLine/snKey.snk diff --git a/artifacts/ReadLine.2.0.3.nupkg b/artifacts/ReadLine.2.0.3.nupkg deleted file mode 100644 index 2538e1bf5992b42b40741fc7ecc23bab9d3eb5fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41824 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 k$K - - - netcoreapp2.1 - portable - ReadLine.Tests - ReadLine.Tests - true - - - - - - - - - - - diff --git a/test/ReadLine.Tests/ReadLineTests.cs b/test/ReadLine.Tests/ReadLineTests.cs deleted file mode 100755 index 2b8cfdc..0000000 --- a/test/ReadLine.Tests/ReadLineTests.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Linq; -using Xunit; -using static ReadLine.ReadLine; - - -namespace ReadLine.Tests -{ - public class ReadLineTests : IDisposable - { - public ReadLineTests() - { - string[] history = { "ls -a", "dotnet run", "git init" }; - AddHistory(history); - } - - [Fact] - public void TestNoInitialHistory() - { - Assert.Equal(3, GetHistory().Count); - } - - [Fact] - public void TestUpdatesHistory() - { - AddHistory("mkdir"); - Assert.Equal(4, GetHistory().Count); - Assert.Equal("mkdir", GetHistory().Last()); - } - - [Fact] - public void TestGetCorrectHistory() - { - Assert.Equal("ls -a", GetHistory()[0]); - Assert.Equal("dotnet run", GetHistory()[1]); - Assert.Equal("git init", GetHistory()[2]); - } - - public void Dispose() - { - // If all above tests pass - // clear history works - ClearHistory(); - } - } -} From f53119532ce7db8ed2ff1110800bb1428e27bab7 Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Tue, 17 Mar 2020 19:38:31 -0700 Subject: [PATCH 19/21] Create dotnetcore.yml --- .github/workflows/dotnetcore.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/dotnetcore.yml diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml new file mode 100644 index 0000000..d243b1f --- /dev/null +++ b/.github/workflows/dotnetcore.yml @@ -0,0 +1,21 @@ +name: .NET Core + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 3.1.101 + - name: Build with dotnet + run: dotnet build --configuration Release From f734a8a6db35a75d31b4662adc6f23bf22922cd0 Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Tue, 17 Mar 2020 19:29:01 -0700 Subject: [PATCH 20/21] Moved SRC and Test folders to root directory. Refactored static ReadLine class to a true singleton. Changed unit tests to use NUnit instead of XUnit. Fixed Ctrl+C issue #59 (Add option to return CTRL+C) Updated version. --- Artifacts/ReadLine.2.1.3.nupkg | Bin 0 -> 43618 bytes .../AutoCompleteHandler.cs | 56 +- .../Program.cs | 62 +- .../ReadLine.Demo.csproj | 30 +- .../Abstractions/Console2.cs | 0 .../AutoCompleteHandler.cs | 0 .../CharExtensions.cs | 2 + .../ConsoleKeyInfoExtensions.cs | 1 + .../KeyHandlerTests.cs | 156 ++-- ReadLine.Tests/ReadLine.Tests.csproj | 22 + ReadLine.Tests/ReadLineTests.cs | 51 ++ ReadLine.sln | 10 +- .../Abstractions/Console2.cs | 0 .../Abstractions/IConsole.cs | 0 .../IAutoCompleteHandler.cs | 0 ReadLine/IReadLine.cs | 12 + {src/ReadLine => ReadLine}/KeyHandler.cs | 709 +++++++++--------- {src/ReadLine => ReadLine}/ReadLine.cs | 24 +- {src/ReadLine => ReadLine}/ReadLine.csproj | 2 +- {src/ReadLine => ReadLine}/snKey.snk | Bin artifacts/ReadLine.2.0.3.nupkg | Bin 41824 -> 0 bytes test/ReadLine.Tests/ReadLine.Tests.csproj | 19 - test/ReadLine.Tests/ReadLineTests.cs | 46 -- 23 files changed, 618 insertions(+), 584 deletions(-) create mode 100644 Artifacts/ReadLine.2.1.3.nupkg rename {src/ReadLine.Demo => ReadLine.Demo}/AutoCompleteHandler.cs (95%) rename {src/ReadLine.Demo => ReadLine.Demo}/Program.cs (65%) mode change 100755 => 100644 rename {src/ReadLine.Demo => ReadLine.Demo}/ReadLine.Demo.csproj (96%) mode change 100755 => 100644 rename {test/ReadLine.Tests => ReadLine.Tests}/Abstractions/Console2.cs (100%) rename {test/ReadLine.Tests => ReadLine.Tests}/AutoCompleteHandler.cs (100%) rename {test/ReadLine.Tests => ReadLine.Tests}/CharExtensions.cs (96%) rename {test/ReadLine.Tests => ReadLine.Tests}/ConsoleKeyInfoExtensions.cs (96%) rename {test/ReadLine.Tests => ReadLine.Tests}/KeyHandlerTests.cs (69%) create mode 100644 ReadLine.Tests/ReadLine.Tests.csproj create mode 100644 ReadLine.Tests/ReadLineTests.cs rename {src/ReadLine => ReadLine}/Abstractions/Console2.cs (100%) rename {src/ReadLine => ReadLine}/Abstractions/IConsole.cs (100%) rename {src/ReadLine => ReadLine}/IAutoCompleteHandler.cs (100%) create mode 100644 ReadLine/IReadLine.cs rename {src/ReadLine => ReadLine}/KeyHandler.cs (96%) rename {src/ReadLine => ReadLine}/ReadLine.cs (61%) mode change 100755 => 100644 rename {src/ReadLine => ReadLine}/ReadLine.csproj (98%) mode change 100755 => 100644 rename {src/ReadLine => ReadLine}/snKey.snk (100%) delete mode 100644 artifacts/ReadLine.2.0.3.nupkg delete mode 100755 test/ReadLine.Tests/ReadLine.Tests.csproj delete mode 100755 test/ReadLine.Tests/ReadLineTests.cs diff --git a/Artifacts/ReadLine.2.1.3.nupkg b/Artifacts/ReadLine.2.1.3.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..f73310b4b17d782f99d40ed01c69c42032118a88 GIT binary patch literal 43618 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 bWc?qEYRd9(@K0ZX3_KWt3zH=0>D~VWD$AVN literal 0 HcmV?d00001 diff --git a/src/ReadLine.Demo/AutoCompleteHandler.cs b/ReadLine.Demo/AutoCompleteHandler.cs similarity index 95% rename from src/ReadLine.Demo/AutoCompleteHandler.cs rename to ReadLine.Demo/AutoCompleteHandler.cs index 44e188b..8fa9a11 100644 --- a/src/ReadLine.Demo/AutoCompleteHandler.cs +++ b/ReadLine.Demo/AutoCompleteHandler.cs @@ -1,28 +1,28 @@ -namespace ReadLine.Demo -{ - internal class AutoCompletionHandler : IAutoCompleteHandler - { - public char[] Separators { get; set; } = - { - ' ', - '.', - '/', - '\\', - ':' - }; - - - public string[] GetSuggestions(string text, int index) - { - return text.StartsWith("git ") - ? new[] - { - "init", - "clone", - "pull", - "push" - } - : null; - } - } -} +namespace ReadLine.Demo +{ + internal class AutoCompletionHandler : IAutoCompleteHandler + { + public char[] Separators { get; set; } = + { + ' ', + '.', + '/', + '\\', + ':' + }; + + + public string[] GetSuggestions(string text, int index) + { + return text.StartsWith("git ") + ? new[] + { + "init", + "clone", + "pull", + "push" + } + : null; + } + } +} diff --git a/src/ReadLine.Demo/Program.cs b/ReadLine.Demo/Program.cs old mode 100755 new mode 100644 similarity index 65% rename from src/ReadLine.Demo/Program.cs rename to ReadLine.Demo/Program.cs index 896f066..5be4213 --- a/src/ReadLine.Demo/Program.cs +++ b/ReadLine.Demo/Program.cs @@ -1,31 +1,33 @@ -using System; - - -namespace ReadLine.Demo -{ - public class Program - { - public static void Main(string[] args) - { - Console.WriteLine("ReadLine Library Demo"); - Console.WriteLine("---------------------"); - Console.WriteLine(); - - string[] history = - { - "ls -a", - "dotnet run", - "git init" - }; - ReadLine.AddHistory(history); - - ReadLine.AutoCompletionHandler = new AutoCompletionHandler(); - - var input = ReadLine.Read("(prompt)> "); - Console.WriteLine(input); - - input = ReadLine.ReadPassword("Enter Password> "); - Console.WriteLine(input); - } - } +using System; + + +namespace ReadLine.Demo +{ + public class Program + { + public static void Main(string[] args) + { + Console.WriteLine("ReadLine Library Demo"); + Console.WriteLine("---------------------"); + Console.WriteLine(); + + string[] history = + { + "ls -a", + "dotnet run", + "git init" + }; + + IReadLine readLine = ReadLine.Instance; + readLine.AddHistory(history); + + readLine.AutoCompletionHandler = new AutoCompletionHandler(); + + var input = readLine.Read("(prompt)> "); + Console.WriteLine(input); + + input = readLine.ReadPassword("Enter Password> "); + Console.WriteLine(input); + } + } } \ No newline at end of file diff --git a/src/ReadLine.Demo/ReadLine.Demo.csproj b/ReadLine.Demo/ReadLine.Demo.csproj old mode 100755 new mode 100644 similarity index 96% rename from src/ReadLine.Demo/ReadLine.Demo.csproj rename to ReadLine.Demo/ReadLine.Demo.csproj index a1a89cb..039c0da --- a/src/ReadLine.Demo/ReadLine.Demo.csproj +++ b/ReadLine.Demo/ReadLine.Demo.csproj @@ -1,15 +1,15 @@ - - - - netcoreapp2.2 - portable - ReadLine.Demo - Exe - ReadLine.Demo - - - - - - - + + + + netcoreapp2.2 + portable + ReadLine.Demo + Exe + ReadLine.Demo + + + + + + + diff --git a/test/ReadLine.Tests/Abstractions/Console2.cs b/ReadLine.Tests/Abstractions/Console2.cs similarity index 100% rename from test/ReadLine.Tests/Abstractions/Console2.cs rename to ReadLine.Tests/Abstractions/Console2.cs diff --git a/test/ReadLine.Tests/AutoCompleteHandler.cs b/ReadLine.Tests/AutoCompleteHandler.cs similarity index 100% rename from test/ReadLine.Tests/AutoCompleteHandler.cs rename to ReadLine.Tests/AutoCompleteHandler.cs diff --git a/test/ReadLine.Tests/CharExtensions.cs b/ReadLine.Tests/CharExtensions.cs similarity index 96% rename from test/ReadLine.Tests/CharExtensions.cs rename to ReadLine.Tests/CharExtensions.cs index 7d0e892..2888008 100644 --- a/test/ReadLine.Tests/CharExtensions.cs +++ b/ReadLine.Tests/CharExtensions.cs @@ -11,6 +11,7 @@ public static class CharExtensions public const char CtrlA = '\u0001'; public const char CtrlB = '\u0002'; + public const char CtrlC = '\u0003'; public const char CtrlD = '\u0004'; public const char CtrlE = '\u0005'; public const char CtrlF = '\u0006'; @@ -29,6 +30,7 @@ public static class CharExtensions {Space, Tuple.Create(ConsoleKey.Spacebar, NoModifiers())}, {CtrlA, Tuple.Create(ConsoleKey.A, ConsoleModifiers.Control)}, {CtrlB, Tuple.Create(ConsoleKey.B, ConsoleModifiers.Control)}, + {CtrlC, Tuple.Create(ConsoleKey.C, ConsoleModifiers.Control)}, {CtrlD, Tuple.Create(ConsoleKey.D, ConsoleModifiers.Control)}, {CtrlE, Tuple.Create(ConsoleKey.E, ConsoleModifiers.Control)}, {CtrlF, Tuple.Create(ConsoleKey.F, ConsoleModifiers.Control)}, diff --git a/test/ReadLine.Tests/ConsoleKeyInfoExtensions.cs b/ReadLine.Tests/ConsoleKeyInfoExtensions.cs similarity index 96% rename from test/ReadLine.Tests/ConsoleKeyInfoExtensions.cs rename to ReadLine.Tests/ConsoleKeyInfoExtensions.cs index e604a17..e2497e9 100644 --- a/test/ReadLine.Tests/ConsoleKeyInfoExtensions.cs +++ b/ReadLine.Tests/ConsoleKeyInfoExtensions.cs @@ -23,6 +23,7 @@ public static class ConsoleKeyInfoExtensions public static readonly ConsoleKeyInfo Space = CharExtensions.Space.ToConsoleKeyInfo(); public static readonly ConsoleKeyInfo CtrlA = CharExtensions.CtrlA.ToConsoleKeyInfo(); public static readonly ConsoleKeyInfo CtrlB = CharExtensions.CtrlB.ToConsoleKeyInfo(); + public static readonly ConsoleKeyInfo CtrlC = CharExtensions.CtrlC.ToConsoleKeyInfo(); public static readonly ConsoleKeyInfo CtrlD = CharExtensions.CtrlD.ToConsoleKeyInfo(); public static readonly ConsoleKeyInfo CtrlE = CharExtensions.CtrlE.ToConsoleKeyInfo(); public static readonly ConsoleKeyInfo CtrlF = CharExtensions.CtrlF.ToConsoleKeyInfo(); diff --git a/test/ReadLine.Tests/KeyHandlerTests.cs b/ReadLine.Tests/KeyHandlerTests.cs similarity index 69% rename from test/ReadLine.Tests/KeyHandlerTests.cs rename to ReadLine.Tests/KeyHandlerTests.cs index 30705e1..4a48dad 100644 --- a/test/ReadLine.Tests/KeyHandlerTests.cs +++ b/ReadLine.Tests/KeyHandlerTests.cs @@ -1,23 +1,25 @@ using System; using System.Collections.Generic; using System.Linq; +using NUnit.Framework; using ReadLine.Abstractions; using ReadLine.Tests.Abstractions; -using Xunit; using static ReadLine.Tests.ConsoleKeyInfoExtensions; namespace ReadLine.Tests { + [TestFixture] public class KeyHandlerTests { private KeyHandler _keyHandler; - private readonly List _history; - private readonly AutoCompleteHandler _autoCompleteHandler; - private readonly string[] _completions; - private readonly IConsole _console; + private List _history; + private AutoCompleteHandler _autoCompleteHandler; + private string[] _completions; + private IConsole _console; - public KeyHandlerTests() + [SetUp] + public void Initialize() { _autoCompleteHandler = new AutoCompleteHandler(); _completions = _autoCompleteHandler.GetSuggestions("", 0); @@ -31,59 +33,65 @@ public KeyHandlerTests() .ForEach(_keyHandler.Handle); } - [Fact] + [Test] public void TestWriteChar() { - Assert.Equal("Hello", _keyHandler.Text); + Assert.AreEqual("Hello", _keyHandler.Text); " World".Select(c => c.ToConsoleKeyInfo()) .ToList() .ForEach(_keyHandler.Handle); - Assert.Equal("Hello World", _keyHandler.Text); + Assert.AreEqual("Hello World", _keyHandler.Text); } - [Fact] + [Test] public void TestBackspace() { _keyHandler.Handle(Backspace); - Assert.Equal("Hell", _keyHandler.Text); + Assert.AreEqual("Hell", _keyHandler.Text); } - [Fact] + [Test] public void TestDelete() { new List() { LeftArrow, Delete } .ForEach(_keyHandler.Handle); - Assert.Equal("Hell", _keyHandler.Text); + Assert.AreEqual("Hell", _keyHandler.Text); } - [Fact] + [Test] public void TestDelete_EndOfLine() { _keyHandler.Handle(Delete); - Assert.Equal("Hello", _keyHandler.Text); + Assert.AreEqual("Hello", _keyHandler.Text); } - [Fact] + [Test] + public void TestControlC() { + //_keyHandler.Handle(CtrlC); + Assert.Ignore("Unable to test."); + } + + [Test] public void TestControlH() { _keyHandler.Handle(CtrlH); - Assert.Equal("Hell", _keyHandler.Text); + Assert.AreEqual("Hell", _keyHandler.Text); } - [Fact] + [Test] public void TestControlT() { var initialCursorCol = _console.CursorLeft; _keyHandler.Handle(CtrlT); - Assert.Equal("Helol", _keyHandler.Text); - Assert.Equal(initialCursorCol, _console.CursorLeft); + Assert.AreEqual("Helol", _keyHandler.Text); + Assert.AreEqual(initialCursorCol, _console.CursorLeft); } - [Fact] + [Test] public void TestControlT_LeftOnce_CursorMovesToEnd() { var initialCursorCol = _console.CursorLeft; @@ -91,11 +99,11 @@ public void TestControlT_LeftOnce_CursorMovesToEnd() new List() { LeftArrow, CtrlT } .ForEach(_keyHandler.Handle); - Assert.Equal("Helol", _keyHandler.Text); - Assert.Equal(initialCursorCol, _console.CursorLeft); + Assert.AreEqual("Helol", _keyHandler.Text); + Assert.AreEqual(initialCursorCol, _console.CursorLeft); } - [Fact] + [Test] public void TestControlT_CursorInMiddleOfLine() { Enumerable @@ -107,11 +115,11 @@ public void TestControlT_CursorInMiddleOfLine() _keyHandler.Handle(CtrlT); - Assert.Equal("Hlelo", _keyHandler.Text); - Assert.Equal(initialCursorCol + 1, _console.CursorLeft); + Assert.AreEqual("Hlelo", _keyHandler.Text); + Assert.AreEqual(initialCursorCol + 1, _console.CursorLeft); } - [Fact] + [Test] public void TestControlT_CursorAtBeginningOfLine_HasNoEffect() { _keyHandler.Handle(CtrlA); @@ -120,47 +128,47 @@ public void TestControlT_CursorAtBeginningOfLine_HasNoEffect() _keyHandler.Handle(CtrlT); - Assert.Equal("Hello", _keyHandler.Text); - Assert.Equal(initialCursorCol, _console.CursorLeft); + Assert.AreEqual("Hello", _keyHandler.Text); + Assert.AreEqual(initialCursorCol, _console.CursorLeft); } - [Fact] + [Test] public void TestHome() { new List() { Home, 'S'.ToConsoleKeyInfo() } .ForEach(_keyHandler.Handle); - Assert.Equal("SHello", _keyHandler.Text); + Assert.AreEqual("SHello", _keyHandler.Text); } - [Fact] + [Test] public void TestControlA() { new List() { CtrlA, 'S'.ToConsoleKeyInfo() } .ForEach(_keyHandler.Handle); - Assert.Equal("SHello", _keyHandler.Text); + Assert.AreEqual("SHello", _keyHandler.Text); } - [Fact] + [Test] public void TestEnd() { new List() { Home, End, ExclamationPoint } .ForEach(_keyHandler.Handle); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.AreEqual("Hello!", _keyHandler.Text); } - [Fact] + [Test] public void TestControlE() { new List() { CtrlA, CtrlE, ExclamationPoint } .ForEach(_keyHandler.Handle); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.AreEqual("Hello!", _keyHandler.Text); } - [Fact] + [Test] public void TestLeftArrow() { " N".Select(c => c.ToConsoleKeyInfo()) @@ -168,10 +176,10 @@ public void TestLeftArrow() .ToList() .ForEach(_keyHandler.Handle); - Assert.Equal("Hell No", _keyHandler.Text); + Assert.AreEqual("Hell No", _keyHandler.Text); } - [Fact] + [Test] public void TestControlB() { " N".Select(c => c.ToConsoleKeyInfo()) @@ -179,19 +187,19 @@ public void TestControlB() .ToList() .ForEach(_keyHandler.Handle); - Assert.Equal("Hell No", _keyHandler.Text); + Assert.AreEqual("Hell No", _keyHandler.Text); } - [Fact] + [Test] public void TestRightArrow() { new List() { LeftArrow, RightArrow, ExclamationPoint } .ForEach(_keyHandler.Handle); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.AreEqual("Hello!", _keyHandler.Text); } - [Fact] + [Test] public void TestControlD() { Enumerable.Repeat(LeftArrow, 4) @@ -199,44 +207,44 @@ public void TestControlD() .ToList() .ForEach(_keyHandler.Handle); - Assert.Equal("Hllo", _keyHandler.Text); + Assert.AreEqual("Hllo", _keyHandler.Text); } - [Fact] + [Test] public void TestControlF() { new List() { LeftArrow, CtrlF, ExclamationPoint } .ForEach(_keyHandler.Handle); - Assert.Equal("Hello!", _keyHandler.Text); + Assert.AreEqual("Hello!", _keyHandler.Text); } - [Fact] + [Test] public void TestControlL() { _keyHandler.Handle(CtrlL); - Assert.Equal(string.Empty, _keyHandler.Text); + Assert.AreEqual(string.Empty, _keyHandler.Text); } - [Fact] + [Test] public void TestUpArrow() { _history.AsEnumerable().Reverse().ToList().ForEach((history) => { _keyHandler.Handle(UpArrow); - Assert.Equal(history, _keyHandler.Text); + Assert.AreEqual(history, _keyHandler.Text); }); } - [Fact] + [Test] public void TestControlP() { _history.AsEnumerable().Reverse().ToList().ForEach((history) => { _keyHandler.Handle(CtrlP); - Assert.Equal(history, _keyHandler.Text); + Assert.AreEqual(history, _keyHandler.Text); }); } - [Fact] + [Test] public void TestDownArrow() { Enumerable.Repeat(UpArrow, _history.Count) @@ -244,12 +252,12 @@ public void TestDownArrow() .ForEach(_keyHandler.Handle); _history.ForEach( history => { - Assert.Equal(history, _keyHandler.Text); + Assert.AreEqual(history, _keyHandler.Text); _keyHandler.Handle(DownArrow); }); } - [Fact] + [Test] public void TestControlN() { Enumerable.Repeat(UpArrow, _history.Count) @@ -257,40 +265,40 @@ public void TestControlN() .ForEach(_keyHandler.Handle); _history.ForEach( history => { - Assert.Equal(history, _keyHandler.Text); + Assert.AreEqual(history, _keyHandler.Text); _keyHandler.Handle(CtrlN); }); } - [Fact] + [Test] public void TestControlU() { _keyHandler.Handle(LeftArrow); _keyHandler.Handle(CtrlU); - Assert.Equal("o", _keyHandler.Text); + Assert.AreEqual("o", _keyHandler.Text); _keyHandler.Handle(End); _keyHandler.Handle(CtrlU); - Assert.Equal(string.Empty, _keyHandler.Text); + Assert.AreEqual(string.Empty, _keyHandler.Text); } - [Fact] + [Test] public void TestControlK() { _keyHandler.Handle(LeftArrow); _keyHandler.Handle(CtrlK); - Assert.Equal("Hell", _keyHandler.Text); + Assert.AreEqual("Hell", _keyHandler.Text); _keyHandler.Handle(Home); _keyHandler.Handle(CtrlK); - Assert.Equal(string.Empty, _keyHandler.Text); + Assert.AreEqual(string.Empty, _keyHandler.Text); } - [Fact] + [Test] public void TestControlW() { " World".Select(c => c.ToConsoleKeyInfo()) @@ -298,20 +306,20 @@ public void TestControlW() .ToList() .ForEach(_keyHandler.Handle); - Assert.Equal("Hello ", _keyHandler.Text); + Assert.AreEqual("Hello ", _keyHandler.Text); _keyHandler.Handle(Backspace); _keyHandler.Handle(CtrlW); - Assert.Equal(string.Empty, _keyHandler.Text); + Assert.AreEqual(string.Empty, _keyHandler.Text); } - [Fact] + [Test] public void TestTab() { _keyHandler.Handle(Tab); // Nothing happens when no auto complete handler is set - Assert.Equal("Hello", _keyHandler.Text); + Assert.AreEqual("Hello", _keyHandler.Text); _keyHandler = new KeyHandler(new Console2(), _history, _autoCompleteHandler); @@ -319,17 +327,17 @@ public void TestTab() _completions.ToList().ForEach(completion => { _keyHandler.Handle(Tab); - Assert.Equal($"Hi {completion}", _keyHandler.Text); + Assert.AreEqual($"Hi {completion}", _keyHandler.Text); }); } - [Fact] + [Test] public void TestBackwardsTab() { _keyHandler.Handle(Tab); // Nothing happens when no auto complete handler is set - Assert.Equal("Hello", _keyHandler.Text); + Assert.AreEqual("Hello", _keyHandler.Text); _keyHandler = new KeyHandler(new Console2(), _history, _autoCompleteHandler); @@ -340,17 +348,17 @@ public void TestBackwardsTab() _completions.Reverse().ToList().ForEach(completion => { _keyHandler.Handle(ShiftTab); - Assert.Equal($"Hi {completion}", _keyHandler.Text); + Assert.AreEqual($"Hi {completion}", _keyHandler.Text); }); } - [Fact] + [Test] public void MoveCursorThenPreviousHistory() { _keyHandler.Handle(LeftArrow); _keyHandler.Handle(UpArrow); - Assert.Equal("clear", _keyHandler.Text); + Assert.AreEqual("clear", _keyHandler.Text); } } } \ No newline at end of file diff --git a/ReadLine.Tests/ReadLine.Tests.csproj b/ReadLine.Tests/ReadLine.Tests.csproj new file mode 100644 index 0000000..568a4fb --- /dev/null +++ b/ReadLine.Tests/ReadLine.Tests.csproj @@ -0,0 +1,22 @@ + + + + net472 + ReadLine.Tests + ReadLine.Tests + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/ReadLine.Tests/ReadLineTests.cs b/ReadLine.Tests/ReadLineTests.cs new file mode 100644 index 0000000..f07e200 --- /dev/null +++ b/ReadLine.Tests/ReadLineTests.cs @@ -0,0 +1,51 @@ +using System.Linq; +using NUnit.Framework; + + +namespace ReadLine.Tests +{ + [TestFixture] + public class ReadLineTests + { + private readonly IReadLine _readLine = ReadLine.Instance; + private static readonly string[] History = { "ls -a", "dotnet run", "git init" }; + + [SetUp] + public void Initialize() { + _readLine.AddHistory(History); + } + + [TearDown] + public void Destruct() { + _readLine.ClearHistory(); + } + + [Test] + public void TestClearHistory() { + _readLine.ClearHistory(); + Assert.AreEqual(0, _readLine.GetHistory().Count); + } + + [Test] + public void TestNoInitialHistory() + { + Assert.AreEqual(3, _readLine.GetHistory().Count); + } + + [Test] + public void TestUpdatesHistory() + { + _readLine.AddHistory("mkdir"); + Assert.AreEqual(4, _readLine.GetHistory().Count); + Assert.AreEqual("mkdir", _readLine.GetHistory().Last()); + } + + [Test] + public void TestGetCorrectHistory() + { + Assert.AreEqual("ls -a", _readLine.GetHistory()[0]); + Assert.AreEqual("dotnet run", _readLine.GetHistory()[1]); + Assert.AreEqual("git init", _readLine.GetHistory()[2]); + } + } +} diff --git a/ReadLine.sln b/ReadLine.sln index d0fa19b..489bf7c 100755 --- a/ReadLine.sln +++ b/ReadLine.sln @@ -2,15 +2,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27130.2036 MinimumVisualStudioVersion = 15.0.26124.0 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{06FC0E85-E73C-4DC1-B6FD-A583B7B1DFE4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine", "ReadLine\ReadLine.csproj", "{9EB290C9-BB52-4B24-9779-5A816AC75E18}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine", "src\ReadLine\ReadLine.csproj", "{9EB290C9-BB52-4B24-9779-5A816AC75E18}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine.Demo", "ReadLine.Demo\ReadLine.Demo.csproj", "{4C512FD1-A0E8-4908-B0A4-B0D85947716A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine.Demo", "src\ReadLine.Demo\ReadLine.Demo.csproj", "{4C512FD1-A0E8-4908-B0A4-B0D85947716A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{38C56AEB-DB08-4CBF-AAC0-EBFC2B0EE045}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine.Tests", "test\ReadLine.Tests\ReadLine.Tests.csproj", "{631582D9-EEEA-4F9D-8069-71ECA24ED282}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadLine.Tests", "ReadLine.Tests\ReadLine.Tests.csproj", "{631582D9-EEEA-4F9D-8069-71ECA24ED282}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/ReadLine/Abstractions/Console2.cs b/ReadLine/Abstractions/Console2.cs similarity index 100% rename from src/ReadLine/Abstractions/Console2.cs rename to ReadLine/Abstractions/Console2.cs diff --git a/src/ReadLine/Abstractions/IConsole.cs b/ReadLine/Abstractions/IConsole.cs similarity index 100% rename from src/ReadLine/Abstractions/IConsole.cs rename to ReadLine/Abstractions/IConsole.cs diff --git a/src/ReadLine/IAutoCompleteHandler.cs b/ReadLine/IAutoCompleteHandler.cs similarity index 100% rename from src/ReadLine/IAutoCompleteHandler.cs rename to ReadLine/IAutoCompleteHandler.cs diff --git a/ReadLine/IReadLine.cs b/ReadLine/IReadLine.cs new file mode 100644 index 0000000..e7ab988 --- /dev/null +++ b/ReadLine/IReadLine.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace ReadLine { + public interface IReadLine { + IAutoCompleteHandler AutoCompletionHandler { get; set; } + void AddHistory(params string[] text); + List GetHistory(); + void ClearHistory(); + string Read(string prompt = "", string @default = ""); + string ReadPassword(string prompt = ""); + } +} diff --git a/src/ReadLine/KeyHandler.cs b/ReadLine/KeyHandler.cs similarity index 96% rename from src/ReadLine/KeyHandler.cs rename to ReadLine/KeyHandler.cs index 075700e..5fb3824 100644 --- a/src/ReadLine/KeyHandler.cs +++ b/ReadLine/KeyHandler.cs @@ -1,355 +1,356 @@ -using System; -using System.Collections.Generic; -using System.Text; -using ReadLine.Abstractions; - - -namespace ReadLine -{ - public class KeyHandler - { - private readonly IConsole _console2; - private readonly List _history; - private readonly Dictionary _keyActions; - private readonly StringBuilder _text; - private string[] _completions; - private int _completionsIndex; - private int _completionStart; - private int _cursorLimit; - private int _cursorPos; - private int _historyIndex; - private ConsoleKeyInfo _keyInfo; - - public KeyHandler(IConsole console, List history, IAutoCompleteHandler autoCompleteHandler) - { - _console2 = console; - - _history = history ?? new List(); - _historyIndex = _history.Count; - _text = new StringBuilder(); - _keyActions = new Dictionary - { - ["LeftArrow"] = MoveCursorLeft, - ["Home"] = MoveCursorHome, - ["End"] = MoveCursorEnd, - ["ControlA"] = MoveCursorHome, - ["ControlB"] = MoveCursorLeft, - ["RightArrow"] = MoveCursorRight, - ["ControlF"] = MoveCursorRight, - ["ControlE"] = MoveCursorEnd, - ["Backspace"] = Backspace, - ["Delete"] = Delete, - ["ControlD"] = Delete, - ["ControlH"] = Backspace, - ["ControlL"] = ClearLine, - ["Escape"] = ClearLine, - ["UpArrow"] = PrevHistory, - ["ControlP"] = PrevHistory, - ["DownArrow"] = NextHistory, - ["ControlN"] = NextHistory, - ["ControlU"] = () => { Backspace(_cursorPos); }, - ["ControlK"] = () => - { - var pos = _cursorPos; - MoveCursorEnd(); - Backspace(_cursorPos - pos); - }, - ["ControlW"] = () => - { - while (!IsStartOfLine() && _text[_cursorPos - 1] != ' ') - Backspace(); - }, - ["ControlT"] = TransposeChars, - ["Tab"] = () => - { - if (IsInAutoCompleteMode()) - { - NextAutoComplete(); - } - else - { - if (autoCompleteHandler == null || !IsEndOfLine()) - return; - - var text = _text.ToString(); - - _completionStart = text.LastIndexOfAny(autoCompleteHandler.Separators); - _completionStart = _completionStart == -1 ? 0 : _completionStart + 1; - - _completions = autoCompleteHandler.GetSuggestions(text, _completionStart); - _completions = _completions?.Length == 0 ? null : _completions; - - if (_completions == null) - return; - - StartAutoComplete(); - } - }, - ["ShiftTab"] = () => - { - if (IsInAutoCompleteMode()) - PreviousAutoComplete(); - } - }; - } - - - public string Text => _text.ToString(); - - - private bool IsStartOfLine() => _cursorPos == 0; - - - private bool IsEndOfLine() => _cursorPos == _cursorLimit; - - - private bool IsStartOfBuffer() => _console2.CursorLeft == 0; - - - private bool IsEndOfBuffer() => _console2.CursorLeft == _console2.BufferWidth - 1; - - - private bool IsInAutoCompleteMode() => _completions != null; - - - private void MoveCursorLeft() => MoveCursorLeft(1); - - private void MoveCursorLeft(int count) - { - if (count > _cursorPos) - count = _cursorPos; - - if (count > _console2.CursorLeft) - _console2.SetCursorPosition(_console2.BufferWidth - 1, _console2.CursorTop - 1); - else - _console2.SetCursorPosition(_console2.CursorLeft - 1, _console2.CursorTop); - - _cursorPos -= count; - } - - - private void MoveCursorHome() - { - while (!IsStartOfLine()) - MoveCursorLeft(); - } - - - private string BuildKeyInput() => _keyInfo.Modifiers != ConsoleModifiers.Control && _keyInfo.Modifiers != ConsoleModifiers.Shift ? _keyInfo.Key.ToString() : _keyInfo.Modifiers + _keyInfo.Key.ToString(); - - - private void MoveCursorRight() - { - if (IsEndOfLine()) - return; - - if (IsEndOfBuffer()) - _console2.SetCursorPosition(0, _console2.CursorTop + 1); - else - _console2.SetCursorPosition(_console2.CursorLeft + 1, _console2.CursorTop); - - _cursorPos++; - } - - - private void MoveCursorEnd() - { - while (!IsEndOfLine()) - MoveCursorRight(); - } - - - private void ClearLine() - { - MoveCursorEnd(); - Backspace(_cursorPos); - } - - - private void WriteNewString(string str) - { - ClearLine(); - WriteString(str); - } - - - private void WriteString(string str) - { - foreach (var character in str) - WriteChar(character); - } - - - private void WriteChar() => WriteChar(_keyInfo.KeyChar); - - - private void WriteChar(char c) - { - if (IsEndOfLine()) - { - _text.Append(c); - _console2.Write(c.ToString()); - _cursorPos++; - } - else - { - var left = _console2.CursorLeft; - var top = _console2.CursorTop; - var str = _text.ToString().Substring(_cursorPos); - _text.Insert(_cursorPos, c); - _console2.Write(c + str); - _console2.SetCursorPosition(left, top); - MoveCursorRight(); - } - - _cursorLimit++; - } - - - private void Backspace() => Backspace(1); - - private void Backspace(int count) - { - if (count > _cursorPos) - count = _cursorPos; - - MoveCursorLeft(count); - var index = _cursorPos; - _text.Remove(index, count); - var replacement = _text.ToString().Substring(index); - var left = _console2.CursorLeft; - var top = _console2.CursorTop; - var spaces = new string(' ', count); - _console2.Write($"{replacement}{spaces}"); - _console2.SetCursorPosition(left, top); - _cursorLimit -= count; - } - - - private void Delete() - { - if (IsEndOfLine()) - return; - - var index = _cursorPos; - _text.Remove(index, 1); - var replacement = _text.ToString().Substring(index); - var left = _console2.CursorLeft; - var top = _console2.CursorTop; - _console2.Write($"{replacement} "); - _console2.SetCursorPosition(left, top); - _cursorLimit--; - } - - - private void TransposeChars() - { - // local helper functions - bool AlmostEndOfLine() => _cursorLimit - _cursorPos == 1; - - int IncrementIf(Func expression, int index) => expression() ? index + 1 : index; - - int DecrementIf(Func expression, int index) => expression() ? index - 1 : index; - - if (IsStartOfLine()) - return; - - var firstIdx = DecrementIf(IsEndOfLine, _cursorPos - 1); - var secondIdx = DecrementIf(IsEndOfLine, _cursorPos); - - var secondChar = _text[secondIdx]; - _text[secondIdx] = _text[firstIdx]; - _text[firstIdx] = secondChar; - - var left = IncrementIf(AlmostEndOfLine, _console2.CursorLeft); - var cursorPosition = IncrementIf(AlmostEndOfLine, _cursorPos); - - WriteNewString(_text.ToString()); - - _console2.SetCursorPosition(left, _console2.CursorTop); - _cursorPos = cursorPosition; - - MoveCursorRight(); - } - - - private void StartAutoComplete() - { - Backspace(_cursorPos - _completionStart); - - _completionsIndex = 0; - - WriteString(_completions[_completionsIndex]); - } - - - private void NextAutoComplete() - { - Backspace(_cursorPos - _completionStart); - - _completionsIndex++; - - if (_completionsIndex == _completions.Length) - _completionsIndex = 0; - - WriteString(_completions[_completionsIndex]); - } - - - private void PreviousAutoComplete() - { - Backspace(_cursorPos - _completionStart); - - _completionsIndex--; - - if (_completionsIndex == -1) - _completionsIndex = _completions.Length - 1; - - WriteString(_completions[_completionsIndex]); - } - - - private void PrevHistory() - { - if (_historyIndex > 0) - { - _historyIndex--; - WriteNewString(_history[_historyIndex]); - } - } - - - private void NextHistory() - { - if (_historyIndex < _history.Count) - { - _historyIndex++; - if (_historyIndex == _history.Count) - ClearLine(); - else - WriteNewString(_history[_historyIndex]); - } - } - - - private void ResetAutoComplete() - { - _completions = null; - _completionsIndex = 0; - } - - - public void Handle(ConsoleKeyInfo keyInfo) - { - _keyInfo = keyInfo; - - // If in auto complete mode and Tab wasn't pressed - if (IsInAutoCompleteMode() && _keyInfo.Key != ConsoleKey.Tab) - ResetAutoComplete(); - - _keyActions.TryGetValue(BuildKeyInput(), out var action); - action = action ?? WriteChar; - action.Invoke(); - } - } +using System; +using System.Collections.Generic; +using System.Text; +using ReadLine.Abstractions; + + +namespace ReadLine +{ + public class KeyHandler + { + private readonly IConsole _console2; + private readonly List _history; + private readonly Dictionary _keyActions; + private readonly StringBuilder _text; + private string[] _completions; + private int _completionsIndex; + private int _completionStart; + private int _cursorLimit; + private int _cursorPos; + private int _historyIndex; + private ConsoleKeyInfo _keyInfo; + + public KeyHandler(IConsole console, List history, IAutoCompleteHandler autoCompleteHandler) + { + _console2 = console; + + _history = history ?? new List(); + _historyIndex = _history.Count; + _text = new StringBuilder(); + _keyActions = new Dictionary + { + ["LeftArrow"] = MoveCursorLeft, + ["Home"] = MoveCursorHome, + ["End"] = MoveCursorEnd, + ["ControlA"] = MoveCursorHome, + ["ControlB"] = MoveCursorLeft, + ["ControlC"] = () => Environment.Exit(0), + ["RightArrow"] = MoveCursorRight, + ["ControlF"] = MoveCursorRight, + ["ControlE"] = MoveCursorEnd, + ["Backspace"] = Backspace, + ["Delete"] = Delete, + ["ControlD"] = Delete, + ["ControlH"] = Backspace, + ["ControlL"] = ClearLine, + ["Escape"] = ClearLine, + ["UpArrow"] = PrevHistory, + ["ControlP"] = PrevHistory, + ["DownArrow"] = NextHistory, + ["ControlN"] = NextHistory, + ["ControlU"] = () => { Backspace(_cursorPos); }, + ["ControlK"] = () => + { + var pos = _cursorPos; + MoveCursorEnd(); + Backspace(_cursorPos - pos); + }, + ["ControlW"] = () => + { + while (!IsStartOfLine() && _text[_cursorPos - 1] != ' ') + Backspace(); + }, + ["ControlT"] = TransposeChars, + ["Tab"] = () => + { + if (IsInAutoCompleteMode()) + { + NextAutoComplete(); + } + else + { + if (autoCompleteHandler == null || !IsEndOfLine()) + return; + + var text = _text.ToString(); + + _completionStart = text.LastIndexOfAny(autoCompleteHandler.Separators); + _completionStart = _completionStart == -1 ? 0 : _completionStart + 1; + + _completions = autoCompleteHandler.GetSuggestions(text, _completionStart); + _completions = _completions?.Length == 0 ? null : _completions; + + if (_completions == null) + return; + + StartAutoComplete(); + } + }, + ["ShiftTab"] = () => + { + if (IsInAutoCompleteMode()) + PreviousAutoComplete(); + } + }; + } + + + public string Text => _text.ToString(); + + + private bool IsStartOfLine() => _cursorPos == 0; + + + private bool IsEndOfLine() => _cursorPos == _cursorLimit; + + + private bool IsStartOfBuffer() => _console2.CursorLeft == 0; + + + private bool IsEndOfBuffer() => _console2.CursorLeft == _console2.BufferWidth - 1; + + + private bool IsInAutoCompleteMode() => _completions != null; + + + private void MoveCursorLeft() => MoveCursorLeft(1); + + private void MoveCursorLeft(int count) + { + if (count > _cursorPos) + count = _cursorPos; + + if (count > _console2.CursorLeft) + _console2.SetCursorPosition(_console2.BufferWidth - 1, _console2.CursorTop - 1); + else + _console2.SetCursorPosition(_console2.CursorLeft - 1, _console2.CursorTop); + + _cursorPos -= count; + } + + + private void MoveCursorHome() + { + while (!IsStartOfLine()) + MoveCursorLeft(); + } + + + private string BuildKeyInput() => _keyInfo.Modifiers != ConsoleModifiers.Control && _keyInfo.Modifiers != ConsoleModifiers.Shift ? _keyInfo.Key.ToString() : _keyInfo.Modifiers + _keyInfo.Key.ToString(); + + + private void MoveCursorRight() + { + if (IsEndOfLine()) + return; + + if (IsEndOfBuffer()) + _console2.SetCursorPosition(0, _console2.CursorTop + 1); + else + _console2.SetCursorPosition(_console2.CursorLeft + 1, _console2.CursorTop); + + _cursorPos++; + } + + + private void MoveCursorEnd() + { + while (!IsEndOfLine()) + MoveCursorRight(); + } + + + private void ClearLine() + { + MoveCursorEnd(); + Backspace(_cursorPos); + } + + + private void WriteNewString(string str) + { + ClearLine(); + WriteString(str); + } + + + private void WriteString(string str) + { + foreach (var character in str) + WriteChar(character); + } + + + private void WriteChar() => WriteChar(_keyInfo.KeyChar); + + + private void WriteChar(char c) + { + if (IsEndOfLine()) + { + _text.Append(c); + _console2.Write(c.ToString()); + _cursorPos++; + } + else + { + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + var str = _text.ToString().Substring(_cursorPos); + _text.Insert(_cursorPos, c); + _console2.Write(c + str); + _console2.SetCursorPosition(left, top); + MoveCursorRight(); + } + + _cursorLimit++; + } + + + private void Backspace() => Backspace(1); + + private void Backspace(int count) + { + if (count > _cursorPos) + count = _cursorPos; + + MoveCursorLeft(count); + var index = _cursorPos; + _text.Remove(index, count); + var replacement = _text.ToString().Substring(index); + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + var spaces = new string(' ', count); + _console2.Write($"{replacement}{spaces}"); + _console2.SetCursorPosition(left, top); + _cursorLimit -= count; + } + + + private void Delete() + { + if (IsEndOfLine()) + return; + + var index = _cursorPos; + _text.Remove(index, 1); + var replacement = _text.ToString().Substring(index); + var left = _console2.CursorLeft; + var top = _console2.CursorTop; + _console2.Write($"{replacement} "); + _console2.SetCursorPosition(left, top); + _cursorLimit--; + } + + + private void TransposeChars() + { + // local helper functions + bool AlmostEndOfLine() => _cursorLimit - _cursorPos == 1; + + int IncrementIf(Func expression, int index) => expression() ? index + 1 : index; + + int DecrementIf(Func expression, int index) => expression() ? index - 1 : index; + + if (IsStartOfLine()) + return; + + var firstIdx = DecrementIf(IsEndOfLine, _cursorPos - 1); + var secondIdx = DecrementIf(IsEndOfLine, _cursorPos); + + var secondChar = _text[secondIdx]; + _text[secondIdx] = _text[firstIdx]; + _text[firstIdx] = secondChar; + + var left = IncrementIf(AlmostEndOfLine, _console2.CursorLeft); + var cursorPosition = IncrementIf(AlmostEndOfLine, _cursorPos); + + WriteNewString(_text.ToString()); + + _console2.SetCursorPosition(left, _console2.CursorTop); + _cursorPos = cursorPosition; + + MoveCursorRight(); + } + + + private void StartAutoComplete() + { + Backspace(_cursorPos - _completionStart); + + _completionsIndex = 0; + + WriteString(_completions[_completionsIndex]); + } + + + private void NextAutoComplete() + { + Backspace(_cursorPos - _completionStart); + + _completionsIndex++; + + if (_completionsIndex == _completions.Length) + _completionsIndex = 0; + + WriteString(_completions[_completionsIndex]); + } + + + private void PreviousAutoComplete() + { + Backspace(_cursorPos - _completionStart); + + _completionsIndex--; + + if (_completionsIndex == -1) + _completionsIndex = _completions.Length - 1; + + WriteString(_completions[_completionsIndex]); + } + + + private void PrevHistory() + { + if (_historyIndex > 0) + { + _historyIndex--; + WriteNewString(_history[_historyIndex]); + } + } + + + private void NextHistory() + { + if (_historyIndex < _history.Count) + { + _historyIndex++; + if (_historyIndex == _history.Count) + ClearLine(); + else + WriteNewString(_history[_historyIndex]); + } + } + + + private void ResetAutoComplete() + { + _completions = null; + _completionsIndex = 0; + } + + + public void Handle(ConsoleKeyInfo keyInfo) + { + _keyInfo = keyInfo; + + // If in auto complete mode and Tab wasn't pressed + if (IsInAutoCompleteMode() && _keyInfo.Key != ConsoleKey.Tab) + ResetAutoComplete(); + + _keyActions.TryGetValue(BuildKeyInput(), out var action); + action = action ?? WriteChar; + action.Invoke(); + } + } } \ No newline at end of file diff --git a/src/ReadLine/ReadLine.cs b/ReadLine/ReadLine.cs old mode 100755 new mode 100644 similarity index 61% rename from src/ReadLine/ReadLine.cs rename to ReadLine/ReadLine.cs index 0bb765e..434744a --- a/src/ReadLine/ReadLine.cs +++ b/ReadLine/ReadLine.cs @@ -5,27 +5,29 @@ namespace ReadLine { - public static class ReadLine + public class ReadLine : IReadLine { - private static List _history; + private List _history; + private ReadLine() { + _history = new List(); + } - static ReadLine() => _history = new List(); - + public static ReadLine Instance = new ReadLine(); // Singleton implementation - public static IAutoCompleteHandler AutoCompletionHandler { private get; set; } + public IAutoCompleteHandler AutoCompletionHandler { get; set; } - public static void AddHistory(params string[] text) => _history.AddRange(text); + public void AddHistory(params string[] text) => _history.AddRange(text); - public static List GetHistory() => _history; + public List GetHistory() => _history; - public static void ClearHistory() => _history = new List(); + public void ClearHistory() => _history = new List(); - public static string Read(string prompt = "", string @default = "") + public string Read(string prompt = "", string @default = "") { Console.Write(prompt); var keyHandler = new KeyHandler(new Console2(), _history, AutoCompletionHandler); @@ -40,7 +42,7 @@ public static string Read(string prompt = "", string @default = "") } - public static string ReadPassword(string prompt = "") + public string ReadPassword(string prompt = "") { Console.Write(prompt); var keyHandler = new KeyHandler(new Console2 @@ -53,6 +55,8 @@ public static string ReadPassword(string prompt = "") private static string GetText(KeyHandler keyHandler) { + Console.TreatControlCAsInput = true; + var keyInfo = Console.ReadKey(true); while (keyInfo.Key != ConsoleKey.Enter) { diff --git a/src/ReadLine/ReadLine.csproj b/ReadLine/ReadLine.csproj old mode 100755 new mode 100644 similarity index 98% rename from src/ReadLine/ReadLine.csproj rename to ReadLine/ReadLine.csproj index 88d7801..b23b06a --- a/src/ReadLine/ReadLine.csproj +++ b/ReadLine/ReadLine.csproj @@ -13,7 +13,7 @@ snKey.snk true Updated to support .NET Standard v2.0 / Core 2.2 & 3.0 / Framework v4.5 - v4.8 - 2.0.3 + 2.1.3 A GNU-Readline like library for .NET artifacts MIT diff --git a/src/ReadLine/snKey.snk b/ReadLine/snKey.snk similarity index 100% rename from src/ReadLine/snKey.snk rename to ReadLine/snKey.snk diff --git a/artifacts/ReadLine.2.0.3.nupkg b/artifacts/ReadLine.2.0.3.nupkg deleted file mode 100644 index 2538e1bf5992b42b40741fc7ecc23bab9d3eb5fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41824 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 k$K - - - netcoreapp2.1 - portable - ReadLine.Tests - ReadLine.Tests - true - - - - - - - - - - - diff --git a/test/ReadLine.Tests/ReadLineTests.cs b/test/ReadLine.Tests/ReadLineTests.cs deleted file mode 100755 index 2b8cfdc..0000000 --- a/test/ReadLine.Tests/ReadLineTests.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Linq; -using Xunit; -using static ReadLine.ReadLine; - - -namespace ReadLine.Tests -{ - public class ReadLineTests : IDisposable - { - public ReadLineTests() - { - string[] history = { "ls -a", "dotnet run", "git init" }; - AddHistory(history); - } - - [Fact] - public void TestNoInitialHistory() - { - Assert.Equal(3, GetHistory().Count); - } - - [Fact] - public void TestUpdatesHistory() - { - AddHistory("mkdir"); - Assert.Equal(4, GetHistory().Count); - Assert.Equal("mkdir", GetHistory().Last()); - } - - [Fact] - public void TestGetCorrectHistory() - { - Assert.Equal("ls -a", GetHistory()[0]); - Assert.Equal("dotnet run", GetHistory()[1]); - Assert.Equal("git init", GetHistory()[2]); - } - - public void Dispose() - { - // If all above tests pass - // clear history works - ClearHistory(); - } - } -} From ccc6d074f681248b198bcdf9504727a0be95959d Mon Sep 17 00:00:00 2001 From: Latency McLaughlin Date: Wed, 18 Mar 2020 16:46:48 -0700 Subject: [PATCH 21/21] Added missing member to interface IConsole.cs --- .github/workflows/dotnetcore.yml | 21 --------------------- .gitignore | 5 ++++- Artifacts/ReadLine.2.1.3.nupkg | Bin 43617 -> 0 bytes Artifacts/ReadLine.2.1.4.nupkg | Bin 0 -> 43750 bytes ReadLine.Tests/Abstractions/Console2.cs | 2 ++ ReadLine/Abstractions/IConsole.cs | 1 + ReadLine/ReadLine.csproj | 2 +- 7 files changed, 8 insertions(+), 23 deletions(-) delete mode 100644 .github/workflows/dotnetcore.yml delete mode 100644 Artifacts/ReadLine.2.1.3.nupkg create mode 100644 Artifacts/ReadLine.2.1.4.nupkg diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml deleted file mode 100644 index d243b1f..0000000 --- a/.github/workflows/dotnetcore.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: .NET Core - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Setup .NET Core - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 3.1.101 - - name: Build with dotnet - run: dotnet build --configuration Release diff --git a/.gitignore b/.gitignore index 69d95ef..89a2bca 100644 --- a/.gitignore +++ b/.gitignore @@ -217,4 +217,7 @@ project.lock.json # Advanced Installer *-cache/ -*-SetupFiles/ \ No newline at end of file +*-SetupFiles/ + +# GitHub +.github/* \ No newline at end of file diff --git a/Artifacts/ReadLine.2.1.3.nupkg b/Artifacts/ReadLine.2.1.3.nupkg deleted file mode 100644 index 1bde9315b8d16e3899cb46849823d56d326c2ed1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43617 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

-|0|ociE3^00Cu zRf&+1;QXb|Lg@d7n)OgLK&2lQ7-pJ8$bg+vNdiRMnDa3*I(0B*H}0d z_WLQmdzLp@_03L9d_xyV+2}lX8mx8ze3wLAOiYv|riBSg+V$qtQqR6}n$qRqzEqI?iNTVj4}! zzS1(+G;)>fy%LvV0*$0%sHh^OT~Dtp4IONa1ctG<1f6z@bqQx|+iLw0nBB`-3F7p1QxNF$ZZkPFE9EWL4_A z*j3}Ra)evr{?rw~FkLc~H7H<-4MU%9B~DHZLRUzi$GS?KU@=|D_s8|W)thVwOA;ar z3|iqtkAzVIi|Cc%mx{h0hUY`dF04A8frq&4t!175Ai+r6fl*5~qYXb4 zNqsWVocRQYp^$W?{^%q<`ieFs}y{%fQ~P3@CY{3#SUBAZGP~NV~Bm`*>H1j?*Y&U8Ba5%#jXJb7U|f zq_8I2?AS(jyq8X{v#1#1MY->+3E+G6>=+|(tjP_Mz!%m1x#4+3AlWB!{iTH)e7l7C znL*={IxOqNRFSOz+O8(r_H*^~@Zd$N_oCU|`|(EFhxsa`)5#2- z!`zP&0}tGj$l5TLBQkdU?A=bG}A!py4a z8nHaeCc)$~<6ZDjh0i4Kl2BX>dANZ`1@$kt(Pk&Ow7)Vx}dG zXA>Q4S858x#@H>=8-3(*%;D~Y{dqC=jI8Zx!Ew3fFp<#sf}w(pe1CG&D?QZd2ZF}L=3wdxMZBEsW{J#UT7-3h0Dmkf|O*{NDN^SsYK z)3lu_cgeWlLo^Kx^u4=T{j-ZyzsJiyX1~-H`h0ub16BuS>CPi9S}Y$ID6N=A!>7R~ zt*8aC@o&f6N)aD6E^=Ph(}ccN?}JBPDrLo|aR0(;BVxb#wXw4t#G7HuXq{_H>oL?P zL{4R7Sq9BANhW0G%kBD7)@V*(N6#VLZ#euSR~{oM@LF(hY)e#2w--l`A}0=i8@@7T zE&kXSgY2jK`i{Vw=p4JjUs4iV2@T?Ka{ft(O*M}@2rGaXK5$^D7`XVTnk&Y%MrfQ0ur-0F9W zZ%pqAZ-#yf_LppM?8S!d$g$U5Z*etHdZ4JM)(BI3Dt_*(~hK=q`T(pSWR@!`=-2J z$e(XF=#ofk)K)JHJ9TXy7vJhupEl>-9`oAXDz6toM(*5RLtmPp-7d_IMRv}WEl-%z zXX_lEqdfiqGwhA7!c3-fi_C60d9wOA;_Fe`#J|S#u6^-saboIdF4p7dHakPJc)I^q zd6!Wfu68$nyT&>9$LHsA&52b43x_CrzPpp>aC&&JZ&%Sma3ZRi@oL2lHCBr8T`f!j zZw5u8ZUV+GE^{ii%ocO}gdUtAHU4)AiLeeUN!OwLk@dugg9zip)#T4lp6kve@;CjM zb(*HP2I?&wFS08jWw9+5eoIX=h>>T(y>QgJv5=d3Lvtzig#=7co(->(RKcG$;_hTM zFZ2sOaJ=rsSI|n@;l-m-VIjzl6RPXSqyYITCj}=lDOg5UrUic%ieK(HfSB1eE^U+8Sz#L*D^$~F z2y|AA#Pu`*dQY6NTv_6uo&ypm_WftuRmf?r`(|98$L4*0EB@|FU`G{gpekuxfcg!Dj!q8*p^tQ!p&JgC{yqN&m1{4na=!rF!v3Y&(b? zI)oc4mhv~q8uMOuoFxa&)%*BulPRB7^G}Zg=({LpzB<1mt^NzgS&(#00`H4)(hLg# zi4)r3mnzxJ=rQS-^>1M_T*n!^9T9AEZ zn5O2xk~=EHuj(mR1-j4QdS-|`=B$=#IqUENA2!C^+kch3-*r3=@|k4)|EuG4l+^!o z2d?tpI-Vp~}9|cg=gLfX7QcUDee%821N{Hv_%LPB2#=-(x2a@3E8pf#ks4R$|kD2%=-F_Zj%T zo)dk#NK(>y5NvI}%myFna*Zi9n{foHblaNZ-ag7c=zc7M)7>UTx#7(#ddXL0QHoC^ zU*$TQa*%~l&hVjz>d7J7fG#ELRnId>VkiZd|KCGKq$Por%@TfL*69_i6QeFd&A z09b)f0aoBQ#WSGj%B}A`Z#HolIw2@*nqwPMmwF}d9v8@^yd6};hu`YK7`Ct^Wpzm4 z9{RYR4eNmr4`j$uYxQ2Qn15p@yx$acYYYW2`ypmBvXV>om;6J1^B~>=KOZ4mU3B@h zl|;Rvc4%t!za0WU6C;hk>p10hTl1$k`;Kz5?WeqtgO#mOYqg)+&>s%N(8#vWke^q1 z-eV^Smj(W>R=963JgwzXo+;~RsUv{c$>`KPsif>}60=cjuYfa}VL*Y2fXOmm$Yr%e zQhOrpVz+X>jQgN}8r~=egWdNdsc>Y}I64tsUyKmBaoV{c+rH0p!A0m__zN?l-A$?} z2lZn%Ct2{3O-Eom67$x8FrkJiCs*W{M9W&F{;t5!>Dl|SQK>ndrETbuhoRjbBGhhR*@b#Y!xTzmL%R7$G&osa( z?mZ86g|q;Jkfyqg`=qmY9Pu}N;CK}P$7=vM&UlNMp81aBCkp#x_CwaajWBZsb(h53 zmwlhxfLFVG|1|-33P7PFWig)H?WMJ&o)jXXs|$GO>C_)7*#cavJV3Y_c2S|mj5y6i zWr&%JJJQla{Clmk$2wO1{aU4~D!roxD0^zP1Qr8FvbcdW8eOlg6yRE=y$T{2Bo*LV zWf%MVwaU?du2q_p0j^cr`s}(^-R2_+y{&Tczi}tL@|V<$jV=x-vL?TKYpg1ddh83x@I3dbA8D)Yk;O!7YmoGjk8Z zE*>&v`v6YkGy1}?|NFJdnXfhvQp2VyxxsoTL-#>aooPlyfuYV15!Dxz0_2*um4O-A zSA;HAeX`5j$l>(13`G;q;!?jx{@Qr0G&b#=Y&$8Lp|TNh_?@*I;%CkpaQ^IRA_Qe# zZ_`d7X_DV2@t=2a1iHp@q)SR)rE~oYnw5D(mEiZorO{7*8$L^vh*VW>c5e2oEOsCZ zs`TWDv&~NAa9{9IZhnuE%u>^Umo=*#VGSuUgk9w{H5kg|$`ttzjh9K`A%_BJ{GpTC zKpOSmG|s~{9G?0?H3oA5NgTFLB)V1(V<8x@n;V_#% zO38P@hL8@ec%h2tW=rRAXFyZeZ~>+vg*Fjn;xb=l2bwml_GE4XSWL6AhmdH34fmGv9Jryort&D&=No{*VRFvX26~4;zLly`~5^dB>?eJ zwUZqhgw66VpXxjy#?_x>3h86?jRd)H6_NP51WU181Ij0&_l`xNCZQU9fT=8DZry%c z96>$T)91;y3B#x|!$;TfeSWbs!%=k&;rM!U#MFdlB@QA)+!c}seZr74sr;Zltsslgs|4%+g;wYU-tEaqKMB%H~7(XJa?vf0zO@_i2?! zvex!Vx1|%RSL7Wts%2-jam4lm4u$O_)xMCKpdQTapP)=Jgq3-tZv&1)GP3NG3ba5! z<|T~dg1tcIY(YQf@a?04xvO^_d!^U_j#pMoWWMYtU@v0Qd(Xa{Gk~Sd6_({`WU3PI z@IpU+ulu>1>3Q=Dmvt+%4;ExS6x!wMRT)BS3NL`OmnU(?bqlMYPKR*^i_7AG-BBsN zY#4)mGxkdl`g*Nf<|_}}(z_qz+uFOo1Py@*JBbcLYCyk}c}4z!CBVcL?j{G_SuCLr z2{p6>n1eSWLUTb#=lP!U%Yoa6m34f`c>jJ6AaFvuZ}ono@)`nA_x4-Qd^d62cPlp$ z`U$9hqoq51-x<;wKbR6@hCG{*>=#|noR z8c@LP%AfnO8a!tfVPK z*Xjbg(2rDqWqgbugj5?)_wI8+yq~M5kSm3a>3OevFR}4i&KP?-2|3yh4iYH&$_3~Y zh&?+b5gdgWS(3;HSA{$%7CDD3=|{XtQ%!tcZT4_{7%>kobWTFExcM!xb7m^%F`iP6 zI6dMxWT@XH-`T)N)9|SXMwg~2zC$G+J;{MOoMvU@8V7K{@=M(d@YETu z`WNB`waxJzm(RN#ab!uWLDh&u?5p2?Jd_k*S_Dd)e?7o|5EK`rLBix-k zIj1NOMmvo!^Vw5=eZQFkWm9`JhyN0^$G9!_+fm0-=t|kb70IQhJo{#-d5uez$t9hu zDOCUPLg&GF8*FE9138nlt+N(Jq#TEss3joPLp{L*DDu!F*SG=rV6W!;q@+tQXi{r? zswc{U11?tvRL37MVVZQ+Ujip+u3t*(#eAW% z?i5=}O4oL&%Ost!6-(ekj<}OR`HXJixA4i9S`EeyShy0pzGT6CMLp+%~1zBDc++Z z;6KyCGM1CWmTK3bl`np!F`DZhP1NgKCZS-R3P~h8-Q*KmIZ&U%KkCTNHi|Xw! zg~-epWNVY?RkWSxRR@P^8wQWmc0zxUTOCN)nvoitWl6QK3;)y=6R1lb$n7{h*>}L# zR|=M%*X{1h)HQ>m#B8TlH&)S|AD_1|bE>D~aDiImsU-{}m~{}-A1>Y1V>Om~N_R3L zH&(Lkc1Z3EFO`iqS3!~47b^JX78P7#6SVLmJFrb@`ZmGWiz3!1_zmY9V}cIJPk2df z?aqFvrWc^5DA+1pk_1Umx=L)<%_49ayJa>5FDtq=_XynXKOn?~3yS=+EaU;ITKokHwE^ zVlLp-{_HVgRao(a8C)WMwmudO)bEiT-Rsw5O}CL}Zs>Rx(;O+BMRV=sJZ*#pl1M zV+qswe*C;|FGbXidAi(_RvT(oVAej2k=tNlc=V@>NFcz05IW$;$ZDC=mo)J(Vru0o z-c&=Wo6P9mBtL0b6SeO>f?KHb3^pvRyMw+Qx@=o2`hY^p)hz*0gn`<_vM%*jp%b(F zzNi=x?YKMeKq3uRh6tVzrlgWVh=U?vIUcpiBS~+rEk}F0ZY48Orn~-LNC|TST^Us} zurUR*pgAalvJ$aTfw$>o=i_X{g;Z-txw1|4jN5|tBxf*4_0q=BgBlR_h7(I$-jmKV z^mygcTpq31FT04C7XHV^^?+1Hkc<`k*6fW^zCE=fYaTxd+}Lu?H@}s6ev(xBJ01V}QAoKnl5w7IDs;<1Xm?Rpm0QIH z8*FOPR#s6d#Vz%M05=8x_jKI1$=8)#`|ByuALKO{U~ex)S>Q&WWJKEB!eqf&ds-PR zdeuHDP&vy5t^UAQ(yix&#Tp-6Ep?(P&TEtKLA+zD2^NQ*;p3Ir+c?(R;YKyi0> zhi`b^^PN6V-*bMxla-ldvSuffHS7MdXW!R81!^w0ui@g*o7pczY{nAm(=aYW*Th8@ zqRB-YOiB!yTsk(ITZ;uQci-{LJul`?h=FYF&v;yND>YOfj}2?tF9a<#s@~Y%d{cZN zUzlQXU+=x47K3$>=b7S8oyNNn zpTQ-5(zid4GxPe|bMlAqDOj>{`dLTo(h;303OYW<qc?6ny@mxtr;i9hMZz&nyG?cKSlzjegUZ}073qo91zB<+8+NODiXQ1O!8^ePdf4{Syz*rkpPHyZrsb`RSP~=veztvdZ z5%03+z_}wUJ(<<6y}pTK6@R|uf$T<~f`)0F)rDGJjmg8QZyfb zm%A@82`(mDI=6Ow6~(_2h@&vQ`k80y_)JQWo(`=YV55x5FMF#GUjeysqihiAU%7D~ z${N~wPhsus0`WRbM16cS?%h^ZG^ZtIfskQOfj5W6MN2y=aVCDAiF9)Nt_c}mglOn5 zKX4?ID_fK8*Sy%4J^Vl!z<r@#dHT|?u+HNt0y{BIEG811 zh7Sd^bZP};$(Dw3?MggcWkOl^R39nA;M|>veCa}@*O^v+!EPsU`D68V!|B0w7r{Mx z;~k}Mj%%1_|Hm6=2E6f&tmXZ4jkW_-|S zLlp`ls`EO7#1!7lA2i+UHv%gmsnIZbYeZZa_e;+Q5ASY~CcedXU78~j&1;vZq)eYY zrwrv5PWllsXp#?qScT361|G^#Bv-v&(g(^eGuwN?HE!wx0{WqeP(9X?w(-(>q*Nu9 zrNLs4lamjP!ai$D2ASxo$UfArHk}cEM;>4G=_dV8iC*fq34VLXf8)KvcWQ^7`QV`n7ML3E?>=Apqw12o-(52tSzhY)nl9)baFL zJ6(2Ocs{O%RY~c>k9cTAF>g#yX`YOoulB2}82{VMZ@O=LbZfnD0}xJiLv9(M2;kbR zBRR|SLDTwjF?5>TR}9xGx#@Mv{^c+aE2uRt-&ZGbkI5o#GyQLinOeM@o(LAp+%JpW ze@6vK;8zSNSE3-#d(~bW+STF@-j5`3sbJjW3;FwVF;CTF7UoqY`MV{t`%u+Kb3A|b zAbwET$6{#mCo@3YXH2RPc^ehq6|wAsHP&wXChHLj~yBE;aYp7w`H4p zZjiya*Ab^rmX3Td$CoDOr58NFN4Zi)9IX2qU9Lt&D~&&*=`}9#I(9a;uLHMJBT(-J z(ok4{fay^pIw=nAmjv^WvNm!@q7lW^8m)xfqCPGOTRapFNTptV$fO3B4h8n|T$UsU z*)yzJWezl@LSn;8Zon7E==JdzQ*~%T@12cT>yP&nV5^0<3(a<3B~Do=?9mypT>R&pDynsVQXssD z&HAzH^7UiarFQCPJU=x2&@Bw&C?N|$wafn7D_oz_f`~k1q#xXg=1fsxt6D(UrNQu` zoPaMXGkX4zJx-48i73m-;L!|i-v&rZm@^>bsr%$Rjl0x-w@uR2FTbDFKLbUysF z>mSf7^y`S*CD}EpiW#_Ddgw`~3Z%Fyf>x*nplReL(ttT`6??@4lwF#CqW?Z%0GQ+4 zwB<5tkdf8Sw&6GM`-ersxXV*#0ybV#2<314&*JKYVt$;>r+cL$j5c2kLxne?x}8Dt zk`szmM{r%Xo{+ zmTP6I?wMOn#AC56M3q=WCJjPMt`A^FcnprG(5?qc7HZ08Zame{SSgH$_O9qNAA zq!OsSS_3oAM(7ZO4wMR16FUG#<9=4K!51*^_hDy%EoMJglm1&Q4*m#I#HA$5$2p zoW4*TM*su_jBLJCCH&xs!UoOAIDi1J~QQ%y=KzI?f}|3UYc zHqiim>V0D^zj)wGKJ!BG#m0nGb-7IyX+t{{qn;ya(7nOXJtOe^^7ZU9yfu&I@z1`+ zJ7VmLI&`)U_CCw|P%5NHU9Bfz8k)9&RgyCoeFFJiA zru&|0(*c1j&n)SUJNW}9`t*&91qO@ML`dcmv1e(9#qSa)~L)KKSMLy%_ zWVff0KFdvO(x`R1VG_R8<7{tyMaiJ_oJCBZl}tMxzFzY}5J{SXZwYUsi>faPBj*wFanPN%)P&p5&OGzHT6IlKS=-LaYtC{+PcJ_2dSd5z`hGR^h><&e zHF3@x+Z=e7M3ZyxxGV2D37Fwzr}|LT`$mdzL_Y~3_c*cODs{^?O}322&&tS)T;7}S zTtsI4pnTysg}9ie9eXhE=+<}uZY=6{nX0Ms)0lR}Swqh!!tY{R%eyRO4kqSB>Yy&_ zDvLAI2a!(r>@pAHG}o?K#ikNB2{t#lX|@aIE|N!vcVAWgz+bR&2xs$RDDG;TWeR*d zw|oBC4H+D0X-cP}F3qqWvPg1F5m4?6rR=6 zstlhRpo5p;57m475ES{!>c;N)PP6Rf&<$!v||SO5aPP??Ug4~CLHR2t9;Y^6I(&=oCnYk}#~ z*AA`axr#Y+hS%LA3O2Al3{#e+NM|>E^DK*#UX>RIdM{%DKb-Qgsr#CqRTEhoRUIY` zm-$lwG$(jo|1>^Wg#6TAEgf5`ul7o#`14||4(j-ZT(7}|nA=*VP&ytyScv#_L(-@! zf@e-#EQ*Unoa3?$Hq}*M00BS3*&D^tlE;ZEk3eL7p{+?*U|i>8Ml*&#Ca8dvKpjtA zd(f`%fMAA8yzwbe9@167Gk7MKl^s!K*f`Wo`l@+l$9pDCgG_|a7_BXMBwsh^w7IfB z;vVZ{$Ejw}CN01%I=nSp<6iQz^nl8K{-68*}fa${Ag3a1jC(D zYGJ>}aQd8-D5W)yNrWzqCwy@`|8m@~3)!{Fo0$)WnXv<3__%CD!YDn4L{jxTsx z>6DWU`gWjpsv3Ta^Z`4TN>H7Msn2Hd;MD1rU+E7bdy+Ab!gGZ;S+YM=1{&%maSm8@ zCFjm-;4O`ZpiAakw0oGKG6gebc;kp5 zf;I7N=|=>3;4`kRY}+?#77(#dDMwpccbI)vGEvtikveNM*QjJrq6BtfT}_pdu!^t`weQ0R(U}rFl&L=thHcJmn3BixbIq5v8Ej3ky8!c~*{!PiM+RTKGWm`T6=1 zbHR_A61dNBWIuRM>ZS$jrqlR& zzsYKD`FY$b^IMjVhQ+*|(Kn^~*xz4t^mFpl_J)eaVjIcCrdr>uLYnub9gU%)M72h4 zbnkZZCKtQabT8H>_w$SqUOp7O{VrB*>#2-i&{=mQ(;Nmidw2*Tz}?2Fa#92pFimtA z_5HYS3_LaMtJwIuR}z-^G0U>MjP1t=FRz(FBp16PB0trx3RfH_Je$de8hvH|ycbUb z+e%a*)^nNf?UfpdeEOi-0W?<+xag}cC09y&gA5;oB~G&b(6MX8@F z_Qjk&d#mJ`u)EbzhN8|StD`hD;bje)6syXu13ooFGTMlE_|tVofyWMHOZ9E4ifbKZ449uG8?6+P1ETOcBeo)=JUo~B4)f$Sf@i6{GoIe#38kVIx5T2&3^GYky z)7#Z@l#9gv37;!w53gxhZ9Ocy2($lOY?M)0y(Tl4tD^qq*N^1vs^FGHKeVPPuj!Q< zbbedyuq+Gu1VYZeU9oQ&y)2oG=hSue?IH%Gqy+KK!pow=3!gDS`O?Sl<~btm0Sb86 z5B>yvrIpqQVmp)#w))fMEDsJ|1HS#`HkHw;l||2bCsSGno-NxFqnzYhV#m=6YAt5# zoe#n!ElELR^p0g#Qwb5RS!2H4G#2IIxBvybx0EXDgVV$@nt9mws2W7uRMk+V^h+5E zxcUH=c7a0$D+q7w(QY`}+j7^t-lKK`rJ(b~0UkzFXEcxAKqJIYVdMmy-PmvG;I}el zXXM7{XwfzCb!MXi6{qoILb!R7XuuTl8WAUORS7+*GXyhoR$Co=UiS2GNuZ=$zgaV) zR7hn6LXlobE%CB$y-Pcpe0XBF-qQ_qaeJ+Fs<+(9t|++!EXbSkJOnT1I42T>6r~l5 zcUdq47)A1@==V0J_()KuK25NSNRrJ13~=9zzZl@esX2K4$aS^bf)QQ(0}m6a`+#hrF|BfbKq%o z;PJ@GK;jHb?UEfWHD!rKb*mz}+gy)5MUvS|YM>{PdYkUOgDU{{ZMNWDGMUW!?0IN-OL zop-of!E1D%<9w*R+ajAN4C-#jv}$%-D?D5rY!u$M^CWWHIhV(9iIcz5JM74joi0(QrlwWaJ*}Xc2tF^Tl#u~ zJVZQDj)b&tC3(@4ud9>RKPtW$@XPow}GS_jqzP#|m)7<6fxUb+%?pFE?sTMjzsce{&PLGn(9Q9vwd`!+oO4%)D?`|Q zIiIBq;$~WMo^AfnxGKKhVqxQ5X2|_&$If8n0Pp*WQsF9thqM@^lBBz8C57u#%uqo5 z-rNyOh2_s|3*C9An}rJ`vfbuD&-kYR{M+dxOxz$nQe5W zqc-_$fHOmM<=#oywEJ?nMRYg{e@IV}f{&LE?Fe9hpG^2z+-!+Xa)sJlgdW_L9u&on zdEjRDv6nU!3lH8SI;Bh|#N#bpSvzN|@?-aMDDY6mTJ_D)H_qFLkofEONQM)>0KDz& zTf_n@QlZAp`a!rawkLYF^6;9|j ztvS^mb(Qj-OcB?>{8W6qewDEyL1&ZTesRdmRXM4d;kRy|I0DA2_n(Uk?uFEa8@cQu zyF8m!A|`^NHue*j8#^-rZtt27gxpsU=Ekx~8b6|+5@<&omSBCRC0i+tvLxip5+Hps z{neh)2vO=Xil)vv)PaR?jVf$-XfD<$(YZ8Kn^|~ky5~CnzTC2xXMdf)>k<3?nvAfU zYh?YDE<{G?f3V-bwgK$-kX6uz(rjLf&&G@`F;e!D0F=N$G=eUK3*_mkmJ*#ZfR~ft|4V*A1bO z2MKb#oE%yv>?QSgkWn}#4A|qGFx2OM%}f>h=V@nu@Ad@F-*DCgnhTtJ4=fCf3UL0m z`i2(zCLk6EkiC_RF^B@ z7=iZ(3%IiyvmeIN&#*}(Vw@~m`&V~8>a!})-(wjnso4gh5dEBoh8S@Wd#cJ4w>Gk{Z5F;v<%{}LwahI(S+@i8- zG#V0bqP-9?TN5=Dmk0!sR?)2Zlkb8$mio$gIqS3{-5wpOQ}>3L2-?_Dsiq(JnQ+L-vZrvyWNjUB4-Ir!bm-3nG`nk z>c23CT2ImI4#`}Pgg-D* zZ%891*ua%>4m?qTz5iTv?Ln3fEX(ASQzqRN>|E=}kZW8`O>^}^{zr_%L{KrB0Pk}$jvA+pq a{vV8L%JK+^k6(cbJeYtBlQjGB-TwmvvX}t? diff --git a/Artifacts/ReadLine.2.1.4.nupkg b/Artifacts/ReadLine.2.1.4.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..72cf285f8e8ce20eb93b5ede422ade95a8d00d38 GIT binary patch literal 43750 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 literal 0 HcmV?d00001 diff --git a/ReadLine.Tests/Abstractions/Console2.cs b/ReadLine.Tests/Abstractions/Console2.cs index 1b0a56e..ad000e4 100644 --- a/ReadLine.Tests/Abstractions/Console2.cs +++ b/ReadLine.Tests/Abstractions/Console2.cs @@ -5,6 +5,8 @@ namespace ReadLine.Tests.Abstractions { internal class Console2 : IConsole { + public bool PasswordMode { get; set; } + public int CursorLeft { get; private set; } public int CursorTop { get; private set; } diff --git a/ReadLine/Abstractions/IConsole.cs b/ReadLine/Abstractions/IConsole.cs index c128a00..b6f4e57 100644 --- a/ReadLine/Abstractions/IConsole.cs +++ b/ReadLine/Abstractions/IConsole.cs @@ -2,6 +2,7 @@ namespace ReadLine.Abstractions { public interface IConsole { + bool PasswordMode { get; set; } int CursorLeft { get; } int CursorTop { get; } int BufferWidth { get; } diff --git a/ReadLine/ReadLine.csproj b/ReadLine/ReadLine.csproj index b3d4a1f..53097b4 100644 --- a/ReadLine/ReadLine.csproj +++ b/ReadLine/ReadLine.csproj @@ -13,7 +13,7 @@ snKey.snk true Updated to support .NET Standard v2.0 / Core 2.2 & 3.0 / Framework v4.5 - v4.8 - 2.1.3 + 2.1.4 A GNU-Readline like library for .NET artifacts MIT