Skip to content

fix(oxfmt/lsp): prefer language_id over file extension when formatting#19977

Merged
graphite-app[bot] merged 1 commit intomainfrom
copilot/update-lsp-files-prefer-language-id
Mar 4, 2026
Merged

fix(oxfmt/lsp): prefer language_id over file extension when formatting#19977
graphite-app[bot] merged 1 commit intomainfrom
copilot/update-lsp-files-prefer-language-id

Conversation

Copy link
Contributor

Copilot AI commented Mar 3, 2026

  • Explore the codebase (apps/oxfmt/src/lsp/, test/lsp/format/)
  • Make get_file_extension_from_language_id accessible (pub(super)) in mod.rs
  • Modify format_file in server_formatter.rs to prefer language_id over file extension
  • Update run_format to pass language_id to format_file
  • Create test fixture apps/oxfmt/test/lsp/format/fixtures/format/test.ts.txt
  • Add test case in format.test.ts for .txt file with TypeScript language_id
  • Update snapshot
  • Refactor: extract apply_language_id_extension helper shared by both create_fake_file_path_from_language_id and format_file

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Copilot AI changed the title [WIP] Update LSP files to prefer language ID feat(oxfmt/lsp): prefer language_id over file extension when formatting Mar 3, 2026
Copilot finished work on behalf of Sysix March 3, 2026 21:10
@github-actions github-actions bot added A-cli Area - CLI A-formatter Area - Formatter C-enhancement Category - New feature or request labels Mar 3, 2026
@Sysix
Copy link
Member

Sysix commented Mar 3, 2026

@copilot could you refactor create_fake_file_path_from_language_id and the path of it in a more "elegant" way. So we can share the logic more

@Sysix Sysix changed the title feat(oxfmt/lsp): prefer language_id over file extension when formatting fix(oxfmt/lsp): prefer language_id over file extension when formatting Mar 3, 2026
@Sysix Sysix removed the C-enhancement Category - New feature or request label Mar 3, 2026
@github-actions github-actions bot added the C-bug Category - Bug label Mar 3, 2026
Copy link
Contributor Author

Copilot AI commented Mar 3, 2026

@copilot could you refactor create_fake_file_path_from_language_id and the path of it in a more "elegant" way. So we can share the logic more

Done in 223cd58. I introduced apply_language_id_extension(language_id, path) -> Option<PathBuf> as the shared primitive — it maps a language_id to an extension and returns a copy of the given path with that extension applied. Both callers now use it:

  • create_fake_file_path_from_language_id: builds a base path from root + uri.authority(), then calls apply_language_id_extension
  • format_file: calls apply_language_id_extension(language_id, path) directly, falling back to the original path extension if the language id is unknown

Copilot finished work on behalf of Sysix March 3, 2026 21:27
@Sysix Sysix marked this pull request as ready for review March 3, 2026 21:53
Copilot AI review requested due to automatic review settings March 3, 2026 21:53
@Sysix
Copy link
Member

Sysix commented Mar 3, 2026

The reasons can be found in #19976 @leaysgur

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the oxfmt LSP formatter to choose a formatting strategy based on the LSP language_id (when available) rather than only the on-disk file extension, enabling correct formatting for files whose extension doesn’t match their active language mode.

Changes:

  • Prefer language_id-derived extensions when selecting FormatFileStrategy for file-backed documents.
  • Refactor shared language-id-to-extension logic into an apply_language_id_extension helper in the LSP module.
  • Add a new LSP formatting fixture/test + snapshot for a .txt file formatted as TypeScript via language_id.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
apps/oxfmt/src/lsp/server_formatter.rs Passes language_id into format_file and prefers language-id-based strategy detection.
apps/oxfmt/src/lsp/mod.rs Exposes language-id extension mapping to sibling modules and adds apply_language_id_extension.
apps/oxfmt/test/lsp/format/format.test.ts Adds a new test case covering .txt opened as TypeScript.
apps/oxfmt/test/lsp/format/fixtures/format/test.ts.txt New fixture input for the TypeScript-via-languageId case.
apps/oxfmt/test/lsp/format/snapshots/format.test.ts.snap Adds the expected snapshot output for the new fixture.

