Beispiel #1
0
        private Collection <CompletionResult> FilterCompletions(CommandCompletion completion, string completionFilter)
        {
            var newMatches = new Collection <CompletionResult>();
            var matches    = completion.CompletionMatches;

            bool consistentQuoting = IsConsistentQuoting(matches);

            // add possible first quote to userCompletionText
            if (consistentQuoting)
            {
                var quote = matches[0].CompletionText[0];
                if (IsSingleQuote(quote) || IsDoubleQuote(quote))
                {
                    completionFilter = quote + completionFilter;
                }
            }

            foreach (CompletionResult item in matches)
            {
                if (item.ListItemText.StartsWith(completionFilter, StringComparison.OrdinalIgnoreCase) ||
                    GetUnquotedText(item, consistentQuoting).StartsWith(completionFilter, StringComparison.OrdinalIgnoreCase))
                {
                    newMatches.Add(item);
                }
            }

            return(newMatches);
        }
        public void Completion_NoMatch_Test()
        {
            var completion = new CommandCompletion(_TestCommands);

            completion.Completion("foo").Is("foo");
            completion.Completion("foo").Is("foo");
        }
Beispiel #3
0
        private CommandCompletion GetCompletions()
        {
            if (_tabCommandCount == 0)
            {
                try
                {
                    _tabCompletions = null;

                    // Could use the overload that takes an AST as it's faster (we've already parsed the
                    // input for coloring) but that overload is a little more complicated in passing in the
                    // cursor position.
                    System.Management.Automation.PowerShell ps;
                    if (!_mockableMethods.RunspaceIsRemote(_runspace))
                    {
                        ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace);
                    }
                    else
                    {
                        ps          = System.Management.Automation.PowerShell.Create();
                        ps.Runspace = _runspace;
                    }
                    _tabCompletions = _mockableMethods.CompleteInput(_buffer.ToString(), _current, null, ps);

                    if (_tabCompletions.CompletionMatches.Count == 0)
                    {
                        return(null);
                    }
                }
                catch (Exception)
                {
                }
            }

            return(_tabCompletions);
        }
        public object GetAutoCompletionPrefix(string guid, string command)
        {
            if (!IsLoggedInUserAuthorized ||
                !SessionElevationManager.IsSessionTokenElevated(ApplicationNames.ISE))
            {
                return(string.Empty);
            }

            PowerShellLog.Info($"Auto completion requested in session '{guid}' by user: '******'");

            var serializer = new JavaScriptSerializer();
            var session    = GetScriptSession(guid);

            try
            {
                var result = serializer.Serialize(CommandCompletion.GetPrefix(session, command));
                return(result);
            }
            finally
            {
                if (string.IsNullOrEmpty(guid))
                {
                    ScriptSessionManager.RemoveSession(session);
                }
            }
        }
        /// <summary>
        /// Gets completions for a statement contained in the given
        /// script file at the specified line and column position.
        /// </summary>
        /// <param name="scriptFile">
        /// The script file in which completions will be gathered.
        /// </param>
        /// <param name="lineNumber">
        /// The 1-based line number at which completions will be gathered.
        /// </param>
        /// <param name="columnNumber">
        /// The 1-based column number at which completions will be gathered.
        /// </param>
        /// <returns>
        /// A CommandCompletion instance completions for the identified statement.
        /// </returns>
        internal async Task <IEnumerable <CompletionItem> > GetCompletionsInFileAsync(
            ScriptFile scriptFile,
            int lineNumber,
            int columnNumber,
            CancellationToken cancellationToken)
        {
            Validate.IsNotNull(nameof(scriptFile), scriptFile);

            CommandCompletion result = await AstOperations.GetCompletionsAsync(
                scriptFile.ScriptAst,
                scriptFile.ScriptTokens,
                scriptFile.GetOffsetAtPosition(lineNumber, columnNumber),
                _executionService,
                _logger,
                cancellationToken).ConfigureAwait(false);

            if (result.CompletionMatches.Count == 0)
            {
                return(Array.Empty <CompletionItem>());
            }

            BufferRange replacedRange = scriptFile.GetRangeBetweenOffsets(
                result.ReplacementIndex,
                result.ReplacementIndex + result.ReplacementLength);

            // Create OmniSharp CompletionItems from PowerShell CompletionResults. We use a for loop
            // because the index is used for sorting.
            CompletionItem[] completionItems = new CompletionItem[result.CompletionMatches.Count];
            for (int i = 0; i < result.CompletionMatches.Count; i++)
            {
                completionItems[i] = CreateCompletionItem(result.CompletionMatches[i], replacedRange, i + 1);
            }
            return(completionItems);
        }
Beispiel #6
0
        /// <summary>
        /// Completion lists calculator.
        /// </summary>
        /// <param name="script">The active script.</param>
        /// <param name="caretPosition">The caret position.</param>
        /// <param name="runspace">Runspace for completion computing.</param>
        /// <returns></returns>
        public static CommandCompletion GetCommandCompletionList(string script, int caretPosition, Runspace runspace)
        {
            Ast ast;

            Token[]         tokens;
            IScriptPosition cursorPosition;

            GetCommandCompletionParameters(script, caretPosition, out ast, out tokens, out cursorPosition);
            if (ast == null)
            {
                return(null);
            }

            CommandCompletion commandCompletion = null;

            if (runspace.RunspaceAvailability == RunspaceAvailability.Available)
            {
                using (_currentPowerShell = PowerShell.Create())
                {
                    _currentPowerShell.Runspace = runspace;
                    commandCompletion           = CommandCompletion.CompleteInput(ast, tokens, cursorPosition, null, _currentPowerShell);
                }
            }

            return(commandCompletion);
        }
