in src/Trinity.VSExtension/TrinityVSExtension/EditorExtension/AutoCompletion/CompletionHandler.cs [115:213]
private List<ExecutionCommand> GetExecutionCommands(Guid cmdGroup, uint nCmdID, IntPtr pvaIn, out char? typedChar)
{
typedChar = null;
List<ExecutionCommand> ret = new List<ExecutionCommand>();
/* If there's automation, or we can't recognize cmdGroup, just pass on. */
if (VsShellUtilities.IsInAutomationFunction(provider.ServiceProvider) ||
(cmdGroup != VSConstants.VSStd2K))
{
ret.Add(ExecutionCommand.CMD_PassToNextHandler);
return ret;
}
bool sessionActive = (session != null && !session.IsDismissed);
bool sessionSelectionActive = (sessionActive && session.SelectedCompletionSet.SelectionStatus.IsSelected);
switch ((VSConstants.VSStd2KCmdID)nCmdID)
{
case VSConstants.VSStd2KCmdID.AUTOCOMPLETE:
case VSConstants.VSStd2KCmdID.COMPLETEWORD:
ret.Add(sessionActive ? ExecutionCommand.CMD_PassToNextHandler : ExecutionCommand.CMD_StartSession);
break;
case VSConstants.VSStd2KCmdID.TYPECHAR:
typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
bool commitChr = TypedCharLeadsToCommit(typedChar.Value);
bool triggerChr = TypedCharLeadsToTrigger(typedChar.Value);
if (commitChr && sessionActive)
{
/* Ready to commit the completion.
* We first check if we can commit something meaningful.
* If so, we then check if this commit will lead to another
* completion trigger.
* */
if (sessionSelectionActive)
{
ret.Add(ExecutionCommand.CMD_Commit);
ret.Add(ExecutionCommand.CMD_PassToNextHandler);
if (triggerChr)
ret.Add(ExecutionCommand.CMD_StartSession);
}
else
{
ret.Add(ExecutionCommand.CMD_Dismiss);
ret.Add(ExecutionCommand.CMD_PassToNextHandler);
}
}
else if (sessionActive)
{
/* Typed char doesn't lead to a commit. It leads to filter of completion results. */
ret.Add(ExecutionCommand.CMD_PassToNextHandler);
ret.Add(ExecutionCommand.CMD_Filter);
}
else
{
ret.Add(ExecutionCommand.CMD_PassToNextHandler);
/* Session not active, check if we have a trigger*/
if (triggerChr)
{
ret.Add(ExecutionCommand.CMD_StartSession);
}
}
/* At last, we issue a CheckInputChar command to see if we
* could do something about auto brackets completion, indention.
*/
ret.Add(ExecutionCommand.CMD_CheckInputChar);
break;
case VSConstants.VSStd2KCmdID.RETURN:
case VSConstants.VSStd2KCmdID.TAB:
if (sessionActive)
{
if(!sessionSelectionActive)
{
session.SelectedCompletionSet.SelectBestMatch();
}
ret.Add(ExecutionCommand.CMD_Commit);
}
else
{
ret.Add(ExecutionCommand.CMD_PassToNextHandler);
if (nCmdID == (uint)(VSConstants.VSStd2KCmdID.RETURN))
{
typedChar = '\n';
ret.Add(ExecutionCommand.CMD_CheckInputChar);
}
}
break;
case VSConstants.VSStd2KCmdID.BACKSPACE:
case VSConstants.VSStd2KCmdID.DELETE:
ret.Add(ExecutionCommand.CMD_PassToNextHandler);
if (sessionActive)
ret.Add(ExecutionCommand.CMD_Filter);
break;
case VSConstants.VSStd2KCmdID.CANCEL:
ret.Add(sessionActive ? ExecutionCommand.CMD_Dismiss : ExecutionCommand.CMD_PassToNextHandler);
break;
default:
ret.Add(ExecutionCommand.CMD_PassToNextHandler);
break;
}
return ret;
}