Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 23, 2025

Resolves #68537 by extracting the custom Visual Studio behavior for raw string literal auto-insertion into a workspace service that can be shared between the VS command handler and LSP OnAutoInsert handler.

raw_string_insert

Problem

Previously, the logic for automatically expanding raw string literals when typing quote characters was hardcoded in the VS-specific command handler (RawStringLiteralCommandHandler_TypeChar.cs). This made it impossible to provide the same functionality through LSP for other editors.

Solution

This PR extracts the raw string literal expansion logic into a new workspace service:

  1. Created IRawStringLiteralOnAutoInsertService interface in the Features layer

    • Takes a document and caret position as input
    • Returns a TextChange if raw string expansion should occur
    • Returns null if no special handling is needed
  2. Implemented CSharpRawStringLiteralOnAutoInsertService in the C# Features layer

    • Extracted the three expansion scenarios from the command handler:
      • Generate initial empty raw string: "" + """""""
      • Grow initial empty raw string: """$$""" + """""$$""""
      • Grow raw string delimiters: """$$ content """ + """"" content """"
  3. Updated RawStringLiteralCommandHandler_TypeChar.cs to use the service

    • Maintains all existing VS behavior and user experience
    • Code is now cleaner and more maintainable
    • Removed ~170 lines of inline logic in favor of service call
  4. Integrated with OnAutoInsertHandler.cs

    • Added support for quote character auto-insertion
    • Foundation in place for LSP-based editors to provide raw string expansion

Impact

  • VS users: No behavior change, existing functionality preserved
  • LSP users: Infrastructure now available for raw string literal support
  • Codebase: Better separation of concerns, reusable service interface

The service follows Roslyn's standard patterns with [ExportLanguageService] and proper MEF construction.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/dotnet/roslyn/issues/68537
    • Triggering command: curl -s REDACTED (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

I'd like you to resolve this issue #68537 using the implementation notes below.

This should essentially just be extracting out the existing, custom VS behavior from here -

into its own workspace service and calling that service in on auto insert - https://github.com/dotnet/roslyn/blob/main/src/LanguageServer/Protocol/Handler/OnAutoInsert/OnAutoInsertHandler.cs

Generally, the service can take in the document and caret position and return a text edit (if any). This service interface should be defined in features, with the implementation in c# features layer. The autoinsert implementation should call the service to get the text edit and return it. The existing VS command handler should be updated to use the service


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: dibarbet <5749229+dibarbet@users.noreply.github.com>
Copilot AI and others added 2 commits October 23, 2025 19:22
Co-authored-by: dibarbet <5749229+dibarbet@users.noreply.github.com>
Co-authored-by: dibarbet <5749229+dibarbet@users.noreply.github.com>
Copilot AI changed the title [WIP] Extract custom VS behavior into workspace service Extract raw string literal auto-insert logic into reusable service Oct 23, 2025
Copilot AI requested a review from dibarbet October 23, 2025 19:31
Copilot finished work on behalf of dibarbet October 23, 2025 19:31
@CyrusNajmabadi
Copy link
Member

I can review tomorrow

@dibarbet dibarbet marked this pull request as ready for review October 24, 2025 03:27
@dibarbet dibarbet requested a review from a team as a code owner October 24, 2025 03:27
namespace Microsoft.CodeAnalysis.LanguageServer.UnitTests.OnAutoInsert;

[Trait(Traits.Feature, Traits.Features.AutomaticCompletion)]
public abstract class AbstractOnAutoInsertTests(ITestOutputHelper testOutputHelper) : AbstractLanguageServerProtocolTests(testOutputHelper)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all this is moved

TryGenerateInitialEmptyRawString(caret.Value, cancellationToken) ??
TryGrowInitialEmptyRawString(caret.Value, cancellationToken) ??
TryGrowRawStringDelimiters(caret.Value, cancellationToken);
var root = document.GetRequiredSyntaxRootSynchronously(cancellationToken);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a problem for me. A core idea in the original code was that it did nothing related to syntax unless it first had verified textually that it was in a reasonable position to do so (like checking if it was around quotes). This prevented parsing the syntax tree for most edits.

I don't want to roll that logic back. Can the service just take the document and defer creating the root until needed?

var textChange = service.GetTextChangeForQuote(root, text, caret.Value.Position);

if (textChangeOpt is not TextChange textChange)
if (textChange is null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like you could keep this code :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reverted - but originally changed this because thjere was an info diagnostic on it

Image

Copy link
Member

@CyrusNajmabadi CyrusNajmabadi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tentatively approving, since hte overall change is good. just please change to defer syntaxroot acquisition until needed.

@dibarbet dibarbet merged commit 326ae03 into main Oct 24, 2025
25 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the Next milestone Oct 24, 2025
davidwengier added a commit to dotnet/razor that referenced this pull request Nov 3, 2025
Three things I've been tracking from Roslyn:

1. Auto insert support for raw string literals:
dotnet/roslyn#80871
2. Line Folding Only support in VS Code:
dotnet/roslyn#80955 (fixes
#12414)
	* We already did this in our folding range response anyway
3. Allow FormattingLogTest can use real types, and remove our temporary
equivalent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[LSP] [Feature Suggestion]: Automatic formatting for raw string literals

3 participants