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);
        }
Beispiel #2
0
    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();
        }
    }
Beispiel #3
0
    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();
        }
    }
Beispiel #4
0
    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;
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
 private static void EnableAnsiInput(ref ICharMap charMap)
 {
     charMap = new WindowsAnsiCharMap(PSConsoleReadLine.GetOptions().AnsiEscapeTimeout);
 }