private void CheckEscapeInput(ICharMap map, ConsoleKeyInfo intended, ConsoleKeyInfo[] keys, bool inputOnly = false) { for (int i = 0; i < keys.Length; i++) { map.ProcessKey(keys[i]); if (i < keys.Length - 1) { Assert.AreEqual(false, map.KeyAvailable); } } if (inputOnly) { // Hack to make the map process escapes now. var escapeTimeout = map.EscapeTimeout; map.EscapeTimeout = 0; bool unused = map.KeyAvailable; map.EscapeTimeout = escapeTimeout; return; } Assert.AreEqual(true, map.KeyAvailable); var processedKey = map.ReadKey(); Assert.AreEqual(false, map.KeyAvailable); Assert.AreEqual(intended, processedKey); }
internal static void Init(ref ICharMap charMap) { // If either stdin or stdout is redirected, PSReadLine doesn't really work, so throw // and let PowerShell call Console.ReadLine or do whatever else it decides to do. if (IsHandleRedirected(stdin: false) || IsHandleRedirected(stdin: true)) { // If running in AppVeyor or local testing, this environment variable can be set // to skip the exception. if (Environment.GetEnvironmentVariable("PSREADLINE_TESTRUN") == null && Environment.GetEnvironmentVariable("APPVEYOR") == null) { throw new NotSupportedException(); } } if (_enableVtOutput) { // This is needed because PowerShell does not restore the console mode // after running external applications, and some popular applications // clear VT, e.g. git. SetConsoleOutputVirtualTerminalProcessing(); } // If input is redirected, we can't use console APIs and have to use VT input. if (IsHandleRedirected(stdin: true)) { EnableAnsiInput(ref charMap); } else { _prePSReadLineConsoleInputMode = GetConsoleInputMode(); // This envvar will force VT mode on or off depending on the setting 1 or 0. var overrideVtInput = Environment.GetEnvironmentVariable("PSREADLINE_VTINPUT"); if (overrideVtInput == "1") { _enableVtInput = true; } else if (overrideVtInput == "0") { _enableVtInput = false; } else { // If the console was already in VT mode, use the appropriate CharMap. // This handles the case where input was not redirected and the user // didn't specify a preference. The default is to use the pre-existing // console mode. _enableVtInput = (_prePSReadLineConsoleInputMode & ENABLE_VIRTUAL_TERMINAL_INPUT) == ENABLE_VIRTUAL_TERMINAL_INPUT; } if (_enableVtInput) { EnableAnsiInput(ref charMap); } SetOurInputMode(); } }
internal static void Init(ref ICharMap charMap) { if (_enableVtOutput) { // This is needed because PowerShell does not restore the console mode // after running external applications, and some popular applications // clear VT, e.g. git. SetConsoleOutputVirtualTerminalProcessing(); } // If input is redirected, we can't use console APIs and have to use VT input. if (IsHandleRedirected(stdin: true)) { EnableAnsiInput(ref charMap); } else { _prePSReadLineConsoleInputMode = GetConsoleInputMode(); // This envvar will force VT mode on or off depending on the setting 1 or 0. var overrideVtInput = Environment.GetEnvironmentVariable("PSREADLINE_VTINPUT"); if (overrideVtInput == "1") { _enableVtInput = true; } else if (overrideVtInput == "0") { _enableVtInput = false; } else { // If the console was already in VT mode, use the appropriate CharMap. // This handles the case where input was not redirected and the user // didn't specify a preference. The default is to use the pre-existing // console mode. _enableVtInput = (_prePSReadLineConsoleInputMode & ENABLE_VIRTUAL_TERMINAL_INPUT) == ENABLE_VIRTUAL_TERMINAL_INPUT; } if (_enableVtInput) { EnableAnsiInput(ref charMap); } SetOurInputMode(); } }
internal static void Init(ref ICharMap charMap) { // If either stdin or stdout is redirected, PSReadline doesn't really work, so throw // and let PowerShell call Console.ReadLine or do whatever else it decides to do. if (IsHandleRedirected(stdin: false) || IsHandleRedirected(stdin: true)) { throw new NotSupportedException(); } // If input is redirected, we can't use console APIs and have to use VT input. if (IsHandleRedirected(stdin: true)) { EnableAnsiInput(ref charMap); return; } _prePSReadlineConsoleInputMode = GetConsoleInputMode(); // This envvar will force VT mode on or off depending on the setting 1 or 0. var overrideVtInput = Environment.GetEnvironmentVariable("PSREADLINE_VTINPUT"); if (overrideVtInput == "1") { _enableVtInput = true; } else if (overrideVtInput == "0") { _enableVtInput = false; } else { // If the console was already in VT mode, use the appropriate CharMap. // This handles the case where input was not redirected and the user // didn't specify a preference. The default is to use the pre-existing // console mode. _enableVtInput = (_prePSReadlineConsoleInputMode & ENABLE_VIRTUAL_TERMINAL_INPUT) == ENABLE_VIRTUAL_TERMINAL_INPUT; } if (_enableVtInput) { EnableAnsiInput(ref charMap); } SetOurInputMode(); }
private void CheckPartialEscapeInput(ICharMap map, int expectedCount, ConsoleKeyInfo[] keys) { foreach (var key in keys) { map.ProcessKey(key); Assert.AreEqual(false, map.KeyAvailable); } int keyCount = 0; // Hack to make the map think the timeout is up. var escapeTimeout = map.EscapeTimeout; map.EscapeTimeout = 0; while (map.KeyAvailable) { map.ReadKey(); keyCount++; } Assert.AreEqual(expectedCount, keyCount); map.EscapeTimeout = escapeTimeout; }
private PSConsoleReadLine() { _mockableMethods = this; _console = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? PlatformWindows.OneTimeInit(this) : new VirtualTerminal(); _charMap = new DotNetCharMap(); _buffer = new StringBuilder(8 * 1024); _statusBuffer = new StringBuilder(256); _savedCurrentLine = new HistoryItem(); _queuedKeys = new Queue <PSKeyInfo>(); // Initialize this event handler early because it could be used by PowerShell // Editor Services before 'DelayedOneTimeInitialize' runs. _forceEventWaitHandle = new AutoResetEvent(false); string hostName = null; // This works mostly by luck - we're not doing anything to guarantee the constructor for our // singleton is called on a thread with a runspace, but it is happening by coincidence. using (var ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace)) { try { var results = ps.AddScript("$Host", useLocalScope: true).Invoke <PSHost>(); PSHost host = results.Count == 1 ? results[0] : null; hostName = host?.Name; } catch { } } if (hostName == null) { hostName = "PSReadLine"; } _options = new PSConsoleReadLineOptions(hostName); _prediction = new Prediction(this); SetDefaultBindings(_options.EditMode); }
private PSConsoleReadLine() { _mockableMethods = this; _console = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? PlatformWindows.OneTimeInit(this) : new VirtualTerminal(); _charMap = new DotNetCharMap(); _buffer = new StringBuilder(8 * 1024); _statusBuffer = new StringBuilder(256); _savedCurrentLine = new HistoryItem(); _queuedKeys = new Queue <ConsoleKeyInfo>(); string hostName = null; // This works mostly by luck - we're not doing anything to guarantee the constructor for our // singleton is called on a thread with a runspace, but it is happening by coincidence. using (var ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace)) { try { ps.AddCommand("Get-Variable").AddParameter("Name", "host").AddParameter("ValueOnly"); var results = ps.Invoke(); dynamic host = results.Count == 1 ? results[0] : null; if (host != null) { hostName = host.Name as string; } } catch { } } if (hostName == null) { hostName = "PSReadLine"; } _options = new PSConsoleReadLineOptions(hostName); SetDefaultBindings(_options.EditMode); }
private static void EnableAnsiInput(ref ICharMap charMap) { charMap = new WindowsAnsiCharMap(PSConsoleReadLine.GetOptions().AnsiEscapeTimeout); }