Feature: Implement concatenation on Enter for string literals#320286
Open
clarafdomingos wants to merge 1 commit into
Open
Feature: Implement concatenation on Enter for string literals#320286clarafdomingos wants to merge 1 commit into
clarafdomingos wants to merge 1 commit into
Conversation
When a developer is editing a string literal and presses
Enter in the middle of it, the editor currently has no built
in mechanism to automatically split the string into
two syntactically valid, concatenated substrings.
The implementation consists in concatenating
the string automatically when Enter is pressed,
using per-language adaptation.
Example in C++:
Before: std::string s = "hel|lo world";
After: std::string s = "hel"
+ "lo world";
Closes microsoft#83196
Co-authored-by: Vasco Reino <vasco.reino@tecnico.ulisboa.pt>
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds an “automatic string concatenation on Enter” editor feature, configurable per-language and via a new editor option/command.
Changes:
- Introduces
stringConcatenationin language configurations (withexcludedPatterns) and wires it into resolved language configuration. - Adds the
editor.stringConcatenationOnEnteroption (Monaco + VS Code) plus a command to toggle it. - Hooks Enter handling to perform string-splitting/concatenation and adds targeted cursor tests and language-configuration updates.
Reviewed changes
Copilot reviewed 18 out of 19 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/vs/workbench/contrib/codeEditor/common/languageConfigurationExtensionPoint.ts | Parses stringConcatenation from language configuration extension point JSON. |
| src/vs/monaco.d.ts | Exposes new editor option + language configuration shape in Monaco typings. |
| src/vs/editor/test/browser/controller/cursor.test.ts | Adds tests + a tokenizer helper for string-concat-on-enter behavior. |
| src/vs/editor/editor.all.ts | Loads the new toggle action contribution. |
| src/vs/editor/contrib/stringConcatenation/browser/stringConcatenationActions.ts | Adds command to toggle the setting. |
| src/vs/editor/common/standalone/standaloneEnums.ts | Adds standalone enum entry for the new editor option. |
| src/vs/editor/common/languages/stringConcatenation.ts | Implements detection + operator selection for concatenation-on-enter. |
| src/vs/editor/common/languages/languageConfigurationRegistry.ts | Plumbs stringConcatenation through resolved language configuration. |
| src/vs/editor/common/languages/languageConfiguration.ts | Adds IStringConcatenation and an internal action payload type. |
| src/vs/editor/common/cursorCommon.ts | Carries option + language config into cursor configuration. |
| src/vs/editor/common/cursor/cursorTypeEditOperations.ts | Applies concatenation logic during Enter operations. |
| src/vs/editor/common/config/editorOptions.ts | Registers stringConcatenationOnEnter editor option + docs. |
| extensions/*/language-configuration.json | Supplies per-language excludedPatterns defaults. |
Comment on lines
+132
to
+140
| "stringConcatenation":{ | ||
| "excludedPatterns": [ | ||
| "^\\s*#\\s*include", | ||
| "^\\s*#\\s*pragma", | ||
| "^\\s*#\\s*error", | ||
| "^\\s*#\\s*warning", | ||
| "^\\s*#\\s*define", | ||
| ] | ||
| } |
Comment on lines
+555
to
+567
| // Expand range to cover the whole line, replacing it entirely | ||
| const fullLineRange = new Range( | ||
| range.startLineNumber, | ||
| 1, | ||
| range.endLineNumber, | ||
| model.getLineMaxColumn(range.endLineNumber) | ||
| ); | ||
|
|
||
| return typeCommand( | ||
| fullLineRange, | ||
| stringConcatAction.beforeText + '\n' + config.normalizeIndentation(indentation) + stringConcatAction.afterText, | ||
| keepPosition | ||
| ); |
Comment on lines
+32
to
+41
| for (let i = 0; i < excludedPatterns.length; i++) { | ||
| const pattern = new RegExp(excludedPatterns[i]); | ||
|
|
||
| const matches = pattern.test(lineText); | ||
|
|
||
| if (matches) { | ||
| isExcluded = true; | ||
| break; | ||
| } | ||
| } |
Comment on lines
+81
to
+85
| const isEscaped = i > 0 && lineText[i - 1].charCodeAt(0) === 92; | ||
|
|
||
| if (!isEscaped) { | ||
| return ch; | ||
| } |
Comment on lines
+1608
to
+1612
| class BlockCommentState implements IState { | ||
| constructor(public readonly parentState: State) { } | ||
| clone(): IState { return this; } | ||
| equals(other: IState): boolean { return other instanceof StringState && this.parentState.equals(other.parentState); } | ||
| } |
Comment on lines
+1661
to
+1665
| } else if (state instanceof BlockCommentState) { | ||
| const m1 = line.match(/^[^*]+/g); | ||
| if (m1) { return generateToken(m1[0].length, StandardTokenType.String); } | ||
| if (/^\*\//.test(line)) { return generateToken(2, StandardTokenType.Comment, state.parentState); } | ||
| return generateToken(1, StandardTokenType.Other, state); |
|
|
||
| const excludedPatterns = config.stringConcatenation?.excludedPatterns ?? []; | ||
|
|
||
| const stringConcatAction = getStringConcatenation(model, range, config.stringConcatenationOnEnter, excludedPatterns,); |
Author
|
@microsoft-github-policy-service agree |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is the main purpose of this Feature?
When a developer is editing a string literal and presses Enter in the middle of it, the editor currently has no built in mechanism to automatically split the string into two syntactically valid, concatenated substrings.
The implementation consists in concatenating the string automatically when Enter is pressed, using per-language adaptation.
Example in C++:
std::string s = "hel|lo world";What are the main changes that led to this Feature implementation?
Using VS Code's already implemented logic to detect when Enter is pressed, as well as Token processing to detect if this action was done inside a string literal.
Displaying the expected output based on the language of the current file.
How can you test it?
Open Command Palette and activate 'Toggle String Concatenation on Enter', create a string for the given language your current coding file is on and press Enter.
Closes #83196