3

I am attempting to implement a Language Service in a VSPackage using the MPF, and it's not working quite as I understand it should.

I have several implementations already, such as ParseSource parsing the input file with a ParseRequest. However, when it finds an error, it adds it with AuthoringSink.AddError. The documentation for this implies it adds it to the Error List for me; it doesn't.

I also have a simple MySource class, a subclass of Source. I return this new class with an overridden LanguageService.CreateSource method. The documentation for OnCommand says it's fired 'when a command is entered'. However, it's not.

There's obviously some intermediate step which I haven't done correctly. I've already rambled enough, so I'll be glad to give any additional details by request.

Any clarification is much appreciated.

  • Note that for extensions targeting Visual Studio 2010 and newer, the MPF language services are obsolete. If possible, you should consider using the new MEF interfaces instead (unless of course you need to target Visual Studio 2008 or earlier). – Sam Harwell Mar 26 '14 at 12:50

2 Answers2

1

For the AuthoringSink error list question, I use this behavior in my Language Service. In ParseSource, the ParseRequest class has an AuthoringSink. You can also create a new ErrorListProvider if you want to work outside of the parser's behavior. Here is some example code:

error_list = new ErrorListProvider(this.Site);
    error_list.ProviderName = "MyLanguageService Errors";
    error_list.ProviderGuid = new Guid(this.errorlistGUIDstring.);
}

ErrorTask task = new ErrorTask();
task.Document = filename;
task.CanDelete = true;
task.Category = TaskCategory.CodeSense;
task.Column = column;
task.Line = line;
task.Text = message;
task.ErrorCategory = TaskErrorCategory.Error;
task.Navigate += NavigateToParseError;
error_list.Tasks.Add(task);

I hope this was helpful.

OnCommand should be firing every time there is a command, in your MySource class you can do something like this (pulled from working code):

public override void OnCommand(IVsTextView textView, VsCommands2K command, char ch)
{
    if (textView == null || this.LanguageService == null 
        || !this.LanguageService.Preferences.EnableCodeSense)
        return;

    if (command == Microsoft.VisualStudio.VSConstants.VSStd2KCmdID.TYPECHAR)
    {
        if (char.IsLetterOrDigit(ch))
        {
            //do something cool
        }
    }

    base.OnCommand(textView, command, ch);
}

If that doesn't work double check that CodeSense = true in your ProvideLanguageService attribute when you setup your LanguageService package. A whole lot of what is cool to do in the LanguageService requires these attributes to be correctly turned on. Some even give cool behaviors for free!

Another thing to be careful of is that some behaviors like colorizer don't function correctly in the hive in my experience. I don't think these were ones that gave me trouble, but I implemented these a couple of years ago so I'm mostly just looking back at old code.

ColinCren
  • 595
  • 3
  • 13
1

AuthoringSink.AddError only adds errors to the error list if ParseRequest.Reason is ParseReason.Check. When your ParseSource function attempts to add errors while parsing for any other ParseReason, nothing will happen.

It's possible that your language service is never calling ParseSource with this ParseReason. As far as I know, the only way to get a ParseReason of Check (outside of manually calling BeginParse or ParseSource yourself) is to proffer your service with an idle timer.

Community
  • 1
  • 1
Jon Senchyna
  • 7,867
  • 2
  • 26
  • 46