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); }
public ICommandExpansion GetCommandExpansion(WpfConsole console) { return(GetSingletonHostService <ICommandExpansion, ICommandExpansionProvider>(console, CommandExpansionProviders, (factory, host) => factory.Create(host), () => null)); }
public ICommandTokenizer GetCommandTokenizer(WpfConsole console) { return(GetSingletonHostService <ICommandTokenizer, ICommandTokenizerProvider>(console, CommandTokenizerProviders, (factory, host) => factory.Create(host), () => null)); }
protected void PromptNewLine() { WpfConsole.Write(WpfConsole.Host.Prompt + (char)32); // 32 is the space WpfConsole.BeginInputLine(); }
protected void PromptNewLine() { NuGetUIThreadHelper.JoinableTaskFactory.Run(() => WpfConsole.WriteAsync(WpfConsole.Host.Prompt + ' ')); WpfConsole.BeginInputLine(); }
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 ); } } }
private static Task EndInputLineAsync(WpfConsole wpfConsole) { wpfConsole.EndInputLine(); return(Task.CompletedTask); }
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); }