public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { Logger.Exec(pguidCmdGroup, nCmdID); if (VsShellUtilities.IsInAutomationFunction(Provider.ServiceProvider)) { return(NextCmdHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut)); } 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); } while (true) { //check for a commit character if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB || (char.IsWhiteSpace(typedChar) || JavaSessionCompletions.AutocompleteCommitChars.Contains(typedChar))) { if (CompletionSession != null && !CompletionSession.IsDismissed) { if (CompletionSession.SelectedCompletionSet.SelectionStatus.IsSelected) { // Only commit selection if typedChar is not part of the current selection. This will allow typing . when autocompleting package names without closing ACL if (CompletionSession.SelectedCompletionSet.SelectionStatus.Completion.InsertionText.Contains(typedChar)) { break; } int adjustCursor = 0; if (CompletionSession.SelectedCompletionSet.SelectionStatus.Completion.InsertionText.EndsWith(")")) // Eclipse returns functions already appended with (); we'll fix up cursor position post insertion { adjustCursor = -1; } JavaSessionCompletions sessionCompletions = null; if (CompletionSession.Properties.TryGetProperty <JavaSessionCompletions>(typeof(JavaSessionCompletions), out sessionCompletions)) { sessionCompletions.Commit(CompletionSession, typedChar); } if (adjustCursor != 0) { TextView.Caret.MoveTo(TextView.Caret.Position.BufferPosition.Add(adjustCursor)); if (SignatureSession != null) { SignatureSession.Dismiss(); } TriggerSignatureHelp(); } Telemetry.Client.Get().TrackTrace(String.Format("ACL Session completed on nCMDID = {0}; typedChar = {1}; adjustCursor = {2}", nCmdID, typedChar, adjustCursor)); if (typedChar == char.MinValue || (typedChar == '(' && adjustCursor != 0)) { return(VSConstants.S_OK); // don't add the character to the buffer if it's an ENTER, TAB or a open-paran (in the case of a method call) } } else { // If no selection, dismiss the session CompletionSession.Dismiss(); Telemetry.Client.Get().TrackTrace(String.Format("ACL Session dismissed on nCMDID = {0}; typedChar = {1}", nCmdID, typedChar)); } } } break; } // Update param help? if (commandID == (uint)VSConstants.VSStd2KCmdID.LEFT) { if (SignatureSession != null) { UpdateCurrentParameter(TextView.Caret.Position.BufferPosition.Position - 1); } } else if (commandID == (uint)VSConstants.VSStd2KCmdID.RIGHT) { if (SignatureSession != null) { UpdateCurrentParameter(TextView.Caret.Position.BufferPosition.Position + 1); } } else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE) { if (SignatureSession != null) { SnapshotPoint?caretPoint = TextView.Caret.Position.Point.GetPoint( textBuffer => (!textBuffer.ContentType.IsOfType("projection")), PositionAffinity.Predecessor); if (caretPoint.HasValue && caretPoint.Value.Position != 0) { var deleting = TextView.TextSnapshot.GetText(caretPoint.Value.Position - 1, 1).First(); if (JavaSignatureHelpSessionSignatures.ParamHelpReevaluateTriggers.Contains(deleting)) { UpdateCurrentParameter(caretPoint.Value.Position - 1); } else if (JavaSignatureHelpSessionSignatures.ParamHelpTriggers.Contains(deleting)) { SignatureSession.Dismiss(); // TODO: May need to launch the nested param help } } } } if (commandID == (uint)VSConstants.VSStd97CmdID.GotoDefn) { SnapshotPoint?caretPoint = TextView.Caret.Position.Point.GetPoint( textBuffer => (!textBuffer.ContentType.IsOfType("projection")), PositionAffinity.Predecessor); if (caretPoint.HasValue && caretPoint.Value.Position != 0) { var fireAndForgetTask = new JavaGotoDefinition(TextView, Provider, caretPoint.Value).Run(Provider.EditorFactory); } return(VSConstants.S_OK); } // Pass along the command so the char is added to the buffer int retVal = NextCmdHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); bool handled = false; // Trigger Param help? if (JavaSignatureHelpSessionSignatures.ParamHelpTriggers.Contains(typedChar) || commandID == (uint)VSConstants.VSStd2KCmdID.PARAMINFO) { if (SignatureSession != null) { SignatureSession.Dismiss(); } TriggerSignatureHelp(); Telemetry.Client.Get().TrackTrace(String.Format("ParamHelp Session started on nCMDID = {0}; typedChar = {1}", VSConstants.VSStd2KCmdID.PARAMINFO.ToString(), typedChar)); } // Comma found while typing -> update paramhelp else if (JavaSignatureHelpSessionSignatures.ParamHelpReevaluateTriggers.Contains(typedChar)) { if (SignatureSession != null) { UpdateCurrentParameter(); } } // End of param help? else if (JavaSignatureHelpSessionSignatures.ParamHelpEndTrigger.Contains(typedChar)) { if (SignatureSession != null) { SignatureSession.Dismiss(); TriggerSignatureHelp(); // Just in case there is a nested call Telemetry.Client.Get().TrackTrace(String.Format("ParamHelp Session ended and restarted on nCMDID = {0}; typedChar = {1}", commandID, typedChar)); } } else if (commandID == (uint)VSConstants.VSStd2KCmdID.HOME || commandID == (uint)VSConstants.VSStd2KCmdID.BOL || commandID == (uint)VSConstants.VSStd2KCmdID.BOL_EXT || commandID == (uint)VSConstants.VSStd2KCmdID.END || commandID == (uint)VSConstants.VSStd2KCmdID.WORDPREV || commandID == (uint)VSConstants.VSStd2KCmdID.WORDPREV_EXT || commandID == (uint)VSConstants.VSStd2KCmdID.DELETEWORDLEFT) { if (SignatureSession != null) { SignatureSession.Dismiss(); Telemetry.Client.Get().TrackTrace(String.Format("ParamHelp Session ended on nCMDID = {0}; typedChar = {1}", commandID, typedChar)); } } // Trigger autocomplete? if (JavaSessionCompletions.AutocompleteTriggers.Contains(typedChar)) { if (CompletionSession == null || CompletionSession.IsDismissed) { // If there is no active session, begin one TriggerCompletion(); Telemetry.Client.Get().TrackTrace(String.Format("ACL Session started on nCMDID = {0}; typedChar = {1}", commandID, typedChar)); } else { CompletionSession.SelectedCompletionSet.SelectBestMatch(); } handled = true; } else if (commandID == (uint)VSConstants.VSStd2KCmdID.COMPLETEWORD || commandID == (uint)VSConstants.VSStd2KCmdID.AUTOCOMPLETE) { if (CompletionSession != null) { CompletionSession.Dismiss(); } TriggerCompletion(); Telemetry.Client.Get().TrackTrace(String.Format("ACL Session started on nCMDID = {0}; typedChar = {1}", commandID, typedChar)); handled = true; } else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || commandID == (uint)VSConstants.VSStd2KCmdID.DELETE) { // Redo the filter if there is a deletion if (CompletionSession != null && !CompletionSession.IsDismissed) { CompletionSession.SelectedCompletionSet.SelectBestMatch(); } handled = true; } // For any other char, we update the list if a session is already started else if (!typedChar.Equals(char.MinValue) && char.IsLetterOrDigit(typedChar)) { if (CompletionSession != null && !CompletionSession.IsDismissed) { CompletionSession.SelectedCompletionSet.SelectBestMatch(); } handled = true; } if (handled) { return(VSConstants.S_OK); } return(retVal); }
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { Logger.Exec(pguidCmdGroup, nCmdID); if (VsShellUtilities.IsInAutomationFunction(Provider.ServiceProvider)) { return NextCmdHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); } 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); } while (true) { //check for a commit character if (nCmdID == (uint)VSConstants.VSStd2KCmdID.RETURN || nCmdID == (uint)VSConstants.VSStd2KCmdID.TAB || (char.IsWhiteSpace(typedChar) || JavaSessionCompletions.AutocompleteCommitChars.Contains(typedChar))) { if (CompletionSession != null && !CompletionSession.IsDismissed) { if (CompletionSession.SelectedCompletionSet.SelectionStatus.IsSelected) { // Only commit selection if typedChar is not part of the current selection. This will allow typing . when autocompleting package names without closing ACL if (CompletionSession.SelectedCompletionSet.SelectionStatus.Completion.InsertionText.Contains(typedChar)) break; int adjustCursor = 0; if (CompletionSession.SelectedCompletionSet.SelectionStatus.Completion.InsertionText.EndsWith(")")) // Eclipse returns functions already appended with (); we'll fix up cursor position post insertion adjustCursor = -1; JavaSessionCompletions sessionCompletions = null; if (CompletionSession.Properties.TryGetProperty<JavaSessionCompletions>(typeof(JavaSessionCompletions), out sessionCompletions)) { sessionCompletions.Commit(CompletionSession, typedChar); } if (adjustCursor != 0) { TextView.Caret.MoveTo(TextView.Caret.Position.BufferPosition.Add(adjustCursor)); if (SignatureSession != null) SignatureSession.Dismiss(); TriggerSignatureHelp(); } Telemetry.Client.Get().TrackTrace(String.Format("ACL Session completed on nCMDID = {0}; typedChar = {1}; adjustCursor = {2}", nCmdID, typedChar, adjustCursor)); if (typedChar == char.MinValue || (typedChar == '(' && adjustCursor != 0)) return VSConstants.S_OK; // don't add the character to the buffer if it's an ENTER, TAB or a open-paran (in the case of a method call) } else { // If no selection, dismiss the session CompletionSession.Dismiss(); Telemetry.Client.Get().TrackTrace(String.Format("ACL Session dismissed on nCMDID = {0}; typedChar = {1}", nCmdID, typedChar)); } } } break; } // Update param help? if (commandID == (uint)VSConstants.VSStd2KCmdID.LEFT) { if (SignatureSession != null) UpdateCurrentParameter(TextView.Caret.Position.BufferPosition.Position - 1); } else if (commandID == (uint)VSConstants.VSStd2KCmdID.RIGHT) { if (SignatureSession != null) UpdateCurrentParameter(TextView.Caret.Position.BufferPosition.Position + 1); } else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE) { if (SignatureSession != null) { SnapshotPoint? caretPoint = TextView.Caret.Position.Point.GetPoint( textBuffer => (!textBuffer.ContentType.IsOfType("projection")), PositionAffinity.Predecessor); if (caretPoint.HasValue && caretPoint.Value.Position != 0) { var deleting = TextView.TextSnapshot.GetText(caretPoint.Value.Position - 1, 1).First(); if (JavaSignatureHelpSessionSignatures.ParamHelpReevaluateTriggers.Contains(deleting)) { UpdateCurrentParameter(caretPoint.Value.Position - 1); } else if (JavaSignatureHelpSessionSignatures.ParamHelpTriggers.Contains(deleting)) { SignatureSession.Dismiss(); // TODO: May need to launch the nested param help } } } } if (commandID == (uint)VSConstants.VSStd97CmdID.GotoDefn) { SnapshotPoint? caretPoint = TextView.Caret.Position.Point.GetPoint( textBuffer => (!textBuffer.ContentType.IsOfType("projection")), PositionAffinity.Predecessor); if (caretPoint.HasValue && caretPoint.Value.Position != 0) { var fireAndForgetTask = new JavaGotoDefinition(TextView, Provider, caretPoint.Value).Run(Provider.EditorFactory); } return VSConstants.S_OK; } // Pass along the command so the char is added to the buffer int retVal = NextCmdHandler.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); bool handled = false; // Trigger Param help? if (JavaSignatureHelpSessionSignatures.ParamHelpTriggers.Contains(typedChar) || commandID == (uint)VSConstants.VSStd2KCmdID.PARAMINFO) { if (SignatureSession != null) SignatureSession.Dismiss(); TriggerSignatureHelp(); Telemetry.Client.Get().TrackTrace(String.Format("ParamHelp Session started on nCMDID = {0}; typedChar = {1}", VSConstants.VSStd2KCmdID.PARAMINFO.ToString(), typedChar)); } // Comma found while typing -> update paramhelp else if (JavaSignatureHelpSessionSignatures.ParamHelpReevaluateTriggers.Contains(typedChar)) { if (SignatureSession != null) UpdateCurrentParameter(); } // End of param help? else if (JavaSignatureHelpSessionSignatures.ParamHelpEndTrigger.Contains(typedChar)) { if (SignatureSession != null) { SignatureSession.Dismiss(); TriggerSignatureHelp(); // Just in case there is a nested call Telemetry.Client.Get().TrackTrace(String.Format("ParamHelp Session ended and restarted on nCMDID = {0}; typedChar = {1}", commandID, typedChar)); } } else if (commandID == (uint)VSConstants.VSStd2KCmdID.HOME || commandID == (uint)VSConstants.VSStd2KCmdID.BOL || commandID == (uint)VSConstants.VSStd2KCmdID.BOL_EXT || commandID == (uint)VSConstants.VSStd2KCmdID.END || commandID == (uint)VSConstants.VSStd2KCmdID.WORDPREV || commandID == (uint)VSConstants.VSStd2KCmdID.WORDPREV_EXT || commandID == (uint)VSConstants.VSStd2KCmdID.DELETEWORDLEFT) { if (SignatureSession != null) { SignatureSession.Dismiss(); Telemetry.Client.Get().TrackTrace(String.Format("ParamHelp Session ended on nCMDID = {0}; typedChar = {1}", commandID, typedChar)); } } // Trigger autocomplete? if (JavaSessionCompletions.AutocompleteTriggers.Contains(typedChar)) { if (CompletionSession == null || CompletionSession.IsDismissed) { // If there is no active session, begin one TriggerCompletion(); Telemetry.Client.Get().TrackTrace(String.Format("ACL Session started on nCMDID = {0}; typedChar = {1}", commandID, typedChar)); } else CompletionSession.SelectedCompletionSet.SelectBestMatch(); handled = true; } else if (commandID == (uint)VSConstants.VSStd2KCmdID.COMPLETEWORD || commandID == (uint)VSConstants.VSStd2KCmdID.AUTOCOMPLETE) { if (CompletionSession != null) CompletionSession.Dismiss(); TriggerCompletion(); Telemetry.Client.Get().TrackTrace(String.Format("ACL Session started on nCMDID = {0}; typedChar = {1}", commandID, typedChar)); handled = true; } else if (commandID == (uint)VSConstants.VSStd2KCmdID.BACKSPACE || commandID == (uint)VSConstants.VSStd2KCmdID.DELETE) { // Redo the filter if there is a deletion if (CompletionSession != null && !CompletionSession.IsDismissed) CompletionSession.SelectedCompletionSet.SelectBestMatch(); handled = true; } // For any other char, we update the list if a session is already started else if (!typedChar.Equals(char.MinValue) && char.IsLetterOrDigit(typedChar)) { if (CompletionSession != null && !CompletionSession.IsDismissed) CompletionSession.SelectedCompletionSet.SelectBestMatch(); handled = true; } if (handled) return VSConstants.S_OK; return retVal; }