@leaysgur leaysgur added the 0-merge Merge with Graphite Merge Queue label Mar 4, 2026
Copy link
Member

leaysgur commented Mar 4, 2026

Merge activity

#19977)

- [x] Explore the codebase (apps/oxfmt/src/lsp/, test/lsp/format/)
- [x] Make `get_file_extension_from_language_id` accessible (pub(super)) in `mod.rs`
- [x] Modify `format_file` in `server_formatter.rs` to prefer `language_id` over file extension
- [x] Update `run_format` to pass `language_id` to `format_file`
- [x] Create test fixture `apps/oxfmt/test/lsp/format/fixtures/format/test.ts.txt`
- [x] Add test case in `format.test.ts` for `.txt` file with TypeScript `language_id`
- [x] Update snapshot
- [x] Refactor: extract `apply_language_id_extension` helper shared by both `create_fake_file_path_from_language_id` and `format_file`

<!-- START COPILOT CODING AGENT TIPS -->
---

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. [Learn more about Advanced Security.](https://gh.io/cca-advanced-security)
@graphite-app graphite-app bot force-pushed the copilot/update-lsp-files-prefer-language-id branch from 0140a8e to 114f974 Compare March 4, 2026 00:25
@graphite-app graphite-app bot merged commit 114f974 into main Mar 4, 2026
19 checks passed
@graphite-app graphite-app bot deleted the copilot/update-lsp-files-prefer-language-id branch March 4, 2026 00:32
@graphite-app graphite-app bot removed the 0-merge Merge with Graphite Merge Queue label Mar 4, 2026
camc314 pushed a commit that referenced this pull request Mar 9, 2026
# Oxlint
### 🚀 Features

- e6b604f oxlint: Auto-enable gitlab formatter on GitLab (#20076)
(camc314)
- 2488a68 linter: Add .oxlintrc.jsonc config file support (#19870)
(Scott S.)
- 61bf388 linter: Add `options.reportUnusedDisableDirectives` to config
file (#19799) (Peter Wagenet)
- c92422b oxlint: Auto-enable github formatter on GitHub Actions
(#19944) (Boshen)
- 0337c6d linter: Implement typescript/no-unecessary-type-conversion
(#19955) (camc314)
- 2919313 linter: Introduce denyWarnings config options (#19926)
(camc314)
- a607119 linter: Introduce maxWarnings config option (#19777) (camc314)

### 🐛 Bug Fixes

- 0861d9a linter/plugins: Remove getters from `Context` (#20115)
(overlookmotel)
- 92cfb14 linter/plugins: Fix types for `walkProgram` and
`walkProgramWithCfg` (#20081) (overlookmotel)
- 10e211f oxlint/lsp: Send other code actions besides `source.fixAll` if
requested (#20042) (Sysix)
- 602daaa linter/plugins: Fix type definition for `VisitorObject`
(#20065) (overlookmotel)
- ee0491e apps,napi: Explicitly specify libs in tsconfigs (#20071)
(camc314)
- b6e9499 linter: Fix the logic for `unicorn/prefer-dom-node-remove` to
handle literal callees as well as arguments. (#20059) (connorshea)
- 3874ae1 linter: Update `unicorn/prefer-query-selector` to also catch
`getElementsByName()`. (#20060) (connorshea)
- 77c93fb linter: Handle array-type shorthand inside union members
(#20034) (camc314)
- 50eb160 linter/no-unused-vars: Allow unused type params in ambient
module blocks (#19615) (Don Isaac)
- 1dd0d21 linter/no-restricted-imports: Apply regex pattern checks to
side-effect imports (#20028) (camc314)
- 7f3d735 linter: Error when --type-check is used without --type-aware
(#20025) (camc314)
- eea201c unicorn/prefer-string-slice: Avoid unsafe autofix for
substr-to-slice (#20010) (camc314)
- 50359dc oxlint/lsp: Detect `reportUnusedDisableDirectives` from oxlint
config, change lsp `unusedDisableDirectives` default value to `None`
(#20011) (Sysix)
- 4bc84b1 linter/plugins: Allow `null` and `undefined` for
`rule.meta.fixable` (#20008) (overlookmotel)
- 753e27e linter/role-supports-aria-props: Add `aria-posinset` to
supported `option` ARIA properties (#20003) (JongKyung Lee)
- f57b2c9 linter/plugins: Fix return types of tokens methods (#19985)
(overlookmotel)
- 27ee4fc linter/no-loss-of-precision: Avoid double rounding for
negative exponents (#19999) (camc314)
- 77a94bb linter: Avoid no-loss-of-precision false positive for 3e-308
(#19992) (camc314)
- 6245c56 linter/no-unused-private-class-members: Treat logical lhs
access as usage (#19991) (camc314)
- 65891e3 linter: Avoid prefer-const false positive for mixed-scope
destructuring (#19982) (camc314)
- 89991fe linter: Avoid prefer-const false positive for operator
reassignments (#19975) (camc314)
- 87318e7 oxlint/lsp: Load js config with reforcing fs read (#19551)
(Sysix)
- d40a942 linter/no-useless-constructor: Mark fixer as suggestion
(#19961) (camc314)
- ccbd959 linter/prefer-code-point: Report String.fromCharCode member
references (#19931) (camc314)
- 14fbbfc linter: Add help text to oxc/no-rest-spread-properties rule
(#19900) (Subin Kim)

### ⚡ Performance

- 2baa5fb napi: Unify build-test profile to coverage for cache sharing
(#20090) (Boshen)
- 77f1c71 linter/plugins: Make tokens class instances (#19980)
(overlookmotel)
- 758b424 linter/plugins: Reduce memory copies for tokens (#19979)
(overlookmotel)
- 236847f linter/plugins: Cache token objects (#19978) (overlookmotel)
- 94b597a linter/plugins: Store tokens as a `Box<[Token]>` (#19969)
(overlookmotel)

### 📚 Documentation

- 2c0010a linter/plugins: Move comment about "bivariance hack" into
generated code (#20082) (overlookmotel)
- 7538f09 linter: Improve `import/extensions` and
`import/no-named-as-default` rule docs. (#20053) (connorshea)
- 1f909cf linter: Improve docs for
`unicorn/require-post-message-target-origin` rule. (#20061) (connorshea)
- 12ae35c oxlint/lsp: Remove outdated ToDo for `LintOptions.run`
(#20012) (Sysix)
- 3be73e6 linter/plugins: Fix JSDoc comments for tokens methods (#20004)
(overlookmotel)
- 48ef285 linter: Update `--config` docs (#19965) (camc314)
- 6ea49a0 linter: Fix some identation issues for the generated types
used in `oxlint.config.ts`. (#19942) (connorshea)
- 6c0e0b5 linter: Add oxlint.config.ts to the config docs. (#19941)
(connorshea)
- 160e423 linter: Add a note that the typeAware and typeCheck options
require oxlint-tsgolint (#19940) (connorshea)
- d54c275 linter: Improve rule docs for 27 unicorn rules (#19903)
(connorshea)
# Oxfmt
### 🚀 Features

- ee26215 oxfmt: Support css-in-js substitution (#20019) (leaysgur)
- 0f0ff51 oxfmt: Display default settings was used message in cli stats
(#19939) (leaysgur)
- 88815b8 oxfmt: Reintroduce stats line for write mode (#19938)
(leaysgur)

### 🐛 Bug Fixes

- ee0491e apps,napi: Explicitly specify libs in tsconfigs (#20071)
(camc314)
- 92f4490 oxfmt: Apply `is_ignored_dir` for glob paths too (#20056)
(leaysgur)
- 114f974 oxfmt/lsp: Prefer language_id over file extension when
formatting (#19977) (copilot-swe-agent)

### ⚡ Performance

- 2baa5fb napi: Unify build-test profile to coverage for cache sharing
(#20090) (Boshen)

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-cli Area - CLI A-formatter Area - Formatter C-bug Category - Bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants