1

Re: Can ViEmu be conrtrolled from macro/add-in?

Hello,

I'd like to tune ViEmu's behavior somewhat.

From a macro or add-in, is there a way to:
--  find out if it is active?
--  set Normal or Input mode?

Thanks.

2

Re: Can ViEmu be conrtrolled from macro/add-in?

Indeed, ViEmu exposes a VS service. This provides the following methods: EnterInsertMode(), EnterNormalMode() and GetViMode(). All the details are here:

  http://www.viemu.com/forums/viewtopic.php?id=318

On the other hand, there is no way to tell if it is active. What do you mean by "active" exactly? Whether it is enabled on Tools|Options|ViEmu or by Ctrl-Shift-Alt-V? I'd have to add a method to the service to allow this.

Regards,

  -- Jon

3

Re: Can ViEmu be conrtrolled from macro/add-in?

Cool.

How do I get an instance of an object that implements the interface?

I tried running tlbimp on viemu.dll, but the IViEmuService2 interface didn't show up in the dll created.

I'm working with a C# extension.

Thanks.

(ViEmu 2.2.8)

Update:
I have my VisStudio extension all ready to go, as soon as I learn how to communicate with ViEmu...
(The C# extension is ready; I'm having trouble with C++ versions and getting the WindowEvents, or adding WindowEvents handlers.)

Last edited by Number8 (2009-07-04 15:59:05)

4

Re: Can ViEmu be conrtrolled from macro/add-in?

Hello,

The service proffered by ViEmu is not different from other standard VS services like IVSUIShell, IVsStatusBar, etc... so the same techniques apply.

You need to use QueryService() to access it, and you need to declare the COM interface separately. Here is some code from an example I have in C#, which uses CodeRush to get the service:

------------
[Guid("C93926D3-533A-47BD-A085-DDA86F19D8EC"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IViEmuService2
{
    void EnterInsertMode();
    void EnterNormalMode();
    int  GetViMode();
}

// ...

            if (!tried)
            {
                tried = true;

                IOleServiceProvider isp = CodeRush.ApplicationObject as IOleServiceProvider;

                IntPtr ppObj;
                System.Guid guid_service = new System.Guid("D61C5542-1D52-4731-A789-9A9E5798F052");
                System.Guid guid_iviemu = new System.Guid("C93926D3-533A-47BD-A085-DDA86F19D8EC");
             
                if (isp.QueryService(
                    ref guid_service,
                    ref guid_iviemu,
                    out ppObj
                    ) == DevExpress.CodeRush.Win32.HRESULT.S_OK)
                {
                    viemu_service = Marshal.GetObjectForIUnknown(ppObj) as IViEmuService2;
                }
            }
------------

In non-CodeRush scenarios, you have to get to the service differently. In a package, you are given an IServiceProvider in the SetSite() call. If you are using some 3rd party framework, you probably have a QueryService() you can call internally.

If you are doing an add-in, here is sample code from Microsoft to get a service:

  http://msdn.microsoft.com/en-us/library/bb166423(VS.80).aspx?ppud=4

And here is some sample code to do the same from Carlos Quintero, in VB:

  http://www.mztools.com/articles/2007/mz2007015.aspx

Here is some more sample code and an article that seem relevant:

  http://www.code-magazine.com/article.aspx?quickid=0710052&page=2

Best regards,

  -- Jon

5

Re: Can ViEmu be conrtrolled from macro/add-in?

Thanks for the details.  I have implemented this in my C# add-in to get the ViEmu service:

IOleServiceProvider sp = (IOleServiceProvider) _applicationObject;
System.Guid guid_service = new System.Guid("D61C5542-1D52-4731-A789-9A9E5798F052");
System.Guid guid_iviemu = new System.Guid("C93926D3-533A-47BD-A085-DDA86F19D8EC");
IntPtr output;
sp.QueryService(ref guid_service, ref guid_iviemu, out output);
viEmuSvc = (ViEmuIfc.IViEmuService2)Marshal.GetObjectForIUnknown(output);

6

Re: Can ViEmu be conrtrolled from macro/add-in?

Great to hear that. Let me know if anything else is necessary.

Best regards,

  -- Jon

7

Re: Can ViEmu be conrtrolled from macro/add-in?

would it be possible for VIEmu to expose an event that notifies subscribers when the vi mode changes(ie from "normal" to "insert" etc)?

It seems rather less than optimal to have to put all the logic in the CaretMoved, which can have an adverse affect on scrolling speed.

8

Re: Can ViEmu be conrtrolled from macro/add-in?

rhaehnel, I'm not really sure how complex this can be. I suppose exposing a COM event source must be doable, although this kind of thing is always somewhat problematic. I will take note and try to provide this in the future, probably when I have a chance to improve the scripting support in ViEmu.

Meanwhile, checking this on each CaretMove, while clearly overkill, will probably not be noticeable performance-wise.

Regards,

  - Jon