Sublime Forum

Key bindings: following_text never working

#1

When setting up key bindings, I can never get the “following_text” context key to work. As a simple example, I want to replace “&” with “&” in HTML files, when it’s followed by a space. I can replace the ampersand easily enough. But when I try to make it dependent on the following space, it doesn’t work. I’m sure I’m missing something simple, since I’ve never gotten this to work–with this example, or any number of others. This is just the simplest example I’ve tried.

So this works for just the ampersand:

{ "keys": ["&"],
   "command": "insert_snippet",
   		"args": {"contents":"&"},
   		"context":
   		[
     		{ "key": "selector", "operator": "equal", "operand": "text.html", "match_all": true }
   		]
}

But when I try this, it just never matches at all–leaves it a bare ampersand:

{ "keys": ["&"],
   		"command": "insert_snippet",
   		"args": {"contents":"&"},
   		"context":
   		[
     		{ "key": "selector", "operator": "equal", "operand": "text.html", "match_all": true },
     		{ "key": "following_text", "operator": "regex_match", "operand": "^ ", "match_all": true }
   		]
}

(And yes, I know I could accomplish this specific replacement by just using ["&", " "] for the binding keys. But I’m just using this for a simple test. Ultimately what I want is to check the following_text for, say, “\s”.)

Can anyone see what I’m doing wrong and tell me? Thanks.

0 Likes

#2

The regex_match operator matches the pattern against the whole content up to the end of line. You may want to replace it by regex_contains which would be satisfied by the first space directly following the caret’s position.

0 Likes

#3

@deathaxe – Thanks for that suggestion. I tried it, and it didn’t seem to make a difference. I’m glad to learn the distinction between regex_contains and regex_match, though.

0 Likes

#4

This binding works, but perhaps not as you would expect. A regex of "^ " means that the text to the right of the cursor needs to have at least one space at the start, but that is not always the case.

For example, assuming that | is the cursor:

This is|  some text

There’s a space to the right of the cursor, so the binding triggers:

this is&  some text

However, in a case like this:

This is some text|

You might think there’s some virtual space to the right of the cursor, but there’s not; it’s at the end of the line; pressing the right arrow here will move you to the start of the next line (or do nothing, if this is the only line), so it doesn’t trigger.

A context like this may work better; it works in cases where there’s an explicit space to the right of the caret OR when the caret is at the end of the line, but inside of content an & is still an &.

{ "key": "following_text", "operator": "regex_contains", "operand": "^( |$)", "match_all": true }
2 Likes

#5

@OdatNurd Oooooooooooohhhhhhh, I get it now. I thought that following_text would consider the text that I typed immediately after I typed the ampersand, and retroactively make the replacement. But from what you’re saying (which I’ve now tested, so I see), I understand that it’s looking for “following text” that’s already present on the line when the ampersand gets typed. Which actually makes sense, I guess, and I think fully explains why I’ve never gotten this key to work as I expected.

0 Likes