Skip to content

feat(lsp,cli): support auto-fix on save and multi-pass fix#559

Merged
fansenze merged 1 commit intomainfrom
feat/fixall-on-save-20260321
Mar 23, 2026
Merged

feat(lsp,cli): support auto-fix on save and multi-pass fix#559
fansenze merged 1 commit intomainfrom
feat/fixall-on-save-20260321

Conversation

@fansenze
Copy link
Copy Markdown
Contributor

@fansenze fansenze commented Mar 21, 2026

Summary

Add fixAll code action support so users can auto-fix lint issues on save, matching the standard ESLint workflow. Both CLI --fix and LSP fixAll support multi-pass fixing (up to 10 passes) to handle cascading issues.

User configuration:

{
  "editor.codeActionsOnSave": {
    "source.fixAll.rslint": "explicit"
  }
}

Key features:

  • Multi-pass fixing (up to 10 passes) handles cascading issues — e.g. ban-types fix (String→string) triggers no-inferrable-types (removes now-inferrable : string), all resolved in a single save / single --fix run
  • Cycle detection prevents infinite loops when rules undo each other
  • CLI --fix exit code reflects post-fix state: exit 0 when all errors are fixed, exit 1 only when non-fixable errors remain (aligned with ESLint)
  • CLI --fix output only shows remaining unfixed diagnostics, not already-fixed ones (aligned with ESLint/oxlint collect-then-print model)
  • Both CLI and LSP share the same linter.ApplyRuleFixes engine for fix application
  • handleDidSave clears pendingLintURIs to prevent redundant debounce lints
  • computeEndPosition uses core.UTF16Len for correct UTF-16 position encoding

Tests:

  • 70+ Go unit tests (isFixAllRequest, mergeFixGroups, handleFixAllCodeAction, computeEndPosition with emoji/CJK, ApplyRuleFixes edge cases, groupDiagsByFile, routing)
  • 19 VSCode e2e tests covering: fixAll code actions, full on-save integration with real document.save() for both source.fixAll.rslint and generic source.fixAll, cascade fixes, error flows
  • 18 CLI e2e tests covering: exit codes (all-fixable, non-fixable, mixed, warn-only), output content (only remaining diagnostics shown), cascade, edge cases (empty file, syntax errors, multi-file, fix count)

Related Links

  • ESLint VSCode extension uses the same editor.codeActionsOnSave + source.fixAll.eslint mechanism

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).

@gemini-code-assist
Copy link
Copy Markdown

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 rslint developer experience by integrating a robust auto-fix on save feature within the Language Server Protocol (LSP). It allows for seamless, multi-pass correction of linting issues directly within the editor, ensuring code quality is maintained with minimal manual intervention. The changes extend to the CLI as well, providing a consistent fixing mechanism across different environments.

Highlights

  • Auto-fix on Save: Introduced support for source.fixAll.rslint code action, enabling users to automatically fix lint issues on save, similar to the standard ESLint workflow. This is configurable via editor.codeActionsOnSave in VS Code settings.
  • Multi-pass Fixing: Implemented multi-pass fixing (up to 10 passes) to handle cascading lint issues, where one fix might reveal or enable another. This ensures comprehensive resolution of problems in a single operation.
  • Cycle Detection: Added logic to detect and prevent infinite loops that could occur if rules produce fixes that undo each other during multi-pass operations.
  • CLI --fix Enhancement: The CLI --fix command now also supports multi-pass fixing, rebuilding programs from disk and re-linting after each pass to ensure all cascading issues are addressed.
  • LSP Performance Optimization: Optimized LSP handleDidSave to clear pendingLintURIs, preventing redundant debounce lints when a file is saved and immediately re-linted.
  • Code Refactoring: Refactored ruleFixToTextEdit and convertRuleDiagnosticToLSP to reduce code duplication across quickfix, suggestion, and fixAll paths, improving maintainability and consistency.
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.

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

@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 pull request introduces a significant and valuable feature: auto-fixing on save (source.fixAll.rslint), aligning rslint's LSP capabilities with standard tools like ESLint. The implementation is robust, featuring multi-pass fixing to handle cascading issues, both in the CLI (--fix) and the language server. The cycle detection is a thoughtful addition to prevent infinite loops. The refactoring in internal/lsp/service.go to centralize diagnostic and fix conversions into helper functions like ruleFixToTextEdit and convertRuleDiagnosticToLSP greatly improves code clarity and maintainability. The addition of comprehensive unit and e2e tests is commendable. I've found one high-severity issue in the new computeEndPosition helper function that could lead to file corruption with non-ASCII characters, and I've suggested a fix along with an additional test case.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages bot commented Mar 21, 2026

Deploying rslint with  Cloudflare Pages  Cloudflare Pages

Latest commit: be4559a
Status: ✅  Deploy successful!
Preview URL: https://3e117561.rslint.pages.dev
Branch Preview URL: https://feat-fixall-on-save-20260321.rslint.pages.dev

View logs

@fansenze fansenze force-pushed the feat/fixall-on-save-20260321 branch 8 times, most recently from 56763d5 to c58c476 Compare March 23, 2026 02:28
@fansenze fansenze changed the title feat(lsp): support auto-fix on save via source.fixAll.rslint feat(lsp,cli): support auto-fix on save and multi-pass fix Mar 23, 2026
@fansenze fansenze force-pushed the feat/fixall-on-save-20260321 branch 15 times, most recently from be4559a to 5d38a36 Compare March 23, 2026 07:15
Add fixAll code action support so users can auto-fix lint issues on
save by configuring `editor.codeActionsOnSave`. Both CLI `--fix` and
LSP fixAll support multi-pass fixing (up to 10 passes) to handle
cascading issues (e.g. ban-types fix triggers no-inferrable-types).

LSP:
- Declare source.fixAll / source.fixAll.rslint code action kinds
- Add handleFixAllCodeAction with multi-pass loop: lint → apply fixes
  via ApplyRuleFixes → update session overlay → repeat until stable,
  with cycle detection
- Clear pendingLintURIs in handleDidSave and handleFixAllCodeAction
  to prevent redundant debounce lints
- Use core.UTF16Len for correct UTF-16 position encoding
- Extract ruleFixToTextEdit / reuse convertRuleDiagnosticToLSP to
  reduce duplication across quickfix/suggestion/fixAll paths

CLI:
- Add multi-pass --fix: after applying fixes, rebuild Program from
  disk and re-lint to catch cascading issues
- Extract applyFixPass helper and createPrograms closure

Tests:
- Go unit tests (70+) covering isFixAllRequest, mergeFixGroups,
  handleFixAllCodeAction, computeEndPosition, ApplyRuleFixes edge
  cases, handleDidSave, routing
- E2e tests (18) covering fixAll code actions, on-save integration
  with real document.save() for both source.fixAll.rslint and generic
  source.fixAll, cascade fixes, error flows, edge cases

Docs:
- Update website guide and extension README with codeActionsOnSave config
@fansenze fansenze force-pushed the feat/fixall-on-save-20260321 branch from 5d38a36 to aadbc69 Compare March 23, 2026 07:24
@fansenze fansenze enabled auto-merge (squash) March 23, 2026 07:55
@fansenze fansenze merged commit efc9b0d into main Mar 23, 2026
14 of 15 checks passed
@fansenze fansenze deleted the feat/fixall-on-save-20260321 branch March 23, 2026 07:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants