Skip to content

fix(completion): не дублировать скобку — убрать commit character "(" у вызываемых#4127

Merged
nixel2007 merged 1 commit into
developfrom
fix/completion-commit-paren-duplication
Jun 15, 2026
Merged

fix(completion): не дублировать скобку — убрать commit character "(" у вызываемых#4127
nixel2007 merged 1 commit into
developfrom
fix/completion-commit-paren-duplication

Conversation

@nixel2007

@nixel2007 nixel2007 commented Jun 15, 2026

Copy link
Copy Markdown
Member

Проблема

При обычном наборе вызова метода (Список.Добавить(, Сложить( и т.п.) в редакторе появлялась двойная открывающая скобка (Добавить(()), а подсказка по параметрам (signatureHelp) не всплывала.

Причина

Пункту автодополнения метода/функции/конструктора одновременно проставлялись:

По спецификации LSP commit character вставляется после текста выбранного пункта. Поскольку автокомплит открыт во время набора, ввод ( фиксировал пункт (вставив его текст со скобкой) и затем добавлял ещё одну (Имя((. Курсор оказывался в рассогласованных скобках, и signatureHelp не поднимался.

Конфликт двух свежих фич: commit-символ ( × авто-вставка скобки в insertText.

Исправление

Вызываемым (Method/Function/Constructor) commit character "(" больше не задаётся — открывающую скобку и подъём подсказки уже обеспечивает insertText (+ triggerParameterHints). Это совпадает с поведением эталонных LSP-серверов (TypeScript LS, gopls, rust-analyzer), которые не объявляют ( commit-символом при авто-вставке скобок.

Commit character "." для свойств, переменных и модулей сохранён (их insertText — голое имя, дублирования нет).

Тест

methodMemberGetsNoCommitCharacterBecauseInsertTextAddsParen (бывш. methodMemberGetsOpenParenCommitCharacter) теперь проверяет, что метод не получает commit character, а его insertText уже несёт скобку.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Fixed code completion for methods and functions to prevent duplicate opening parentheses when completing callable items.
    • Improved signature help functionality by preventing conflicting character insertion during method completion.

…у вызываемых

Метод/функция/конструктор получали commitCharacters ["("] одновременно со
вставкой открывающей скобки в insertText (`Имя($0)` со snippetSupport либо
`Имя(` без него). По спецификации LSP commit character вставляется ПОСЛЕ
текста пункта, поэтому ввод "(" при открытом автокомплите давал двойную
скобку (`Имя((`) и ломал signatureHelp.

Скобку (и подъём подсказки через triggerParameterHints) обеспечивает
insertText, поэтому commit character "(" вызываемым больше не задаётся;
"." у свойств, переменных и модулей сохранён.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0ce7740b-3ddb-4107-b91a-5fce66502585

📥 Commits

Reviewing files that changed from the base of the PR and between 3ec2a97 and fbae647.

📒 Files selected for processing (2)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/CompletionProvider.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/CompletionProviderTest.java

📝 Walkthrough

Walkthrough

CompletionProvider.applyCommitCharacters no longer assigns "(" as a commit character for callable kinds (Method, Function, Constructor). Only member-like kinds (Field, Property, Variable, Module) receive ".". The corresponding test now asserts commitCharacters is null for method items and verifies insertText already begins with "Добавить(".

Changes

Callable completion commit characters fix

Layer / File(s) Summary
applyCommitCharacters logic, Javadoc, and test
src/main/java/.../providers/CompletionProvider.java, src/test/java/.../providers/CompletionProviderTest.java
Javadoc documents that callable items are excluded from commitCharacters because their insertText already inserts "(". Switch now sets "." only for Field/Property/Variable/Module; default leaves other kinds unset. Test replaces the "(" commit-character assertion with a null check and verifies insertText starts with "Добавить(".

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Possibly related PRs

  • 1c-syntax/bsl-language-server#3969: Also modifies CompletionProvider and CompletionProviderTest around callable parenthesis insertion behavior and signatureHelp interaction, changing insert text for parameterless callables to "()".

Poem

🐇 No more double parentheses in sight,
The callable snippet already writes it right,
Commit chars for dots, but brackets? No way!
signatureHelp can now have its say.
Hoppy fixes keep the editor bright! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: removing the commit character '(' from callable completions to prevent bracket duplication.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/completion-commit-paren-duplication

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nixel2007

Copy link
Copy Markdown
Member Author

ВОПРОС - а нет ли смысла переделать snippet с вставкой скобок с $0 на commit characters? Будет ли, например, vscode вставлять закрывающую скобку?что вообще в протоколе по поводу commit characters написано, когда их надо использовать?

@nixel2007

Copy link
Copy Markdown
Member Author

Хороший вопрос. Коротко: commit characters — это не замена сниппету, это другой механизм, и построить вызов со скобками он не умеет.

Что говорит спецификация

CompletionItem.commitCharacters: «An optional set of characters that when pressed while this completion is active will accept it first and then type that character. Note that all commit characters should have length=1 and that superfluous characters will be ignored.»

То есть commit-символ сначала применяет пункт (вставляет его insertText), а затем вводит сам символ — буквально, ПОСЛЕ текста пункта. Ни позиционирования курсора, ни парной скобки протокол тут не даёт.

Будет ли VS Code вставлять закрывающую скобку?

От механизма commit characters — нет, ( просто допечатается после insertText. Закрывающую ) может подставить отдельная фича редактора editor.autoClosingBrackets, но на неё нельзя полагаться:

  • это не часть LSP и не под нашим контролем (клиентская настройка, зависит от вида скобок, легко выключается);
  • она не ставит курсор между скобок;
  • она не поднимает signatureHelp.

Почему для вызова лучше сниппет

Имя($0) гарантированно даёт обе скобки + курсор между ними, и мы вешаем команду editor.action.triggerParameterHints, чтобы подсказка по параметрам всплыла сразу. Работает одинаково на любом клиенте со snippetSupport. Без него — фолбэк Имя( (открывающую даём, закрывающую ставит пользователь; ( всё равно trigger character для signatureHelp).

Когда commit characters уместны

Их смысл — «принять пункт нажатием символа и продолжить ввод этим символом», когда insertTextголое имя. Поэтому в этом PR они сохранены для свойств/переменных/модулей с символом .: нажал . → пункт принят и сразу идёт обращение к члену (Объект.Объект.Свойство.), дублирования нет. А у вызываемых insertText уже несёт (, поэтому commit ( его дублировал (Имя(() — это и был баг. Чинится удалением именно commit-символа; сниппет трогать не нужно.

Итого: сниппет и commit characters решают разные задачи. Правильное сочетание — сниппет ($0) для вызова + commit . для членов, и не задавать commit ( вызываемым.

@sonarqubecloud

Copy link
Copy Markdown

@nixel2007
nixel2007 merged commit 460c56d into develop Jun 15, 2026
38 of 39 checks passed
@nixel2007
nixel2007 deleted the fix/completion-commit-paren-duplication branch June 15, 2026 22:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant