public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { var handled = false; var hresult = VSConstants.S_OK; if (pguidCmdGroup == VSConstants.VSStd2K) { switch ((VSConstants.VSStd2KCmdID) nCmdID) { case VSConstants.VSStd2KCmdID.AUTOCOMPLETE: case VSConstants.VSStd2KCmdID.COMPLETEWORD: handled = true; if (IsSessionStarted) break; _currentSession = StartSession(); break; case VSConstants.VSStd2KCmdID.RETURN: if (!IsSessionStarted) break; handled = true; _currentSession.Commit(); break; case VSConstants.VSStd2KCmdID.TAB: if (!IsSessionStarted) break; handled = true; _currentSession.Commit(); break; case VSConstants.VSStd2KCmdID.CANCEL: if (!IsSessionStarted) break; handled = true; _currentSession.Dismiss(); break; } } if (!handled) hresult = Next.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); if (ErrorHandler.Succeeded(hresult)) { if (pguidCmdGroup == VSConstants.VSStd2K) { switch ((VSConstants.VSStd2KCmdID) nCmdID) { case VSConstants.VSStd2KCmdID.TYPECHAR: if (IsSessionStarted) _currentSession.Filter(); break; case VSConstants.VSStd2KCmdID.BACKSPACE: if (IsSessionStarted) { _currentSession.Dismiss(); _currentSession = StartSession(); } break; } } } return hresult; }
public bool Commit() { if (_session == null) { return(false); } var isBuilder = _session.SelectedCompletionSet?.SelectionStatus?.Completion != null && _session.SelectedCompletionSet.CompletionBuilders != null && _session.SelectedCompletionSet.CompletionBuilders.Contains(_session.SelectedCompletionSet.SelectionStatus.Completion); // If it's a builder, we don't want to eat the enter key. var sendThrough = isBuilder; //_workspace.CurrentDocumentChanged -= WorkspaceOnCurrentDocumentChanged; _session.Commit(); //_workspace.CurrentDocumentChanged += WorkspaceOnCurrentDocumentChanged; return(!sendThrough); }
private bool SelectSingleBestCompletion(ICompletionSession session) { if (session.CompletionSets.Count != 1) { return(false); } var set = session.CompletionSets[0] as FuzzyCompletionSet; if (set == null) { return(false); } set.Filter(); if (set.SelectSingleBest()) { session.Commit(); return(true); } return(false); }
public virtual bool CommitCompletion() { ICompletionSession session = CompletionSession; if (session != null && session.SelectedCompletionSet != null && session.SelectedCompletionSet.SelectionStatus != null) { Completion completion = session.SelectedCompletionSet.SelectionStatus.Completion; if (completion != null && session.SelectedCompletionSet.SelectionStatus.IsSelected) { ITrackingSpan applicableToSpan = session.SelectedCompletionSet.ApplicableTo; if (applicableToSpan != null && applicableToSpan.GetSpan(applicableToSpan.TextBuffer.CurrentSnapshot).GetText() != completion.InsertionText) { session.Commit(); return(true); } } } DismissCompletion(); return(false); }
private bool Complete(bool force) { // Handle non-existant Sessions if (_currentSession == null) { return(false); } // Based off of the available selection, determine if it should be dismissed (via Dismiss) or // output (via Commit) if (!_currentSession.SelectedCompletionSet.SelectionStatus.IsSelected && !force) { _currentSession.Dismiss(); return(false); } else { _currentSession.Commit(); return(true); } }
public static bool TryShift(ITextView view, ICompletionBroker broker, RotationDirection direction) { try { string key = direction == RotationDirection.Right ? "{DOWN}" : "{UP}"; if (!broker.IsCompletionActive(view)) { ICompletionSession session = broker.TriggerCompletion(view); if (session == null || !session.IsStarted) { return(false); } Completion active = session.CompletionSets?[0]?.SelectionStatus?.Completion; if (active != null) { SendKeys.SendWait(key); session.Commit(); return(true); } } else { SendKeys.Send(key); return(true); } } catch (Exception ex) { var outputPane = ThreadHelper.JoinableTaskContext.Factory.Run(DialPackage.GetOutputPaneAsync); outputPane.WriteLine("Intellisense shifter failed"); outputPane.WriteLine(ex.ToString()); } return(false); }
internal void TriggerCompletionSession(bool completeWord) { Dismiss(); _activeSession = CompletionBroker.TriggerCompletion(_textView); if (_activeSession != null) { if (completeWord && _activeSession.CompletionSets.Count == 1 && _activeSession.CompletionSets[0].Completions.Count == 1) { _activeSession.Commit(); } else { AttachKeyboardFilter(); _activeSession.Dismissed += new EventHandler(OnSessionDismissedOrCommitted); _activeSession.Committed += new EventHandler(OnSessionDismissedOrCommitted); } } }
public bool ExecuteKeyboardCommand(IntellisenseKeyboardCommand command) { switch (command) { case IntellisenseKeyboardCommand.Up: Move(-1); return(true); case IntellisenseKeyboardCommand.Down: Move(1); return(true); case IntellisenseKeyboardCommand.PageUp: Move(-10); return(true); case IntellisenseKeyboardCommand.PageDown: Move(10); return(true); case IntellisenseKeyboardCommand.Enter: _completionSession.Commit(); return(true); case IntellisenseKeyboardCommand.Escape: _completionSession.Dismiss(); return(true); //Maybe one day we'll do something with these below case IntellisenseKeyboardCommand.End: case IntellisenseKeyboardCommand.Home: case IntellisenseKeyboardCommand.DecreaseFilterLevel: case IntellisenseKeyboardCommand.IncreaseFilterLevel: case IntellisenseKeyboardCommand.TopLine: case IntellisenseKeyboardCommand.BottomLine: break; } return(false); }
public virtual void TriggerCompletion(ITrackingPoint triggerPoint, CompletionInfoType completionInfoType, IntellisenseInvocationType intellisenseInvocationType) { DismissCompletion(); CompletionInfo.InfoType = completionInfoType; CompletionInfo.InvocationType = intellisenseInvocationType; ICompletionSession session = Provider.CompletionBroker.TriggerCompletion(TextView, triggerPoint, true); if (session != null) { session.Committed += HandleCompletionCommitted; session.Dismissed += HandleCompletionDismissed; CompletionSession = session; if (completionInfoType == CompletionInfoType.GlobalInfo && !session.IsDismissed && session.SelectedCompletionSet.SelectionStatus.IsSelected && session.SelectedCompletionSet.SelectionStatus.IsUnique) { session.Commit(); } } }
public static bool TryShift(ITextView view, ICompletionBroker broker, RotationDirection direction) { try { string key = direction == RotationDirection.Right ? "{DOWN}" : "{UP}"; if (!broker.IsCompletionActive(view)) { ICompletionSession session = broker.TriggerCompletion(view); if (session == null || !session.IsStarted) { return(false); } Completion active = session.CompletionSets?[0]?.SelectionStatus?.Completion; if (active != null) { SendKeys.SendWait(key); session.Commit(); return(true); } } else { SendKeys.Send(key); return(true); } } catch (Exception ex) { Logger.Instance.Log(ex); } return(false); }
private void StartSession(ITrackingPoint triggerPoint) { Log.Debug("Creating new completion session..."); _broker.DismissAllSessions(_textView); _activeSession = _broker.CreateCompletionSession(_textView, triggerPoint, true); _activeSession.Properties.AddProperty(BufferProperties.SessionOriginIntellisense, "Intellisense"); _activeSession.Dismissed += CompletionSession_Dismissed; _activeSession.Start(); if (_startTabComplete == true) { var completions = _activeSession.SelectedCompletionSet.Completions; if (completions != null && completions.Count > 0) { var startPoint = _activeSession.SelectedCompletionSet.ApplicableTo.GetStartPoint(_textView.TextBuffer.CurrentSnapshot).Position; _tabCompleteSession = new TabCompleteSession(completions, _activeSession.SelectedCompletionSet.SelectionStatus, startPoint); _activeSession.Commit(); } _startTabComplete = false; } }
bool Complete(bool force) { if (m_session == null) { return(false); } if (!m_session.SelectedCompletionSet.SelectionStatus.IsSelected && !force) { m_session.Dismiss(); return(false); } var completion = m_session.SelectedCompletionSet.SelectionStatus.Completion; if (completion != null) { ALanguageCompletionSource.UserSelected(completion.InsertionText); } m_session.Commit(); return(true); }
/// <summary> /// Main method used to determine how to handle keystrokes within a ITextBuffer. /// </summary> /// <param name="pguidCmdGroup">The GUID of the command group.</param> /// <param name="nCmdId">The command ID.</param> /// <param name="nCmdexecopt"> /// Specifies how the object should execute the command. Possible values are taken from the /// Microsoft.VisualStudio.OLE.Interop.OLECMDEXECOPT and Microsoft.VisualStudio.OLE.Interop.OLECMDID_WINDOWSTATE_FLAG /// enumerations. /// </param> /// <param name="pvaIn">The input arguments of the command.</param> /// <param name="pvaOut">The output arguments of the command.</param> /// <returns></returns> public int Exec(ref Guid pguidCmdGroup, uint nCmdId, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { bool?isInStringArea = null; var command = (VSConstants.VSStd2KCmdID)nCmdId; if (VsShellUtilities.IsInAutomationFunction(_serviceProvider) || IsUnhandledCommand(pguidCmdGroup, command) || Utilities.IsCaretInCommentArea(_textView)) { Log.DebugFormat("Non-VSStd2K command: '{0}'", ToCommandName(pguidCmdGroup, nCmdId)); return(NextCommandHandler.Exec(ref pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut)); } //make a copy of this so we can look at it after forwarding some commands var typedChar = char.MinValue; // Exit tab complete session if command is any recognized command other than tab if (_tabCompleteSession != null && command != VSConstants.VSStd2KCmdID.TAB && command != VSConstants.VSStd2KCmdID.BACKTAB) { _tabCompleteSession = null; _startTabComplete = false; } //make sure the input is a char before getting it if (command == VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); Log.DebugFormat("Typed Character: '{0}'", (typedChar == char.MinValue) ? "<null>" : typedChar.ToString()); if (_activeSession == null && IsNotIntelliSenseTriggerWhenInStringLiteral(typedChar)) { isInStringArea = this.IsInStringArea(isInStringArea); if (isInStringArea == true) { return(NextCommandHandler.Exec(ref pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut)); } } } else { Log.DebugFormat("Non-TypeChar command: '{0}'", ToCommandName(pguidCmdGroup, nCmdId)); } switch (command) { case VSConstants.VSStd2KCmdID.RETURN: //check for a a selection if (_activeSession != null && !_activeSession.IsDismissed) { //if the selection is fully selected, commit the current session if (_activeSession.SelectedCompletionSet.SelectionStatus.IsSelected) { Log.Debug("Commit"); _activeSession.Commit(); //also, don't add the character to the buffer return(VSConstants.S_OK); } else { Log.Debug("Dismiss"); //if there is no selection, dismiss the session _activeSession.Dismiss(); } } break; case VSConstants.VSStd2KCmdID.TAB: case VSConstants.VSStd2KCmdID.BACKTAB: if (_activeSession != null && !_activeSession.IsDismissed) { var completions = _activeSession.SelectedCompletionSet.Completions; if (completions != null && completions.Count > 0) { var startPoint = _activeSession.SelectedCompletionSet.ApplicableTo.GetStartPoint(_textView.TextBuffer.CurrentSnapshot).Position; _tabCompleteSession = new TabCompleteSession(_activeSession.SelectedCompletionSet.Completions, _activeSession.SelectedCompletionSet.SelectionStatus, startPoint); _activeSession.Commit(); //also, don't add the character to the buffer return(VSConstants.S_OK); } else { Log.Debug("Dismiss"); //If there are no completions, dismiss the session _activeSession.Dismiss(); } } else if (_tabCompleteSession != null) { if (command == VSConstants.VSStd2KCmdID.TAB) { _tabCompleteSession.ReplaceWithNextCompletion(_textView.TextBuffer, _textView.Caret.Position.BufferPosition.Position); } else { _tabCompleteSession.ReplaceWithPreviousCompletion(_textView.TextBuffer, _textView.Caret.Position.BufferPosition.Position); } //don't add the character to the buffer return(VSConstants.S_OK); } else if (!Utilities.IsPrecedingTextInLineEmpty(_textView.Caret.Position.BufferPosition) && _textView.Selection.IsEmpty) { _startTabComplete = true; TriggerCompletion(); //don't add the character to the buffer return(VSConstants.S_OK); } break; case VSConstants.VSStd2KCmdID.COMPLETEWORD: isInStringArea = this.IsInStringArea(isInStringArea); if (isInStringArea == true) { return(NextCommandHandler.Exec(ref pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut)); } TriggerCompletion(); return(VSConstants.S_OK); default: break; } //check for a commit character if (char.IsWhiteSpace(typedChar) && _activeSession != null && !_activeSession.IsDismissed) { // If user is typing a variable, SPACE shouldn't commit the selection. // If the selection is fully matched with user's input, commit the current session and add the commit character to text buffer. if (_activeSession.SelectedCompletionSet.SelectionStatus.IsSelected && !_activeSession.SelectedCompletionSet.SelectionStatus.Completion.InsertionText.StartsWith("$", StringComparison.InvariantCulture)) { Log.Debug("Commit"); _activeSession.Commit(); bool isCompletionFullyMatched = false; _textView.TextBuffer.Properties.TryGetProperty(BufferProperties.SessionCompletionFullyMatchedStatus, out isCompletionFullyMatched); if (isCompletionFullyMatched) { // If user types all characters in a completion and click Space, then we should commit the selection and add the Space into text buffer. return(NextCommandHandler.Exec(ref pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut)); } //Don't add the character to the buffer if this commits the selection. return(VSConstants.S_OK); } else { Log.Debug("Dismiss"); //if there is no selection, dismiss the session _activeSession.Dismiss(); } } bool justCommitIntelliSense = false; if (IsIntelliSenseTriggerDot(typedChar) && _activeSession != null && !_activeSession.IsDismissed) { var selectionStatus = _activeSession.SelectedCompletionSet.SelectionStatus; if (selectionStatus.IsSelected) { // If user types the full completion text, which ends with a dot, then we should just commit IntelliSense session ignore user's last typing. ITrackingSpan lastWordSpan; var currentSnapshot = _textView.TextBuffer.CurrentSnapshot; _textView.TextBuffer.Properties.TryGetProperty <ITrackingSpan>(BufferProperties.LastWordReplacementSpan, out lastWordSpan); if (lastWordSpan != null) { string lastWordText = lastWordSpan.GetText(currentSnapshot); int completionSpanStart = lastWordSpan.GetStartPoint(currentSnapshot); int completionSpanEnd = _textView.Caret.Position.BufferPosition; var completionText = currentSnapshot.GetText(completionSpanStart, completionSpanEnd - completionSpanStart); completionText += typedChar; Log.DebugFormat("completionSpanStart: {0}", completionSpanStart); Log.DebugFormat("completionSpanEnd: {0}", completionSpanEnd); Log.DebugFormat("completionText: {0}", completionText); if (selectionStatus.Completion.InsertionText.Equals(completionText, StringComparison.OrdinalIgnoreCase)) { Log.Debug(String.Format("Commited by {0}", typedChar)); _activeSession.Commit(); return(VSConstants.S_OK); } } Log.Debug("Commit"); _activeSession.Commit(); justCommitIntelliSense = true; } else { Log.Debug("Dismiss"); //if there is no selection, dismiss the session _activeSession.Dismiss(); } } // Check the char at caret before pass along the command // If command is backspace and completion session is active, then we need to see if the char to be deleted is an IntelliSense triggering char // If yes, then after deleting the char, we also dismiss the completion session // Otherwise, just filter the completion lists char charAtCaret = char.MinValue; if (command == VSConstants.VSStd2KCmdID.BACKSPACE && _activeSession != null && !_activeSession.IsDismissed) { int caretPosition = _textView.Caret.Position.BufferPosition.Position - 1; if (caretPosition >= 0) { // caretPosition == -1 means caret is at the beginning of a file, which means no characters before it. ITrackingPoint caretCharPosition = _textView.TextSnapshot.CreateTrackingPoint(caretPosition, PointTrackingMode.Positive); charAtCaret = caretCharPosition.GetCharacter(_textView.TextSnapshot); } } // pass along the command so the char is added to the buffer int retVal = NextCommandHandler.Exec(ref pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut); bool handled = false; if (IsIntellisenseTrigger(typedChar) || (justCommitIntelliSense || (IsIntelliSenseTriggerDot(typedChar) && IsPreviousTokenVariable())) || // If dot just commit a session or previous token before a dot was a variable, trigger intellisense (char.IsWhiteSpace(typedChar) && IsPreviousTokenParameter())) // If the previous token before a space was a parameter, trigger intellisense { isInStringArea = this.IsInStringArea(isInStringArea); if (isInStringArea == false) { TriggerCompletion(); } } if (!typedChar.Equals(char.MinValue) && IsFilterTrigger(typedChar)) { if (_activeSession != null) { if (_activeSession.IsStarted) { try { Log.Debug("Filter"); _activeSession.Filter(); } catch (Exception ex) { Log.Debug("Failed to filter session.", ex); } } } } else if (command == VSConstants.VSStd2KCmdID.BACKSPACE || command == VSConstants.VSStd2KCmdID.DELETE) //redo the filter if there is a deletion { if (_activeSession != null && !_activeSession.IsDismissed) { try { if (_textView.Caret.Position.BufferPosition <= _completionCaretPosition) { Log.Debug("Dismiss"); _activeSession.Dismiss(); } else { Log.Debug("Filter"); _activeSession.Filter(); } } catch (Exception ex) { Log.Debug("Failed to filter session.", ex); } } handled = true; } if (handled) { return(VSConstants.S_OK); } return(retVal); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { ThreadHelper.ThrowIfNotOnUIThread(); if (VsShellUtilities.IsInAutomationFunction(_serviceProvider)) { return(Next.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } var commandID = nCmdID; var typedChar = char.MinValue; if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); } if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB) { if (_currentSession != null && !_currentSession.IsDismissed) { if (_currentSession.SelectedCompletionSet.SelectionStatus.IsSelected) { _currentSession.Commit(); return(VSConstants.S_OK); } _currentSession.Dismiss(); } } var retVal = Next.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); var handled = false; switch ((VSConstants.VSStd2KCmdID)commandID) { case VSConstants.VSStd2KCmdID.COMPLETEWORD: case VSConstants.VSStd2KCmdID.AUTOCOMPLETE: if (_currentSession == null || _currentSession.IsDismissed) { TriggerCompletion(); } Filter(); handled = true; break; case VSConstants.VSStd2KCmdID.TYPECHAR: if (!typedChar.Equals(char.MinValue) && char.IsLetterOrDigit(typedChar)) { if (_currentSession == null || _currentSession.IsDismissed) { TriggerCompletion(); } Filter(); handled = true; } break; case VSConstants.VSStd2KCmdID.BACKSPACE: case VSConstants.VSStd2KCmdID.DELETE: TriggerCompletion(true); Filter(); handled = true; break; } return(handled ? VSConstants.S_OK : retVal); }
private bool SelectSingleBestCompletion(ICompletionSession session) { if (session.CompletionSets.Count != 1) { return false; } var set = session.CompletionSets[0] as FuzzyCompletionSet; if (set == null) { return false; } set.Filter(); if (set.SelectSingleBest()) { session.Commit(); return true; } return false; }
internal void TriggerCompletionSession(bool completeWord) { Dismiss(); _activeSession = CompletionBroker.TriggerCompletion(_textView); if (_activeSession != null) { if (completeWord && _activeSession.CompletionSets.Count == 1 && _activeSession.CompletionSets[0].Completions.Count == 1) { _activeSession.Commit(); } else { AttachKeyboardFilter(); _activeSession.Dismissed += new EventHandler(OnSessionDismissedOrCommitted); _activeSession.Committed += new EventHandler(OnSessionDismissedOrCommitted); } } }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { ThreadHelper.ThrowIfNotOnUIThread(); if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider)) { return(m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } uint commandID = nCmdID; char typedChar = char.MinValue; if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); } VSConstants.VSStd2KCmdID nCmdIDEnum = (VSConstants.VSStd2KCmdID)nCmdID; //System.Console.WriteLine("Keyboard command: " + nCmdIDEnum); if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB /*|| (char.IsWhiteSpace(typedChar) || char.IsPunctuation(typedChar))*/)//this made auto complete on point or space { if (m_session != null && !m_session.IsDismissed) { if (m_session.SelectedCompletionSet.SelectionStatus.IsSelected) { m_session.Commit(); return(VSConstants.S_OK); } else { m_session.Dismiss(); } } } ThreadHelper.ThrowIfNotOnUIThread(); int retVal = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); bool handled = false; if (!typedChar.Equals(char.MinValue) && char.IsLetterOrDigit(typedChar) || nCmdIDEnum == VSConstants.VSStd2KCmdID.COMPLETEWORD) { if (m_session == null || m_session.IsDismissed) { TriggerCompletion(); } else { m_session.Filter(); } handled = true; } else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || commandID == (uint)VSConstants.VSStd2KCmdID.DELETE) { if (m_session != null && !m_session.IsDismissed) { m_session.Filter(); } handled = true; } if (handled) { return(VSConstants.S_OK); } return(retVal); }
// !EFW - This has been throwing random null reference exceptions in VS 2019. It's not something I've // been able to duplicate so I've added null checks everywhere to see if that stops it. private bool HandleCompletion(char commitCharacter) { ReadOnlyCollection <ICompletionSession> completionSessions = _completionBroker.GetSessions(_textView); if (completionSessions == null || completionSessions.Count == 0) { return(false); } ICompletionSession completionSession = completionSessions[0]; if (completionSession == null || completionSession.IsDismissed) { return(false); } CompletionSet completionSet = completionSession.SelectedCompletionSet; CompletionSelectionStatus selectionStatus = completionSet?.SelectionStatus; if (!(selectionStatus?.Completion is SandcastleCompletion)) { // Workaround some odd behavior in the completion when trying to enter "</". This prevents it // from converting it to an XML comment ("<!--/-->"). if (commitCharacter == '/' && selectionStatus?.Completion?.InsertionText == "!--") { completionSession.Dismiss(); } // Let other providers handle their own completions return(false); } string insertionText = selectionStatus.Completion.InsertionText; if (insertionText == null) { return(false); } completionSession.Commit(); bool passCharacterToEditor; switch (commitCharacter) { case '/': case '>': // If the insertion text doesn't end with '>' or '/>', allow the user to complete the item and insert // the closing element character by typing '/' or '>'. passCharacterToEditor = !insertionText.EndsWith(">"); break; case ' ': // Only pass the space through if the completion item doesn't contain any replaceable elements passCharacterToEditor = insertionText.IndexOf('\xFF') < 0; break; case '\n': case '\t': default: // These items trigger completion, but aren't written to the output passCharacterToEditor = false; break; } return(!passCharacterToEditor); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdId, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (VsShellUtilities.IsInAutomationFunction(provider.ServiceProvider)) { return(nextCommandHandler.Execute(ref pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut)); } //make a copy of this so we can look at it after forwarding some commands uint commandId = nCmdId; char typedChar = char.MinValue; bool handled = false; bool completionRequested = false; lock (DothtmlCompletionSource.activeSessions) { session = DothtmlCompletionSource.activeSessions.FirstOrDefault(); } //make sure the input is a char before getting it if (pguidCmdGroup == VSConstants.VSStd2K && nCmdId == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); } //check for a commit character if (nCmdId == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdId == (uint)VSConstants.VSStd2KCmdID.TAB || (char.IsWhiteSpace(typedChar) //|| char.IsPunctuation(typedChar) || typedChar == '=')) { //check for a a selection if (session != null && session.IsStarted && !session.IsDismissed) { var textView = session.TextView; // if TAB is pressed, select the best match to commit bool selectionTabOverrule = nCmdId == (uint)VSConstants.VSStd2KCmdID.TAB && !session.SelectedCompletionSet.SelectionStatus.IsSelected; //if the selection is fully selected, commit the current session if (session.SelectedCompletionSet.SelectionStatus.IsSelected || selectionTabOverrule) { var customCommit = (session.SelectedCompletionSet.SelectionStatus.Completion as SimpleDothtmlCompletion)?.CustomCommit; if (customCommit != null) { customCommit.Commit(); completionRequested = customCommit.CompletionTriggerRequested; } else { session.Commit(); } var prevChar = textView.TextBuffer.CurrentSnapshot[textView.Caret.Position.BufferPosition]; if (typedChar != '=' || prevChar == '\"' || prevChar == '\'') { handled = true; } } else { //if there is no selection, dismiss the session if (!session.IsDismissed) { session.Dismiss(); } } } } // pass along the command so the char is added to the buffer int retVal = 0; if (!handled) { retVal = nextCommandHandler.Execute(ref pguidCmdGroup, nCmdId, nCmdexecopt, pvaIn, pvaOut); } if ((nCmdId == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdId == (uint)VSConstants.VSStd2KCmdID.TAB) || completionRequested || (!typedChar.Equals(char.MinValue) && IsTriggerChar(typedChar))) { if (session == null || session.IsDismissed) // If there is no active session, bring up completion { this.TriggerCompletion(); } else //the completion session is already active, so just filter { session.Filter(); } handled = true; } else if (commandId == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || // redo the filter if there is a deletion commandId == (uint)VSConstants.VSStd2KCmdID.DELETE) { if (session != null && !session.IsDismissed) { session.Filter(); } handled = true; } if (handled) { return(VSConstants.S_OK); } return(retVal); }
/// <summary> /// Handles a new command. /// </summary> /// <param name="CommandGroupGuid">The GUID of the command group.</param> /// <param name="CommandID">The command ID.</param> /// <param name="ExecOptions">Not used.</param> /// <param name="InputArgs">The input arguments of the command.</param> /// <param name="OutputArgs">The output arguments of the command.</param> /// <returns>A status code, either S_OK on a successful command exection or some other /// code that describes what happened if the command failed.</returns> public int Exec(ref Guid CommandGroupGuid, uint CommandID, uint ExecOptions, IntPtr InputArgs, IntPtr OutputArgs) { ThreadHelper.ThrowIfNotOnUIThread(); try { // If we're in an automation function, we don't actually need to do anything. if (VsShellUtilities.IsInAutomationFunction(Provider.ServiceProvider)) { return(NextCommandHandler.Exec(ref CommandGroupGuid, CommandID, ExecOptions, InputArgs, OutputArgs)); } // Get the character that was just typed (if there was one) char typedChar = char.MinValue; if (CommandGroupGuid == VSConstants.VSStd2K && CommandID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)Marshal.GetObjectForNativeVariant <ushort>(InputArgs); } // Check if the user just entered a triple slash if (typedChar == '/' && Dte != null) { if (UserTypedTripleSlash()) { Logger.Debug("User entered a triple slash, handling it..."); HandleTripleSlash(); return(VSConstants.S_OK); } } // Check if there's an autocomplete session open and the user just tried to accept one // of the autocomplete suggestions else if (MarkdownCompletionSession?.IsDismissed == false) { if (CommandID == (uint)VSConstants.VSStd2KCmdID.RETURN || CommandID == (uint)VSConstants.VSStd2KCmdID.TAB) { if (MarkdownCompletionSession.SelectedCompletionSet.SelectionStatus.IsSelected) { Logger.Debug("User selected a Markdown header autocompletion suggestion."); MarkdownCompletionSession.Commit(); return(VSConstants.S_OK); } } } // Handle the user pressing enter inside of a comment else if (CommandGroupGuid == VSConstants.VSStd2K && CommandID == (uint)VSConstants.VSStd2KCmdID.RETURN) { if (HandleNewlineInCommentBlock()) { Logger.Debug("User added a new line to a comment block."); return(VSConstants.S_OK); } } // If none of the above happened, pass the event onto the regular handler. int nextCommandResult = NextCommandHandler.Exec(ref CommandGroupGuid, CommandID, ExecOptions, InputArgs, OutputArgs); // Check to see if the user typed "#" so we need to start an autocomplete session if (typedChar == '#') { string currentLine = TextView.TextSnapshot.GetLineFromPosition( TextView.Caret.Position.BufferPosition.Position).GetText(); if (currentLine.TrimStart().StartsWith("/// #")) { // Create a new autocompletion session if there isn't one already Logger.Debug("User entered # on a triple-slashed line, starting a new autocomplete session..."); if (MarkdownCompletionSession == null || MarkdownCompletionSession.IsDismissed) { if (StartMarkdownAutocompleteSession()) { MarkdownCompletionSession.SelectedCompletionSet.SelectBestMatch(); MarkdownCompletionSession.SelectedCompletionSet.Recalculate(); return(VSConstants.S_OK); } } } } // Check if there's an active autocomplete session, and the user just modified the text // in the editor else if (CommandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || CommandID == (uint)VSConstants.VSStd2KCmdID.DELETE || char.IsLetter(typedChar)) { if (MarkdownCompletionSession?.IsDismissed == false) { MarkdownCompletionSession.SelectedCompletionSet.SelectBestMatch(); MarkdownCompletionSession.SelectedCompletionSet.Recalculate(); return(VSConstants.S_OK); } } return(nextCommandResult); } catch (Exception ex) { Logger.Error($"Error handling command: {ex.GetType().Name} - {ex.Message}"); Logger.Trace(ex.StackTrace); return(VSConstants.E_FAIL); } }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (pguidCmdGroup == VSConstants.VSStd2K) { if (nCmdID == (uint)VSConstants.VSStd2KCmdID.INSERTSNIPPET || nCmdID == (uint)VSConstants.VSStd2KCmdID.SURROUNDWITH) { IVsTextManager2 textManager = (IVsTextManager2)this.serviceProvider.GetService(typeof(SVsTextManager)); IVsExpansionManager expansionManager; if (VSConstants.S_OK == textManager.GetExpansionManager(out expansionManager)) { expansionManager.InvokeInsertionUI( vsTextView, this, GuidList.guidSpringLanguage, new string[] { "Expansion" }, 1, 0, null, 0, 1, "Insert Snippet", string.Empty); } return(VSConstants.S_OK); } if (this.expansionSession != null) { // Handle VS Expansion (Code Snippets) keys if ((nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB)) { if (expansionSession.GoToNextExpansionField(0) == VSConstants.S_OK) { return(VSConstants.S_OK); } } else if ((nCmdID == (uint)VSConstants.VSStd2KCmdID.BACKTAB)) { if (expansionSession.GoToPreviousExpansionField() == VSConstants.S_OK) { return(VSConstants.S_OK); } } else if ((nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.CANCEL)) { if (expansionSession.EndCurrentExpansion(0) == VSConstants.S_OK) { expansionSession = null; return(VSConstants.S_OK); } } } // Handle Edit.ListMembers or Edit.CompleteWord commands if ((nCmdID == (uint)VSConstants.VSStd2KCmdID.SHOWMEMBERLIST || nCmdID == (uint)VSConstants.VSStd2KCmdID.COMPLETEWORD)) { if (completionSession != null) { completionSession.Dismiss(); } ShowCompletion(); return(VSConstants.S_OK); } // Handle Enter/Tab commit keys if (completionSession != null && (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB)) { if (completionSession.SelectedCompletionSet.SelectionStatus.IsSelected) { completionSession.Commit(); } else { completionSession.Dismiss(); } return(VSConstants.S_OK); } // Handle Code Snippets after pressing the Tab key without completion if (completionSession == null && (nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB)) { IVsTextManager2 expansionManager = (IVsTextManager2)this.serviceProvider.GetService(typeof(SVsTextManager)); SnippetsEnumerable snippetsEnumerator = new SnippetsEnumerable(expansionManager, GuidList.guidSpringLanguage); SnapshotPoint currentPoint = (this.textView.Caret.Position.BufferPosition) - 1; ITextStructureNavigator navigator = this.textStructureNavigatorSelectorService.GetTextStructureNavigator(this.textView.TextBuffer); TextExtent extent = navigator.GetExtentOfWord(currentPoint); string shortcut = this.textView.TextSnapshot.GetText(extent.Span); // Search a snippet that matched the token text VsExpansion expansion = snippetsEnumerator.FirstOrDefault(e => e.title == shortcut); if (expansion.title != null) { // Set the location where the snippet will be inserted int startLine, startColumn, endLine, endColumn; this.vsTextView.GetCaretPos(out startLine, out endColumn); startColumn = endColumn - expansion.title.Length; endLine = startLine; // Insert the snippet InsertCodeExpansion(expansion, startLine, startColumn, endLine, endColumn); return(VSConstants.S_OK); } } // Hanlde other keys if ((nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)) { char typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); if (completionSession == null) { // Handle trigger keys // Check if the typed char is a trigger if (IsTriggerKey(typedChar)) { var result = this.nextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); ShowCompletion(); return(result); } } else { // Handle commit keys // Check if the typed char is a commit key if (IsCommitKey(typedChar)) { SpringCompletion selectedCompletion = completionSession.SelectedCompletionSet.SelectionStatus.Completion as SpringCompletion; if (completionSession.SelectedCompletionSet.SelectionStatus.IsSelected && selectedCompletion != null && selectedCompletion.Type != null && selectedCompletion.Type.Value == SpringCompletionType.Namespace) { completionSession.Commit(); } else { completionSession.Dismiss(); } var result = this.nextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); // Check we should trigger completion after comitting the previous session (for example, after typing dot '.') if (IsTriggerKey(typedChar)) { ShowCompletion(); } return(result); } else { var result = this.nextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); completionSession.Filter(); return(result); } } } // redo the filter if there is a deletion if (nCmdID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || nCmdID == (uint)VSConstants.VSStd2KCmdID.DELETE) { var result = this.nextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); if (completionSession != null && !completionSession.IsDismissed) { completionSession.Filter(); } return(result); } } // we haven't handled this command so pass it onto the next target return(this.nextCommandTarget.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { try { if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider)) { return(m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } // make a copy of this so we can look at it after forwarding some commands uint commandID = nCmdID; char typedChar = char.MinValue; // make sure the input is a char before getting it if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); } // check for the triple slash if (typedChar == '/' && m_dte != null) { string currentLine = m_textView.TextSnapshot.GetLineFromPosition( m_textView.Caret.Position.BufferPosition.Position).GetText(); if ((currentLine + "/").Trim() == "///") { // Calculate how many spaces string spaces = currentLine.Replace(currentLine.TrimStart(), ""); TextSelection ts = m_dte.ActiveDocument.Selection as TextSelection; int oldLine = ts.ActivePoint.Line; int oldOffset = ts.ActivePoint.LineCharOffset; ts.LineDown(); ts.EndOfLine(); CodeElement codeElement = null; FileCodeModel fcm = m_dte.ActiveDocument.ProjectItem.FileCodeModel; if (fcm != null) { codeElement = fcm.CodeElementFromPoint(ts.ActivePoint, vsCMElement.vsCMElementFunction); } if (codeElement != null && codeElement is CodeFunction) { CodeFunction function = codeElement as CodeFunction; StringBuilder sb = new StringBuilder("/ <summary>\r\n" + spaces + "/// \r\n" + spaces + "/// </summary>"); foreach (CodeElement child in codeElement.Children) { CodeParameter parameter = child as CodeParameter; if (parameter != null) { sb.AppendFormat("\r\n" + spaces + "/// <param name=\"{0}\"></param>", parameter.Name); } } if (function.Type.AsString != "void") { sb.AppendFormat("\r\n" + spaces + "/// <returns></returns>"); } ts.MoveToLineAndOffset(oldLine, oldOffset); ts.Insert(sb.ToString()); ts.MoveToLineAndOffset(oldLine, oldOffset); ts.LineDown(); ts.EndOfLine(); return(VSConstants.S_OK); } else { ts.MoveToLineAndOffset(oldLine, oldOffset); ts.Insert("/ <summary>\r\n" + spaces + "/// \r\n" + spaces + "/// </summary>"); ts.MoveToLineAndOffset(oldLine, oldOffset); ts.LineDown(); ts.EndOfLine(); return(VSConstants.S_OK); } } } if (m_session != null && !m_session.IsDismissed) { // check for a commit character if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB || typedChar == '>') { // check for a selection // if the selection is fully selected, commit the current session if (m_session.SelectedCompletionSet.SelectionStatus.IsSelected) { string selectedCompletion = m_session.SelectedCompletionSet.SelectionStatus.Completion.DisplayText; m_session.Commit(); TextSelection ts = m_dte.ActiveDocument.Selection as TextSelection; switch (selectedCompletion) { case "<!-->": ts.CharLeft(false, 3); break; case "<![CDATA[>": ts.CharLeft(false, 3); break; case "<c>": ts.CharLeft(false, 4); break; case "<code>": ts.CharLeft(false, 7); break; case "<example>": ts.CharLeft(false, 10); break; case "<exception>": ts.CharLeft(false, 14); break; case "<include>": ts.CharLeft(false, 21); break; case "<list>": ts.CharLeft(false, 7); break; case "<para>": ts.CharLeft(false, 7); break; case "<param>": ts.CharLeft(false, 10); break; case "<paramref>": ts.CharLeft(false, 13); break; case "<permission>": ts.CharLeft(false, 15); break; case "<remarks>": ts.CharLeft(false, 10); break; case "<returns>": ts.CharLeft(false, 10); break; case "<see>": ts.CharLeft(false, 3); break; case "<seealso>": ts.CharLeft(false, 3); break; case "<typeparam>": ts.CharLeft(false, 14); break; case "<typeparamref>": ts.CharLeft(false, 3); break; case "<value>": ts.CharLeft(false, 8); break; default: break; } // also, don't add the character to the buffer return(VSConstants.S_OK); } else { // if there is no selection, dismiss the session m_session.Dismiss(); } } } else { if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN) { string currentLine = m_textView.TextSnapshot.GetLineFromPosition( m_textView.Caret.Position.BufferPosition.Position).GetText(); if (currentLine.TrimStart().StartsWith("///")) { TextSelection ts = m_dte.ActiveDocument.Selection as TextSelection; string spaces = currentLine.Replace(currentLine.TrimStart(), ""); ts.Insert("\r\n" + spaces + "/// "); return(VSConstants.S_OK); } } } // pass along the command so the char is added to the buffer int retVal = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); if (typedChar == '<') { string currentLine = m_textView.TextSnapshot.GetLineFromPosition( m_textView.Caret.Position.BufferPosition.Position).GetText(); if (currentLine.TrimStart().StartsWith("///")) { if (m_session == null || m_session.IsDismissed) // If there is no active session, bring up completion { if (this.TriggerCompletion()) { m_session.SelectedCompletionSet.SelectBestMatch(); m_session.SelectedCompletionSet.Recalculate(); return(VSConstants.S_OK); } } } } else if ( commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || commandID == (uint)VSConstants.VSStd2KCmdID.DELETE || char.IsLetter(typedChar)) { if (m_session != null && !m_session.IsDismissed) // the completion session is already active, so just filter { m_session.SelectedCompletionSet.SelectBestMatch(); m_session.SelectedCompletionSet.Recalculate(); return(VSConstants.S_OK); } } return(retVal); } catch { } return(VSConstants.E_FAIL); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider)) { return(m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } //make a copy of this so we can look at it after forwarding some commands uint commandID = nCmdID; char typedChar = char.MinValue; //make sure the input is a char before getting it if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); } //check for a commit character if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB || (char.IsWhiteSpace(typedChar) || char.IsPunctuation(typedChar))) { //check for a a selection if (m_session != null && !m_session.IsDismissed) { //if the selection is fully selected, commit the current session if (m_session.SelectedCompletionSet.SelectionStatus.IsSelected) { m_session.Commit(); //also, don't add the character to the buffer return(VSConstants.S_OK); } else { //if there is no selection, dismiss the session m_session.Dismiss(); } } } //pass along the command so the char is added to the buffer int retVal = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); bool handled = false; if ((!typedChar.Equals(char.MinValue) && char.IsLetter(typedChar)) || char.IsWhiteSpace(typedChar)) //||typedChar=='<' { if (m_session == null || m_session.IsDismissed) // If there is no active session, bring up completion { if (this.TriggerCompletion() && m_session != null) { m_session.Filter(); } } else //the completion session is already active, so just filter { m_session.Filter(); } handled = true; } else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || //redo the filter if there is a deletion commandID == (uint)VSConstants.VSStd2KCmdID.DELETE) { if (m_session != null && !m_session.IsDismissed) { m_session.Filter(); } handled = true; } if (handled) { return(VSConstants.S_OK); } return(retVal); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (VsShellUtilities.IsInAutomationFunction(_provider.ServiceProvider)) { return(_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } //make a copy of this so we can look at it after forwarding some commands uint commandID = nCmdID; char typedChar = char.MinValue; //make sure the input is a char before getting it if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); } if (typedChar == '.') { Console.WriteLine(); } //check for a commit character if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB || (char.IsWhiteSpace(typedChar) || char.IsPunctuation(typedChar))) { //check for a a selection if (_session != null && !_session.IsDismissed) { //if the selection is fully selected, commit the current session if (_session.SelectedCompletionSet.SelectionStatus.IsSelected) { if ( typedChar != ':' && (typedChar != '.' || !_session.SelectedCompletionSet.SelectionStatus.Completion.InsertionText.Contains('.'))) { _session.Commit(); //also, don't add the character to the buffer return(VSConstants.S_OK); } else { nCmdID = (uint)VSConstants.VSStd2KCmdID.COMPLETEWORD; } } else { //if there is no selection, dismiss the session _session.Dismiss(); } } } //pass along the command so the char is added to the buffer int retVal = VSConstants.S_OK; bool handled = false; if (nCmdID == (uint)VSConstants.VSStd2KCmdID.COMPLETEWORD || (!typedChar.Equals(char.MinValue) && (char.IsLetterOrDigit(typedChar) || typedChar == '<' || typedChar == ' ' || typedChar == '.' || typedChar == ':'))) { if (typedChar != '\0') { if (typedChar == '.' || typedChar == ':' || typedChar == '<') { if (!_textView.Selection.IsEmpty) { foreach (var span in _textView.Selection.SelectedSpans.OrderByDescending(x => x.Start)) { _textView.TextBuffer.Replace(span, ""); } } _textView.TextBuffer.Insert(_textView.Caret.Position.BufferPosition.Position, typedChar.ToString()); } else { retVal = _realCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); } } if (_session == null || _session.IsDismissed) // If there is no active session, bring up completion { TriggerCompletion(); if (typedChar != '<' && typedChar != 0 && _session != null) { _session.Filter(); } } else { _session.Filter(); } handled = true; } else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || //redo the filter if there is a deletion commandID == (uint)VSConstants.VSStd2KCmdID.DELETE) { if (_session != null && !_session.IsDismissed) { _session.Filter(); } retVal = _nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); handled = true; } else { retVal = _nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); } if (handled) { return(VSConstants.S_OK); } return(retVal); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (VsShellUtilities.IsInAutomationFunction(_provider.ServiceProvider)) { return(_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } uint commandID = nCmdID; char typedChar = char.MinValue; if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); } // return and tab command commit the session and return if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB) { if (_session != null && !_session.IsDismissed) { if (_session.SelectedCompletionSet.SelectionStatus.IsSelected) { _session.Commit(); return(VSConstants.S_OK); } else { _session.Dismiss(); } } } // whitespace and punctuation commit the session if (char.IsWhiteSpace(typedChar) || char.IsPunctuation(typedChar)) { if (_session != null && !_session.IsDismissed) { if (_session.SelectedCompletionSet.SelectionStatus.IsSelected) { _session.Commit(); } else { _session.Dismiss(); } } } int retVal = _nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); bool handled = false; if (!typedChar.Equals(char.MinValue) && char.IsLetterOrDigit(typedChar)) { if (_session == null || _session.IsDismissed) { this.TriggerCompletion(); if (_session != null) { _session.Filter(); } } else { _session.Filter(); } handled = true; } else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || commandID == (uint)VSConstants.VSStd2KCmdID.DELETE) { if (_session != null && _session.IsDismissed) { _session.Filter(); } handled = true; } if (handled) { return(VSConstants.S_OK); } return(retVal); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (int)VSConstants.VSStd2KCmdID.TYPECHAR) { var ch = (char)(ushort)System.Runtime.InteropServices.Marshal.GetObjectForNativeVariant(pvaIn); if (_activeSession != null && !_activeSession.IsDismissed) { if (_activeSession.SelectedCompletionSet.SelectionStatus.IsSelected) { var completion = _activeSession.SelectedCompletionSet.SelectionStatus.Completion; string committedBy = String.Empty; if (_activeSession.SelectedCompletionSet.Moniker == CompletionSource.NodejsRequireCompletionSetMoniker) { if (completion.InsertionText.StartsWith("'")) // require( { committedBy = ")"; } else if (completion.InsertionText.EndsWith("'")) // require(' { committedBy = "'"; } else if (completion.InsertionText.EndsWith("\"")) // require(" { committedBy = "\""; } } else { committedBy = NodejsPackage.Instance != null && NodejsPackage.Instance.IntellisenseOptionsPage.OnlyTabOrEnterToCommit ? string.Empty : NodejsConstants.DefaultIntellisenseCompletionCommittedBy; } if (committedBy.IndexOf(ch) != -1) { _activeSession.Commit(); if ((completion.InsertionText.EndsWith("'") && ch == '\'') || (completion.InsertionText.EndsWith("\"") && ch == '"')) { // https://nodejstools.codeplex.com/workitem/960 // ' triggers the completion, but we don't want to insert the quote. return(VSConstants.S_OK); } } } else if (_activeSession.SelectedCompletionSet.Moniker.Equals(CompletionSource.NodejsRequireCompletionSetMoniker) && !IsRequireIdentifierChar(ch)) { _activeSession.Dismiss(); } else if (!_activeSession.SelectedCompletionSet.Moniker.Equals(CompletionSource.NodejsRequireCompletionSetMoniker) && !IsIdentifierChar(ch)) { _activeSession.Dismiss(); } } int res = _oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); if (_activeSession == null || !_activeSession.SelectedCompletionSet.Moniker.Equals(CompletionSource.NodejsRequireCompletionSetMoniker)) { //Only process the char if we are not in a require completion HandleChar((char)(ushort)System.Runtime.InteropServices.Marshal.GetObjectForNativeVariant(pvaIn)); } if (_activeSession != null && !_activeSession.IsDismissed) { _activeSession.Filter(); } return(res); } if (_activeSession != null) { if (pguidCmdGroup == VSConstants.VSStd2K) { switch ((VSConstants.VSStd2KCmdID)nCmdID) { case VSConstants.VSStd2KCmdID.RETURN: if (/*NodejsPackage.Instance.AdvancedEditorOptionsPage.EnterCommitsIntellisense*/ true && !_activeSession.IsDismissed && _activeSession.SelectedCompletionSet.SelectionStatus.IsSelected) { // If the user has typed all of the characters as the completion and presses // enter we should dismiss & let the text editor receive the enter. For example // when typing "import sys[ENTER]" completion starts after the space. After typing // sys the user wants a new line and doesn't want to type enter twice. bool enterOnComplete = /*NodejsPackage.Instance.AdvancedEditorOptionsPage.AddNewLineAtEndOfFullyTypedWord*/ true && EnterOnCompleteText(); _activeSession.Commit(); if (!enterOnComplete) { return(VSConstants.S_OK); } } else { _activeSession.Dismiss(); } break; case VSConstants.VSStd2KCmdID.TAB: if (!_activeSession.IsDismissed) { _activeSession.Commit(); return(VSConstants.S_OK); } break; case VSConstants.VSStd2KCmdID.BACKSPACE: case VSConstants.VSStd2KCmdID.DELETE: case VSConstants.VSStd2KCmdID.DELETEWORDLEFT: case VSConstants.VSStd2KCmdID.DELETEWORDRIGHT: int res = _oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); if (_activeSession != null && !_activeSession.IsDismissed) { _activeSession.Filter(); } return(res); } } } else if (_sigHelpSession != null) { if (pguidCmdGroup == VSConstants.VSStd2K) { switch ((VSConstants.VSStd2KCmdID)nCmdID) { case VSConstants.VSStd2KCmdID.BACKSPACE: bool fDeleted = Backspace(); if (fDeleted) { return(VSConstants.S_OK); } break; case VSConstants.VSStd2KCmdID.LEFT: _editOps.MoveToPreviousCharacter(false); UpdateCurrentParameter(); return(VSConstants.S_OK); case VSConstants.VSStd2KCmdID.RIGHT: _editOps.MoveToNextCharacter(false); UpdateCurrentParameter(); return(VSConstants.S_OK); case VSConstants.VSStd2KCmdID.HOME: case VSConstants.VSStd2KCmdID.BOL: case VSConstants.VSStd2KCmdID.BOL_EXT: case VSConstants.VSStd2KCmdID.EOL: case VSConstants.VSStd2KCmdID.EOL_EXT: case VSConstants.VSStd2KCmdID.END: case VSConstants.VSStd2KCmdID.WORDPREV: case VSConstants.VSStd2KCmdID.WORDPREV_EXT: case VSConstants.VSStd2KCmdID.DELETEWORDLEFT: _sigHelpSession.Dismiss(); _sigHelpSession = null; break; } } } if (pguidCmdGroup == VSConstants.VSStd2K) { switch ((VSConstants.VSStd2KCmdID)nCmdID) { case VSConstants.VSStd2KCmdID.QUICKINFO: TriggerQuickInfo(); return(VSConstants.S_OK); case VSConstants.VSStd2KCmdID.PARAMINFO: TriggerSignatureHelp(); return(VSConstants.S_OK); case VSConstants.VSStd2KCmdID.RETURN: if (_expansionMgr != null && _expansionClient.InSession && ErrorHandler.Succeeded(_expansionClient.EndCurrentExpansion(false))) { return(VSConstants.S_OK); } break; case VSConstants.VSStd2KCmdID.TAB: if (_expansionMgr != null && _expansionClient.InSession && ErrorHandler.Succeeded(_expansionClient.NextField())) { return(VSConstants.S_OK); } if (_textView.Selection.IsEmpty && _textView.Caret.Position.BufferPosition > 0) { if (TryTriggerExpansion()) { return(VSConstants.S_OK); } } break; case VSConstants.VSStd2KCmdID.BACKTAB: if (_expansionMgr != null && _expansionClient.InSession && ErrorHandler.Succeeded(_expansionClient.PreviousField())) { return(VSConstants.S_OK); } break; case VSConstants.VSStd2KCmdID.SURROUNDWITH: case VSConstants.VSStd2KCmdID.INSERTSNIPPET: TriggerSnippet(nCmdID); return(VSConstants.S_OK); case VSConstants.VSStd2KCmdID.SHOWMEMBERLIST: case VSConstants.VSStd2KCmdID.COMPLETEWORD: ForceCompletions = true; try { TriggerCompletionSession((VSConstants.VSStd2KCmdID)nCmdID == VSConstants.VSStd2KCmdID.COMPLETEWORD && !NodejsPackage.Instance.IntellisenseOptionsPage.OnlyTabOrEnterToCommit); } finally { ForceCompletions = false; } return(VSConstants.S_OK); } } return(_oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); }
void IWordCompletionSession.Commit() { _completionSession.Commit(); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (int)VSConstants.VSStd2KCmdID.TYPECHAR) { var ch = (char)(ushort)System.Runtime.InteropServices.Marshal.GetObjectForNativeVariant(pvaIn); if (_activeSession != null && !_activeSession.IsDismissed) { if (_activeSession.SelectedCompletionSet != null && _activeSession.SelectedCompletionSet.SelectionStatus.IsSelected && _provider.PythonService.AdvancedOptions.CompletionCommittedBy.IndexOf(ch) != -1) { _activeSession.Commit(); } else if (!IsIdentifierChar(ch)) { _activeSession.Dismiss(); } } int res = _oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); HandleChar((char)(ushort)System.Runtime.InteropServices.Marshal.GetObjectForNativeVariant(pvaIn)); if (_activeSession != null && !_activeSession.IsDismissed) { _activeSession.Filter(); } return(res); } if (_activeSession != null) { if (pguidCmdGroup == VSConstants.VSStd2K) { switch ((VSConstants.VSStd2KCmdID)nCmdID) { case VSConstants.VSStd2KCmdID.RETURN: if (_provider.PythonService.AdvancedOptions.EnterCommitsIntellisense && !_activeSession.IsDismissed && _activeSession.SelectedCompletionSet.SelectionStatus.IsSelected) { // If the user has typed all of the characters as the completion and presses // enter we should dismiss & let the text editor receive the enter. For example // when typing "import sys[ENTER]" completion starts after the space. After typing // sys the user wants a new line and doesn't want to type enter twice. bool enterOnComplete = _provider.PythonService.AdvancedOptions.AddNewLineAtEndOfFullyTypedWord && EnterOnCompleteText(); _activeSession.Commit(); if (!enterOnComplete) { return(VSConstants.S_OK); } } else { _activeSession.Dismiss(); } break; case VSConstants.VSStd2KCmdID.TAB: if (!_activeSession.IsDismissed) { _activeSession.Commit(); return(VSConstants.S_OK); } break; case VSConstants.VSStd2KCmdID.BACKSPACE: case VSConstants.VSStd2KCmdID.DELETE: case VSConstants.VSStd2KCmdID.DELETEWORDLEFT: case VSConstants.VSStd2KCmdID.DELETEWORDRIGHT: int res = _oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); if (_activeSession != null && !_activeSession.IsDismissed) { _activeSession.Filter(); } return(res); } } } else if (_sigHelpSession != null) { if (pguidCmdGroup == VSConstants.VSStd2K) { switch ((VSConstants.VSStd2KCmdID)nCmdID) { case VSConstants.VSStd2KCmdID.BACKSPACE: bool fDeleted = Backspace(); if (fDeleted) { return(VSConstants.S_OK); } break; case VSConstants.VSStd2KCmdID.LEFT: _editOps.MoveToPreviousCharacter(false); UpdateCurrentParameter(); return(VSConstants.S_OK); case VSConstants.VSStd2KCmdID.RIGHT: _editOps.MoveToNextCharacter(false); UpdateCurrentParameter(); return(VSConstants.S_OK); case VSConstants.VSStd2KCmdID.HOME: case VSConstants.VSStd2KCmdID.BOL: case VSConstants.VSStd2KCmdID.BOL_EXT: case VSConstants.VSStd2KCmdID.EOL: case VSConstants.VSStd2KCmdID.EOL_EXT: case VSConstants.VSStd2KCmdID.END: case VSConstants.VSStd2KCmdID.WORDPREV: case VSConstants.VSStd2KCmdID.WORDPREV_EXT: case VSConstants.VSStd2KCmdID.DELETEWORDLEFT: _sigHelpSession.Dismiss(); _sigHelpSession = null; break; } } } else { if (pguidCmdGroup == VSConstants.VSStd2K) { switch ((VSConstants.VSStd2KCmdID)nCmdID) { case VSConstants.VSStd2KCmdID.RETURN: if (_expansionMgr != null && _expansionClient.InSession && ErrorHandler.Succeeded(_expansionClient.EndCurrentExpansion(false))) { return(VSConstants.S_OK); } break; case VSConstants.VSStd2KCmdID.TAB: if (_expansionMgr != null && _expansionClient.InSession && ErrorHandler.Succeeded(_expansionClient.NextField())) { return(VSConstants.S_OK); } if (_textView.Selection.IsEmpty && _textView.Caret.Position.BufferPosition > 0) { if (TryTriggerExpansion()) { return(VSConstants.S_OK); } } break; case VSConstants.VSStd2KCmdID.BACKTAB: if (_expansionMgr != null && _expansionClient.InSession && ErrorHandler.Succeeded(_expansionClient.PreviousField())) { return(VSConstants.S_OK); } break; case VSConstants.VSStd2KCmdID.SURROUNDWITH: case VSConstants.VSStd2KCmdID.INSERTSNIPPET: TriggerSnippet(nCmdID); return(VSConstants.S_OK); } } } return(_oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { uint cmdID = nCmdID; char typedChar = char.MinValue; if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); } if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || cmdID == (uint)VSConstants.VSStd2KCmdID.TAB) { if (completionSession != null && !completionSession.IsDismissed) { if (completionSession.SelectedCompletionSet.SelectionStatus.IsSelected) { completionSession.Commit(); return(VSConstants.S_OK); } else { completionSession.Dismiss(); } } } int returnValue = nextCommandHandler.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); bool isHandled = false; if (!typedChar.Equals(char.MinValue)) { if (completionSession == null || completionSession.IsDismissed) { TriggerCompletion(); if (completionSession != null) { completionSession.Filter(); } } else { completionSession.Filter(); } isHandled = true; } else if (cmdID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || cmdID == (uint)VSConstants.VSStd2KCmdID.DELETE) { if (completionSession != null && !completionSession.IsDismissed) { completionSession.Filter(); } isHandled = true; } if (isHandled) { return(VSConstants.S_OK); } return(returnValue); }
bool Commit(bool force) { if (_currentSession == null) { return(false); } if (!_currentSession.SelectedCompletionSet.SelectionStatus.IsSelected && !force) { _currentSession.Dismiss(); return(false); } else { string moniker = _currentSession.SelectedCompletionSet.Moniker; _currentSession.Commit(); if (!EditorConfigPackage.CompletionOptions.AutoInsertDelimiters) { return(true); } SnapshotPoint position = TextView.Caret.Position.BufferPosition; ITextSnapshotLine line = TextView.TextBuffer.CurrentSnapshot.GetLineFromPosition(position); string lineText = line.GetText(); if (moniker == "keyword" && !lineText.Contains("=")) { TextView.TextBuffer.Insert(position, " = "); // Contains placeholders int start = lineText.IndexOf('<'); int end = lineText.IndexOf('>'); if (start > -1 && start < end) { var span = new SnapshotSpan(TextView.TextBuffer.CurrentSnapshot, Span.FromBounds(line.Start + start, line.Start + end + 1)); TextView.Selection.Select(span, false); TextView.Caret.MoveTo(span.Start); return(true); } if (EditorConfigPackage.Language.Preferences.AutoListMembers) { StartSession(); } } else if (moniker == "value" && !lineText.Contains(":")) { var document = EditorConfigDocument.FromTextBuffer(TextView.TextBuffer); Property prop = document.PropertyAtPosition(position - 1); if (SchemaCatalog.TryGetKeyword(prop.Keyword.Text, out Keyword keyword) && prop.Value != null) { if (keyword.RequiresSeverity) { TextView.TextBuffer.Insert(position, ":"); if (EditorConfigPackage.Language.Preferences.AutoListMembers) { StartSession(); } } } } return(true); } }
public int Exec(ref System.Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, System.IntPtr pvaIn, System.IntPtr pvaOut) { if (pguidCmdGroup == VSConstants.VSStd2K) { int res; switch ((VSConstants.VSStd2KCmdID)nCmdID) { case VSConstants.VSStd2KCmdID.TYPECHAR: var ch = (char)(ushort)System.Runtime.InteropServices.Marshal.GetObjectForNativeVariant(pvaIn); if (_curSession != null && !_curSession.IsDismissed) { if (_curSession.SelectedCompletionSet.SelectionStatus.IsSelected && IsCompletionChar(ch)) { _curSession.Commit(); } } res = _oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); switch (ch) { case '<': if (_curSession != null) { _curSession.Dismiss(); } if (ErrorHandler.Succeeded(res)) { _curSession = CompletionBroker.TriggerCompletion(_textView); if (_curSession != null) { _curSession.Dismissed += CurSessionDismissedOrCommitted; _curSession.Committed += CurSessionDismissedOrCommitted; } } return(res); } if (_curSession != null && !_curSession.IsDismissed) { _curSession.Filter(); } return(res); case VSConstants.VSStd2KCmdID.BACKSPACE: res = _oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); if (_curSession != null && !_curSession.IsDismissed) { _curSession.Filter(); } return(res); case VSConstants.VSStd2KCmdID.RETURN: case VSConstants.VSStd2KCmdID.TAB: if (_curSession != null && !_curSession.IsDismissed) { _curSession.Commit(); return(VSConstants.S_OK); } break; } } return(_oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); }
// TODO: clean it up public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { if (VsShellUtilities.IsInAutomationFunction(m_provider.ServiceProvider)) { return(m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } //var tid = pguidCmdGroup; //var t = typeof(VSConstants).GetNestedTypes().FirstOrDefault(tt => tt.GUID == tid); //if (t.IsEnum) //{ // try // { // Debug.Print("cmd: {0}: {1}", t.Name, Enum.ToObject(t, nCmdID)); // } // catch { } //} if (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97 && ( nCmdID == (int)VSConstants.VSStd97CmdID.GotoDefn || nCmdID == (int)VSConstants.VSStd97CmdID.FindReferences )) { var doc = this.DocumentDataLoader.DocumentData; if (doc == null) { this.DocumentDataLoader.ForceReload(); doc = this.DocumentDataLoader.DocumentData; } if (doc != null) { var snapshot = this.DocumentDataLoader.CurrentSnapshot; var pos = m_textView.Caret.Position.BufferPosition; var line = pos.GetContainingLine(); var lineNumber = line.LineNumber; var linePosition = pos.Position - line.Start.Position; var text = doc.FindTextAt(lineNumber, linePosition); var attr = text?.ParentNode as MyXmlAttribute; if (attr != null) { if (nCmdID == (int)VSConstants.VSStd97CmdID.GotoDefn) { if (attr.ReferencedKeyPartData != null && attr.ReferencedKeyPartData.TryGetValueDef(attr.Value, out var targetAttr)) { var targetText = targetAttr.ChildNodes.OfType <MyXmlText>().FirstOrDefault(); if (targetText != null) { var targetLine = this.DocumentDataLoader.CurrentSnapshot.GetLineFromLineNumber(targetText.TextLocation.Line - 1); var targetPosition = targetLine.Start.Position + targetText.TextLocation.Column - 1; m_textView.Caret.MoveTo(new SnapshotPoint(this.DocumentDataLoader.CurrentSnapshot, targetPosition)); m_textView.Caret.EnsureVisible(); } } } else if (nCmdID == (int)VSConstants.VSStd97CmdID.FindReferences) { MyXmlAttribute defAttr; if (attr.ReferencedKeyPartData == null || !attr.ReferencedKeyPartData.TryGetValueDef(attr.Value, out defAttr)) { defAttr = attr; } var defLocation = defAttr.ChildNodes.OfType <MyXmlText>().FirstOrDefault()?.TextLocation ?? defAttr.TextLocation; var refs = defAttr.References; if (refs != null) { IVsOutputWindow outWindow = Package.GetGlobalService(typeof(SVsOutputWindow)) as IVsOutputWindow; // Use e.g. Tools -> Create GUID to make a stable, but unique GUID for your pane. // Also, in a real project, this should probably be a static constant, and not a local variable Guid customGuid = new Guid("D9090DD3-1BA3-4702-9697-C534D95810A9"); string customTitle = "Xml Key References"; outWindow.CreatePane(ref customGuid, customTitle, 1, 1); IVsOutputWindowPane customPane; outWindow.GetPane(ref customGuid, out customPane); ITextDocument document; var filePath = m_provider.TextDocumentFactoryService.TryGetTextDocument(m_textView.TextDataModel.DocumentBuffer, out document) ? document.FilePath : "Current document"; customPane.OutputString("Searching references to key " + attr.Value + " in " + filePath + " at " + DateTime.Now + Environment.NewLine); customPane.Activate(); // Brings this pane into view customPane.OutputString($"{filePath}({defLocation.Line},{defLocation.Column}): Definition: {snapshot.GetLineFromLineNumber(defLocation.Line - 1).GetText()}{Environment.NewLine}"); foreach (var refAttr in defAttr.References ?? new MyXmlAttribute[0]) { var itemLocation = refAttr.ChildNodes.OfType <MyXmlText>().FirstOrDefault()?.TextLocation ?? refAttr.TextLocation; customPane.OutputString($"{filePath}({itemLocation.Line},{itemLocation.Column}): Reference: {snapshot.GetLineFromLineNumber(itemLocation.Line - 1).GetText()}{Environment.NewLine}"); } customPane.OutputString($"Finished.{Environment.NewLine}"); customPane.OutputString(Environment.NewLine); customPane.OutputString(Environment.NewLine); const string vsWindowKindOutput = "{34E76E81-EE4A-11D0-AE2E-00A0C90FFFC3}"; DTE dte = Package.GetGlobalService(typeof(SDTE)) as DTE; Window win = dte.Windows.Item(vsWindowKindOutput); win.Visible = true; win.Activate(); } } } } } //make a copy of this so we can look at it after forwarding some commands uint commandID = nCmdID; char typedChar = char.MinValue; //make sure the input is a char before getting it if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); } //check for a commit character if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB || typedChar == '"') { //check for a selection if (m_session != null && !m_session.IsDismissed) { //if the selection is fully selected, commit the current session if (m_session.SelectedCompletionSet.SelectionStatus.IsSelected) { m_session.Commit(); //also, don't add the character to the buffer // this.DocumentDataLoader.ScheduleReloading(XmlDocumentLoader.EditTimeout); return(VSConstants.S_OK); } else { //if there is no selection, dismiss the session m_session.Dismiss(); } } } //pass along the command so the char is added to the buffer int retVal = m_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); bool handled = false; if ((!typedChar.Equals(char.MinValue) && char.IsLetterOrDigit(typedChar)) || (pguidCmdGroup == VSConstants.VSStd2K && (nCmdID == (uint)VSConstants.VSStd2KCmdID.AUTOCOMPLETE || nCmdID == (uint)VSConstants.VSStd2KCmdID.COMPLETEWORD || nCmdID == (uint)VSConstants.VSStd2KCmdID.SHOWMEMBERLIST ))) { if (m_session == null || m_session.IsDismissed) // If there is no active session, bring up completion { this.TriggerCompletion(); if (m_session != null && !((nCmdID == (uint)VSConstants.VSStd2KCmdID.AUTOCOMPLETE || nCmdID == (uint)VSConstants.VSStd2KCmdID.COMPLETEWORD || nCmdID == (uint)VSConstants.VSStd2KCmdID.SHOWMEMBERLIST ))) // TODO: wtf? { m_session.Filter(); } } else //the completion session is already active, so just filter { m_session.Filter(); } handled = true; } else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || //redo the filter if there is a deletion commandID == (uint)VSConstants.VSStd2KCmdID.DELETE) { if (m_session != null && !m_session.IsDismissed) { m_session.Filter(); } handled = true; } //if ( // (pguidCmdGroup == VSConstants.VSStd2K && ( // nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR|| // nCmdID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || // nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB || // nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN // )) || (pguidCmdGroup == VSConstants.GUID_VSStandardCommandSet97 && ( // nCmdID == (uint)VSConstants.VSStd97CmdID.Cut || // nCmdID == (uint)VSConstants.VSStd97CmdID.Paste || // nCmdID == (uint)VSConstants.VSStd97CmdID.Undo || // nCmdID == (uint)VSConstants.VSStd97CmdID.Redo // )) // ) // this.DocumentDataLoader.ScheduleReloading(XmlDocumentLoader.EditTimeout); if (handled) { return(VSConstants.S_OK); } return(retVal); }
internal void TriggerCompletionSession(bool completeWord) { Dismiss(); _activeSession = CompletionBroker.TriggerCompletion(_textView); if (_activeSession != null) { FuzzyCompletionSet set; if (completeWord && _activeSession.CompletionSets.Count == 1 && (set = _activeSession.CompletionSets[0] as FuzzyCompletionSet) != null && set.SelectSingleBest()) { _activeSession.Commit(); _activeSession = null; } else { _activeSession.Filter(); _activeSession.Dismissed += OnCompletionSessionDismissedOrCommitted; _activeSession.Committed += OnCompletionSessionDismissedOrCommitted; } } }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { ThreadHelper.ThrowIfNotOnUIThread(); if (VsShellUtilities.IsInAutomationFunction(_provider.ServiceProvider)) { return(_nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } uint commandID = nCmdID; char typedChar = char.MinValue; if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR) { typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn); } if (nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB) { if (session != null && !session.IsDismissed) { if (session.SelectedCompletionSet.SelectionStatus.IsSelected) { session.Commit(); MoveCaret(); return(VSConstants.S_OK); } else { session.Dismiss(); } } } int retVal = _nextCommandHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); bool handled = false; if ((!typedChar.Equals(char.MinValue) && char.IsLetterOrDigit(typedChar)) || typedChar.Equals('<')) { if (session == null || session.IsDismissed) { TriggerCompletion(); session.Filter(); } else { session.Filter(); } handled = true; } else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || commandID == (uint)VSConstants.VSStd2KCmdID.DELETE) { if (session != null && !session.IsDismissed) { session.Filter(); } handled = true; } if (handled) { return(VSConstants.S_OK); } return(retVal); }