Skip to content

feat(datagrid): copy focused cell value with Cmd+C, add Cmd+Shift+C for rows (#1332)#1337

Merged
datlechin merged 3 commits into
mainfrom
feat/cmd-c-copy-cell
May 19, 2026
Merged

feat(datagrid): copy focused cell value with Cmd+C, add Cmd+Shift+C for rows (#1332)#1337
datlechin merged 3 commits into
mainfrom
feat/cmd-c-copy-cell

Conversation

@datlechin

Copy link
Copy Markdown
Member

Summary

Closes #1332.

Cmd+C in the data grid now copies the focused cell value when a single row is selected and a cell has focus on a data column. Otherwise it copies the selected row(s) as TSV (existing behavior).

Cmd+Shift+C is a new shortcut that always copies the selected row(s) as TSV, even when a cell is focused. "Copy with Headers" stays in the Edit menu and right-click menu but loses its default shortcut.

Why

The data grid renders a cell focus border and tracks focusedRow/focusedColumn, but Cmd+C ignored both and always copied the whole row. Foreign key cells were the worst-affected case: double-click opens the FK popover instead of inline edit, so users had no keyboard path to copy just the cell value.

This aligns the shortcut with what the UI shows. Apple's HIG and most database clients (DataGrip, DBeaver, Postico, Sequel Ace, MySQL Workbench) target the most specific visible selection. TablePlus uses Cmd+Shift+C for explicit-rows, which this PR matches.

Implementation

Native AppKit responder chain:

  • KeyHandlingTableView.copy(_:) decides cell vs row internally based on focusedDataCell() (mirrors the existing paste(_:) pattern at the same call site).
  • KeyHandlingTableView.copyRowsAsTSV(_:) is a new selector for explicit-row dispatch.
  • PasteboardCommands menu buttons dispatch via NSApp.sendAction(_, to: nil, from: nil), letting the responder chain deliver copy: to NSTextView or the table view.
  • PasteboardActionRouter stays in its original 3-case form (text / rows / table-names). The sidebar table-names case still routes via app state because the sidebar may not be in the responder chain.
  • PasteboardCommands now gets a CommandActionsRegistry fallback for @FocusedValue, matching AppMenuCommands. Without it, .disabled(!hasRowSelection) was always true when NSTableView was first responder, which disabled the "Copy Rows" menu item and blocked the shortcut.
  • AppCommands.copySelectedRows observer routes through copySelectedRows() so the structure-tab guard applies.

Test plan

  • xcodebuild -project TablePro.xcodeproj -scheme TablePro test -skipPackagePluginValidation -only-testing:TableProTests/PasteboardActionRouterTests
  • Open a table, click a cell, press Cmd+C -> clipboard contains only the cell value
  • Open a table, click an FK cell (one that opens the FK popover on double-click), press Cmd+C -> clipboard contains the raw FK value
  • Shift-select multiple rows, press Cmd+C -> clipboard contains TSV of all selected rows
  • Single row + cell focus, press Cmd+Shift+C -> clipboard contains the row as TSV (not the cell)
  • Click row-number column header (selects whole row, clears cell focus), press Cmd+C -> clipboard contains the row TSV
  • Open SQL editor, select text, press Cmd+C -> standard text copy still works
  • Click on sidebar to select tables (no row selection in grid), press Cmd+C -> table names copied
  • Edit menu shows "Copy", "Copy Rows" (Cmd+Shift+C), "Copy with Headers" (no shortcut), "Copy as JSON" with correct enabled/disabled states
  • Structure tab: same behavior — Cmd+C on a single focused cell copies cell value

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.

Shortcut to copy the cell content to clipboard

1 participant