Beispiel #7
0
        private CommandCompletion GetCompletions()
        {
            if (_tabCommandCount == 0)
            {
                try
                {
                    _tabCompletions = null;

                    // Could use the overload that takes an AST as it's faster (we've already parsed the
                    // input for coloring) but that overload is a little more complicated in passing in the
                    // cursor position.
                    var ps = PowerShell.Create(RunspaceMode.CurrentRunspace);
                    _tabCompletions = CommandCompletion.CompleteInput(_buffer.ToString(), _current, null, ps);

                    if (_tabCompletions.CompletionMatches.Count == 0)
                    {
                        return(null);
                    }
                }
                catch (Exception)
                {
                }
            }

            return(_tabCompletions);
        }
Beispiel #8
0
        public async Task<string> GetCompletion(
            string input, int index, bool forward)
        {
            // Suggest a file if the input is blank.
            if (string.IsNullOrWhiteSpace(input))
            {
                input = PATH_BEGIN;
                index = PATH_BEGIN.Length;
            }

            if (index == 0) return null;

            // Check the user has altered the input and we need to update our
            // completion list.
            if (completionListNeedsUpdate(input, index))
            {
                cachedCompletions = await Task.Run(
                    () => CommandCompletion.CompleteInput(
                        input, index, null, ps));
            }

            var result = await Task.Run(
                () => cachedCompletions.GetNextResult(forward));
            if (result == null) return null;

            expectedInput = input.Substring(
                0, cachedCompletions.ReplacementIndex);
            expectedInput += result.CompletionText;
            expectedInputIndex = expectedInput.Length;
            return expectedInput;
        }
Beispiel #9
0
 int getCurrentReplacementLength(CommandCompletion completions)
 {
     var matchIndex = completions.CurrentMatchIndex;
     return matchIndex == -1
         ? completions.ReplacementLength
         : completions.CompletionMatches[matchIndex]
             .CompletionText.Length;
 }
 internal static CompletionResults Create(
     CommandCompletion commandCompletion)
 {
     return(new CompletionResults
     {
         Completions = GetCompletionsArray(commandCompletion),
     });
 }
        /// <summary>
        /// Gets completions for a statement contained in the given
        /// script file at the specified line and column position.
        /// </summary>
        /// <param name="scriptFile">
        /// The script file in which completions will be gathered.
        /// </param>
        /// <param name="lineNumber">
        /// The 1-based line number at which completions will be gathered.
        /// </param>
        /// <param name="columnNumber">
        /// The 1-based column number at which completions will be gathered.
        /// </param>
        /// <returns>
        /// A CommandCompletion instance completions for the identified statement.
        /// </returns>
        public async Task <CompletionResults> GetCompletionsInFileAsync(
            ScriptFile scriptFile,
            int lineNumber,
            int columnNumber)
        {
            Validate.IsNotNull(nameof(scriptFile), scriptFile);

            // Get the offset at the specified position.  This method
            // will also validate the given position.
            int fileOffset =
                scriptFile.GetOffsetAtPosition(
                    lineNumber,
                    columnNumber);

            CommandCompletion commandCompletion = null;

            using (var cts = new CancellationTokenSource(DefaultWaitTimeoutMilliseconds))
            {
                commandCompletion =
                    await AstOperations.GetCompletionsAsync(
                        scriptFile.ScriptAst,
                        scriptFile.ScriptTokens,
                        fileOffset,
                        _powerShellContextService,
                        _logger,
                        cts.Token).ConfigureAwait(false);
            }

            if (commandCompletion == null)
            {
                return(new CompletionResults());
            }

            try
            {
                CompletionResults completionResults =
                    CompletionResults.Create(
                        scriptFile,
                        commandCompletion);

                // save state of most recent completion
                _mostRecentCompletions   = completionResults;
                _mostRecentRequestFile   = scriptFile.Id;
                _mostRecentRequestLine   = lineNumber;
                _mostRecentRequestOffest = columnNumber;

                return(completionResults);
            }
            catch (ArgumentException e)
            {
                // Bad completion results could return an invalid
                // replacement range, catch that here
                _logger.LogError(
                    $"Caught exception while trying to create CompletionResults:\n\n{e.ToString()}");

                return(new CompletionResults());
            }
        }
        private static CompletionDetails[] GetCompletionsArray(
            CommandCompletion commandCompletion)
        {
            IEnumerable<CompletionDetails> completionList =
                commandCompletion.CompletionMatches.Select(
                    CompletionDetails.Create);

            return completionList.ToArray();
        }
        private static CompletionDetails[] GetCompletionsArray(
            CommandCompletion commandCompletion)
        {
            IEnumerable <CompletionDetails> completionList =
                commandCompletion.CompletionMatches.Select(
                    CompletionDetails.Create);

            return(completionList.ToArray());
        }
Beispiel #14
0
        /// <summary>
        /// Gets completions for a statement contained in the given
        /// script file at the specified line and column position.
        /// </summary>
        /// <param name="scriptFile">
        /// The script file in which completions will be gathered.
        /// </param>
        /// <param name="lineNumber">
        /// The 1-based line number at which completions will be gathered.
        /// </param>
        /// <param name="columnNumber">
        /// The 1-based column number at which completions will be gathered.
        /// </param>
        /// <returns>
        /// A CommandCompletion instance completions for the identified statement.
        /// </returns>
        public async Task <CompletionResults> GetCompletionsInFile(
            ScriptFile scriptFile,
            int lineNumber,
            int columnNumber)
        {
            Validate.IsNotNull("scriptFile", scriptFile);

            // Get the offset at the specified position.  This method
            // will also validate the given position.
            int fileOffset =
                scriptFile.GetOffsetAtPosition(
                    lineNumber,
                    columnNumber);

            RunspaceHandle runspaceHandle =
                await this.powerShellContext.GetRunspaceHandle(
                    new CancellationTokenSource(DefaultWaitTimeoutMilliseconds).Token);

            CommandCompletion commandCompletion =
                AstOperations.GetCompletions(
                    scriptFile.ScriptAst,
                    scriptFile.ScriptTokens,
                    fileOffset,
                    runspaceHandle.Runspace);

            runspaceHandle.Dispose();

            if (commandCompletion != null)
            {
                try
                {
                    CompletionResults completionResults =
                        CompletionResults.Create(
                            scriptFile,
                            commandCompletion);

                    // save state of most recent completion
                    mostRecentCompletions   = completionResults;
                    mostRecentRequestFile   = scriptFile.Id;
                    mostRecentRequestLine   = lineNumber;
                    mostRecentRequestOffest = columnNumber;

                    return(completionResults);
                }
                catch (ArgumentException e)
                {
                    // Bad completion results could return an invalid
                    // replacement range, catch that here
                    Logger.Write(
                        LogLevel.Error,
                        $"Caught exception while trying to create CompletionResults:\n\n{e.ToString()}");
                }
            }

            // If all else fails, return empty results
            return(new CompletionResults());
        }
        public void Completion_FromEmpty_to_NoMatch_Test()
        {
            var completion = new CommandCompletion(_TestCommands);

            completion.Completion("").Is("banner");
            completion.Completion("banner").Is("clear");

            completion.Completion("bar").Is("bar");
        }
Beispiel #16
0
        private void StartIntelliSense(int lineStartPosition, int caretPosition, string lineTextUpToCaret)
        {
            if (_intellisenseRunning)
            {
                return;
            }

            _intellisenseRunning = true;
            var statusBar = (IVsStatusbar)PowerShellToolsPackage.Instance.GetService(typeof(SVsStatusbar));

            statusBar.SetText("Running IntelliSense...");
            var sw = new Stopwatch();

            sw.Start();

            Ast ast;

            Token[]         tokens;
            IScriptPosition cursorPosition;

            GetCommandCompletionParameters(caretPosition, out ast, out tokens, out cursorPosition);
            if (ast == null)
            {
                return;
            }

            var ps = PowerShell.Create();

            ps.Runspace = PowerShellToolsPackage.Debugger.Runspace;

            var commandCompletion = CommandCompletion.CompleteInput(ast, tokens, cursorPosition, null, ps);

            var line        = _textView.Caret.Position.BufferPosition.GetContainingLine();
            var caretInLine = (caretPosition - line.Start);
            var text        = line.GetText().Substring(0, caretInLine);

            IList <CompletionResult> list = commandCompletion.CompletionMatches;

            if (string.Equals(lineTextUpToCaret, text, StringComparison.Ordinal) && list.Count != 0)
            {
                if (list.Count != 0)
                {
                    try
                    {
                        IntellisenseDone(commandCompletion.CompletionMatches, lineStartPosition,
                                         commandCompletion.ReplacementIndex + 0, commandCompletion.ReplacementLength, caretPosition);
                    }
                    catch (Exception ex)
                    {
                        Log.Debug("Failed to start IntelliSense.", ex);
                    }
                }
            }

            statusBar.SetText(String.Format("IntelliSense complete in {0:0.00} seconds...", sw.Elapsed.TotalSeconds));
            _intellisenseRunning = false;
        }
Beispiel #17
0
 public string[] GetTabCompletion(string commandLine)
 {
     string[] strArrays;
     if (commandLine != null)
     {
         lock (this.clientRequestLock)
         {
             if (this.State == PowwaSession.SessionState.Available)
             {
                 this.State = PowwaSession.SessionState.ExecutingCommand;
                 System.Management.Automation.PowerShell powerShell = null;
                 try
                 {
                     try
                     {
                         powerShell          = System.Management.Automation.PowerShell.Create();
                         powerShell.Runspace = this.Runspace;
                         CommandCompletion commandCompletion = CommandCompletion.CompleteInput(commandLine, commandLine.Length, null, powerShell);
                         string            str        = commandLine.Substring(0, commandCompletion.ReplacementIndex);
                         string[]          strArrays1 = new string[commandCompletion.CompletionMatches.Count];
                         for (int i = 0; i < commandCompletion.CompletionMatches.Count; i++)
                         {
                             strArrays1[i] = string.Concat(str, commandCompletion.CompletionMatches[i].CompletionText);
                         }
                         strArrays = strArrays1;
                     }
                     catch
                     {
                         strArrays = new string[0];
                     }
                 }
                 finally
                 {
                     if (powerShell != null)
                     {
                         powerShell.Dispose();
                     }
                     this.State = PowwaSession.SessionState.Available;
                 }
             }
             else
             {
                 PowwaEvents.PowwaEVENT_DEBUG_LOG1("GetTabCompletion(): Invalid Session State", "SessionState", this.State.ToString());
                 throw new InvalidOperationException("The session is not available");
             }
         }
         return(strArrays);
     }
     else
     {
         throw new ArgumentNullException("commandLine");
     }
 }
