Re: Could I map tab to ctrl-space (intelligently)?

I really like smart tab autocompletion (http://www.vim.org/tips/tip.php?tip_id=102) in Vim, and a similar thing but with ctrl-space instead of the missing ctrl-p would be pretty close to that functionality.

Probably, it would be a VS macro combined with a mapping to tab, correct? Any thoughts on where to start? How do you map a shortcut to a macro function? Can you?


Re: Could I map tab to ctrl-space (intelligently)?

Hi llimllib,

The key would be to use the ":vscmd" ViEmu command. Something like this:

:inoremap <tab> <esc>:vscmd {whatever}<return><i>

Should do the trick. You can use the command :macro to call a user macro (see the ViEmu documentation, there is a hotlink to your local copy in Tools|Options|ViEmu).




Re: Could I map tab to ctrl-space (intelligently)?

Alright, thanks, I think that's all I need to get started. When I hit a dry spell here I'll see what I can knock up.


Re: Could I map tab to ctrl-space (intelligently)?

Cool, you're welcome.


Re: Could I map tab to ctrl-space (intelligently)?

So I have a macro that does roughly what I want it to:

    Sub Smartcomplete()
        Dim TS As TextSelection = DTE.ActiveDocument.Selection
        Dim instab As String = ".;" + vbNewLine + vbTab
        If instab.IndexOfAny(TS.Text.ToCharArray()) > -1 Then
        End If
    End Sub

But it only works in insert mode. Is there any way to insert text and/or execute a command from a macro when we're in command mode? How about to run the macro from insert mode?

EDIT: or even to bind the tab key from Visual Studio itself?

Last edited by llimllib (2007-05-25 14:03:24)


Re: Could I map tab to ctrl-space (intelligently)?


Why does it only work in insert mode? If it is because of the above mapping example (unsing :inoremap), then it is because "inoremap" is only honored in insert mode. You can use ":nnoremap" for normal mode, ":vnoremap" in visual mode, and there are others too (the documentation has them all, this is vim behavior actually).

For example, if you want do the same as above in normal mode, the line would be:

  :nnoremap <tab> :vscmd {whatever}<return>

I removed the <esc> (because we don't need to exit insert mode to call a : ex command from normal mode), and the 'i' to get back in insert mode.




Re: Could I map tab to ctrl-space (intelligently)?

If I'm on text in command mode, hit "i", then click "Smartcomplete -> Run" in the macro explorer, the macro works as expected. If, however, I bind it to tab, and hit tab, nothing happens. Similarly, if in command mode I type ":vscmd Smartcomplete" nothing happens.

If I stay in command mode, and I click "Smartcomplete -> Run", the macro is run and produces strange results. If it hits the CompleteWord branch, then the completeword box is displayed, but does not have keyboard focus. If it hits the other branch, then a tab is inserted in the wrong place.

So! 2 more Qs: 1) Why doesn't ":vscmd Smartcomplete" do anything? Does the macro need to be in a specific module? and 2) why does the insert work correctly in insert mode, but not in command mode?


Re: Could I map tab to ctrl-space (intelligently)?

Ok, as to why ":vscmd Smartcomplete" doesn't work, that one is easy: you need to provide a full command, the type of commands that work in the QuickFind combo box when preceded with '>' (this is not too well known, but it works). Thus, you need to use ":vscmd Macros.Smartcomplete" and that should work fine. You can also use the ViEmu shortcut ":macro", which prepends the "Macros." itself, so ":macro Smartcomplete" should work.

Regarding he fact that "Tab" by itself does nothing, how have you bound it to the macro? I'm not sure VS allows binding Tab (at least it doesn't allow me to enter it in Tools|Options|Keyboard). Knowing how you have bound it should help.

As to the autocompletion box not paying attention to input, it's normal that does happen if ViEmu is still in normal mode - autocompletion needs ViEmu to pass keypresses through, and it only does so in insert mode. If you're binding <tab> through ViEmu, it would definitely pay off to have an 'i' after ":macro ...<return>", to make ViEmu pass input through. Hopefully that will fix it.

Finally, regarding why the Tab is inserted in the wrong place, I'd need more details about how you have bound it and I'll try to understand what is happening.

VS<->ViEmu integration is pretty complex, as VS is not designed for such a radical change, and I handle all built-in cases in the code, but it's possibly necessary to do something more to do what you are trying to.


Re: Could I map tab to ctrl-space (intelligently)?

Much closer!

The magic incantation was:
:inoremap <tab> <esc>:macro MyMacros.RecordingModule.Smartcomplete<return><i>

Now, if we hit the autocomplete branch, we get the autocomplete box and focus is correctly on it. However, the tab key is still bound to run the macro, so you need to hit enter instead of another tab to autocomplete, and TS.CharRight() doesn't move the cursor to the right.

So, 2 more questions: 1) Any idea how to tell programmatically if the autocomplete box is open? Not your area I know, just asking.


2) Any idea why the character doesn't move right?

If we hit the "insert tab" branch, TS.CharRight() again doesn't work, so we insert the tab one space to the left of where we want it to insert, so an answer to 2) would solve this problem.

It's looking hopeful...


Re: Could I map tab to ctrl-space (intelligently)?

Ah ok. Yes, you need to prepend MyMacros and the module name to the macro invocation.

Regarding the questions: (1) is something I have asked the Microsoft VS developers quite a few times, and it seems there is no satisfactory answer at least on VS.NET 2003. VS2005 seems to have some support to detect it, but ViEmu is not using it. If I knew when it's open, I would be able to know about passing keys through instead of working in them, but it doesn't seem to work. In any case, since it's come up again, I'll have a look at it and get back to you about it.

Regarding (2) why cursor movement doesn't work, I'm not entirely sure. Can you test whether, if you leave out the <i> key from the mapping, it works? It won't work with the autocompletion box, but if the cursor movement works, I can probably find some solution to make it work. One possibility is adding a ViEmu macro command to be able to instruct it to enter insert mode from the macro - this is already accessible to other plug-ins through a VS service, but I could add another hook to call it from VS macros.


Re: Could I map tab to ctrl-space (intelligently)?

Awesome info, hope you hear back about the autocomplete box.

I won't be back in the office until Tuesday, I'm a Mac at home, so I'll let test for you then.

If this works, I'm going to be amped.


Re: Could I map tab to ctrl-space (intelligently)?


I have researched it, and there is a somewhat straightforward way to obtain the information from VS, but only in VS2005 (and later, I guess). Since VS only exposes it internally (IVsTextViewEx interface, IsCompletorWindowActive() call), I would need to provide a bridge from the macro language to query this state. Maybe something like  ViEmu.IsCompletorWindowActive(), which, while having nothing to do with ViEmu, will provide the require info, and you'll be able to query this in the macro.

Possibly, if the macro does something like:

  If ViEmu.IsCompletorWindowActive Then
    ViEmu.EnterInsertMode() 'Make sure ViEmu passes keypresses through
    Edit.BreakLine 'This is a RETURN keypress, will possibly accept the selection
  End If

Do you think something like that would solve the problem?

Since I haven't provided any ViEmu hooks for the VS macro system, it will take a while to get this researched & implemented, but I think it's doable.

And BTW, make sure you are using VS2005, it will be no use on VS.NET 2003 (it's an internal and unexposed VS state).