예제 #1
0
        protected IDisposable UseRequestedDispatchTables()
        {
            bool inViMode           = PSConsoleReadLine.GetOptions().EditMode == EditMode.Vi;
            bool viModeParamPresent = MyInvocation.BoundParameters.ContainsKey("ViMode");

            if (inViMode || viModeParamPresent)
            {
                if (!inViMode)
                {
                    // "-ViMode" must have been specified explicitly. Well, okay... we can
                    // modify the Vi tables... but isn't that an odd thing to do from
                    // not-vi mode?
                    WriteWarning(PSReadLineResources.NotInViMode);
                }

                if (ViMode == ViMode.Command)
                {
                    return(PSConsoleReadLine.UseViCommandModeTables());
                }
                else // default if -ViMode not specified, invalid, or "Insert"
                {
                    return(PSConsoleReadLine.UseViInsertModeTables());
                }
            }

            return(null);
        }
예제 #2
0
        public void PossibleCompletionsPrompt()
        {
            TestSetup(KeyMode.Cmd, new KeyHandler("Ctrl+Spacebar", PSConsoleReadLine.PossibleCompletions));

            PSConsoleReadLine.GetOptions().CompletionQueryItems = 10;
            _console.Clear();
            Test("Get-Many", Keys(
                     "Get-Many", _.CtrlSpace,
                     CheckThat(() => AssertScreenIs(2,
                                                    TokenClassification.Command, "Get-Many", NextLine,
                                                    TokenClassification.None, "Display all 15 possibilities? (y or n) _")),
                     "n"));

            _console.Clear();
            Test("Get-Many", Keys(
                     "Get-Many", _.CtrlSpace,
                     CheckThat(() => AssertScreenIs(2,
                                                    TokenClassification.Command, "Get-Many", NextLine,
                                                    TokenClassification.None, "Display all 15 possibilities? (y or n) _")),
                     "y",
                     CheckThat(() => AssertScreenIs(4,
                                                    TokenClassification.Command, "Get-Many", NextLine,
                                                    TokenClassification.None,
                                                    "Get-Many0   Get-Many3   Get-Many6   Get-Many9   Get-Many12", NextLine,
                                                    "Get-Many1   Get-Many4   Get-Many7   Get-Many10  Get-Many13", NextLine,
                                                    "Get-Many2   Get-Many5   Get-Many8   Get-Many11  Get-Many14"))));
        }
예제 #3
0
        public void ShowTooltips()
        {
            TestSetup(KeyMode.Cmd, new KeyHandler("Ctrl+Spacebar", PSConsoleReadLine.PossibleCompletions));

            PSConsoleReadLine.GetOptions().ShowToolTips = true;
            _console.Clear();
            // TODO:
        }
예제 #4
0
        public void TestShowTooltips()
        {
            TestSetup(KeyMode.Cmd);

            PSConsoleReadLine.GetOptions().ShowToolTips = true;
            Console.Clear();
            Test("Get-Tooltips", Keys(
                     "Get-Tooltips", _.CtrlSpace,
                     CheckThat(() => AssertScreenIs(2,
                                                    TokenClassification.Command, "Get-Tooltips", NextLine,
                                                    TokenClassification.None,
                                                    "item1  - useful description goes here"))));
        }
예제 #5
0
        public void TestSearchHistory()
        {
            TestSetup(KeyMode.Cmd,
                      new KeyHandler("UpArrow", PSConsoleReadLine.HistorySearchBackward),
                      new KeyHandler("DownArrow", PSConsoleReadLine.HistorySearchForward));

            // No history
            SetHistory();
            Test("", Keys(_.UpArrow, _.DownArrow));

            // Clear history in case the above added some history (but it shouldn't)
            SetHistory();
            Test(" ", Keys(' ', _.UpArrow, _.DownArrow));

            var options        = PSConsoleReadLine.GetOptions();
            var emphasisColors = Tuple.Create(options.EmphasisForegroundColor, options.EmphasisBackgroundColor);

            SetHistory("dosomething", "ps p*", "dir", "echo zzz");
            Test("dosomething", Keys(
                     "d",
                     _.UpArrow, CheckThat(() => {
                AssertScreenIs(1,
                               emphasisColors, 'd',
                               TokenClassification.Command, "ir");
                AssertCursorLeftIs(3);
            }),
                     _.UpArrow, CheckThat(() => {
                AssertScreenIs(1,
                               emphasisColors, 'd',
                               TokenClassification.Command, "osomething");
                AssertCursorLeftIs(11);
            }),
                     _.DownArrow, CheckThat(() => {
                AssertScreenIs(1,
                               emphasisColors, 'd',
                               TokenClassification.Command, "ir");
                AssertCursorLeftIs(3);
            }),
                     _.UpArrow, CheckThat(() =>
            {
                AssertScreenIs(1,
                               emphasisColors, 'd',
                               TokenClassification.Command, "osomething");
                AssertCursorLeftIs(11);
            })));
        }