Beispiel #18
0
        /// <summary>
        /// Gets completions for the symbol found in the Ast at
        /// the given file offset.
        /// </summary>
        /// <param name="scriptAst">
        /// The Ast which will be traversed to find a completable symbol.
        /// </param>
        /// <param name="currentTokens">
        /// The array of tokens corresponding to the scriptAst parameter.
        /// </param>
        /// <param name="fileOffset">
        /// The 1-based file offset at which a symbol will be located.
        /// </param>
        /// <param name="runspace">
        /// The Runspace to use for gathering completions.
        /// </param>
        /// <returns>
        /// A CommandCompletion instance that contains completions for the
        /// symbol at the given offset.
        /// </returns>
        static public CommandCompletion GetCompletions(
            Ast scriptAst,
            Token[] currentTokens,
            int fileOffset,
            Runspace runspace)
        {
            var type   = scriptAst.Extent.StartScriptPosition.GetType();
            var method =
#if NanoServer
                type.GetMethod(
                    "CloneWithNewOffset",
                    BindingFlags.Instance | BindingFlags.NonPublic);
#else
                type.GetMethod(
                    "CloneWithNewOffset",
                    BindingFlags.Instance | BindingFlags.NonPublic,
                    null,
                    new[] { typeof(int) }, null);
#endif

            IScriptPosition cursorPosition =
                (IScriptPosition)method.Invoke(
                    scriptAst.Extent.StartScriptPosition,
                    new object[] { fileOffset });

            Logger.Write(
                LogLevel.Verbose,
                string.Format(
                    "Getting completions at offset {0} (line: {1}, column: {2})",
                    fileOffset,
                    cursorPosition.LineNumber,
                    cursorPosition.ColumnNumber));

            CommandCompletion commandCompletion = null;
            if (runspace.RunspaceAvailability == RunspaceAvailability.Available)
            {
                using (System.Management.Automation.PowerShell powerShell =
                           System.Management.Automation.PowerShell.Create())
                {
                    powerShell.Runspace = runspace;

                    commandCompletion =
                        CommandCompletion.CompleteInput(
                            scriptAst,
                            currentTokens,
                            cursorPosition,
                            null,
                            powerShell);
                }
            }

            return(commandCompletion);
        }
 internal static CompletionResults Create(
     ScriptFile scriptFile,
     CommandCompletion commandCompletion)
 {
     return new CompletionResults
     {
         Completions = GetCompletionsArray(commandCompletion),
         ReplacedRange = 
             scriptFile.GetRangeBetweenOffsets(
                 commandCompletion.ReplacementIndex,
                 commandCompletion.ReplacementIndex + commandCompletion.ReplacementLength)
     };
 }
        public void Completion_FromEmpty_Test()
        {
            var completion = new CommandCompletion(_TestCommands);

            completion.Completion("").Is("banner");
            completion.Completion("banner").Is("clear");
            completion.Completion("clear").Is("cls");
            completion.Completion("cls").Is("figgle");
            completion.Completion("figgle").Is("figlet");
            completion.Completion("figlet").Is("help");
            completion.Completion("help").Is("banner");
            completion.Completion("banner").Is("clear");
        }
Beispiel #21
0
 internal static CompletionResults Create(
     ScriptFile scriptFile,
     CommandCompletion commandCompletion)
 {
     return(new CompletionResults
     {
         Completions = GetCompletionsArray(commandCompletion),
         ReplacedRange =
             scriptFile.GetRangeBetweenOffsets(
                 commandCompletion.ReplacementIndex,
                 commandCompletion.ReplacementIndex + commandCompletion.ReplacementLength)
     });
 }
Beispiel #22
0
 public CommandCompletion CompleteInput(string input, int cursorIndex)
 {
     System.Management.Automation.PowerShell ps;
     if (!IsRemote)
     {
         ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace);
     }
     else
     {
         ps          = System.Management.Automation.PowerShell.Create();
         ps.Runspace = _runSpace;
     }
     return(CommandCompletion.CompleteInput(input, cursorIndex, null, ps));
 }
        public void Completion_Match_to_AnotherMatch_Test()
        {
            var completion = new CommandCompletion(_TestCommands);

            completion.Completion("c").Is("clear");
            completion.Completion("clear").Is("cls");
            completion.Completion("cls").Is("clear");

            completion.Completion("he").Is("help");
            completion.Completion("help").Is("help");

            completion.Completion("").Is("banner");
            completion.Completion("banner").Is("clear");
        }
 public static PwshCommandCompletion ToPwshCompletion(this CommandCompletion completion)
 {
     return(new PwshCommandCompletion()
     {
         CurrentMatchIndex = completion.CurrentMatchIndex,
         ReplacementIndex = completion.ReplacementIndex,
         ReplacementLength = completion.ReplacementLength,
         CompletionMatches = completion.CompletionMatches
                             .Select(x => new PwshCompletionResult(x.CompletionText,
                                                                   x.ListItemText,
                                                                   EnumMapper.ToEnum <PwshCompletionResultType, CompletionResultType>(x.ResultType),
                                                                   x.ToolTip))
                             .ToList()
     });
 }
Beispiel #25
0
        public CommandCompletion GetCompletions(string inputText, int currentIndex, bool?forward)
        {
            if (_lastCompletion is null ||
                inputText != _lastInputText)
            {
                _lastInputText  = inputText;
                _lastCompletion = CommandCompletion.CompleteInput(inputText, currentIndex, new(), _powershell);
            }

            if (forward.HasValue)
            {
                _lastCompletion.GetNextResult(forward.Value);
            }

            return(_lastCompletion);
        }
Beispiel #26
0
        private void DoReplacementForCompletion(CompletionResult completionResult, CommandCompletion completions)
        {
            var replacementText  = completionResult.CompletionText;
            int cursorAdjustment = 0;

            if (completionResult.ResultType == CompletionResultType.ProviderContainer)
            {
                replacementText = GetReplacementTextForDirectory(replacementText, ref cursorAdjustment);
            }
            Replace(completions.ReplacementIndex, completions.ReplacementLength, replacementText);
            if (cursorAdjustment != 0)
            {
                MoveCursor(_current + cursorAdjustment);
            }
            completions.ReplacementLength = replacementText.Length;
        }
        private void ProcessCompletion(string script, int caretPosition, int requestWindowId, long triggerTag)
        {
            lock (_syncLock)
            {
                _requestTrigger = triggerTag;
            }

            if (_callback == null)
            {
                _callback = OperationContext.Current.GetCallbackChannel <IIntelliSenseServiceCallback>();
            }

            // Start process the existing waiting request, should only be one
            Task.Run(() =>
            {
                try
                {
                    CommandCompletion commandCompletion = null;

                    lock (ServiceCommon.RunspaceLock)
                    {
                        if (_runspace.RunspaceAvailability == RunspaceAvailability.Available)
                        {
                            commandCompletion = CommandCompletionHelper.GetCommandCompletionList(script, caretPosition, _runspace);
                        }
                        else
                        {
                            // we'll handle it when we work on giving intellisense for debugging command
                            // for now we just simply return with null for this request to complete.
                        }
                    }

                    ServiceCommon.LogCallbackEvent("Callback intellisense at position {0}", caretPosition);
                    _callback.PushCompletionResult(CompletionResultList.FromCommandCompletion(commandCompletion), requestWindowId);

                    // Reset trigger
                    lock (_syncLock)
                    {
                        _requestTrigger = 0;
                    }
                }
                catch (Exception ex)
                {
                    ServiceCommon.Log("Failed to retrieve the completion list per request due to exception: {0}", ex.Message);
                }
            });
        }
        /// <summary>
        /// Gets completions for a statement contained in the given
        /// script file at the specified line and column position.
        /// </summary>
        /// <param name="scriptFile">
        /// The script file in which completions will be gathered.
        /// </param>
        /// <param name="lineNumber">
        /// The 1-based line number at which completions will be gathered.
        /// </param>
        /// <param name="columnNumber">
        /// The 1-based column number at which completions will be gathered.
        /// </param>
        /// <returns>
        /// A CommandCompletion instance completions for the identified statement.
        /// </returns>
        public async Task <CompletionResults> GetCompletionsInFile(
            ScriptFile scriptFile,
            int lineNumber,
            int columnNumber)
        {
            Validate.IsNotNull("scriptFile", scriptFile);

            // Get the offset at the specified position.  This method
            // will also validate the given position.
            int fileOffset =
                scriptFile.GetOffsetAtPosition(
                    lineNumber,
                    columnNumber);

            RunspaceHandle runspaceHandle =
                await this.powerShellContext.GetRunspaceHandle(
                    new CancellationTokenSource(DefaultWaitTimeoutMilliseconds).Token);

            CommandCompletion commandCompletion =
                AstOperations.GetCompletions(
                    scriptFile.ScriptAst,
                    scriptFile.ScriptTokens,
                    fileOffset,
                    runspaceHandle.Runspace);

            runspaceHandle.Dispose();

            if (commandCompletion != null)
            {
                CompletionResults completionResults =
                    CompletionResults.Create(
                        scriptFile,
                        commandCompletion);

                // save state of most recent completion
                mostRecentCompletions   = completionResults;
                mostRecentRequestFile   = scriptFile.Id;
                mostRecentRequestLine   = lineNumber;
                mostRecentRequestOffest = columnNumber;

                return(completionResults);
            }
            else
            {
                return(new CompletionResults());
            }
        }
        private static string[] GetTabCompletionOutputs(string guid, string command, bool lastTokenOnly)
        {
            var session = GetScriptSession(guid);

            try
            {
                var result = CommandCompletion.FindMatches(session, command, lastTokenOnly);
                return(result.ToArray());
            }
            finally
            {
                if (string.IsNullOrEmpty(guid))
                {
                    ScriptSessionManager.RemoveSession(session);
                }
            }
        }
Beispiel #30
0
        /// <summary>
        /// Shows the tab-expansion popup.
        /// </summary>
        /// <param name="placementRectangle">The position to show the popup in.</param>
        /// <param name="list">The list of options</param>
        /// <param name="currentCommand">The current command</param>
        internal void ShowTabPopup(Rect placementRectangle, CommandCompletion list, string currentCommand)
        {
            // TODO: Minor: Sort this intelligently, by type...
            // list.Sort();
            var matches    = list.CompletionMatches;
            var listText   = matches.Select(m => m.ListItemText).ToList();
            var outputText = matches.Select(m => m.CompletionText).ToList();
            var tooltips   = matches.Select(m => m.ToolTip).ToList();

            // And filter it too
            _tabbing  = currentCommand.TrimEnd('\r', '\n');
            _lastWord = _tabbing.GetLastWord();
            // the sweet typeahead auto-filter
            _intellisense.Items.Filter = TypeAheadFilter;

            ShowPopup(placementRectangle, listText, outputText, tooltips, false, false);
        }
Beispiel #31
0
    public Option <CommandCompletion <TSpec> > Complete <TSpec>(CommandResult <TSpec> result)
        where TSpec : CommandSpec <TSpec>, new()
    {
        if (Dispatches.TryGetValue(result.SubmissionId, out ICommandDispatch dispatched))
        {
            var completion = CommandCompletion.Create((CommandDispatch <TSpec>)dispatched, result, now());
            if (!Completions.TryAdd(result.SubmissionId, completion))
            {
                throw new Exception("Can't add task to the memory completion index");
            }
            else
            {
                return(completion);
            }
        }

        return(none <CommandCompletion <TSpec> >());
    }
Beispiel #32
0
    public void Completion_FromEmpty_to_AnotherMatch_Test()
    {
        var completion = new CommandCompletion(this._TestCommands);

        completion.Completion("").Is("banner");
        completion.Completion("banner").Is("clear");

        completion.Completion("fig").Is("figgle");
        completion.Completion("figgle").Is("figlet");
        completion.Completion("figlet").Is("figgle");
        completion.Completion("figgle").Is("figlet");

        completion.Completion("he").Is("help");
        completion.Completion("help").Is("help");

        completion.Completion("").Is("banner");
        completion.Completion("banner").Is("clear");
    }
Beispiel #33
0
    public Option <ReadOnlyList <ICommandCompletion> > Complete(IEnumerable <ICommandResult> results)
    {
        var completions = MutableList.Create <ICommandCompletion>();

        foreach (var result in results)
        {
            if (Dispatches.TryGetValue(result.SubmissionId, out ICommandDispatch dispatched))
            {
                var completion = new CommandCompletion(dispatched, result, now());
                if (!Completions.TryAdd(result.SubmissionId, completion))
                {
                    throw new Exception("Can't add task to the memory completion index");
                }
                completions.Add(completion);
            }
        }

        return(ReadOnlyList.Create(completions));
    }
Beispiel #34
0
        private void PossibleCompletionsImpl(CommandCompletion completions, bool menuSelect)
        {
            if (completions == null || completions.CompletionMatches.Count == 0)
            {
                Ding();
                return;
            }

            if (completions.CompletionMatches.Count >= _options.CompletionQueryItems)
            {
                if (!PromptYesOrNo(string.Format(CultureInfo.CurrentCulture, PSReadLineResources.DisplayAllPossibilities, completions.CompletionMatches.Count)))
                {
                    return;
                }
            }

            var menu = CreateCompletionMenu(completions.CompletionMatches);

            if (menuSelect)
            {
                // Make sure the menu and line can appear on the screen at the same time,
                // if not, we'll skip the menu.

                var endBufferPoint = ConvertOffsetToPoint(_buffer.Length);
                menu.BufferLines = endBufferPoint.Y - _initialY + 1 + _options.ExtraPromptLineCount;
                if (menu.BufferLines + menu.Rows > _console.WindowHeight)
                {
                    menuSelect = false;
                }
            }

            if (menuSelect)
            {
                MenuCompleteImpl(menu, completions);
            }
            else
            {
                menu.DrawMenu(null, menuSelect: false);
                InvokePrompt(key: null, arg: _console.CursorTop);
            }
        }
Beispiel #35
0
        public bool GetCompletion(ref string input, ref int index, bool forward)
        {
            // Suggest a file if the input is blank.
            if (string.IsNullOrWhiteSpace(input))
            {
                input = PATH_BEGIN;
                index = PATH_BEGIN.Length;
            }

            if (index == 0) return false;

            // Check the user has altered the input and we need to update our
            // completion list.
            if (completionListNeedsUpdate(input, index))
            {
                completions = CommandCompletion.CompleteInput(
                    input, index, null, powerShell);
            }

            // Determine the length of the text to replace with the new
            // completion.
            var replacementLength = getCurrentReplacementLength(completions);

            // Get the completion data.
            var result = completions.GetNextResult(forward);
            if (result == null) return false;
            
            // Set input and index of the new completion.
            var replacementIndex = completions.ReplacementIndex;
            var completionText = result.CompletionText;
            expectedInput = input
                .Remove(replacementIndex, replacementLength)
                .Insert(replacementIndex, completionText);
            expectedIndex = replacementIndex + completionText.Length;

            input = expectedInput;
            index = expectedIndex;
            return true;
        }
Beispiel #36
0
        // [rgn] Public Methods (4)
        //private IPoshConsoleService _service;
        //public void SetService(IPoshConsoleService service)
        //{
        //    _service = service;
        //}
        public CommandCompletion GetChoices(string currentCommand, int cursorIndex)
        {
            ConsoleControl.TabExpansionTrace.TraceEvent(TraceEventType.Information, 1, "GetChoices for '{0}'", currentCommand);
            if (_command != currentCommand || (_choices == null || _choices.CompletionMatches.Count == 0) && (_command == null || _command != currentCommand))
            {
                if (TabComplete == null)
                    return null;

                _command = currentCommand;
                _choices = TabComplete(currentCommand, cursorIndex);
            }

            if (ConsoleControl.TabExpansionTrace.Switch.Level >= SourceLevels.Information)
            {
                ConsoleControl.TabExpansionTrace.TraceEvent(TraceEventType.Information, 2, "Choice List:");
                foreach (var ch in _choices.CompletionMatches.Select(m => m.ListItemText))
                {
                    ConsoleControl.TabExpansionTrace.TraceEvent(TraceEventType.Information, 2, ch);
                }
            }
            return _choices;
        }
Beispiel #37
0
 public void Reset()
 {
     _index = 0;
     _command = null;
     _choices = null;
 }
Beispiel #38
0
        private CommandCompletion GetCompletions()
        {
            if (_tabCommandCount == 0)
            {
                try
                {
                    _tabCompletions = null;

                    // Could use the overload that takes an AST as it's faster (we've already parsed the
                    // input for coloring) but that overload is a little more complicated in passing in the
                    // cursor position.
                    System.Management.Automation.PowerShell ps;
                    if (!_mockableMethods.RunspaceIsRemote(_runspace))
                    {
                        ps = System.Management.Automation.PowerShell.Create(RunspaceMode.CurrentRunspace);
                    }
                    else
                    {
                        ps = System.Management.Automation.PowerShell.Create();
                        ps.Runspace = _runspace;
                    }
                    String tmpBufferStringForCompleteInput = Options.UseTraditionalCompleteInput ? _buffer.ToString().Substring(0, _current) : _buffer.ToString();
                    _tabCompletions = _mockableMethods.CompleteInput(tmpBufferStringForCompleteInput, _current, null, ps);

                    if (_tabCompletions.CompletionMatches.Count == 0)
                        return null;
                }
                catch (Exception)
                {
                }
            }

            return _tabCompletions;
        }
Beispiel #39
0
        private CommandCompletion GetCompletions()
        {
            if (_tabCommandCount == 0)
            {
                try
                {
                    _tabCompletions = null;

                    // Could use the overload that takes an AST as it's faster (we've already parsed the
                    // input for coloring) but that overload is a little more complicated in passing in the
                    // cursor position.
                    PowerShell ps;
                    if (_remoteRunspace == null)
                    {
                        ps = PowerShell.Create(RunspaceMode.CurrentRunspace);
                    }
                    else
                    {
                        ps = PowerShell.Create();
                        ps.Runspace = _remoteRunspace;
                    }
                    _tabCompletions = _mockableMethods.CompleteInput(_buffer.ToString(), _current, null, ps);

                    if (_tabCompletions.CompletionMatches.Count == 0)
                        return null;
                }
                catch (Exception)
                {
                }
            }

            return _tabCompletions;
        }
