Home > Plug-in Development > Creating a custom CodeRush Intellassist extension

Creating a custom CodeRush Intellassist extension

October 18th, 2011

In this topic we are going to extend the CodeRush Intellassist feature using the DXCore IntellassistExtension component. A sample extension will suggest all possible variable names of a local declaration based on its entered type in C# language.

For example, if you are declaring a variable of the StackOverflowException type, an extension will suggest several names such as: overflow, overflowException, exception, stackOverflowException, etc.

Bear in mind that you have to type at least a single character, so Intellassist can make suggestions based on this character. So, using the StackOverflow as a sample type, an extension will suggest the following names:

  • after typing “s”: stack, stackOverflowException
  • after typing “o”: overflow, overflowExcepion
  • after typing “e”: exception

Here are the steps we should perform:

1. Create a new DXCore standard plug-in
2. Drop the IntellassistExtension DXCore control on the plug-ins surface:

DXCore IntellassistExtention on the Toolbox

3. Fill its properties (at least ExtensionName):

DXCore custom Intellassist Extention properties

We do not need this extension to be available inside comments and strings, so the high values are set to make it unavailable. Also, it will perform only with local declarations, so set the InMethod property to ‘true’.

4. Subscribe to the GetSuggestions event:

DXCore custom Intellassist Extention events

5. Implement the GetSuggestions event handler.

The algorithm for the GetSuggestions event handler is the following: once a single character is typed, the Intellassist Engine will ask all registered Intelliassist extensions for suggestions. In C#, we declare variables in the following way:

VarType VarName;

The type of a variable goes first, then its name. An extension will add its hints when a user starts typing a variable name. When he starts to type a variable name, the editor caret location is right after the first character typed (| – represents the editor caret):

VarType v|

First, we get the left text before the editor caret using the DXCore Caret service and check if it has the correct form:

string leftText = CodeRush.Caret.LeftText.Trim();

We are trimming the text, because we do not need the leading and trailing whitespace. If there’s some valid text before the caret, we search for the last space character that delimits the VarType and VarName parts:

int lastSpaceCharIndex = leftText.LastIndexOf(" ");

If we have a non-negative index of the space character, we extract the VarType part of a variable from the text:

leftText = leftText.Substring(0, lastSpaceCharIndex);

The extracted string should correspond to the variable type C# declaration rules. Here, the DXCore Language service will help us to analyze it, and check if the string is a valid type identifier in C#. First, we check if it starts from the correct character:

if (!CodeRush.Language.IsLeadingIdentifierChar(leftText[0]))
  return;

then, we verify all other characters:

for (int i = 1; i < leftText.Length; i++)
  if (!CodeRush.Language.IsTrailingIdentifierChar(leftText[i]))
   return;

If the string is valid, we parse its words character by character and add suggestions to the Intelliassist suggestions list using the StandardPriorityList accessible through the GetIntellassistSuggestionsEventArgs instance.

The resulting code looks like this:

private void intellassistExtension1_GetSuggestions(GetIntellassistSuggestionsEventArgs e)
{
  string leftText = CodeRush.Caret.LeftText.Trim();
  if (String.IsNullOrEmpty(leftText))
    return;

  int lastSpaceCharIndex = leftText.LastIndexOf(" ");
  if (lastSpaceCharIndex < 0)
    return;

  leftText = leftText.Substring(0, lastSpaceCharIndex);

  if (!CodeRush.Language.IsLeadingIdentifierChar(leftText[0]))
    return;
  for (int i = 1; i < leftText.Length; i++)
    if (!CodeRush.Language.IsTrailingIdentifierChar(leftText[i]))
      return;

  string currentWord = String.Empty;
  int textLength = leftText.Length;
  int lastCharacterIndex = textLength - 1;
  for (int i = 0; i < textLength; i++)
  {
    char currentChar = leftText[i];
    bool currectCharIsLast = i == lastCharacterIndex;
    if ((Char.IsUpper(currentChar) && i > 0) || currectCharIsLast)
    {
      if (currectCharIsLast)
        currentWord += currentChar;

      if (!String.IsNullOrEmpty(currentWord))
      {
        string subIdentifierSuggestion = CodeRush.Strings.Get("FormatLocalName", currentWord);
        if (subIdentifierSuggestion.StartsWith(e.ValueToMatch))
          e.StandardPriorityList.Add(new IntellassistSuggestion(subIdentifierSuggestion));

        if (subIdentifierSuggestion.StartsWith(e.ValueToMatch) && !currectCharIsLast)
        {
          string endPart = subIdentifierSuggestion + leftText.Substring(i);
          e.StandardPriorityList.Add(new IntellassistSuggestion(endPart));
        }
        currentWord = String.Empty;
      }
    }
    currentWord += currentChar;
  }
}

After the plug-in is compiled, we can see it in action for each case we discussed before:

  • after typing “s”:

CodeRush Custom Intellassist Extension sample #1

CodeRush Custom Intellassist Extension sample #2

  • after typing “o”:

CodeRush Custom Intellassist Extension sample #3

CodeRush Custom Intellassist Extension sample #4

  • after typing “e”:

CodeRush Custom Intellassist Extension sample #5

The sample code is attached (11,134 bytes, C#, VS2010).

—–
Products: DXCore, CodeRush Pro
Versions: 11.1 and up
VS IDEs: any
Updated: Oct/18/2011
ID: D121

Similar Posts: