Skip to content

fix(editor): format SQL scopes to selection when text is selected#1661

Merged
datlechin merged 2 commits into
mainfrom
fix/1656-format-selection-scope
Jun 12, 2026
Merged

fix(editor): format SQL scopes to selection when text is selected#1661
datlechin merged 2 commits into
mainfrom
fix/1656-format-selection-scope

Conversation

@datlechin

@datlechin datlechin commented Jun 12, 2026

Copy link
Copy Markdown
Member

Fixes #1656.

What

Format SQL (menu, editor toolbar, or right-click) now formats only the selected text when a selection is active. With no selection it formats the whole document, same as before. Undo reverts exactly the range that was formatted.

Root cause

SQLEditorCoordinator.performFormatSQL() read textView.selectedRange() only as a cursor hint, then unconditionally formatted textView.string and replaced the full document range. The selection was available at the call site and simply never used for scoping. The undo half of #1656 was already fixed by #1658: TextView.replaceCharacters registers a single TextMutation in CEUndoManager. This change keeps that exact path, so a selection-scoped format is a single undo step covering only the selection.

Design

Matches the documented DataGrip / VS Code / SSMS convention: selection formats the selection, empty selection formats the whole document. No statement-at-cursor mode: no mainstream DB client formats the statement under the cursor on an empty selection, and adopting it would surprise users. One command, selection-aware; no new menu items or shortcuts.

  • New FormatScopeResolver, a pure helper that resolves (fullText, selectedRange) to the range and substring to format. Selections that extend past the document fall back to the full document instead of crashing in substring(with:).
  • After formatting a selection the caret lands at the end of the formatted range, the standard macOS behavior after replacing a selection. The no-selection path keeps the formatter's proportional caret mapping.
  • All ranges are UTF-16 NSRange, covered by a dedicated Unicode test.
  • The selection's leading and trailing whitespace survives formatting. The formatter trims its output, so without this a line-wise selection (triple click) would lose its trailing newline and glue the next statement onto the formatted one. reapplyBoundaryWhitespace re-attaches the boundary whitespace around the formatted text; whole-document formatting keeps the existing trim behavior.

Testing

  • New FormatScopeResolverTests (7 cases). selectionReturnsSubrange is the regression test: it fails against the old behavior. Edge cases covered: cursor-only, NSNotFound, selection == whole document, out-of-bounds selection, UTF-16 offsets with emoji.
  • Full SQLFormatterServiceTests suite still passes.
  • No UI automation: the select-format-undo flow needs a live editor window and the UI suite does not run deterministically in CI (quarantine list). Manual QA steps: two statements in a tab, select the first, Cmd+Shift+L, confirm the second is untouched, Cmd+Z restores the first.

CHANGELOG entry added under Unreleased > Fixed; keyboard-shortcuts doc updated.

@mintlify

mintlify Bot commented Jun 12, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
TablePro 🟢 Ready View Preview Jun 12, 2026, 4:27 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f92368a03e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

)
let fullRange = NSRange(location: 0, length: (textView.string as NSString).length)
textView.replaceCharacters(in: fullRange, with: result.formattedSQL)
textView.replaceCharacters(in: scope.range, with: result.formattedSQL)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve boundary newlines when formatting a selection

When the active selection includes the line break that separates it from unselected SQL, this replacement drops that separator because SQLTokenFormatter.format trims leading/trailing whitespace from result.formattedSQL. For example, selecting select 1;\n at the start of select 1;\nselect 2; replaces it with SELECT 1;, leaving SELECT 1;select 2; and changing the query text. This is a common selection shape from selecting whole lines, so the selected-range path needs to preserve boundary whitespace or adjust the range before replacing.

Useful? React with 👍 / 👎.

@datlechin datlechin merged commit 87de7c2 into main Jun 12, 2026
3 checks passed
@datlechin datlechin deleted the fix/1656-format-selection-scope branch June 12, 2026 04:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Apply Formatting Only to Selected Query and Support Undo

1 participant