Пример #1
0
        protected override int InternalExec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            int hr = OLECMDERR_E_NOTSUPPORTED;

            if (!WpfConsole.Host.IsCommandEnabled)
            {
                return(hr);
            }

            // if the console has not been successfully started, do not accept any key inputs
            if (!WpfConsole.Dispatcher.IsStartCompleted)
            {
                return(hr);
            }

            // if the console is in the middle of executing a command, do not accept any key inputs
            if (WpfConsole.Dispatcher.IsExecutingCommand)
            {
                return(hr);
            }

            if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
            {
                //Debug.Print("Exec: GUID_VSStandardCommandSet97: {0}", (VSConstants.VSStd97CmdID)nCmdID);

                switch ((VSConstants.VSStd97CmdID)nCmdID)
                {
                case VSConstants.VSStd97CmdID.Paste:
                    if (IsCaretInReadOnlyRegion || IsSelectionReadonly)
                    {
                        hr = VSConstants.S_OK;     // eat it
                    }
                    else
                    {
                        PasteText(ref hr);
                    }
                    break;
                }
            }
            else if (pguidCmdGroup == VSConstants.VSStd2K)
            {
                //Debug.Print("Exec: VSStd2K: {0}", (VSConstants.VSStd2KCmdID)nCmdID);

                switch ((VSConstants.VSStd2KCmdID)nCmdID)
                {
                case VSConstants.VSStd2KCmdID.TYPECHAR:
                    if (IsCompletionSessionActive)
                    {
                        char ch = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
                        if (IsCommitChar(ch))
                        {
                            if (_completionSession.SelectedCompletionSet.SelectionStatus.IsSelected)
                            {
                                _completionSession.Commit();
                            }
                            else
                            {
                                _completionSession.Dismiss();
                            }
                        }
                    }
                    else
                    {
                        if (IsSelectionReadonly)
                        {
                            WpfTextView.Selection.Clear();
                        }
                        if (IsCaretInReadOnlyRegion)
                        {
                            WpfTextView.Caret.MoveTo(WpfConsole.InputLineExtent.End);
                        }
                    }
                    break;

                case VSConstants.VSStd2KCmdID.LEFT:
                case VSConstants.VSStd2KCmdID.LEFT_EXT:
                case VSConstants.VSStd2KCmdID.LEFT_EXT_COL:
                case VSConstants.VSStd2KCmdID.WORDPREV:
                case VSConstants.VSStd2KCmdID.WORDPREV_EXT:
                case VSConstants.VSStd2KCmdID.WORDPREV_EXT_COL:
                    if (IsCaretAtInputLineStart)
                    {
                        //
                        // Note: This simple implementation depends on Prompt containing a trailing space.
                        // When caret is on the right of InputLineStart, editor will handle it correctly,
                        // and caret won't move left to InputLineStart because of the trailing space.
                        //
                        hr = VSConstants.S_OK;     // eat it
                    }
                    break;

                case VSConstants.VSStd2KCmdID.BOL:
                case VSConstants.VSStd2KCmdID.BOL_EXT:
                case VSConstants.VSStd2KCmdID.BOL_EXT_COL:
                    if (IsCaretOnInputLine)
                    {
                        VirtualSnapshotPoint oldCaretPoint = WpfTextView.Caret.Position.VirtualBufferPosition;

                        WpfTextView.Caret.MoveTo(WpfConsole.InputLineStart.Value);
                        WpfTextView.Caret.EnsureVisible();

                        if ((VSConstants.VSStd2KCmdID)nCmdID == VSConstants.VSStd2KCmdID.BOL)
                        {
                            WpfTextView.Selection.Clear();
                        }
                        else if ((VSConstants.VSStd2KCmdID)nCmdID != VSConstants.VSStd2KCmdID.BOL)     // extend selection
                        {
                            VirtualSnapshotPoint anchorPoint = WpfTextView.Selection.IsEmpty ?
                                                               oldCaretPoint.TranslateTo(WpfTextView.TextSnapshot) : WpfTextView.Selection.AnchorPoint;
                            WpfTextView.Selection.Select(anchorPoint, WpfTextView.Caret.Position.VirtualBufferPosition);
                        }

                        hr = VSConstants.S_OK;
                    }
                    break;

                case VSConstants.VSStd2KCmdID.UP:
                    if (!IsCompletionSessionActive)
                    {
                        if (IsCaretInReadOnlyRegion)
                        {
                            ExecuteCommand(VSConstants.VSStd2KCmdID.END);
                        }
                        WpfConsole.NavigateHistory(-1);
                        hr = VSConstants.S_OK;
                    }
                    break;

                case VSConstants.VSStd2KCmdID.DOWN:
                    if (!IsCompletionSessionActive)
                    {
                        if (IsCaretInReadOnlyRegion)
                        {
                            ExecuteCommand(VSConstants.VSStd2KCmdID.END);
                        }
                        WpfConsole.NavigateHistory(+1);
                        hr = VSConstants.S_OK;
                    }
                    break;

                case VSConstants.VSStd2KCmdID.RETURN:
                    if (IsCompletionSessionActive)
                    {
                        if (_completionSession.SelectedCompletionSet.SelectionStatus.IsSelected)
                        {
                            _completionSession.Commit();
                        }
                        else
                        {
                            _completionSession.Dismiss();
                        }
                    }
                    else if (IsCaretOnInputLine || !IsCaretInReadOnlyRegion)
                    {
                        ExecuteCommand(VSConstants.VSStd2KCmdID.END);
                        ExecuteCommand(VSConstants.VSStd2KCmdID.RETURN);

                        WpfConsole.EndInputLine();
                    }
                    hr = VSConstants.S_OK;
                    break;

                case VSConstants.VSStd2KCmdID.TAB:
                    if (!IsCaretInReadOnlyRegion)
                    {
                        if (IsCompletionSessionActive)
                        {
                            _completionSession.Commit();
                        }
                        else
                        {
                            TriggerCompletion();
                        }
                    }
                    hr = VSConstants.S_OK;
                    break;

                case VSConstants.VSStd2KCmdID.CANCEL:
                    if (IsCompletionSessionActive)
                    {
                        _completionSession.Dismiss();
                        hr = VSConstants.S_OK;
                    }
                    else if (!IsCaretInReadOnlyRegion)
                    {
                        // Delete all text after InputLineStart
                        WpfTextView.TextBuffer.Delete(WpfConsole.AllInputExtent);
                        hr = VSConstants.S_OK;
                    }
                    break;

                case VSConstants.VSStd2KCmdID.CUTLINE:
                    // clears the console when CutLine shortcut key is pressed,
                    // usually it is Ctrl + L
                    WpfConsole.ClearConsole();
                    hr = VSConstants.S_OK;
                    break;
                }
            }

            return(hr);
        }
Пример #2
0
 public ICommandExpansion GetCommandExpansion(WpfConsole console)
 {
     return(GetSingletonHostService <ICommandExpansion, ICommandExpansionProvider>(console, CommandExpansionProviders,
                                                                                   (factory, host) => factory.Create(host),
                                                                                   () => null));
 }
Пример #3
0
 public ICommandTokenizer GetCommandTokenizer(WpfConsole console)
 {
     return(GetSingletonHostService <ICommandTokenizer, ICommandTokenizerProvider>(console, CommandTokenizerProviders,
                                                                                   (factory, host) => factory.Create(host),
                                                                                   () => null));
 }
Пример #4
0
 protected void PromptNewLine()
 {
     WpfConsole.Write(WpfConsole.Host.Prompt + (char)32); // 32 is the space
     WpfConsole.BeginInputLine();
 }
Пример #5
0
 protected void PromptNewLine()
 {
     NuGetUIThreadHelper.JoinableTaskFactory.Run(() => WpfConsole.WriteAsync(WpfConsole.Host.Prompt + ' '));
     WpfConsole.BeginInputLine();
 }
Пример #6
0
        public void Start()
        {
            // Only Start once
            lock (_lockObj)
            {
                if (_dispatcher == null)
                {
                    IHost host = WpfConsole.Host;

                    if (host == null)
                    {
                        throw new InvalidOperationException("Can't start Console dispatcher. Host is null.");
                    }

                    if (host is IAsyncHost)
                    {
                        _dispatcher = new AsyncHostConsoleDispatcher(this);
                    }
                    else
                    {
                        _dispatcher = new SyncHostConsoleDispatcher(this);
                    }

                    // capture the cultures to assign to the worker thread below
                    CultureInfo currentCulture   = CultureInfo.CurrentCulture;
                    CultureInfo currentUICulture = CultureInfo.CurrentUICulture;

                    // changed from Task.Factory.StartNew to Task.Run in order to run with
                    // default TaskSchedular instead of current.
                    Task.Run(
                        // gives the host a chance to do initialization works before the console starts accepting user inputs
                        () =>
                    {
                        // apply the culture of the main thread to this thread so that the PowerShell engine
                        // will have the same culture as Visual Studio.
                        Thread.CurrentThread.CurrentCulture   = currentCulture;
                        Thread.CurrentThread.CurrentUICulture = currentUICulture;

                        host.Initialize(WpfConsole);
                    }
                        ).ContinueWith(
                        task =>
                    {
                        NuGetUIThreadHelper.JoinableTaskFactory.Run(async delegate
                        {
                            await NuGetUIThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
                            if (task.IsFaulted)
                            {
                                var exception = ExceptionUtilities.Unwrap(task.Exception);
                                if (WpfConsole != null)
                                {
                                    await WpfConsole.WriteAsync(exception.Message + Environment.NewLine, Colors.Red, null);
                                }
                            }

                            if (host.IsCommandEnabled &&
                                _dispatcher != null)
                            {
                                _dispatcher.Start();
                            }

                            RaiseEventSafe(StartCompleted);
                            IsStartCompleted = true;
                        });
                    },
                        TaskContinuationOptions.NotOnCanceled
                        );
                }
            }
        }
Пример #7
0
 private static Task EndInputLineAsync(WpfConsole wpfConsole)
 {
     wpfConsole.EndInputLine();
     return(Task.CompletedTask);
 }
Пример #8
0
        protected override int InternalExec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            int hr = OLECMDERR_E_NOTSUPPORTED;

            if (WpfConsole == null ||
                WpfConsole.Host == null ||
                WpfConsole.Dispatcher == null)
            {
                return(hr);
            }

            if (!WpfConsole.Host.IsCommandEnabled)
            {
                return(hr);
            }

            if (!WpfConsole.Dispatcher.IsExecutingReadKey)
            {
                // if the console has not been successfully started, do not accept any key inputs, unless
                // we are in the middle of a ReadKey call. This happens when the execution group policy setting
                // is set to AllSigned, and PS is asking user to trust the certificate.
                if (!WpfConsole.Dispatcher.IsStartCompleted)
                {
                    return(hr);
                }

                // if the console is in the middle of executing a command, do not accept any key inputs unless
                // we are in the middle of a ReadKey call.
                if (WpfConsole.Dispatcher.IsExecutingCommand)
                {
                    return(hr);
                }
            }

            if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97)
            {
                //Debug.Print("Exec: GUID_VSStandardCommandSet97: {0}", (VSConstants.VSStd97CmdID)nCmdID);

                switch ((VSConstants.VSStd97CmdID)nCmdID)
                {
                case VSConstants.VSStd97CmdID.Paste:
                    if (IsCaretInReadOnlyRegion || IsSelectionReadonly)
                    {
                        hr = VSConstants.S_OK;     // eat it
                    }
                    else
                    {
                        PasteText(ref hr);
                    }
                    break;
                }
            }
            else if (pguidCmdGroup == VSConstants.VSStd2K)
            {
                //Debug.Print("Exec: VSStd2K: {0}", (VSConstants.VSStd2KCmdID)nCmdID);

                var commandID = (VSConstants.VSStd2KCmdID)nCmdID;

                if (WpfConsole.Dispatcher.IsExecutingReadKey)
                {
                    switch (commandID)
                    {
                    case VSConstants.VSStd2KCmdID.TYPECHAR:
                    case VSConstants.VSStd2KCmdID.BACKSPACE:
                    case VSConstants.VSStd2KCmdID.RETURN:
                        var keyInfo = GetVsKeyInfo(pvaIn, commandID);
                        WpfConsole.Dispatcher.PostKey(keyInfo);
                        break;

                    case VSConstants.VSStd2KCmdID.CANCEL:     // Handle ESC
                        WpfConsole.Dispatcher.CancelWaitKey();
                        break;
                    }
                    hr = VSConstants.S_OK; // eat everything
                }
                else
                {
                    switch (commandID)
                    {
                    case VSConstants.VSStd2KCmdID.TYPECHAR:
                        if (IsCompletionSessionActive)
                        {
                            char ch = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
                            if (IsCommitChar(ch))
                            {
                                if (_completionSession.SelectedCompletionSet.SelectionStatus.IsSelected)
                                {
                                    _completionSession.Commit();
                                }
                                else
                                {
                                    _completionSession.Dismiss();
                                }
                            }
                        }
                        else
                        {
                            if (IsSelectionReadonly)
                            {
                                WpfTextView.Selection.Clear();
                            }
                            if (IsCaretInReadOnlyRegion)
                            {
                                WpfTextView.Caret.MoveTo(WpfConsole.InputLineExtent.End);
                            }
                        }
                        break;

                    case VSConstants.VSStd2KCmdID.LEFT:
                    case VSConstants.VSStd2KCmdID.LEFT_EXT:
                    case VSConstants.VSStd2KCmdID.LEFT_EXT_COL:
                    case VSConstants.VSStd2KCmdID.WORDPREV:
                    case VSConstants.VSStd2KCmdID.WORDPREV_EXT:
                    case VSConstants.VSStd2KCmdID.WORDPREV_EXT_COL:
                        if (IsCaretAtInputLineStart)
                        {
                            //
                            // Note: This simple implementation depends on Prompt containing a trailing space.
                            // When caret is on the right of InputLineStart, editor will handle it correctly,
                            // and caret won't move left to InputLineStart because of the trailing space.
                            //
                            hr = VSConstants.S_OK;     // eat it
                        }
                        break;

                    case VSConstants.VSStd2KCmdID.BOL:
                    case VSConstants.VSStd2KCmdID.BOL_EXT:
                    case VSConstants.VSStd2KCmdID.BOL_EXT_COL:
                        if (IsCaretOnInputLine)
                        {
                            VirtualSnapshotPoint oldCaretPoint = WpfTextView.Caret.Position.VirtualBufferPosition;

                            WpfTextView.Caret.MoveTo(WpfConsole.InputLineStart.Value);
                            WpfTextView.Caret.EnsureVisible();

                            if ((VSConstants.VSStd2KCmdID)nCmdID == VSConstants.VSStd2KCmdID.BOL)
                            {
                                WpfTextView.Selection.Clear();
                            }
                            else if ((VSConstants.VSStd2KCmdID)nCmdID != VSConstants.VSStd2KCmdID.BOL)
                            // extend selection
                            {
                                VirtualSnapshotPoint anchorPoint = WpfTextView.Selection.IsEmpty
                                        ? oldCaretPoint.TranslateTo(
                                    WpfTextView.TextSnapshot)
                                        : WpfTextView.Selection.AnchorPoint;
                                WpfTextView.Selection.Select(anchorPoint,
                                                             WpfTextView.Caret.Position.VirtualBufferPosition);
                            }

                            hr = VSConstants.S_OK;
                        }
                        break;

                    case VSConstants.VSStd2KCmdID.UP:
                        if (!IsCompletionSessionActive)
                        {
                            if (IsCaretInReadOnlyRegion)
                            {
                                ExecuteCommand(VSConstants.VSStd2KCmdID.END);
                            }
                            WpfConsole.NavigateHistory(-1);
                            hr = VSConstants.S_OK;
                        }
                        break;

                    case VSConstants.VSStd2KCmdID.DOWN:
                        if (!IsCompletionSessionActive)
                        {
                            if (IsCaretInReadOnlyRegion)
                            {
                                ExecuteCommand(VSConstants.VSStd2KCmdID.END);
                            }
                            WpfConsole.NavigateHistory(+1);
                            hr = VSConstants.S_OK;
                        }
                        break;

                    case VSConstants.VSStd2KCmdID.RETURN:
                        if (IsCompletionSessionActive)
                        {
                            if (_completionSession.SelectedCompletionSet.SelectionStatus.IsSelected)
                            {
                                _completionSession.Commit();
                            }
                            else
                            {
                                _completionSession.Dismiss();
                            }
                        }
                        else if (IsCaretOnInputLine || !IsCaretInReadOnlyRegion)
                        {
                            ExecuteCommand(VSConstants.VSStd2KCmdID.END);
                            ExecuteCommand(VSConstants.VSStd2KCmdID.RETURN);

                            NuGetUIThreadHelper.JoinableTaskFactory
                            .RunAsync(() => EndInputLineAsync(WpfConsole))
                            .PostOnFailure(nameof(WpfConsoleKeyProcessor));
                        }
                        hr = VSConstants.S_OK;
                        break;

                    case VSConstants.VSStd2KCmdID.TAB:
                        if (!IsCaretInReadOnlyRegion)
                        {
                            if (IsCompletionSessionActive)
                            {
                                _completionSession.Commit();
                            }
                            else
                            {
                                NuGetUIThreadHelper.JoinableTaskFactory.RunAsync(async delegate { await TriggerCompletionAsync(); })
                                .PostOnFailure(nameof(WpfConsoleKeyProcessor));
                            }
                        }
                        hr = VSConstants.S_OK;
                        break;

                    case VSConstants.VSStd2KCmdID.CANCEL:
                        if (IsCompletionSessionActive)
                        {
                            _completionSession.Dismiss();
                            hr = VSConstants.S_OK;
                        }
                        else if (!IsCaretInReadOnlyRegion)
                        {
                            // Delete all text after InputLineStart
                            WpfTextView.TextBuffer.Delete(WpfConsole.AllInputExtent);
                            hr = VSConstants.S_OK;
                        }
                        break;

                    case VSConstants.VSStd2KCmdID.CUTLINE:
                        // clears the console when CutLine shortcut key is pressed,
                        // usually it is Ctrl + L
                        WpfConsole.ClearConsole();
                        hr = VSConstants.S_OK;
                        break;
                    }
                }
            }
            return(hr);
        }