Sublime Forum

Parenthesis don't close correctly with nested functions

#1

I’m on Mac OS 10.6.8.

Reproduce:
Start with the following code:

functionCall(some_variable)

Wrap the inner variable in another function by adding the function call and opening parenthesis:

functionCall(otherFunctionCall(some_variable)

Move the cursor to directly after “some_variable” and type “)” to close the parenthesis for the function you just added.

Expected:
A closing parenthesis is added.

Actual
You have to move to the end of the line or press the closing parenthesis again.

This is true for as many levels deep as you go so if you have 3 or 4 functions nested you have to press the “)” 3 or 4 times in order to close the one you just added.

0 Likes

#2

What language?

0 Likes

#3

This is not language specific. It happens for every language I have tried including plain text.

The simplest reproduce code is to select plain text and paste this into sublime:

function1(function2(var)

Then move the cursor to directly after the “r” in var and type “)”. The ) is not inserted.

0 Likes

#4

[quote=“craig”]This is not language specific. It happens for every language I have tried including plain text.

The simplest reproduce code is to select plain text and paste this into sublime:

function1(function2(var)

Then move the cursor to directly after the “r” in var and type “)”. The ) is not inserted.[/quote]

Oh. Yeah, what you can do is edit the keybinding regex that does a look behind and checks for multiple open parenthesis.
The keybinding to edit would be the close parenthesis keybinding with the move_to forward true regex.

Thats my best suggestion.

0 Likes

#5

I can confirm this is also an issue in Ubuntu.

0 Likes

#6

FYI I don’t think this is a bug (per se). I think the point of the keybinding is that when ST adds in your closing brackets for free it needs to allow for people who accidentally try to close them. Thus if you’re about to type a closing bracket, brace or quote and you’re next to one, it’ll overwrite/move the cursor forward rather than insert a new one. Consider the following use case:

Someone types

var a = '

ST2 shows (| denoting insertion point cursor):

var a = '|'

Developer then completes the string and types the ending quote (by mistake - ST2 already gave them one for free). Typed:

some string'

ST2 realises they ended the string it already tried to end for them, and skips over the quote (rather than doubling it up):

var a = 'a string'|

Rather than:

var a = 'a string'|'

So that’s a use case where it makes sense to skip over a bracket/brace/quote. But I understand in your situation this behaviour is unexpected and unwanted. Unfortunately there’s probably not a lot you can do about that. ST2 really tried to help by always automatically closing these things whenever it sees fit (presumably based on scope), but can’t always do so, thus leaving the developer having to add the ending bracket/brace/quote, and in those circumstances the behaviour I just described shouldn’t be used. But presumably it’s difficult for ST2 to know when and when not to use this heuristic, so it always does it, hoping that it doesn’t happen much.

So I can’t offer a fix, and nor am I defending the behaviour per se, just saying that I don’t think it’s a bug: it’s there to help you out in other situations and unfortunately gets in the way in this one. The bug in my eye is more that when you type your inside open bracket, the editor doesn’t automatically add a closing bracket for you. Having said that, I’ve noticed less of this happening lately (maybe some definitions were updated at some point).

The only time this is an issue for me now is when typing an opening bracket next to a word character, and then I understand completely that the editor can’t automatically close it for me. Consider the following example:

if (a == 5 && |b == 8) {
    console.log('great');
}

If I go to add an opening bracket at the insertion point just to the left of the variable ‘b’ for a bit more specificity, then the editor doesn’t automatically close it for me (it’s unlikely I’ll want a closing one right next to the opening one, and the editor can’t read my mind as to where it should go (should it be ‘(b) == 8’ or ‘(b == 8)’?)). Then when I go to add the closing one to the right of the number ‘8’, it doesn’t appear to do anything because it thinks I’m inadvertently closing the bracket that (it assumes) it created automatically for me. This is the exact problem you’re having as described in your first post. It’d be interesting to see if you agree with me that the benefits of the system outweigh this one drawback.

If you really want a fix, I think there’s a setting to not dot he automatic completion of brackets and the like, which will presumably stop this closing-skip behaviour too, but then you lose the automatic closing which is so useful.

0 Likes

#7

I’ve learned to accept this behaviour - as it’s much better than the alternative of disabling bracket-completion. It’s caught me out on a few occasions, when I assumed I was closing a second bracket, but was only closing the same one twice :frowning: . On occasions I’ve had to type a space, then go back and delete it.

I think it’s helpful to try and make use of the fact that we can highlight text and type a bracket, and ST will (bracket the text) for us. But, for anyone struggling, there are bracket-highlighting plug-ins that, presumably, are helpful? Andy.

0 Likes

#8

I just wanted to point out a temporary work around is to overwrite the default key bindings:

{ "keys": ")"], "command": "insert", "args": {"characters": ")"} },
{ "keys": "]"], "command": "insert", "args": {"characters": "]"} },
{ "keys": "}"], "command": "insert", "args": {"characters": "}"} }

This still allows the matching parenthesis to be created when you open a parenthesis.

This is not ideal when you try to type function() cause you end up with function()) when you explicitly type the closing parenthesis.

What is interesting is the way TextMate behaves. Basically if a closing parenthesis is created automatically in the context of adding code then typing ) again will be ignored. I actually think this is really smart because a lot of the time I find myself typing the closing parenthesis anyway without thinking about it.

Maybe I will try to make a sublime package to deal with this.

0 Likes

#9

FIX

ADD TO USER PREFERENCES: "auto_match_enabled": false

ADD TO USER KEYBINDINGS: [code]{ “keys”: “tab”], “command”: “move”, “args”: {“by”: “characters”, “forward”: true}, “context”:

    { "key": "following_text", "operator": "regex_contains", "operand": "^)\"'\\]\\};]", "match_all": true },
    { "key": "auto_complete_visible", "operator": "equal", "operand": false },
    { "key": "has_next_field", "operator": "equal", "operand": false }
]   

}[/code]

The second thing is option but I like to use tab to move out of parenthesis.

0 Likes

#10

Setting auto_match_enabled to false doesn’t exactly fix the original issue it just makes it so that you have to explicitly type every character.

Having the auto match is a nice thing it’s just that when you try to close one of the automatch tags it should not always ignore it.

0 Likes

#11

In case anyone is interested. I made a package to correct this behavior for myself :smile:

It should be available via Sublime Package Control soon, but in the meantime:
github.com/ccampbell/sublime-smart-match

0 Likes

#12

To Sublime Text management: It’s a bug! Please fix it.

By the way, this is not just with nested functions, it’s with nested anything. Example:

Type (a == b)
Then put an open parenthesis in like this
((a == b)
Try to close it: It will be eaten.

0 Likes