How to implement CODE SNIPPET by native code?

Hi,

Our language service is COM components written by native code. We want to implement CODE SNIPPET. Someone have told us how to implement that function in MPF. But we can't use the languagesevice.dll file correctly in our project.

It seems that we have to inplement the interface IVsExpansionProvider by ourself, But there is no valid help information about this interface in VSIP document. Could any one give us some advice


Thanks.


Best wishes.



Answer this question

How to implement CODE SNIPPET by native code?

  • BabuMan

    Actually there are three interfaces that you need to implement, IOleCommandTarget, IVsExpansionClient and IVsTextBufferEvents. 

    IOleCommandTarget needs to be implemented so that you can add your language service to the command chain(which you've likely already done). 

    In the Exec methods you should handle the cmdids for Edit.InsertSnippet, Edit.SurroundWith, Edit.InsertTab, Edit.TabLeft,and Edit.BreakLine

    On Edit.InsertSnippet/Edit.SurroundWith, you want to get a pointer to the ExpansionManager and call InvokeInsertionUI.

    On Edit.InsertTab, if you have a snippet active (Active ExpansionSession) you want to call GoToNextExpansionField on the Tab.  On Edit.TabLeft you want to GoToPreviousExpansionField.  On Edit.BreakLine, if you have an active snippet and you are inside an active field, you want to call EndCurrentExpansion to commit.

    On Edit.Insert Tab, you do not have a snippet active, you should determine if the text to the left of the cursor is a valid shortcut and if it is you should get the IVsExpansion interface from the buffer and call InsertExpansion. 

    On IVSExpansionClient, OnItemChosen you should call InsertNamedExpansion on the IVSExpansion interface from the buffer to insert the snippet into the code and start the session.

    In Query Status, you should indicate you support these commands as appropriate.

    For IVsTextBufferEvents, you need to make sure that you are responding to the changes in the language service ID so that if the language service changes to yours you know to add yourself to the command filter and if it changes away from yours then you can remove yourself from the command filter.

    You also need to make sure that the registration is handled in the same way as the other languages which I believe is documented with the MPF. 

    If you have any further questions, let me know!  I'm curious as to what language we'll start having Code Snippets for

    Thanks,
    Sean



  • JameyMcElveen


    Hi,Sean Laberee

    Thank you for reply.

    I am confused in another three questions.

    1.what is the difference between Edit.InsertSnippet and Edit.SurroundWith   May I just implement Edit.InsertSnippet  It seems that the meanings of InsertSnippet  and  SurroundWith are same.

    2. where can I get the definition of IVsTextBufferEvents and IVsTextBufferEvents The version of VSSDK which I am using is "Visual Studio 2005 SDK(English version)".  In this SDK, I can not find out the definition.

    3.About "responding  the changes in the language service" , Could you give me some advice  in detail to implement


    Thanks!!!


    Best wishes.


  • Remi Szyndler

    1. I'm following up on the differences in the two commands as it appears to work differently than I was expecting. Stay tuned.

    2. IVsTextBufferEvents is available in textmgr.idl which should be part of the SDK.

    3. Basically if the Guid represents your language service, you need to add yourself to the command filter (IVsTextView::AddCommandFilter).  If you it isn't your language service and you are actively listening to that command filter, you should remove yourself (IVsTextView::RemoveCommandFilter).



  • kumarkadali

    Hi,Sean Laberee

    Thank you very much for your timely reply.

    1. Could you tell me how to get a pointer to the ExpansionManager and how to  call InvokeInsertionUI   I have not got the definition of ExpansionManager. Is it IVsExpansionManager   If so, could I defined a point of IVsExpansionManager directly and call InvokeInsertionUI
        For example: CComPtr<IVsExpansionManager > srpExpansionManager;
                          srpExpansionManager->InvokeInsertionUI(....);

    2. I have got that all of the functions of IVsExpansionClient are Virtual function. Should I implement all of these function or should I just need to implement OnItemChosen It seems all of this functions are related with code snippet. If I should implement all of these functions, could you give me some advice

    3. The function InsertNamedExpansion in IVsExpansion is a virtual function. Because I need to call it in IVsExpansionClient::OnItemChosen(), is it means that I must implement InsertNamedExpansion by myself. If so, in its implemention, what should I do

    4. there are plenty of functions which need pass in the point of IVsExpansionClient as a parameter. For example,
             virtual HRESULT STDMETHODCALLTYPE InsertExpansion(
                /* [in] */ TextSpan tsContext,
                /* [in] */ TextSpan tsInsertPos,
                /* [in] */ IVsExpansionClient *pExpansionClient,
                /* [in] */ GUID guidLang,
                /* [out] */ IVsExpansionSession **pSession) = 0;
    How can I correctly set values for the parameters of tsContext, tsInsertPos, pExpansionClient

    5. I have implement the UI for code snippet. But I can not establish the Message_Map to the menu correctly. Could you do me a favor

    Thanks Very Much!!!

    Best regards.

  • omengware

    Sean,

    This info is very useful. I managed to get to call IVsExpansionManager::InvokeInsertionUI with all the proper parameters but it throws a memory access exception. I'm using unmanaged code and the call looks like this:

    hr = expansionManager->InvokeInsertionUI(m_textView, expansionClient, GUID_MY_LANGUAGE, NULL, 0, FALSE, NULL, 0, FALSE, NULL, NULL);

    This is called in viewfilter.cpp in my babel-derived language service.

    On another note, I found a problem with getting the list of code snippets when running devenv with the /RootSuffix Exp. Even the C# code snippets don't show up.

    Thanks,

    Juan

  • How to implement CODE SNIPPET by native code?