예제 #6
0
        public void TestHistorySearchCursorMovesToEnd()
        {
            TestSetup(KeyMode.Cmd,
                      new KeyHandler("UpArrow", PSConsoleReadLine.HistorySearchBackward),
                      new KeyHandler("DownArrow", PSConsoleReadLine.HistorySearchForward));

            PSConsoleReadLine.SetOptions(new SetPSReadlineOption {
                HistorySearchCursorMovesToEnd = true
            });
            var options        = PSConsoleReadLine.GetOptions();
            var emphasisColors = Tuple.Create(options.EmphasisForegroundColor, options.EmphasisBackgroundColor);

            SetHistory("dosomething", "ps p*", "dir", "echo zzz");
            Test("dosomething", Keys(
                     "d",
                     _.UpArrow, CheckThat(() => {
                AssertScreenIs(1,
                               emphasisColors, 'd',
                               TokenClassification.Command, "ir");
                AssertCursorLeftIs(3);
            }),
                     _.UpArrow, CheckThat(() => {
                AssertScreenIs(1,
                               emphasisColors, 'd',
                               TokenClassification.Command, "osomething");
                AssertCursorLeftIs(11);
            }),
                     _.DownArrow, CheckThat(() => {
                AssertScreenIs(1,
                               emphasisColors, 'd',
                               TokenClassification.Command, "ir");
                AssertCursorLeftIs(3);
            }),
                     _.UpArrow, CheckThat(() =>
            {
                AssertScreenIs(1,
                               emphasisColors, 'd',
                               TokenClassification.Command, "osomething");
                AssertCursorLeftIs(11);
            })));
        }
예제 #7
0
        static void Main(string[] args)
        {
            var handle = GetStdHandle((uint)StandardHandleId.Output);

            GetConsoleMode(handle, out var mode);
            var vtEnabled = SetConsoleMode(handle, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);

            var iss = InitialSessionState.CreateDefault2();

            if (args.Any())
            {
                iss.ImportPSModule(args[0]);
            }
            iss.ExecutionPolicy = ExecutionPolicy.Bypass;
            var rs = RunspaceFactory.CreateRunspace(iss);

            rs.Open();
            Runspace.DefaultRunspace = rs;

            PSConsoleReadLine.SetOptions(new SetPSReadLineOption
            {
                HistoryNoDuplicates = false,
                PredictionViewStyle = PredictionViewStyle.ListView,
                PredictionSource    = PredictionSource.HistoryAndPlugin,
            });

            if (vtEnabled)
            {
                var options = PSConsoleReadLine.GetOptions();
                options.CommandColor = "#8181f7";
                options.StringColor  = "\x1b[38;5;100m";
            }

            using (var ps = PowerShell.Create(rs))
            {
                var executionContext = ps.AddScript("$ExecutionContext").Invoke <EngineIntrinsics>().First();

                // Detect if the read loop will enter VT input mode.
                var vtInputEnvVar = Environment.GetEnvironmentVariable("PSREADLINE_VTINPUT");
                var stdin         = GetStdHandle((uint)StandardHandleId.Input);
                GetConsoleMode(stdin, out var inputMode);
                if (vtInputEnvVar == "1" || (inputMode & ENABLE_VIRTUAL_TERMINAL_INPUT) != 0)
                {
                    Console.WriteLine("\x1b[33mDefault input mode = virtual terminal\x1b[m");
                }
                else
                {
                    Console.WriteLine("\x1b[33mDefault input mode = Windows\x1b[m");
                }

                // This is a workaround to ensure the command analysis cache has been created before
                // we enter into ReadLine.  It's a little slow and infrequently needed, so just
                // uncomment if you hit a hang, run it once, then comment it out again.
                //ps.Commands.Clear();
                //ps.AddCommand("Get-Command").Invoke();

                executionContext.InvokeProvider.Item.Set("function:prompt", ScriptBlock.Create("'TestHostPS> '"));

                while (true)
                {
                    ps.Commands.Clear();
                    Console.Write(string.Join("", ps.AddCommand("prompt").Invoke <string>()));

                    var line = PSConsoleReadLine.ReadLine(rs, executionContext);
                    Console.WriteLine(line);
                    line = line.Trim().ToLower();
                    if (line.Equals("exit"))
                    {
                        Environment.Exit(0);
                    }
                    if (line.Equals("cmd"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
                            EditMode = EditMode.Windows
                        });
                    }
                    if (line.Equals("emacs"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
                            EditMode = EditMode.Emacs
                        });
                    }
                    if (line.Equals("vi"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
                            EditMode = EditMode.Vi
                        });
                    }
                    if (line.Equals("nodupes"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
                            HistoryNoDuplicates = true
                        });
                    }
                    if (line.Equals("vtinput"))
                    {
                        Environment.SetEnvironmentVariable("PSREADLINE_VTINPUT", "1");
                    }
                    if (line.Equals("novtinput"))
                    {
                        Environment.SetEnvironmentVariable("PSREADLINE_VTINPUT", "0");
                    }
                    if (line.Equals("listview"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
                            PredictionViewStyle = PredictionViewStyle.ListView
                        });
                    }
                    if (line.Equals("inlineview"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
                            PredictionViewStyle = PredictionViewStyle.InlineView
                        });
                    }
                    if (line.Equals("history"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
                            PredictionSource = PredictionSource.History
                        });
                    }
                    if (line.Equals("plugin"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
                            PredictionSource = PredictionSource.Plugin
                        });
                    }
                    if (line.Equals("historyplugin"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
                            PredictionSource = PredictionSource.HistoryAndPlugin
                        });
                    }
                    if (line.StartsWith("import-module"))
                    {
                        ps.AddScript(line).Invoke();
                    }
                    if (line.StartsWith("get-module"))
                    {
                        var modules = ps.AddScript(line).Invoke().ToList();
                        foreach (var m in modules)
                        {
                            Console.WriteLine(((PSModuleInfo)m.BaseObject).Name);
                        }
                    }
                }
            }
        }
예제 #8
0
        static void Main()
        {
            var handle = GetStdHandle((uint)StandardHandleId.Output);

            GetConsoleMode(handle, out var mode);
            var vtEnabled = SetConsoleMode(handle, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);

            var iss = InitialSessionState.CreateDefault2();
            var rs  = RunspaceFactory.CreateRunspace(iss);

            rs.Open();
            Runspace.DefaultRunspace = rs;

            PSConsoleReadLine.SetOptions(new SetPSReadLineOption
            {
                EditMode            = EditMode.Emacs,
                HistoryNoDuplicates = false,
            });

            if (vtEnabled)
            {
                var options = PSConsoleReadLine.GetOptions();
                options.CommandColor = "#8181f7";
                options.StringColor  = "\x1b[38;5;100m";
            }
            PSConsoleReadLine.SetKeyHandler(new[] { "Ctrl+LeftArrow" }, PSConsoleReadLine.ShellBackwardWord, "ShellBackwardWord", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "Ctrl+RightArrow" }, PSConsoleReadLine.ShellNextWord, "ShellNextWord", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "F4" }, PSConsoleReadLine.HistorySearchBackward, "HistorySearchBackward", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "F5" }, PSConsoleReadLine.HistorySearchForward, "HistorySearchForward", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "Ctrl+d,Ctrl+c" }, PSConsoleReadLine.CaptureScreen, "CaptureScreen", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "Ctrl+d,Ctrl+p" }, PSConsoleReadLine.InvokePrompt, "InvokePrompt", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "Ctrl+d,Ctrl+x" }, CauseCrash, "CauseCrash", "Throw exception to test error handling");
            PSConsoleReadLine.SetKeyHandler(new[] { "F6" }, PSConsoleReadLine.PreviousLine, "PreviousLine", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "F7" }, PSConsoleReadLine.NextLine, "NextLine", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "F2" }, PSConsoleReadLine.ValidateAndAcceptLine, "ValidateAndAcceptLine", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "Enter" }, PSConsoleReadLine.AcceptLine, "AcceptLine", "");

            using (var ps = PowerShell.Create(RunspaceMode.CurrentRunspace))
            {
                var executionContext = ps.AddScript("$ExecutionContext").Invoke <EngineIntrinsics>().First();

                // Detect if the read loop will enter VT input mode.
                var vtInputEnvVar = Environment.GetEnvironmentVariable("PSREADLINE_VTINPUT");
                var stdin         = GetStdHandle((uint)StandardHandleId.Input);
                GetConsoleMode(stdin, out var inputMode);
                if (vtInputEnvVar == "1" || (inputMode & ENABLE_VIRTUAL_TERMINAL_INPUT) != 0)
                {
                    Console.WriteLine("\x1b[33mDefault input mode = virtual terminal\x1b[m");
                }
                else
                {
                    Console.WriteLine("\x1b[33mDefault input mode = Windows\x1b[m");
                }

                // This is a workaround to ensure the command analysis cache has been created before
                // we enter into ReadLine.  It's a little slow and infrequently needed, so just
                // uncomment if you hit a hang, run it once, then comment it out again.
                //ps.Commands.Clear();
                //ps.AddCommand("Get-Command").Invoke();

                executionContext.InvokeProvider.Item.Set("function:prompt", ScriptBlock.Create("'TestHostPS> '"));

                while (true)
                {
                    ps.Commands.Clear();
                    Console.Write(string.Join("", ps.AddCommand("prompt").Invoke <string>()));

                    var line = PSConsoleReadLine.ReadLine(rs, executionContext);
                    Console.WriteLine(line);
                    line = line.Trim();
                    if (line.Equals("exit"))
                    {
                        Environment.Exit(0);
                    }
                    if (line.Equals("cmd"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
                            EditMode = EditMode.Windows
                        });
                    }
                    if (line.Equals("emacs"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
                            EditMode = EditMode.Emacs
                        });
                    }
                    if (line.Equals("vi"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
                            EditMode = EditMode.Vi
                        });
                    }
                    if (line.Equals("nodupes"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadLineOption {
                            HistoryNoDuplicates = true
                        });
                    }
                    if (line.Equals("vtinput"))
                    {
                        Environment.SetEnvironmentVariable("PSREADLINE_VTINPUT", "1");
                    }
                    if (line.Equals("novtinput"))
                    {
                        Environment.SetEnvironmentVariable("PSREADLINE_VTINPUT", "0");
                    }
                }
            }
        }
예제 #9
0
 protected override void EndProcessing()
 {
     WriteObject(PSConsoleReadLine.GetOptions());
 }
예제 #10
0
        static void Main()
        {
            var  handle = GetStdHandle((uint)StandardHandleId.Output);
            uint mode;

            GetConsoleMode(handle, out mode);
            var b = SetConsoleMode(handle, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);

            var iss = InitialSessionState.CreateDefault2();
            var rs  = RunspaceFactory.CreateRunspace(iss);

            rs.Open();
            Runspace.DefaultRunspace = rs;

            PSConsoleReadLine.SetOptions(new SetPSReadlineOption
            {
                EditMode            = EditMode.Emacs,
                HistoryNoDuplicates = true,
            });
            var options = PSConsoleReadLine.GetOptions();

            options.CommandColor = "#8181f7";
            options.StringColor  = "\x1b[38;5;100m";
            PSConsoleReadLine.SetKeyHandler(new[] { "Ctrl+LeftArrow" }, PSConsoleReadLine.ShellBackwardWord, "", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "Ctrl+RightArrow" }, PSConsoleReadLine.ShellNextWord, "", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "F4" }, PSConsoleReadLine.HistorySearchBackward, "", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "F5" }, PSConsoleReadLine.HistorySearchForward, "", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "Ctrl+D,Ctrl+C" }, PSConsoleReadLine.CaptureScreen, "", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "Ctrl+D,Ctrl+P" }, PSConsoleReadLine.InvokePrompt, "", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "Ctrl+D,Ctrl+X" }, CauseCrash, "", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "F6" }, PSConsoleReadLine.PreviousLine, "", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "F7" }, PSConsoleReadLine.NextLine, "", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "F2" }, PSConsoleReadLine.ValidateAndAcceptLine, "", "");
            PSConsoleReadLine.SetKeyHandler(new[] { "Enter" }, PSConsoleReadLine.AcceptLine, "", "");


            EngineIntrinsics executionContext;

            using (var ps = PowerShell.Create(RunspaceMode.CurrentRunspace))
            {
                executionContext =
                    ps.AddScript("$ExecutionContext").Invoke <EngineIntrinsics>().FirstOrDefault();

                // This is a workaround to ensure the command analysis cache has been created before
                // we enter into ReadLine.  It's a little slow and infrequently needed, so just
                // uncomment if you hit a hang, run it once, then comment it out again.
                //ps.Commands.Clear();
                //ps.AddCommand("Get-Command").Invoke();

                executionContext.InvokeProvider.Item.Set("function:prompt", ScriptBlock.Create("'TestHostPS> '"));

                while (true)
                {
                    ps.Commands.Clear();
                    Console.Write(string.Join("", ps.AddCommand("prompt").Invoke <string>()));

                    var line = PSConsoleReadLine.ReadLine(rs, executionContext);
                    Console.WriteLine(line);
                    line = line.Trim();
                    if (line.Equals("exit"))
                    {
                        Environment.Exit(0);
                    }
                    if (line.Equals("cmd"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadlineOption {
                            EditMode = EditMode.Windows
                        });
                    }
                    if (line.Equals("emacs"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadlineOption {
                            EditMode = EditMode.Emacs
                        });
                    }
                    if (line.Equals("vi"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadlineOption {
                            EditMode = EditMode.Vi
                        });
                    }
                    if (line.Equals("nodupes"))
                    {
                        PSConsoleReadLine.SetOptions(new SetPSReadlineOption {
                            HistoryNoDuplicates = true
                        });
                    }
                }
            }
        }
예제 #11
0
 private static void EnableAnsiInput(ref ICharMap charMap)
 {
     charMap = new WindowsAnsiCharMap(PSConsoleReadLine.GetOptions().AnsiEscapeTimeout);
 }
