1

I use vim mainly for latex. The main reason why I do it is actually Ultisnips, which greatly reduces the number of symbols that I need to type in latex. Alongside it, I use auto-pairs, which matches brackets for me. One small gripe that I have with this setup is that I cannot use tab in order to both expand a snippet and jump outside of a pair of brackets - the relevant options are:

let g:UltiSnipsExpandTrigger = '<tab>'
let g:UltisnipsJumpForwardTrigger = '<tab>'
let g:AutoPairsShortcutJump = '<tab>'

The behavior that I would like is to expand a snippet if one is available, otherwise jump out of the bracket. But that does not work by default. Is there anything I can do, like some kind of conditional key mapping?

I have tried other solutions, like implementing bracket matching in Ultisnips for example, but never with satisfactory results.

Yes, I could simply use another key, but using tab for both would be the most convenient.

ge0rg
  • 63
  • 1
  • 11

1 Answers1

2

This can be done with user functions, utilizing the return values of the UltiSnips Trigger functions. Since you have everything mapped to the same key, I'll create an example using the combined UltiSnips function, ExpandSnippetOrJump, which sets the global variable ulti_expand_or_jump_res to 0 if it could neither expand a snippet nor jump to the next one.

So you'll define a function (cheekily named Ulti_Pairs()) with:

function! Ulti_Pairs()
    call UltiSnips#ExpandSnippetOrJump()
    if g:ulti_expand_or_jump_res == 0
        call AutoPairsJump()
    endif
endfunction

Then you'll set your mapping (you shouldn't need your other ones after this):

inoremap <Tab> <ESC>:call Ulti_Pairs()<CR>a

So to walk through what this is doing, when you press Tab Vim will call your custom function, which in turn calls ExpandSnippetOrJump(). If that function, returns anything else but 0 (meaning there was something to expand or jump to in UltiSnips) it won't do anything more. But on a return value of 0, it'll call the AutoPairsJump() function.

Das_Geek
  • 2,775
  • 7
  • 20
  • 26
  • I tried it out - unfortunately, it does not work. More precisely, expanding snippets works, but not jumping - neither with UltiSnips nor with auto-pairs. I don't really know vimscript, but trying to follow your logic: the custom function returns `g:ulti_expand_or_jump_res`, which is never changed, but is what is returned by the custom function. Am I missing something here? – ge0rg Jan 21 '20 at 19:20
  • As I mentioned in the first paragraph, the function `UltiSnips#ExpandSnippetOrJump()`, rather than properly returning a value, sets a global variable instead. So if that function is able to expand or jump, it'll set `g:ulti_expand_or_jump_res` to something other than `0`. It's set before the function because that's how UltiSnip's example usage did it, and I figured don't fix what ain't broke. You can debug that the variable is being set by adding some form of `echo` in the function, which should hopefully be a value that you'd expect. – Das_Geek Jan 21 '20 at 19:30
  • Thanks. As I said, I know next to nothing about vimscript. I tried adding an `echo g:ulti_expand_or_jump_res` before and after `call UltiSnips#ExpandSnippetOrJump()`, which returned 0 as expected when called on its own. However, when I pressed tab, regardless if there was something to expand or not, simply nothing happened, and nothing was echoed. So maybe something is wrong with the remap? – ge0rg Jan 21 '20 at 19:44
  • Maybe, but it shouldn't be. Let's troubleshoot in a [chat room I created](https://chat.stackoverflow.com/rooms/206378/conversation-about-ultisnips); comments shouldn't be used for extended discussion – Das_Geek Jan 21 '20 at 19:57