question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Code completion unexpectedly consumes closing paren (from auto-closing-brackets) that was inserted automatically when `(` triggered code completion

See original GitHub issue

I’m unable to reproduce this, but a user was able to provide an LSP log that makes it seem like a VS Code issue. If not, I think it at least needs some direction to help debug.

Here’s what’s happening:

  • The user types foo(
  • The ( triggers code completion (because it’s a trigger character) but also causes a ) to be inserted automatically (auto closing brackets)
  • The user then types ba and selects bar from the completion list
  • VS Code replaces ba) with bar, instead of only ba

It seems like the automatically-inserted ) is being compensated for by VS Code as if it was a character typed since the completion request was sent, so the replacement range VS Code computes is 3 characters long (), b, a) but should only be two (since the ) is on the other side of the cursor).

Here’s the LSP log:


// User types the opening paren (
[18:47:31] [Analyzer] [Info] ==> {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///Users/s-katoh/development/playground/sample_app/lib/main.dart","version":68},"contentChanges":[{"range":{"start":{"line":9,"character":9},"end":{"line":9,"character":9}},"rangeLength":0,"text":"("}]}}

// Code completion is triggered because ( is a trigger character
[18:47:31] [Analyzer] [Info] ==> {"jsonrpc":"2.0","id":162,"method":"textDocument/completion","params":{"textDocument":{"uri":"file:///Users/s-katoh/development/playground/sample_app/lib/main.dart"},"position":{"line":9,"character":10},"context":{"triggerKind":2,"triggerCharacter":"("}}}

// A closing paren ) is also inserted (this happens after the completion request is sent)
[18:47:31] [Analyzer] [Info] ==> {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///Users/s-katoh/development/playground/sample_app/lib/main.dart","version":69},"contentChanges":[{"range":{"start":{"line":9,"character":10},"end":{"line":9,"character":10}},"rangeLength":0,"text":")"}]}}

// The server responds with "bar" which has a text edit at line 9 character 10 and a length of 0 (the entire thing will be inserted, as the user has not typed any of "bar" yet). This location corresponds to _between_ the parens since the closing paren ) was also inserted at 9:10.
[18:47:31] [Analyzer] [Info] <== {"id":162,"jsonrpc":"2.0","result":[{"label":"bar","kind":5,"detail":"bool","sortText":"999442","textEdit":{"range":{"start":{"line":9,"character":10},"end":{"line":9,"character":10}},"newText":"bar"}}

// The server is asked to resolve the completion item (it does, with no change to the range)
[18:47:32] [Analyzer] [Info] ==> {"jsonrpc":"2.0","id":168,"method":"completionItem/resolve","params":{"label":"bar","detail":"bool","insertTextFormat":1,"textEdit":{"newText":"bar","range":{"start":{"line":9,"character":10},"end":{"line":9,"character":10}}},"kind":5,"sortText":"999442"}}
[18:47:32] [Analyzer] [Info] <== {"id":168,"jsonrpc":"2.0","result":{"label":"bar","kind":5,"detail":"bool","sortText":"999442","insertTextFormat":1,"textEdit":{"range":{"start":{"line":9,"character":10},"end":{"line":9,"character":10}},"newText":"bar"}}}

// The user types "ba"
[18:47:33] [Analyzer] [Info] ==> {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///Users/s-katoh/development/playground/sample_app/lib/main.dart","version":70},"contentChanges":[{"range":{"start":{"line":9,"character":10},"end":{"line":9,"character":10}},"rangeLength":0,"text":"b"}]}}
[18:47:33] [Analyzer] [Info] ==> {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///Users/s-katoh/development/playground/sample_app/lib/main.dart","version":71},"contentChanges":[{"range":{"start":{"line":9,"character":11},"end":{"line":9,"character":11}},"rangeLength":0,"text":"a"}]}}

// User user completes "bar", which should be inserted at 9:10 but compensate for the "ba" they typed, making a replace range of 2 - however the range is 3 (as if the closing ) was somehow compensated for
[18:47:33] [Analyzer] [Info] ==> {"jsonrpc":"2.0","method":"textDocument/didChange","params":{"textDocument":{"uri":"file:///Users/s-katoh/development/playground/sample_app/lib/main.dart","version":72},"contentChanges":[{"range":{"start":{"line":9,"character":10},"end":{"line":9,"character":13}},"rangeLength":3,"text":"bar"}]}}

Based on the log, it seems like the server has behaved correctly. It wants to insert “bar” at 9:10 and there’s no reason for the ) to be replaced. Although it was typed after the completion request was sent, it was inserted automatically after the cursor and should be excluded from the range compensation (although in my testing, it seems like it is, because everything works as expected).

I don’t know of any way to debug this further - is there any way to get more information from VS Code about how its compensating for typing during async completion requests?

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:3
  • Comments:14 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
jriekencommented, Nov 1, 2021

Fixing this will conflict https://github.com/microsoft/vscode/issues/26012 - basically the unwanted behaviour here is the wanted behaviour for #26012

0reactions
Rameray1commented, Nov 21, 2022

hello, i have the same issue. Do you know how to fix it? The Github copilot auto complete doesn’t put closing brackets and quotes…

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to disable automatically adding a closing curly brace or ...
I don't want it to auto insert any closing character or any indentations. I basically just want it to stop helping me and...
Read more >
Typing assistance | JetBrains Rider Documentation
With JetBrains Rider, you can select a code block or an expression, then type an opening { or a closing } brace to...
Read more >
JupyterLab Changelog — JupyterLab 3.6.0b0 documentation
The closing bracket is no longer automatically added by default; the old behaviour can be re-enabled from the menu bar ( Settings ->...
Read more >
Solved: How to enable auto-completion in Jupyter Notebook
Hi, Yes you have auto-complete built-in Jupyter, like you have in any other Jupyter environment. Simply hit the "Tab" key while writing code....
Read more >
R Studio: Paul's tips & tricks
1. Tab to auto-complete · 2. Close parenthesis and quotation highlighting · 3. Disable automatic insertion of closing parenthesis/quotation mark
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found