Sublime Forum

Tab completion for snippets with unexpected behavior

#1

Hi,

I’m new to sublime text 3 after using Notetab Pro for many years.

I made a clip library for my programming niche and set up tab triggers. One of the things that’s confusing me is that sometimes I have to hit the tab two or three times for it to trigger the snippet. It appears to search for any text in the document that matches what I typed and waits to see if I want to select some other text before running the snippet.

In Notetab Pro the trigger is the spacebar and there is no ambiguity- it just slaps the snippet up ready to use.

Any ideas on this?

Also related to snippets, I’m having trouble figuring out how to wrap selected text with a snippet. Sometimes I want to comment out or otherwise process a bunch of text in place with a snippet, but the selected text ‘inside’ the snippet. Any tutorials on doing this? I saw a few discussions on stack exchange but they didn’t really clear things up.

Thanks a lot-

Scot

1 Like

#2

Does this happen after using a previous snippet by any chance?

Sublime handles snippets with fields in them by requiring you to press Tab to move between the fields, with a Tab press at the end of the snippet causing the cursor to jump to the end of the snippet. This can catch you unaware.

For example, given this snippet:

<snippet>
    <content><![CDATA[
Sample:$1
]]></content>
    <tabTrigger>sample</tabTrigger>
</snippet>

Typing sampleTab inserts the text of the snippet, with the cursor sitting after the : character. Now you’re sitting in field $1 so Sublime is waiting for you to type the text that goes there and press Tab again to jump to the end of the snippet.

Instead, you type loremTab (for example) to expand a lorem ipsum, but you have to press it twice. The first time ends the previous snippet, and the next press does the expansion for the next snippet.

If that’s the situation, you can sometimes remind yourself by changing the snippet to include a default placeholder, which will be inserted and selected for you to replace, reminding you that Sublime is waiting for text there. For example, the content of the snippet could be:

Sample: ${1:sample text}

Alternatively, you can press Esc to escape out of the snippet entirely. However, unless you’re using to using vi you probably aren’t used to obsessively pressing escape all the time. :wink:

1 Like

#3

Hi, thanks for the response. I understand that I can tab through placeholders in the snippet, I rather enjoy that functionality.

What I’m talking about is that the tab-trigger doesn’t fire sometime unless I hit the tab key two or three times. It seems like it’s wait for me to select from a similar batch of snippets that show up in a dropdown list near the cursor. However, I don’t want to move my hand to the mouse, I want it all text.

Also related is that sometimes a snippet seems to ignore the tab trigger completely and instead the cursor goes to the next line, leaving my tab trigger alone.

Part of this might be that I’m still trying to figure out how to make syntax highlighting, snippets, and auto complete all work together. I program in a niche language so I have to kind of build all this stuff myself.

0 Likes

#4

This is totally do-able, but you need to do something like map a key binding or use some other method to invoke the command since typing while there is a selection will replace the selection.

Snippets can contain the special placeholder $SELECTION, which is replaced with whatever the selected text was at the time that you invoked the snippet (or nothing, if nothing was selected).

As an example:

<snippet>
    <content><![CDATA[
/****** DEBUG *******
$SELECTION
********************/
]]></content>
</snippet>

You could use a key binding like the following to insert this snippet:

    {
        "keys": ["ctrl+alt+c"],
        "command": "insert_snippet",
        "args": {"name": "Packages/User/sample.sublime-snippet"}
    },

This will replace any selected text by wrapping it with the snippet body, or just insert the snippet at the current cursor location if there is nothing selected.

Snippets that have a tabTrigger defined also show up in the command palette, which is another way for you to insert the snippet. This can be useful if you only occasionally need to use a snippet and you don’t want to bind a specific key for it. Such a snippet shows up in the command palette as a command named Snippet: snippetName (which also includes the tab trigger as a hint) where SnippetName is the first part of the filename (in this example it would show up as Snippet: sample).

If your snippet has a scope defined in it, it won’t show up in the command palette if the scope doesn’t match, so you can use this to hide snippets for languages that you don’t want them to appear in.

In this case the key binding will still work even if the scope is not correct. In order to modify that behavior you need to modify the key binding as well so that it only operates in the given scope. For example, if we wanted the above snippet to only trigger for C code, we could do this:


        "keys": ["ctrl+alt+c"],
        "command": "insert_snippet",
        "args": {"name": "Packages/User/sample.sublime-snippet"},
        "context": [
            {"key": "selector", "operator": "equal", "operand": "source.c"}
        ]
    },
2 Likes

#5

You can describe a situation where this happens? It really sounds like Sublime might be in the process of inserting a snippet while you’re trying to insert another one or otherwise think something other than simple text editing is going on.

Does this only happen for certain snippets? Can you provide an example?

0 Likes

#6

Go to Preferences->Key Bindings->User

Add this code between the square brackets:

{ "keys": ["tab"], "command": "commit_completion", "context":
	[
		{ "key": "auto_complete_visible" },
		{ "key": "setting.auto_complete_commit_on_tab", "operand": false }
	]
},

Save it.
Now you just hit tab once for triggering the snippet.

0 Likes

#7

Hello guys,

I’m also having some confusion with tab completion. It says on this link https://www.granneman.com/webdev/editors/sublime-text/top-features-of-sublime-text/auto-completion-in-sublime-text/#code that, for instance, we autocomplete an <a> tag like so: <a href=""></a>. So after pressing tab, the cursor jumps to the tagged href value, then a second tab would allow your cursor jump in between the opening and closing tag, and then a third tab would jump your cursor after the closing </a> tag.

In my case, though, I only get to as far as the second tab. After I hit a third tab, it inserts a tab whitespace after the text inside the opening and closing <a> tag.

I’m using Sublime Text 3 by the way. And below are the packages I installed:

  • Git Gutter
  • Package Control
  • Sidebar Enhancement
  • Sublime Linter
  • Terminal

Do you guys have any idea why this is so?

Thanks in advance for the response!

Marion

0 Likes

#8

probably the website is wrong, but you might be able to fix it by applying this PR locally

EDIT: yeah the website has no date but refers to ST2, maybe things were different there

2 Likes

#9

Thanks for the response kingkeith! Yeah I guess that makes sense. Maybe ST2 has that feature built-in to it, but not ST3.

Okay, I’ll surely try to apply that PR. Thanks a lot again! :slight_smile:

0 Likes