Skip to content

feat(lsp): support untitled:// URI scheme for unsaved documents#192

Merged
tinovyatkin merged 2 commits intomainfrom
feat/lsp-untitled-uri-support
Feb 27, 2026
Merged

feat(lsp): support untitled:// URI scheme for unsaved documents#192
tinovyatkin merged 2 commits intomainfrom
feat/lsp-untitled-uri-support

Conversation

@tinovyatkin
Copy link
Copy Markdown
Collaborator

@tinovyatkin tinovyatkin commented Feb 27, 2026

Summary

  • Enable the LSP server to lint unsaved Dockerfile buffers (e.g. new untitled editors in VS Code) that use the untitled: URI scheme instead of file:
  • uriToPath now returns a synthetic cwd-based path for non-file URIs so config discovery and workspace settings matching work correctly
  • Pull diagnostics and contentForURI gracefully return empty results for closed untitled documents instead of reading from a nonexistent path
  • Adds isUntitledURI helper for clean scheme detection

Context

Inspired by oxc-project/oxc#19287. When a user creates a new file in their editor and sets the language to Dockerfile (without saving), the editor assigns an untitled: URI. Previously the LSP server silently failed because uriToPath couldn't convert this to a valid file path. Now all LSP features (diagnostics, code actions, formatting, fix-all) work for unsaved documents.

Closes #168

Test plan

  • TestURIToPath — verifies untitled and vscode-notebook URIs resolve to absolute synthetic paths
  • TestIsUntitledURI — scheme detection for various URI forms
  • TestPublishDiagnostics_UntitledURI — push diagnostics dispatched with correct URI and content
  • TestHandleDiagnostic_UntitledURI_ClosedDocument — pull diagnostics return empty for closed untitled docs
  • TestContentForURI_ReturnsOpenUntitledDocumentContent — open untitled docs return in-memory content
  • TestContentForURI_UntitledURI_ClosedDocument — closed untitled docs return error (no disk fallback)
  • Full test suite (3723 tests), lint clean

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Fixed diagnostic handling for untitled documents by preventing unnecessary disk read attempts and returning empty diagnostic reports instead.
    • Added support for virtual documents including unsaved files and notebook cells with proper URI detection.
    • Improved URI-to-path conversion to handle non-file URIs gracefully.
  • Tests

    • Added comprehensive test coverage for untitled and virtual document scenarios.

Enable the LSP server to lint unsaved Dockerfile buffers that have not
yet been saved to disk. Editors assign an untitled: URI to new documents
instead of the usual file: scheme, and the server now handles this
gracefully instead of silently failing.

Changes:
- uriToPath returns a synthetic cwd-based path for non-file URIs so
  config discovery and workspace settings matching still work.
- isUntitledURI helper for scheme detection.
- Pull diagnostics for closed untitled documents return empty results
  instead of attempting to read from a non-existent path.
- contentForURI returns os.ErrNotExist for closed untitled documents
  instead of reading the wrong file.

Inspired by oxc-project/oxc#19287.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 881b54a and 56ddf1d.

📒 Files selected for processing (4)
  • internal/lspserver/diagnostics.go
  • internal/lspserver/execute_command.go
  • internal/lspserver/execute_command_test.go
  • internal/lspserver/server_test.go

📝 Walkthrough

Walkthrough

Adds handling for virtual/untitled URIs in the LSP server: detects non-file URIs, avoids reading unsaved documents from disk, returns empty FullDocumentDiagnosticReport for closed untitled docs, and generates synthetic paths for non-file URIs to enable project config discovery. Tests for these behaviors were added.

Changes

Cohort / File(s) Summary
Diagnostics
internal/lspserver/diagnostics.go, internal/lspserver/diagnostics_test.go
Introduce isVirtualURI(docURI string) bool. handleDiagnostic returns an empty FullDocumentDiagnosticReport for virtual (untitled/notebook) URIs instead of reading disk. uriToPath can produce a synthetic project-anchored path for non-file URIs. Added tests for untitled diagnostic flows.
Content resolution / Execute command
internal/lspserver/execute_command.go, internal/lspserver/execute_command_test.go
contentForURI now short-circuits for virtual URIs (uses isVirtualURI) and returns os.ErrNotExist when the document has no backing file; tests added for opened vs closed untitled documents.
Server tests
internal/lspserver/server_test.go
Expanded TestURIToPath with subtests for file, untitled, and vscode-notebook URIs and added TestIsVirtualURI table-driven cases covering various URI patterns and edge cases.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately describes the main change: adding support for the untitled:// URI scheme for unsaved documents in the LSP server.
Linked Issues check ✅ Passed The PR fully addresses issue #168 by implementing virtual URI scheme support (untitled: and vscode-notebook-cell:), enabling URI-to-path resolution without disk fallback, and adding comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing virtual URI support in the LSP server; no unrelated modifications are present in the diagnostics, execute_command, or test files.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/lsp-untitled-uri-support

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.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the Language Server Protocol (LSP) server's capabilities by extending its support to unsaved Dockerfile documents. Previously, the server could not process files using the 'untitled:' URI scheme, leading to a lack of features like linting for new, unsaved files. The changes introduce mechanisms to correctly interpret these URIs, generate appropriate temporary paths for internal processing, and handle the lifecycle of these in-memory documents, ensuring a consistent user experience across both saved and unsaved files.

Highlights

  • LSP Support for Untitled Documents: Enabled the Language Server Protocol (LSP) server to provide linting and other features for unsaved Dockerfile buffers identified by the 'untitled:' URI scheme.
  • Synthetic Path Generation: Updated 'uriToPath' to generate a synthetic, current working directory-based path for non-file URIs, ensuring correct configuration discovery and workspace settings for unsaved documents.
  • Graceful Handling of Closed Untitled Documents: Implemented logic in diagnostic pulling and content retrieval ('contentForURI') to gracefully return empty results or errors for closed untitled documents, as they lack a backing file.
  • URI Scheme Helper: Introduced a new 'isUntitledURI' helper function for clear and consistent detection of 'untitled:' URI schemes.
Changelog
  • internal/lspserver/diagnostics.go
    • Modified 'handleDiagnostic' to return an empty diagnostic report for closed untitled documents.
    • Added 'isUntitledURI' function to detect 'untitled:' URI schemes.
    • Updated 'uriToPath' to return a synthetic 'Dockerfile' path for non-file URIs, anchored at the current working directory.
  • internal/lspserver/diagnostics_test.go
    • Imported the 'protocol' package.
    • Added 'TestPublishDiagnostics_UntitledURI' to verify diagnostics are published for untitled URIs.
    • Added 'TestHandleDiagnostic_UntitledURI_ClosedDocument' to confirm empty diagnostics for closed untitled documents.
  • internal/lspserver/execute_command.go
    • Modified 'contentForURI' to return 'os.ErrNotExist' when attempting to read content for a closed untitled URI.
  • internal/lspserver/execute_command_test.go
    • Added 'TestContentForURI_ReturnsOpenUntitledDocumentContent' to ensure content is retrieved for open untitled documents.
    • Added 'TestContentForURI_UntitledURI_ClosedDocument' to verify error handling for closed untitled documents.
  • internal/lspserver/server_test.go
    • Expanded 'TestURIToPath' with subtests for 'untitled:' and 'vscode-notebook-cell:' URIs, asserting synthetic path generation.
    • Added 'TestIsUntitledURI' to validate the new URI scheme detection helper.
Activity
  • The author provided a detailed summary of the changes and their context.
  • A comprehensive test plan was outlined, including specific tests for 'URIToPath', 'IsUntitledURI', 'PublishDiagnostics_UntitledURI', 'HandleDiagnostic_UntitledURI_ClosedDocument', 'ContentForURI_ReturnsOpenUntitledDocumentContent', and 'ContentForURI_UntitledURI_ClosedDocument'.
  • All 3723 existing tests passed, and the linting process was clean.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This is a great feature that improves the LSP experience for unsaved files. The approach of using a synthetic path for config discovery is clever, and the changes are well-tested. I have one main suggestion to improve consistency in handling different types of virtual URIs (like untitled: and vscode-notebook-cell:), which will make the implementation more robust.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Feb 27, 2026

Merging this PR will not alter performance

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

✅ 4 untouched benchmarks


Comparing feat/lsp-untitled-uri-support (56ddf1d) with main (ffe129f)

Open in CodSpeed

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/lspserver/execute_command_test.go`:
- Around line 156-163: The test TestContentForURI_UntitledURI_ClosedDocument
currently accepts any error; tighten it to assert the specific "not-exist"
sentinel so the contract is locked. Replace require.Error(t, err) with an
assertion that the returned error is the sentinel (e.g. require.ErrorIs(t, err,
ErrNotExist) or require.True(t, errors.Is(err, ErrNotExist))) when calling
s.contentForURI("untitled:Untitled-1"); add an import for errors if you use
errors.Is. Ensure you reference the sentinel symbol ErrNotExist (or
fs.ErrNotExist if that is the project sentinel) in the assertion.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ffe129f and 881b54a.

📒 Files selected for processing (5)
  • internal/lspserver/diagnostics.go
  • internal/lspserver/diagnostics_test.go
  • internal/lspserver/execute_command.go
  • internal/lspserver/execute_command_test.go
  • internal/lspserver/server_test.go

…hemes

Rename isUntitledURI → isVirtualURI to correctly handle any virtual
document scheme (e.g. vscode-notebook-cell:, untitled:) rather than
only untitled:. The new implementation checks for any non-file scheme
using url.Parse, consistent with uriToPath's existing logic.

Also tightens TestContentForURI_UntitledURI_ClosedDocument to assert
os.ErrNotExist specifically.

Addresses: #192 (comment)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@tinovyatkin tinovyatkin merged commit 8dd8529 into main Feb 27, 2026
14 of 17 checks passed
@tinovyatkin tinovyatkin deleted the feat/lsp-untitled-uri-support branch February 27, 2026 01:09
@github-actions github-actions bot locked and limited conversation to collaborators Feb 27, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

untitled schema

1 participant