in Python/Product/PythonTools/PythonTools/Intellisense/IntellisenseController.cs [1071:1223]
public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) {
var session = Volatile.Read(ref _activeSession);
ISignatureHelpSession sigHelpSession;
if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (int)VSConstants.VSStd2KCmdID.TYPECHAR) {
var ch = (char)(ushort)System.Runtime.InteropServices.Marshal.GetObjectForNativeVariant(pvaIn);
bool suppressChar = false;
if (session != null && !session.IsDismissed) {
if (session.SelectedCompletionSet != null &&
session.SelectedCompletionSet.SelectionStatus.IsSelected &&
_services.Python.AdvancedOptions.CompletionCommittedBy.IndexOf(ch) != -1) {
if ((ch == '\\' || ch == '/') && session.SelectedCompletionSet.Moniker == "PythonFilenames") {
// We want to dismiss filename completions on slashes
// rather than committing them. Then it will probably
// be retriggered after the slash is inserted.
session.Dismiss();
} else {
if (ch == session.SelectedCompletionSet.SelectionStatus.Completion.InsertionText.LastOrDefault()) {
suppressChar = true;
}
session.Commit();
}
} else if (!Tokenizer.IsIdentifierChar(ch)) {
session.Dismiss();
}
}
int res = VSConstants.S_OK;
if (!suppressChar) {
res = _oldTarget != null ? _oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut) : VSConstants.S_OK;
HandleChar(ch);
if (session != null && session.IsStarted && !session.IsDismissed) {
session.Filter();
}
}
return res;
}
if (session != null) {
if (pguidCmdGroup == VSConstants.VSStd2K) {
switch ((VSConstants.VSStd2KCmdID)nCmdID) {
case VSConstants.VSStd2KCmdID.RETURN:
if (_services.Python.AdvancedOptions.EnterCommitsIntellisense &&
!session.IsDismissed &&
(session.SelectedCompletionSet?.SelectionStatus.IsSelected ?? false)) {
// 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 = _services.Python.AdvancedOptions.AddNewLineAtEndOfFullyTypedWord &&
EnterOnCompleteText(session);
session.Commit();
if (!enterOnComplete) {
return VSConstants.S_OK;
}
} else {
session.Dismiss();
}
break;
case VSConstants.VSStd2KCmdID.TAB:
if (!session.IsDismissed) {
session.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 != null ? _oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut) : VSConstants.S_OK;
if (session != null && session.IsStarted && !session.IsDismissed) {
session.Filter();
}
return res;
}
}
} else if ((sigHelpSession = Volatile.Read(ref _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();
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;
}
}
}
if (_oldTarget != null) {
return _oldTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
}
return (int)Constants.OLECMDERR_E_UNKNOWNGROUP;
}