예제 #12
0
        public void TestInteractiveHistorySearch()
        {
            TestSetup(KeyMode.Emacs);

            SetHistory("echo aaa");
            Test("echo aaa", Keys(_.CtrlR, 'a'));

            var options        = PSConsoleReadLine.GetOptions();
            var emphasisColors = Tuple.Create(options.EmphasisForegroundColor, options.EmphasisBackgroundColor);
            var statusColors   = Tuple.Create(_console.ForegroundColor, _console.BackgroundColor);

            // Test entering multiple characters and the line is updated with new matches
            SetHistory("zz1", "echo abc", "zz2", "echo abb", "zz3", "echo aaa", "zz4");
            Test("echo abc", Keys(_.CtrlR,
                                  'a',
                                  CheckThat(() => AssertScreenIs(2,
                                                                 TokenClassification.Command, "echo",
                                                                 TokenClassification.None, " ",
                                                                 emphasisColors, 'a',
                                                                 TokenClassification.None, "aa",
                                                                 NextLine,
                                                                 statusColors, "bck-i-search: a_")),
                                  'b', CheckThat(() => AssertScreenIs(2,
                                                                      TokenClassification.Command, "echo",
                                                                      TokenClassification.None, " ",
                                                                      emphasisColors, "ab",
                                                                      TokenClassification.None, 'b',
                                                                      NextLine,
                                                                      statusColors, "bck-i-search: ab_")),
                                  'c', CheckThat(() => AssertScreenIs(2,
                                                                      TokenClassification.Command, "echo",
                                                                      TokenClassification.None, " ",
                                                                      emphasisColors, "abc",
                                                                      NextLine,
                                                                      statusColors, "bck-i-search: abc_"))));

            // Test repeated Ctrl+R goes back through multiple matches
            SetHistory("zz1", "echo abc", "zz2", "echo abb", "zz3", "echo aaa", "zz4");
            Test("echo abc", Keys(_.CtrlR,
                                  'a',
                                  CheckThat(() => AssertScreenIs(2,
                                                                 TokenClassification.Command, "echo",
                                                                 TokenClassification.None, " ",
                                                                 emphasisColors, 'a',
                                                                 TokenClassification.None, "aa",
                                                                 NextLine,
                                                                 statusColors, "bck-i-search: a_")),
                                  _.CtrlR, CheckThat(() => AssertScreenIs(2,
                                                                          TokenClassification.Command, "echo",
                                                                          TokenClassification.None, " ",
                                                                          emphasisColors, 'a',
                                                                          TokenClassification.None, "bb",
                                                                          NextLine,
                                                                          statusColors, "bck-i-search: a_")),
                                  _.CtrlR, CheckThat(() => AssertScreenIs(2,
                                                                          TokenClassification.Command, "echo",
                                                                          TokenClassification.None, " ",
                                                                          emphasisColors, 'a',
                                                                          TokenClassification.None, "bc",
                                                                          NextLine,
                                                                          statusColors, "bck-i-search: a_"))));

            // Test that the current match doesn't change when typing
            // additional characters, only emphasis should change.
            SetHistory("zz1", "echo abzz", "echo abc", "zz2");
            Test("echo abc", Keys(_.CtrlR,
                                  'a',
                                  CheckThat(() => AssertScreenIs(2,
                                                                 TokenClassification.Command, "echo",
                                                                 TokenClassification.None, " ",
                                                                 emphasisColors, 'a',
                                                                 TokenClassification.None, "bc",
                                                                 NextLine,
                                                                 statusColors, "bck-i-search: a_")),
                                  'b',
                                  CheckThat(() => AssertScreenIs(2,
                                                                 TokenClassification.Command, "echo",
                                                                 TokenClassification.None, " ",
                                                                 emphasisColors, "ab",
                                                                 TokenClassification.None, 'c',
                                                                 NextLine,
                                                                 statusColors, "bck-i-search: ab_"))));

            // Test that abort restores line state before Ctrl+R
            SetHistory("zz1", "echo abzz", "echo abc", "zz2");
            Test("echo zed", Keys("echo zed", _.CtrlR,
                                  'a',
                                  CheckThat(() => AssertScreenIs(2,
                                                                 TokenClassification.Command, "echo",
                                                                 TokenClassification.None, " ",
                                                                 emphasisColors, 'a',
                                                                 TokenClassification.None, "bc",
                                                                 NextLine,
                                                                 statusColors, "bck-i-search: a_")),
                                  _.CtrlG,
                                  CheckThat(() => AssertScreenIs(2,
                                                                 TokenClassification.Command, "echo",
                                                                 TokenClassification.None, " ",
                                                                 TokenClassification.None, "zed",
                                                                 NextLine))));

            // Test that a random function terminates the search and has an
            // effect on the line found in history
            SetHistory("zz1", "echo abzz", "echo abc", "zz2");
            Test("echo zed", Keys(_.CtrlR,
                                  'a',
                                  CheckThat(() => AssertScreenIs(2,
                                                                 TokenClassification.Command, "echo",
                                                                 TokenClassification.None, " ",
                                                                 emphasisColors, 'a',
                                                                 TokenClassification.None, "bc",
                                                                 NextLine,
                                                                 statusColors, "bck-i-search: a_")),
                                  _.AltD, "zed"));

            // Test that Escape terminates the search leaving the
            // cursor at the point in the match.
            SetHistory("zz1", "echo abzz", "echo abc", "zz2");
            Test("echo yabc", Keys(_.CtrlR,
                                   'a',
                                   CheckThat(() => AssertScreenIs(2,
                                                                  TokenClassification.Command, "echo",
                                                                  TokenClassification.None, " ",
                                                                  emphasisColors, 'a',
                                                                  TokenClassification.None, "bc",
                                                                  NextLine,
                                                                  statusColors, "bck-i-search: a_")),
                                   _.Escape, "y"));

            // Test entering multiple characters, then backspace, make sure we restore
            // the correct line
            SetHistory("zz1", "echo abc", "zz2", "echo abb", "zz3", "echo aaa", "zz4");
            Test("echo aaa", Keys(_.CtrlR,
                                  _.Backspace, // Try backspace on empty search string
                                  "ab", CheckThat(() => AssertScreenIs(2,
                                                                       TokenClassification.Command, "echo",
                                                                       TokenClassification.None, " ",
                                                                       emphasisColors, "ab",
                                                                       TokenClassification.None, 'b',
                                                                       NextLine,
                                                                       statusColors, "bck-i-search: ab_")),
                                  _.Backspace,
                                  CheckThat(() => AssertScreenIs(2,
                                                                 TokenClassification.Command, "echo",
                                                                 TokenClassification.None, " ",
                                                                 emphasisColors, 'a',
                                                                 TokenClassification.None, "aa",
                                                                 NextLine,
                                                                 statusColors, "bck-i-search: a_"))));

            SetHistory("zz1", "echo abzz", "echo abc", "zz2");
            Test("", Keys(_.CtrlR,
                          'a',
                          CheckThat(() => AssertScreenIs(2,
                                                         TokenClassification.Command, "echo",
                                                         TokenClassification.None, " ",
                                                         emphasisColors, 'a',
                                                         TokenClassification.None, "bc",
                                                         NextLine,
                                                         statusColors, "bck-i-search: a_")),
                          _.CtrlR,
                          CheckThat(() => AssertScreenIs(2,
                                                         TokenClassification.Command, "echo",
                                                         TokenClassification.None, " ",
                                                         emphasisColors, 'a',
                                                         TokenClassification.None, "bzz",
                                                         NextLine,
                                                         statusColors, "bck-i-search: a_")),
                          _.CtrlR,
                          CheckThat(() => AssertScreenIs(2,
                                                         TokenClassification.Command, "echo",
                                                         TokenClassification.None, " ",
                                                         TokenClassification.None, "abzz",
                                                         NextLine,
                                                         statusColors, "failed-bck-i-search: a_")),
                          _.CtrlS,
                          CheckThat(() => AssertScreenIs(2,
                                                         TokenClassification.Command, "echo",
                                                         TokenClassification.None, " ",
                                                         emphasisColors, 'a',
                                                         TokenClassification.None, "bzz",
                                                         NextLine,
                                                         statusColors, "fwd-i-search: a_")),
                          _.CtrlG));

            // Test that searching works after a failed search
            SetHistory("echo aa1", "echo bb1", "echo bb2", "echo aa2");
            Test("echo aa1", Keys(_.CtrlR, "zz", _.Backspace, _.Backspace, "a1",
                                  CheckThat(() => AssertScreenIs(2,
                                                                 TokenClassification.Command, "echo",
                                                                 TokenClassification.None, " a",
                                                                 emphasisColors, "a1",
                                                                 NextLine,
                                                                 statusColors, "bck-i-search: a1_"))
                                  ));

            // Test that searching works after backspace after a successful search
            SetHistory("echo aa1", "echo bb1", "echo bb2", "echo aa2");
            Test("echo aa2", Keys(
                     _.CtrlR,
                     "aa",
                     CheckThat(() => AssertScreenIs(2,
                                                    TokenClassification.Command, "echo",
                                                    TokenClassification.None, " ",
                                                    emphasisColors, "aa",
                                                    TokenClassification.None, "2",
                                                    NextLine,
                                                    statusColors, "bck-i-search: aa_")),
                     _.CtrlR,
                     CheckThat(() => AssertScreenIs(2,
                                                    TokenClassification.Command, "echo",
                                                    TokenClassification.None, " ",
                                                    emphasisColors, "aa",
                                                    TokenClassification.None, "1",
                                                    NextLine,
                                                    statusColors, "bck-i-search: aa_")),
                     _.Backspace,
                     CheckThat(() => AssertScreenIs(2,
                                                    TokenClassification.Command, "echo",
                                                    TokenClassification.None, " ",
                                                    emphasisColors, "a",
                                                    TokenClassification.None, "a2",
                                                    NextLine,
                                                    statusColors, "bck-i-search: a_")),
                     'a', _.CtrlR,
                     CheckThat(() => AssertScreenIs(2,
                                                    TokenClassification.Command, "echo",
                                                    TokenClassification.None, " ",
                                                    emphasisColors, "aa",
                                                    TokenClassification.None, "1",
                                                    NextLine,
                                                    statusColors, "bck-i-search: aa_")),
                     _.Backspace));

            // TODO: long search line
            // TODO: start with Ctrl+S
            // TODO: "fast" typing in search where buffered keys after search is accepted
        }
예제 #13
0
        public void SensitiveHistoryDefaultBehavior()
        {
            TestSetup(KeyMode.Cmd);

            // No history
            SetHistory();
            Test("", Keys(_.UpArrow, _.DownArrow));

            var options             = PSConsoleReadLine.GetOptions();
            var oldHistoryFilePath  = options.HistorySavePath;
            var oldHistorySaveStyle = options.HistorySaveStyle;

            // AddToHistoryHandler should be set to the default handler.
            Assert.Same(PSConsoleReadLineOptions.DefaultAddToHistoryHandler, options.AddToHistoryHandler);

            var newHistoryFilePath  = Path.GetTempFileName();
            var newHistorySaveStyle = HistorySaveStyle.SaveIncrementally;

            string[] expectedHistoryItems = new[] {
                "gcm c*",
                "ConvertTo-SecureString -AsPlainText -String abc -Force",
                "dir p*",
                "Publish-Module -NuGetApiKey abc",
                "ps c*",
                "mycommand -password abc",
                "echo foo",
                "cmd1 /token abc",
                "echo bar",
                "cmd2 --key abc",
                "echo zoo",
                "pki secret",
                "gcm p*"
            };

            string[] expectedSavedItems = new[] {
                "gcm c*",
                "dir p*",
                "ps c*",
                "echo foo",
                "echo bar",
                "echo zoo",
                "gcm p*"
            };

            try
            {
                options.HistorySavePath  = newHistoryFilePath;
                options.HistorySaveStyle = newHistorySaveStyle;
                SetHistory(expectedHistoryItems);

                // Sensitive input history should be kept in the internal history queue.
                var historyItems = PSConsoleReadLine.GetHistoryItems();
                Assert.Equal(expectedHistoryItems.Length, historyItems.Length);
                for (int i = 0; i < expectedHistoryItems.Length; i++)
                {
                    Assert.Equal(expectedHistoryItems[i], historyItems[i].CommandLine);
                }

                // Sensitive input history should NOT be saved to the history file.
                string[] text = File.ReadAllLines(newHistoryFilePath);
                Assert.Equal(expectedSavedItems.Length, text.Length);
                for (int i = 0; i < text.Length; i++)
                {
                    Assert.Equal(expectedSavedItems[i], text[i]);
                }
            }
            finally
            {
                options.HistorySavePath  = oldHistoryFilePath;
                options.HistorySaveStyle = oldHistorySaveStyle;
                File.Delete(newHistoryFilePath);
            }
        }
예제 #14
0
        public void SensitiveHistoryOptionalBehaviorWithScriptBlock()
        {
            TestSetup(KeyMode.Cmd);

            // No history
            SetHistory();
            Test("", Keys(_.UpArrow, _.DownArrow));

            var options             = PSConsoleReadLine.GetOptions();
            var oldHistoryFilePath  = options.HistorySavePath;
            var oldHistorySaveStyle = options.HistorySaveStyle;

            // AddToHistoryHandler should be set to the default handler.
            Assert.Same(PSConsoleReadLineOptions.DefaultAddToHistoryHandler, options.AddToHistoryHandler);

            var newHistoryFilePath  = Path.GetTempFileName();
            var newHistorySaveStyle = HistorySaveStyle.SaveIncrementally;
            Func <string, object> newAddToHistoryHandler_ReturnBool = LanguagePrimitives.ConvertTo <Func <string, object> >(
                ScriptBlock.Create(@"
                    param([string]$line)
                    $line.Contains('gal')"));
            Func <string, object> newAddToHistoryHandler_ReturnEnum = LanguagePrimitives.ConvertTo <Func <string, object> >(
                ScriptBlock.Create(@"
                    param([string]$line)
                    if ($line.Contains('gal')) {
                        [psobject]::AsPSObject([Microsoft.PowerShell.AddToHistoryOption]::MemoryOnly)
                    } elseif ($line.Contains('gmo')) {
                        'SkipAdding'
                    } else {
                        [Microsoft.PowerShell.AddToHistoryOption]::MemoryAndFile
                    }"));
            Func <string, object> newAddToHistoryHandler_ReturnOther = LanguagePrimitives.ConvertTo <Func <string, object> >(
                ScriptBlock.Create(@"
                    param([string]$line)
                    'string value'"));

            string[] commandInputs = new[] {
                "gmo p*",
                "gcm c*",
                "gal dir",
                "ConvertTo-SecureString -AsPlainText -String abc -Force"
            };

            string[] expectedQueuedItems = new[] {
                "gcm c*",
                "gal dir",
                "ConvertTo-SecureString -AsPlainText -String abc -Force"
            };

            string[] expectedSavedItems = new[] {
                "gcm c*",
                "ConvertTo-SecureString -AsPlainText -String abc -Force"
            };

            try
            {
                options.HistorySavePath  = newHistoryFilePath;
                options.HistorySaveStyle = newHistorySaveStyle;

                //
                // Set null to the handler means we don't do the check.
                //
                options.AddToHistoryHandler = null;
                SetHistory(commandInputs);

                // All commands should be kept in the internal history queue.
                var historyItems = PSConsoleReadLine.GetHistoryItems();
                Assert.Equal(commandInputs.Length, historyItems.Length);
                for (int i = 0; i < commandInputs.Length; i++)
                {
                    Assert.Equal(commandInputs[i], historyItems[i].CommandLine);
                }

                // All commands are saved to the history file when 'ScrubSensitiveHistory' is set to 'false'.
                string[] text = File.ReadAllLines(newHistoryFilePath);
                Assert.Equal(commandInputs.Length, text.Length);
                for (int i = 0; i < text.Length; i++)
                {
                    Assert.Equal(commandInputs[i], text[i]);
                }

                //
                // Use a handler that return boolean value.
                //   true: Add to memory and file
                //   false: Skip adding to history
                //
                options.AddToHistoryHandler = newAddToHistoryHandler_ReturnBool;
                // Clear the history file.
                File.WriteAllText(newHistoryFilePath, string.Empty);
                SetHistory(commandInputs);

                historyItems = PSConsoleReadLine.GetHistoryItems();
                Assert.Single(historyItems);
                Assert.Equal("gal dir", historyItems[0].CommandLine);

                text = File.ReadAllLines(newHistoryFilePath);
                Assert.Single(text);
                Assert.Equal("gal dir", text[0]);

                //
                // Use a handler that return the expected enum type.
                //
                options.AddToHistoryHandler = newAddToHistoryHandler_ReturnEnum;
                File.WriteAllText(newHistoryFilePath, string.Empty);
                SetHistory(commandInputs);

                historyItems = PSConsoleReadLine.GetHistoryItems();
                Assert.Equal(expectedQueuedItems.Length, historyItems.Length);
                for (int i = 0; i < expectedQueuedItems.Length; i++)
                {
                    Assert.Equal(expectedQueuedItems[i], historyItems[i].CommandLine);
                }

                text = File.ReadAllLines(newHistoryFilePath);
                Assert.Equal(expectedSavedItems.Length, text.Length);
                for (int i = 0; i < text.Length; i++)
                {
                    Assert.Equal(expectedSavedItems[i], text[i]);
                }

                //
                // Use a handler that return unexpected value.
                //   - same behavior as setting the handler to null.
                //
                options.AddToHistoryHandler = newAddToHistoryHandler_ReturnOther;
                File.WriteAllText(newHistoryFilePath, string.Empty);
                SetHistory(commandInputs);

                historyItems = PSConsoleReadLine.GetHistoryItems();
                Assert.Equal(commandInputs.Length, historyItems.Length);
                for (int i = 0; i < commandInputs.Length; i++)
                {
                    Assert.Equal(commandInputs[i], historyItems[i].CommandLine);
                }

                // All commands are saved to the history file when 'ScrubSensitiveHistory' is set to 'false'.
                text = File.ReadAllLines(newHistoryFilePath);
                Assert.Equal(commandInputs.Length, text.Length);
                for (int i = 0; i < text.Length; i++)
                {
                    Assert.Equal(commandInputs[i], text[i]);
                }
            }
            finally
            {
                options.HistorySavePath     = oldHistoryFilePath;
                options.HistorySaveStyle    = oldHistorySaveStyle;
                options.AddToHistoryHandler = PSConsoleReadLineOptions.DefaultAddToHistoryHandler;
                File.Delete(newHistoryFilePath);
            }
        }