Beispiel #40
0
        /// <summary>
        /// Shows the tab-expansion popup.
        /// </summary>
        /// <param name="placementRectangle">The position to show the popup in.</param>
        /// <param name="list">The list of options</param>
        /// <param name="currentCommand">The current command</param>
        internal void ShowTabPopup(Rect placementRectangle, CommandCompletion list, string currentCommand)
        {
            // TODO: Minor: Sort this intelligently, by type...
            // list.Sort();
            var matches = list.CompletionMatches;
            var listText = matches.Select(m => m.ListItemText).ToList();
            var outputText = matches.Select(m => m.CompletionText).ToList();
            var tooltips = matches.Select(m => m.ToolTip).ToList();

            // And filter it too
            _tabbing = currentCommand.TrimEnd('\r', '\n');
            _lastWord = _tabbing.GetLastWord();
            // the sweet typeahead auto-filter
            _intellisense.Items.Filter = TypeAheadFilter;

            ShowPopup(placementRectangle, listText, outputText, tooltips, false, false);
        }
 internal static CompletionResults Create(
     CommandCompletion commandCompletion)
 {
     return new CompletionResults
     {
         Completions = GetCompletionsArray(commandCompletion),
     };
 }
        private void PossibleCompletionsImpl(CommandCompletion completions, bool menuSelect)
        {
            if (completions == null || completions.CompletionMatches.Count == 0)
            {
                Ding();
                return;
            }

            if (completions.CompletionMatches.Count >= _options.CompletionQueryItems)
            {
                if (!PromptYesOrNo(string.Format(CultureInfo.CurrentCulture, PSReadLineResources.DisplayAllPossibilities, completions.CompletionMatches.Count)))
                {
                    return;
                }
            }

            var matches = completions.CompletionMatches;
            var minColWidth = matches.Max(c => c.ListItemText.Length);
            minColWidth += 2;
            var menuColumnWidth = minColWidth;

            int displayRows;
            var bufferWidth = Console.BufferWidth;
            ConsoleBufferBuilder cb;
            if (Options.ShowToolTips)
            {
                const string seperator = "- ";
                var maxTooltipWidth = bufferWidth - minColWidth - seperator.Length;

                displayRows = matches.Count;
                cb = new ConsoleBufferBuilder(displayRows * bufferWidth);
                for (int index = 0; index < matches.Count; index++)
                {
                    var match = matches[index];
                    var listItemText = HandleNewlinesForPossibleCompletions(match.ListItemText);
                    cb.Append(listItemText);
                    var spacesNeeded = minColWidth - listItemText.Length;
                    if (spacesNeeded > 0)
                    {
                        cb.Append(' ', spacesNeeded);
                    }
                    cb.Append(seperator);
                    var toolTip = HandleNewlinesForPossibleCompletions(match.ToolTip);
                    toolTip = toolTip.Length <= maxTooltipWidth
                                  ? toolTip
                                  : toolTip.Substring(0, maxTooltipWidth);
                    cb.Append(toolTip);

                    // Make sure we always write out exactly 1 buffer width
                    spacesNeeded = (bufferWidth * (index + 1)) - cb.Length;
                    if (spacesNeeded > 0)
                    {
                        cb.Append(' ', spacesNeeded);
                    }
                }
                menuColumnWidth = bufferWidth;
            }
            else
            {
                var screenColumns = bufferWidth;
                var displayColumns = Math.Max(1, screenColumns / minColWidth);
                displayRows = (completions.CompletionMatches.Count + displayColumns - 1) / displayColumns;
                cb = new ConsoleBufferBuilder(displayRows * bufferWidth);
                for (var row = 0; row < displayRows; row++)
                {
                    for (var col = 0; col < displayColumns; col++)
                    {
                        var index = row + (displayRows * col);
                        if (index >= matches.Count)
                            break;
                        var match = matches[index];
                        var item = HandleNewlinesForPossibleCompletions(match.ListItemText);
                        cb.Append(item);
                        cb.Append(' ', minColWidth - item.Length);
                    }

                    // Make sure we always write out exactly 1 buffer width
                    var spacesNeeded = (bufferWidth * (row + 1)) - cb.Length;
                    if (spacesNeeded > 0)
                    {
                        cb.Append(' ', spacesNeeded);
                    }
                }
            }

            var menuBuffer = cb.ToArray();

            if (menuSelect)
            {
                // Make sure the menu and line can appear on the screen at the same time,
                // if not, we'll skip the menu.

                var endBufferCoords = ConvertOffsetToCoordinates(_buffer.Length);
                var bufferLines = endBufferCoords.Y - _initialY + 1;
                if ((bufferLines + displayRows) > Console.WindowHeight)
                {
                    menuSelect = false;
                }
            }

            if (menuSelect)
            {
                RemoveEditsAfterUndo();
                var undoPoint = _edits.Count;

                int selectedItem = 0;
                bool undo = false;

                DoReplacementForCompletion(matches[0], completions);

                // Recompute end of buffer coordinates as the replacement could have
                // added a line.
                var endBufferCoords = ConvertOffsetToCoordinates(_buffer.Length);
                var menuAreaTop = endBufferCoords.Y + 1;
                var previousMenuTop = menuAreaTop;

                InvertSelectedCompletion(menuBuffer, selectedItem, menuColumnWidth, displayRows);
                WriteBufferLines(menuBuffer, ref menuAreaTop);

                // Showing the menu may have scrolled the screen or moved the cursor, update initialY to reflect that.
                _initialY -= (previousMenuTop - menuAreaTop);
                PlaceCursor();
                previousMenuTop = menuAreaTop;

                int previousItem = selectedItem;

                bool processingKeys = true;
                while (processingKeys)
                {
                    var nextKey = ReadKey();
                    if (nextKey == Keys.RightArrow)
                    {
                        selectedItem = Math.Min(selectedItem + displayRows, matches.Count - 1);
                    }
                    else if (nextKey == Keys.LeftArrow)
                    {
                        selectedItem = Math.Max(selectedItem - displayRows, 0);
                    }
                    else if (nextKey == Keys.DownArrow)
                    {
                        selectedItem = Math.Min(selectedItem + 1, matches.Count - 1);
                    }
                    else if (nextKey == Keys.UpArrow)
                    {
                        selectedItem = Math.Max(selectedItem - 1, 0);
                    }
                    else if (nextKey == Keys.Tab)
                    {
                        selectedItem = (selectedItem + 1) % matches.Count;
                    }
                    else if (nextKey == Keys.ShiftTab)
                    {
                        selectedItem = (selectedItem - 1) % matches.Count;
                        if (selectedItem < 0)
                        {
                            selectedItem += matches.Count;
                        }
                    }
                    else if (nextKey == Keys.CtrlG || nextKey == Keys.Escape)
                    {
                        undo = true;
                        processingKeys = false;
                    }
                    else
                    {
                        PrependQueuedKeys(nextKey);
                        processingKeys = false;
                    }

                    if (selectedItem != previousItem)
                    {
                        DoReplacementForCompletion(matches[selectedItem], completions);

                        endBufferCoords = ConvertOffsetToCoordinates(_buffer.Length);
                        menuAreaTop = endBufferCoords.Y + 1;

                        InvertSelectedCompletion(menuBuffer, previousItem, menuColumnWidth, displayRows);
                        InvertSelectedCompletion(menuBuffer, selectedItem, menuColumnWidth, displayRows);
                        WriteBufferLines(menuBuffer, ref menuAreaTop);
                        previousItem = selectedItem;

                        if (previousMenuTop > menuAreaTop)
                        {
                            WriteBlankLines(previousMenuTop - menuAreaTop, menuAreaTop + displayRows);
                        }
                    }
                }

                WriteBlankLines(displayRows, menuAreaTop);

                var lastInsert = ((GroupedEdit)_edits[_edits.Count - 1])._groupedEditItems[1];
                Debug.Assert(lastInsert is EditItemInsertString, "The only edits possible here are pairs of Delete/Insert");
                var firstDelete = ((GroupedEdit)_edits[undoPoint])._groupedEditItems[0];
                Debug.Assert(firstDelete is EditItemDelete, "The only edits possible here are pairs of Delete/Insert");

                var groupEditCount = _edits.Count - undoPoint;
                _edits.RemoveRange(undoPoint, groupEditCount);
                _undoEditIndex = undoPoint;

                if (undo)
                {
                    // Pretend it never happened.
                    lastInsert.Undo();
                    firstDelete.Undo();
                    Render();
                }
                else
                {
                    // Leave one edit instead of possibly many to undo
                    SaveEditItem(GroupedEdit.Create(new List<EditItem> { firstDelete, lastInsert }));
                }
            }
            else
            {
                var endBufferCoords = ConvertOffsetToCoordinates(_buffer.Length);
                var menuAreaTop = endBufferCoords.Y + 1;

                WriteBufferLines(menuBuffer, ref menuAreaTop);
                _initialY = menuAreaTop + displayRows;
                Render();
            }
        }
Beispiel #43
0
 private void DoReplacementForCompletion(CompletionResult completionResult, CommandCompletion completions)
 {
     var replacementText = completionResult.CompletionText;
     int cursorAdjustment = 0;
     if (completionResult.ResultType == CompletionResultType.ProviderContainer)
     {
         replacementText = GetReplacementTextForDirectory(replacementText, ref cursorAdjustment);
     }
     Replace(completions.ReplacementIndex, completions.ReplacementLength, replacementText);
     if (cursorAdjustment != 0)
     {
         _current += cursorAdjustment;
         PlaceCursor();
     }
     completions.ReplacementLength = replacementText.Length;
 }