From 9dd01c3d298a0dc241b9524f399da4282c38acb2 Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Sun, 25 Oct 2026 18:06:54 +0700 Subject: [PATCH 1/2] docs(features): describe the rebuilt data grid --- customization/appearance.mdx | 25 ++++++++++----------- customization/general-settings.mdx | 2 +- features/change-tracking.mdx | 10 ++++----- features/data-files.mdx | 6 ++--- features/data-grid.mdx | 35 ++++++++++++++++++++---------- features/keyboard-shortcuts.mdx | 30 +++++++++++++++---------- features/table-structure.mdx | 4 ++-- 7 files changed, 64 insertions(+), 48 deletions(-) diff --git a/customization/appearance.mdx b/customization/appearance.mdx index 0d0ee2ce..e0aa77c2 100644 --- a/customization/appearance.mdx +++ b/customization/appearance.mdx @@ -18,7 +18,7 @@ A theme colors content: the SQL editor and every other code view, the data grid, Its window background fills the area behind those panes on every macOS version. On macOS 26 and later it is also the window color of the main window, data file windows, Compare & Sync and value viewers, and the sidebar, inspector, toolbar and title bar take on its tone through the system glass. Before macOS 26 the sidebar and toolbar keep the system look. The bars along the top and bottom of a pane, such as the filter bar, drop their system material while the theme sets a window background, so the theme shows through them. -Controls, Settings, the welcome window, the connection form, sheets and popovers keep the system look and your Accent color. A code field inside one of them, such as **Startup Commands**, **Pre-Connect Script**, a favorite's query or the **Startup SQL** of a connection link, takes the editor colors. +Controls, Settings, the welcome window, the connection form, sheets and popovers keep the system look and your Accent color, and so do a data grid's header, its selection and the border on the selected cell. A code field inside one of them, such as **Startup Commands**, **Pre-Connect Script**, a favorite's query or the **Startup SQL** of a connection link, takes the editor colors. With Increase Contrast on, the window background goes back to the macOS color and the rest of the theme stays. @@ -84,7 +84,7 @@ Each theme opens in a Theme Editor window of its own, titled with the theme's na The preview is the real SQL editor and data grid over sample content, drawn in the theme's own appearance, so a dark theme previews dark on a light Mac. It shows the current line and statement, a selection, invisibles, alternate rows, NULL, booleans, and a modified, an inserted and a deleted row. -Under it, **General** holds the theme's name, its appearance (Light or Dark) and its author. The colors follow in **Window**, **Editor**, **Syntax**, **Data Grid**, **Selection** and **Changes**. +Under it, **General** holds the theme's name, its appearance (Light or Dark) and its author. The colors follow in **Window**, **Editor**, **Syntax**, **Data Grid** and **Changes**. The line under each color's name says where the color comes from: @@ -95,7 +95,7 @@ The line under each color's name says where the color comes from: | **Default Light color** or **Default Dark color** | An unset syntax color, drawn in the default theme's value | | **Based on** and another color's name | Unset, and taken from that color. See [Colors a theme leaves out](#colors-a-theme-leaves-out) | -The arrow beside a color the theme sets clears it, under the name **Use System Color** or **Use Default Color**. The same action is in the color's right-click menu. Opacity is offered only for washes drawn over content: the editor selection, current line, current statement and invisibles, the alternate row, both grid selections, and the four row change colors. +The arrow beside a color the theme sets clears it, under the name **Use System Color** or **Use Default Color**. The same action is in the color's right-click menu. Opacity is offered only for washes drawn over content: the editor selection, current line, current statement and invisibles, the alternate row, and the four row change colors. `Cmd+Z` and `Cmd+Shift+Z` undo and redo, one step per color you drag through the picker. **Revert Changes** at the bottom puts the theme back the way it was when the window opened, and undoes like any other step. @@ -114,10 +114,10 @@ A VS Code color theme imports like any other theme file, from **Import…** or b | Window background | `editorPane.background`, else `editor.background` | | Editor | `editor.background`, `editor.foreground`, `editorCursor.foreground`, `editor.selectionBackground`, `editor.lineHighlightBackground` (else `editor.lineHighlightBorder`), `editor.rangeHighlightBackground` for the current statement, `editorLineNumber.foreground`, `editorWhitespace.foreground` | | Syntax | `tokenColors` rules, matched the way VS Code matches them against the scopes of its SQL grammar. A token no rule colors takes `editor.foreground`, and NULL, when no rule colors it, takes the keyword color | -| Data grid | The editor background and text; `foreground` for header text; `list.activeSelectionBackground`, `list.activeSelectionForeground` and `list.inactiveSelectionBackground`; `list.focusOutline` or `focusBorder`; `input.placeholderForeground` for NULL; `editorLineNumber.foreground` for row numbers; `tree.tableColumnsBorder` for grid lines; `tree.tableOddRowsBackground` for alternate rows and the header; booleans from the token rules for SQL `TRUE` and `FALSE` | +| Data grid | The editor background and text; `input.placeholderForeground`, else `foreground` at half opacity, for NULL; `editorLineNumber.foreground` for row numbers; `tree.tableColumnsBorder` for grid lines; `keybindingTable.rowsBackground`, else `tree.tableOddRowsBackground`, for alternate rows; booleans from the token rules for SQL `TRUE` and `FALSE` | | Row changes | `diffEditor.insertedLineBackground` and `diffEditor.removedLineBackground`, and the `gitDecoration` modified and deleted colors, made translucent, for modified rows and deleted text | -A color the file does not set stays unset and draws as [Colors a theme leaves out](#colors-a-theme-leaves-out) describes. A translucent window, editor, grid or header background is flattened over the editor background. +A color the file does not set stays unset and draws as [Colors a theme leaves out](#colors-a-theme-leaves-out) describes. A translucent window, editor or grid background is flattened over the editor background. ### What is left out @@ -126,6 +126,7 @@ A color the file does not set stays unset and draws as [Colors a theme leaves ou - `semanticTokenColors` and `semanticHighlighting`. - Rules scoped to other languages, such as `source.json`. Syntax colors are read from SQL scopes only. - Colors TablePro has no place for: the inactive editor selection, selected text in the editor, the active line number, find matches and word highlights. +- List selection, focus outline and table header colors. A grid's header and selection keep the system look in every theme. ### How the file is read @@ -149,7 +150,7 @@ A custom theme is one JSON file in `~/Library/Application Support/TablePro/Theme | `appearance` | `light` or `dark`. Decides which popup lists the theme | | `window` | Window background, under `background` | | `editor` | Editor colors, with syntax colors nested under `syntax` | -| `dataGrid` | Data grid colors, the Selection and Changes sections of the Theme Editor included | +| `dataGrid` | Data grid colors, the Changes section of the Theme Editor included | ```json { @@ -164,11 +165,11 @@ A custom theme is one JSON file in `~/Library/Application Support/TablePro/Theme "text": "#D8DEE9", "syntax": { "keyword": "#81A1C1", "string": "#A3BE8C" } }, - "dataGrid": { "background": "#2E3440", "selection": "#434C5E" } + "dataGrid": { "background": "#2E3440", "alternateRow": "#3B4252" } } ``` -A color is sRGB hex, `#RRGGBB`, or `#RRGGBBAA` for a translucent wash such as a selection. The window, editor, data grid and header backgrounds are always opaque: an alpha value there is dropped. Every color is optional. +A color is sRGB hex, `#RRGGBB`, or `#RRGGBBAA` for a translucent wash such as the editor selection. The window, editor and data grid backgrounds are always opaque: an alpha value there is dropped. Every color is optional. ### Colors a theme leaves out @@ -176,14 +177,10 @@ A color is sRGB hex, `#RRGGBB`, or `#RRGGBBAA` for a translucent wash such as a |----------|-------| | Keyword, string, number, comment, NULL, function, type | The Default Light or Default Dark value | | Operator | The theme's editor text, else the macOS color | -| Header text, bool true, bool false | The theme's data grid text, else the macOS color | +| Bool true, bool false | The theme's data grid text, else the macOS color | | Alternate row | The theme's data grid background moved 4% toward its grid text, or toward black in a light theme and white in a dark one. Without a grid background, the macOS stripe | -| Header background | The theme's data grid background, else the macOS color | -| Selected text | The theme's data grid text, while the theme sets the grid selection | | Anything else | The macOS color for that spot | -Without a grid selection color, the grid draws the macOS selection and its own text, even when the file sets selected text. - ### Files that do not load A file in the themes folder that breaks one of these is listed under **Not Loaded** with the reason, and a JSON error names the line and column: @@ -191,7 +188,7 @@ A file in the themes folder that breaks one of these is listed under **Not Loade - It is not plain JSON. Comments are refused here; a VS Code theme goes through **Import…** instead. - It has no `schema`, or a `schema` other than `3`. A theme file from TablePro 0.80 or earlier needs to be made again. - It lacks `id`, `name` or `appearance`, or a field breaks the rules in the table. -- It holds a key TablePro does not use, or a value that is not a `#RRGGBB` or `#RRGGBBAA` string. +- It holds a key TablePro does not use, or a value that is not a `#RRGGBB` or `#RRGGBBAA` string. The six data grid keys earlier versions wrote for the header and the selection, `headerBackground`, `headerText`, `selection`, `selectionText`, `inactiveSelection` and `focusBorder`, are the exception: a file that has them loads, and those keys are dropped. - Its `id` is one another file in the folder already uses. The first file by name loads. ## Connection colors diff --git a/customization/general-settings.mdx b/customization/general-settings.mdx index f814ab9a..a8f4101a 100644 --- a/customization/general-settings.mdx +++ b/customization/general-settings.mdx @@ -28,7 +28,7 @@ System (the default), English, Tiếng Việt, 简体中文, 繁體中文, 한 | **Show connections** | On | The [connections strip](/features/workspace-rail) on the window's leading edge | | **Show recent tables** | Off | A [Recent section](/features/favorites#recent-tables) at the top of the sidebar | | **Show object icons** | On | A type icon before each object name. Off gives a plain list of names | -| **Show object comments** | On | Database object comments beside tables in the sidebar and in grid column headers | +| **Show object comments** | On | Database object comments beside tables in the sidebar and in a grid column header's tooltip | | **Show partitions** | On | A partitioned table's partitions listed under it, and how many it holds beside its name | | **Show system databases and schemas** | Off | `mysql`, `information_schema`, `master` and the other system databases and schemas in the sidebar tree and its database and schema filters. The database switcher lists them either way | | **Row size** | Match System | Match System follows **Sidebar icon size** in **System Settings > Appearance**. Small, Medium, or Large overrides it to fit more objects on screen | diff --git a/features/change-tracking.mdx b/features/change-tracking.mdx index 8dd84a07..ab3a62f7 100644 --- a/features/change-tracking.mdx +++ b/features/change-tracking.mdx @@ -18,7 +18,7 @@ A queued change also marks the value itself, so it stays legible once the row is ## Editing a cell -Double-click a cell, or press `Enter` on it. `Enter` commits the edit to the queue, `Escape` cancels. Setting a value back to what it was drops it from the queue again. Delete the text of a date, number, boolean, JSON, array or vector cell to store NULL. In a NOT NULL column of those types the cell keeps its value, and an emptied text cell stores an empty string. Some types open an editor of their own: +Double-click a cell, or press `Return` on it, and type. `Return` queues the edit and `Escape` cancels it; `Tab`, `Shift+Tab`, `Up` and `Down` queue it and edit the neighboring cell. A value that holds a line break, or runs past 256 characters, opens in a multi-line editor anchored to the cell, where `Option+Enter` starts a new line. Setting a value back to what it was drops it from the queue again. Delete the text of a date, number, boolean, JSON, array or vector cell to store NULL. In a NOT NULL column of those types the cell keeps its value, and an emptied text cell stores an empty string. Some types open an editor of their own: | Column type | Editor | |---|---| @@ -46,9 +46,9 @@ Right-click an editable cell and open **Set Value**. Each item appears only wher - **Generate UUID** (version 4) and **Generate UUIDv7** (ordered by creation time) on a `uuid` or `uniqueidentifier` column, and on a text or binary column whose display format is UUID. A foreign key column and a Cassandra `timeuuid` column get neither. - **Set Cells to Value…** on any cell you could type into. Type the value once and click **Set**. It is read the way a typed value is, so an empty value stores NULL in a date or number column, and a function such as `NOW()` in a date or time column runs on the server. -Select several cells first to set all of them at once; Generate UUID gives each cell its own value. With whole rows selected, the clicked column changes on every selected row. Cells that cannot take the value keep what they hold: **Set Cells to Value…** skips a column the server owns, a binary column and a deleted row, and says how many cells it sets before you confirm. **Edit > Set Value** holds the same items for the focused cell or the selection, and [Settings > Keyboard](/features/keyboard-shortcuts#customizing-shortcuts) assigns them shortcuts. +Select several cells first to set all of them at once; Generate UUID gives each cell its own value. Whatever the count, one `Cmd+Z` undoes the whole command. With whole rows selected, the clicked column changes on every selected row. Cells that cannot take the value keep what they hold: **Set Cells to Value…** skips a column the server owns, a binary column and a deleted row, and says how many cells it sets before you confirm. **Edit > Set Value** holds the same items for the focused cell or the selection, and [Settings > Keyboard](/features/keyboard-shortcuts#customizing-shortcuts) assigns them shortcuts. -To copy one value into many cells, copy it, select the cells and press `Cmd+V`. A copied block of several cells pastes from the focused cell rightward and down instead. +To copy one value into many cells, copy it, select the cells and press `Cmd+V`, or choose **Paste** on a cell's right-click menu. A copied block of several cells pastes from the focused cell rightward and down instead. On MongoDB, Firestore and the Firebase Realtime Database a document can lack a field altogether, and on Bigtable a row can lack a cell; the grid shows either as **No Field**. **Remove Field** on the same right-click menu deletes the field rather than storing NULL. Bigtable stores no NULL, so **NULL** and **Remove Field** both delete the cell. See [missing fields and null](/databases/mongodb#missing-fields-and-null). @@ -56,8 +56,8 @@ On MongoDB, Firestore and the Firebase Realtime Database a document can lack a f - **Add Row** (`Cmd+Shift+N`), the **+** button, or **Edit > Add Row**. The row appears at the bottom with the cursor in its first writable cell. A UUID primary key the server does not fill gets a new UUID, and the cursor skips it. Later edits fold into the INSERT rather than queueing as updates. - **Duplicate Row** (`Cmd+Shift+D`) on the right-click menu copies a row and resets its primary key and its identity columns to `DEFAULT`, so the database assigns new ones. A UUID primary key the server does not fill gets a new UUID instead. -- **Delete**: select rows by their row numbers (`Shift`-click for a range, `Cmd`-click for separate rows) and press `Delete`. They stay visible with a strikethrough, and saving asks "Delete 5 rows from customers?" before they go. -- **Paste** on the right-click menu inserts copied rows as new rows, with a new UUID in a UUID primary key the server does not fill. +- **Delete**: select rows by their row numbers (`Shift`-click for a range, `Cmd`-click for separate rows), or cells in them, and press `Delete` or `Forward Delete`. They stay visible with a strikethrough, and saving asks "Delete 5 rows from customers?" before they go. +- **Paste** (`Cmd+V`, or **Paste** on the right-click menu) inserts copied rows as new rows, with a new UUID in a UUID primary key the server does not fill. - **Fill Column** on the header right-click menu writes one value, NULL, or a new UUID or UUIDv7 per row into every loaded row. It is absent on primary key columns and on columns the server owns. A new row starts at `DEFAULT` in every column the server fills in. That covers a column with a default expression, and an identity or `AUTO_INCREMENT` column, which carries no default of its own. The INSERT leaves those columns out, so the server assigns them. diff --git a/features/data-files.mdx b/features/data-files.mdx index d5bd6fd1..a05aba6f 100644 --- a/features/data-files.mdx +++ b/features/data-files.mdx @@ -47,15 +47,15 @@ A comparison is numeric whenever the cell and the value both read as numbers, so Right-click a cell and choose **Filter** to add a condition built from its value. The **Search All Columns** field in the toolbar keeps the rows where any column contains the text, ignoring case and accents, and works alongside the filter bar. -Click a column header to sort by it, and `Shift`-click another header to add a tie-breaker. Numbers sort by value, text sorts naturally so `Item 2` comes before `Item 10`, and blank cells always sort last. +Click a column header to sort by it and click it again to reverse it; `Option`-click another header to add a tie-breaker. Numbers sort by value, text sorts naturally so `Item 2` comes before `Item 10`, and blank cells always sort last. Changing a filter, the search or the sort goes back to page 1. ## Find and replace -`Cmd+F` opens the find bar and `Cmd+Option+F` opens it with a replace field. It searches every row in the file, not the current page, and counts the matches as `3 of 1,204`. `Return` or `Cmd+G` moves to the next match and reveals it; `Cmd+Shift+G` goes back. +`Cmd+F` opens the find bar and `Cmd+Option+F` opens it with a replace field. It searches every row in the file, not the current page, and counts the matches as `3 of 1,204`. `Return` or `Cmd+G` moves to the next match and selects it; `Shift+Enter` or `Cmd+Shift+G` goes back, and `Escape` closes the bar. -The options menu beside the field turns on **Match Case**, **Whole Words** and **Regular Expression**. With a regular expression, `$1` in the replacement inserts the first capture group. +The options menu beside the field turns on **Match Case**, **Whole Words** and **Regular Expression**, and **Search In** limits the search to one column. With a regular expression, `$1` in the replacement inserts the first capture group. **Replace All** changes every match in one step, so one `Cmd+Z` puts all of them back. To search one column, right-click its header and choose **Replace in Column…**. Hidden columns are not searched. diff --git a/features/data-grid.mdx b/features/data-grid.mdx index e5b2e1f5..efc302df 100644 --- a/features/data-grid.mdx +++ b/features/data-grid.mdx @@ -14,13 +14,15 @@ A narrow window trims that bar rather than cutting it off. The Columns and Filte ## Sorting -Click a header to cycle through the first direction, its opposite, and off. `Shift`-click a second header to sort by both. Sorting re-runs the query with a new `ORDER BY`, so it orders the whole table rather than the page in front of you. In a query tab that query is the one statement behind the result, never the rest of the script. +Click a header to sort by that column, and click it again to reverse the order. `Option`-click another header to add it as a further sort key, or `Option`-click a key already in the sort to reverse that one alone. A plain click always starts over with the column you clicked. Sorting re-runs the query with a new `ORDER BY`, so it orders the whole table rather than the page in front of you. In a query tab that query is the one statement behind the result, never the rest of the script. + +The arrow marks the first sort key. With more than one key, point at a header to see where that column falls in the order. **Don't Sort** in the header menu returns to the server's order and stays there. A Cassandra, ScyllaDB or Bigtable table has no header sort, and a query result there sorts the rows it holds. See [Cassandra](/databases/cassandra#browsing-and-editing) and [Bigtable](/databases/bigtable#browsing-tables). **Sort direction** in [Settings > Data](/customization/data-settings) decides which way that first click goes. It is Ascending out of the box; set it to Descending to open on the newest rows and reach them in one click. -To sort on open, set **Default row sort** to **Primary key** or **First column**; out of the box the order is the server's. That order is marked with a dimmed arrow rather than the solid one a click leaves, so a table you have not sorted does not look sorted. Clicking the same header reverses it, and **Don't Sort** in the header menu returns to the server's order and stays there. +To sort on open, set **Default row sort** to **Primary key** or **First column**; out of the box the order is the server's. A sort the setting applies carries the same arrow as one you clicked, and clicking that header reverses it. Sorting on a `BLOB`, `JSON`, or spatial column the server cannot order on fails the query. Sort on another column, or set **Default row sort** back to the engine's order. @@ -32,7 +34,7 @@ The header menu carries two filters that answer different questions. | Header menu item | What it filters | |---|---| -| **Filter Values…**, or the funnel icon on hover | The rows already loaded, without a re-query | +| **Filter Values…** | The rows already loaded, without a re-query. A filtered column shows a funnel after its name | | **Filter with column** | The whole table. It adds a row to the [filter bar](/features/filtering) and opens it | The cell menu has a third: **Filter** turns the clicked cell's value into a condition such as `status = “paid”` and runs it against the whole table. [Filter by cell value](/features/filtering#filter-by-cell-value) lists what it offers. @@ -67,15 +69,17 @@ Rules belong to the table, scoped to the connection, database, and schema, and f Drag a border to resize a column, or double-click it to fit the content; **Size to Fit** and **Size All Columns to Fit** on the header menu do the same. A fitted column stops at half the visible grid width. +Point at a header for the column's type and, with **Show object comments** on in [General settings](/customization/general-settings), its comment. + Hide columns from the columns button in the status bar or from the header menu. A hidden column is not fetched, so hiding a large one makes the table load faster; the primary key and the sorted column are fetched either way. On a schemaless store the popover lists every field the grid can draw, including ones that turn up only in later documents. Widths, order, hidden and frozen columns are remembered per table, scoped to the connection, database, and schema; **Reset Columns** in the popover puts them back. Right-click a header and choose **Display As** to read a column's stored values in a different form; [Cell and Row Viewers](/features/json-viewer) lists the formats. ### Freeze columns -Right-click a column's header and choose **Freeze Up to This Column** to hold it and every column before it beside the row numbers. The rest scroll under them, and a line marks where the frozen columns end. Select, copy, edit, and jump to a frozen column as to any other. **Unfreeze Columns** on the header menu lets them scroll again. +Right-click a column's header and choose **Freeze Up to This Column** to hold it and every column before it beside the row numbers. The rest scroll under them, and a line marks where the frozen columns end. Select, copy, edit, find and jump to a frozen column as to any other. **Unfreeze Columns** on the header menu lets them scroll again. -Frozen columns cover at most two thirds of the grid's width. The menu item is dimmed for a column that would freeze more, and frozen columns that no longer fit after the window narrows scroll until it widens again. Click a frozen header to sort it, or drag its edge to resize it, at any scroll position. To move a frozen column, scroll back to the first column and drag its header. On a query result they stay frozen until the tab closes or the app quits. +Frozen columns cover at most two thirds of the grid's width. The menu item is dimmed for a column that would freeze more, and frozen columns that no longer fit after the window narrows scroll until it widens again. Sort, resize and reorder frozen columns from their own headers at any scroll position. A drag keeps a column on its side of the line, so freeze or unfreeze to move one across. On a query result they stay frozen until the tab closes or the app quits. ### Large binary values @@ -135,7 +139,9 @@ With no row selected and a table open, the inspector shows that table's size, ro ## Find in the loaded rows -`Cmd+F` opens the find bar above the grid. `Return` and `Cmd+G` step forward, `Cmd+Shift+G` back, `Escape` clears the term and then closes the bar. Matching ignores case and accents and runs over the text as displayed; spatial columns are skipped, and so is a binary column still showing hex. The counter says which rows were searched: +Press `Cmd+F` to open the find bar above the grid that has focus, or `Cmd+Option+F` to open it with a replace field. The first match after the cell cursor becomes the selected cell, so `Cmd+C`, `Return` and the arrow keys act on it. `Return` and `Cmd+G` step forward, `Shift+Enter` and `Cmd+Shift+G` step back, and `Escape` closes the bar and hands the keyboard back to the grid. `Cmd+E` searches for the value of the selected cell. Query results and the Structure lists have the same bar. In a query tab, click into the result first: with the editor focused, `Cmd+F` searches the SQL. + +Matching runs over the text as displayed and ignores case and accents. The options menu beside the field turns on **Match Case**, **Whole Words** and **Regular Expression**, each of which matches accents exactly, and **Search In** limits the search to one column. Spatial columns are skipped, and so is a binary column still showing hex. The counter says which rows were searched: | What you see | What it means | |---|---| @@ -144,7 +150,9 @@ With no row selected and a table open, the inspector shows that table's size, ro | `No matches` | Every row is loaded and none match | | `Not on this page` | None of the loaded rows match, and more rows exist | -**Search All Rows** turns the term into a filter that runs at the database, covering the whole table. It replaces the tab's filters, so it appears only when none are applied; with a filter set, add the term to the filter bar instead. Cassandra and ScyllaDB cannot match any one of several columns, so it never appears there. +When none of the loaded rows match and more rows exist, **Search All Rows** in the bar turns the term into a filter that runs at the database, covering the whole table. It replaces the tab's filters, so it appears only when none are applied; with a filter set, add the term to the filter bar instead. Cassandra and ScyllaDB cannot match any one of several columns, so it never appears there. + +In an editable table, select **Replace** in the bar to show the replacement field. **Replace** changes the current match and moves to the next; **Replace All** changes every match in the loaded rows as one step, so one `Cmd+Z` puts all of them back, and the bar says how many cells changed. With a regular expression, `$1` in the replacement inserts the first capture group. Replace works on the stored value, so a match that exists only in a **Display As** form is left alone, and so is a cell you could not type into. Replacements wait in the queue like any edit until you save. ## Pages and row counts @@ -168,16 +176,21 @@ Saving edits, importing rows, **Insert Document…**, a structure change and **R ## Copying -Click a cell to select it, drag or `Shift`-click for a range, and `Cmd`-click to add or remove a cell. Click a row number for a whole row. For a whole column, `Cmd`-click its header or right-click the header and choose **Select Column**; a plain click on a header sorts. The row-number gutter stays at the left edge on a table wider than the window, so whole rows are still selectable when the columns have scrolled past it. `Shift+Space` widens whatever is selected to every row it touches. Copy acts on the whole selection. +Click a cell to select its row and put the cell cursor on that cell. Drag or `Shift`-click for a range of cells, and `Cmd`-click to add or remove a cell. Click a row number to select a whole row; drag down the row numbers, or `Shift`-click or `Cmd`-click them, for several. `Cmd+A` selects every row and leaves no cell cursor. `Escape` shrinks a range of cells to the cursor's row, and a second `Escape` clears the selection. + +For a whole column, `Cmd`-click its header or right-click the header and choose **Select Column**; `Cmd`-`Shift`-click another header to take every column between the two. A plain click on a header sorts. The row numbers stay at the left edge on a table wider than the window, so whole rows are still selectable when the columns have scrolled past them. `Shift+Space` widens whatever is selected to every row it touches. + +The selection draws in your Accent color, and the cell the cursor is on carries a focus border. A right-click never changes the selection: inside it, the menu acts on the whole selection; outside it, on the cell or row you clicked. + +After a plain click on a cell, `Cmd+C` copies the value of the cell under the cursor. Rows selected by their row numbers or with `Cmd+A` copy in the **Copy rows as** format from [Settings > Data](/customization/data-settings#copying). A range of cells copies as tab-separated cells. | Shortcut | Copies | |---|---| -| `Cmd+C` | A cell range as cells, a clicked cell as its value, selected rows in the **Copy rows as** format | | `Cmd+Shift+C` | The selected rows as TSV | | `Cmd+Option+C` | The same, with a header row | | `Cmd+Option+J` | The selected rows as JSON | -**Copy rows as** in [Settings > Data](/customization/data-settings#copying) sets what `Cmd+C` writes for whole rows, picked by their row numbers or with `Cmd+A`: TSV, TSV with Headers, JSON, CSV, CSV with Headers or Markdown. Whatever the format, `Cmd+V` in a table pastes the copied rows, not the text. To copy one value out of a selection, choose **Edit > Copy Special > Copy Cell Value** for the cell the cursor is on, or **Copy Cell Value** in the right-click menu for the cell under the pointer. +**Copy rows as** offers TSV, TSV with Headers, JSON, CSV, CSV with Headers and Markdown. Whatever the format, `Cmd+V` in a table pastes the copied rows, not the text. To copy one value out of a selection, choose **Edit > Copy Special > Copy Cell Value** for the cell the cursor is on, or **Copy Cell Value** in the right-click menu for the cell under the pointer. Right-click and open **Copy as** for CSV, CSV with Headers, Markdown, and **IN Clause**, which writes `('a', 'b', 'c')` for a `WHERE col IN (…)`. **INSERT Statement(s)** and **UPDATE Statement(s)** appear when the result comes from a single table whose structure has loaded, and never on MongoDB or Redis. UPDATE is also missing on a table without a primary key that has a column no match can compare, such as a SQL Server `sql_variant`. **Copy Column Values** on the header menu copies one column, one value per line. Every format is also in **Edit > Copy Special**, where IN Clause takes the one column a cell selection covers, or the cursor's column. Those items have no shortcut until you record one in **Settings > Keyboard**. @@ -231,7 +244,7 @@ SQL Server, Oracle, SpatiaLite, Teradata, Trino, Presto, Spanner, Cassandra and ## Editing and display -Double-click a cell to edit it. A long value stays on one line and scrolls sideways rather than wrapping into the column's width. Nothing reaches the database until you save, and [Change Tracking](/features/change-tracking) covers the type-specific editors, the row operations, and what a Save runs. +Double-click a cell, or press `Return` on it, to edit it in place. A value that holds a line break, or runs past 256 characters, opens in a larger editor anchored to the cell instead: `Return` saves, `Option+Enter` starts a new line and `Escape` cancels. `Option+Enter` while editing in the cell moves the text into that editor. In a grid you cannot edit, the same gestures open the value in a viewer. Nothing reaches the database until you save, and [Change Tracking](/features/change-tracking) covers the type-specific editors, the row operations, and what a Save runs. With the grid focused, `Cmd+=` and `Cmd+-` make its text bigger or smaller. They change the Data Grid Font size in [data settings](/customization/data-settings), so every grid, the inspector and the cell popovers follow, and the size is kept between launches. diff --git a/features/keyboard-shortcuts.mdx b/features/keyboard-shortcuts.mdx index 2b34b8a5..7db6ecbd 100644 --- a/features/keyboard-shortcuts.mdx +++ b/features/keyboard-shortcuts.mdx @@ -93,8 +93,11 @@ Every row except the five find rows is built into the editor and cannot be rebou | Action | Shortcut | |--------|----------| -| Move between cells | Arrow keys | -| Next / previous cell | `Tab` / `Shift+Tab` | +| Move the cursor one cell left or right | `Left` / `Right` | +| Select the row above or below, keeping the cursor's column | `Up` / `Down` | +| Move to the first or last column | `Cmd+Left` / `Cmd+Right` | +| Next / previous cell, on to the next row at the end of one | `Tab` / `Shift+Tab` | +| Jump to the row whose value in the cursor's column starts with what you type | Type its first letters | | Jump to column | `Cmd+Shift+J` | | Scroll to first / last row | `Home` / `End` | | Scroll page up / down | `Page Up` / `Page Down` | @@ -102,16 +105,16 @@ Every row except the five find rows is built into the editor and cannot be rebou | Extend selection to grid edge | `Cmd+Shift+Arrow` | | Select every row the selection touches | `Shift+Space` | | Select all | `Cmd+A` | -| Clear selection | `Escape` | +| Shrink a range of cells to the cursor's row, then clear the selection | `Escape` | ### Editing | Action | Shortcut | |--------|----------| -| Edit cell | `Enter` | -| Edit the next / previous cell | `Tab` / `Shift+Tab` | -| Edit the cell above / below | `Up` / `Down` | -| Insert a line break while editing | `Option+Enter` | +| Edit cell | `Return` or `Enter` | +| Save and edit the next / previous cell | `Tab` / `Shift+Tab` | +| Save and edit the cell above / below | `Up` / `Down` | +| Open the multi-line editor while editing, or start a new line in it | `Option+Enter` | | Cancel edit | `Escape` | | Add row | `Cmd+Shift+N` | | Duplicate row | `Cmd+Shift+D` | @@ -119,14 +122,15 @@ Every row except the five find rows is built into the editor and cannot be rebou | Set Value to Empty, NULL or Default | none by default, rebindable | | Set Cells to Value… | none by default, rebindable | | Generate UUID, Generate UUIDv7 | none by default, rebindable | -| Delete selected rows | `Delete` or `Cmd+Delete` | +| Delete selected rows | `Delete`, `Forward Delete` or `Cmd+Delete` | | Truncate table (tables selected in the sidebar) | `Option+Delete` | | Preview FK reference | `Space` | +| Include or leave out the selected rows (Compare & Sync) | `Space` | | Commit changes | `Cmd+S` | | Undo change | `Cmd+Z` | | Redo change | `Cmd+Shift+Z` | -`Tab`, `Shift+Tab`, `Up` and `Down` save the cell before they move. In a value that holds line breaks, `Up` and `Down` move the insertion point between its lines and leave the cell only from the first or last one. +`Tab`, `Shift+Tab`, `Up` and `Down` save the cell before they move. In the multi-line editor, `Up` and `Down` move between its lines and leave it only from the first or last one, `Return` saves, and a click outside it saves too. Truncate table opens a dialog with **Cascade** and **Ignore foreign key checks**, then stages a pending truncate that `Cmd+S` runs. @@ -159,8 +163,10 @@ Truncate table opens a dialog with **Cascade** and **Ignore foreign key checks** | Action | Shortcut | |--------|----------| | Find | `Cmd+F` | +| Find and replace | `Cmd+Option+F` | | Next match | `Return` or `Cmd+G` | -| Previous match | `Cmd+Shift+G` | +| Previous match | `Shift+Enter` or `Cmd+Shift+G` | +| Find the selected cell's value | `Cmd+E` | | Close the find bar | `Escape` | | Toggle filter bar (table tab) | `Cmd+Shift+F` | | Apply filters | `Cmd+Enter` | @@ -308,8 +314,8 @@ In [Open Quickly](/features/open-quickly), `Ctrl+J`/`Ctrl+N` and `Ctrl+K`/`Ctrl+ |--------|----------| | Find in the file | `Cmd+F` | | Find and replace in the file | `Cmd+Option+F` | -| Next match | `Cmd+G` | -| Previous match | `Cmd+Shift+G` | +| Next match | `Return` or `Cmd+G` | +| Previous match | `Shift+Enter` or `Cmd+Shift+G` | | Show or hide the filter bar | `Cmd+Shift+F` | | Show or hide Row Details | `Cmd+Option+I` | | Switch first row between header and data | `Cmd+Shift+H` | diff --git a/features/table-structure.mdx b/features/table-structure.mdx index a0f05618..e94c3842 100644 --- a/features/table-structure.mdx +++ b/features/table-structure.mdx @@ -14,7 +14,7 @@ This is a DDL editor with a grid in front of it. Rename a column, add an index, Open a table and switch the result view to **Structure**, or right-click it in the sidebar and choose **Show Structure**. -The tabs are **Columns**, **Indexes**, **Foreign Keys**, **Constraints**, **Triggers**, **DDL**, and **Parts** (ClickHouse only); the first five carry item counts. A tab the engine has no concept of is hidden: ClickHouse has no Foreign Keys, Redshift no Triggers, Redis no Constraints. Every grid has a filter field, and clicking a header sorts. +The tabs are **Columns**, **Indexes**, **Foreign Keys**, **Constraints**, **Triggers**, **DDL**, and **Parts** (ClickHouse only); the first five carry item counts. A tab the engine has no concept of is hidden: ClickHouse has no Foreign Keys, Redshift no Triggers, Redis no Constraints. Every grid has a filter field, and clicking a header sorts by that one column. ## Table comment @@ -93,7 +93,7 @@ Add a column with **+** at the right of the status bar or `Cmd+Shift+N`. Select Flag **Primary Key** on one column, or several for a composite key in one `PRIMARY KEY (col1, col2)` clause. On an existing table that becomes a drop of the old constraint followed by an add. -Drag a column row to reorder it, or right-click one and choose **Move Column Up** or **Move Column Down**. Both are dimmed with the reason spelled out under them while unsaved changes exist, while the list is filtered or sorted, on anything but a table, and on an engine that cannot change column order. +Drag a column row by its row number to reorder it, or right-click one and choose **Move Column Up** or **Move Column Down**. Both are dimmed with the reason spelled out under them while unsaved changes exist, while the list is filtered or sorted, on anything but a table, and on an engine that cannot change column order. What the drag does depends on the engine: From 176ae014ae0dc23cfa66cf26ebea9b4b86aa007a Mon Sep 17 00:00:00 2001 From: Ngo Quoc Dat Date: Mon, 26 Oct 2026 02:08:15 +0700 Subject: [PATCH 2/2] docs(appearance): themes color the data grid header and selection again --- customization/appearance.mdx | 19 +++++++++---------- features/data-grid.mdx | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/customization/appearance.mdx b/customization/appearance.mdx index e0aa77c2..12cbb5c8 100644 --- a/customization/appearance.mdx +++ b/customization/appearance.mdx @@ -18,7 +18,7 @@ A theme colors content: the SQL editor and every other code view, the data grid, Its window background fills the area behind those panes on every macOS version. On macOS 26 and later it is also the window color of the main window, data file windows, Compare & Sync and value viewers, and the sidebar, inspector, toolbar and title bar take on its tone through the system glass. Before macOS 26 the sidebar and toolbar keep the system look. The bars along the top and bottom of a pane, such as the filter bar, drop their system material while the theme sets a window background, so the theme shows through them. -Controls, Settings, the welcome window, the connection form, sheets and popovers keep the system look and your Accent color, and so do a data grid's header, its selection and the border on the selected cell. A code field inside one of them, such as **Startup Commands**, **Pre-Connect Script**, a favorite's query or the **Startup SQL** of a connection link, takes the editor colors. +Controls, Settings, the welcome window, the connection form, sheets and popovers keep the system look and your Accent color. A code field inside one of them, such as **Startup Commands**, **Pre-Connect Script**, a favorite's query or the **Startup SQL** of a connection link, takes the editor colors. With Increase Contrast on, the window background goes back to the macOS color and the rest of the theme stays. @@ -84,7 +84,7 @@ Each theme opens in a Theme Editor window of its own, titled with the theme's na The preview is the real SQL editor and data grid over sample content, drawn in the theme's own appearance, so a dark theme previews dark on a light Mac. It shows the current line and statement, a selection, invisibles, alternate rows, NULL, booleans, and a modified, an inserted and a deleted row. -Under it, **General** holds the theme's name, its appearance (Light or Dark) and its author. The colors follow in **Window**, **Editor**, **Syntax**, **Data Grid** and **Changes**. +Under it, **General** holds the theme's name, its appearance (Light or Dark) and its author. The colors follow in **Window**, **Editor**, **Syntax**, **Data Grid**, **Selection** and **Changes**. The line under each color's name says where the color comes from: @@ -95,7 +95,7 @@ The line under each color's name says where the color comes from: | **Default Light color** or **Default Dark color** | An unset syntax color, drawn in the default theme's value | | **Based on** and another color's name | Unset, and taken from that color. See [Colors a theme leaves out](#colors-a-theme-leaves-out) | -The arrow beside a color the theme sets clears it, under the name **Use System Color** or **Use Default Color**. The same action is in the color's right-click menu. Opacity is offered only for washes drawn over content: the editor selection, current line, current statement and invisibles, the alternate row, and the four row change colors. +The arrow beside a color the theme sets clears it, under the name **Use System Color** or **Use Default Color**. The same action is in the color's right-click menu. Opacity is offered only for washes drawn over content: the editor selection, current line, current statement and invisibles, the alternate row, both grid selections, and the four row change colors. `Cmd+Z` and `Cmd+Shift+Z` undo and redo, one step per color you drag through the picker. **Revert Changes** at the bottom puts the theme back the way it was when the window opened, and undoes like any other step. @@ -114,10 +114,10 @@ A VS Code color theme imports like any other theme file, from **Import…** or b | Window background | `editorPane.background`, else `editor.background` | | Editor | `editor.background`, `editor.foreground`, `editorCursor.foreground`, `editor.selectionBackground`, `editor.lineHighlightBackground` (else `editor.lineHighlightBorder`), `editor.rangeHighlightBackground` for the current statement, `editorLineNumber.foreground`, `editorWhitespace.foreground` | | Syntax | `tokenColors` rules, matched the way VS Code matches them against the scopes of its SQL grammar. A token no rule colors takes `editor.foreground`, and NULL, when no rule colors it, takes the keyword color | -| Data grid | The editor background and text; `input.placeholderForeground`, else `foreground` at half opacity, for NULL; `editorLineNumber.foreground` for row numbers; `tree.tableColumnsBorder` for grid lines; `keybindingTable.rowsBackground`, else `tree.tableOddRowsBackground`, for alternate rows; booleans from the token rules for SQL `TRUE` and `FALSE` | +| Data grid | The editor background and text; `foreground` for header text; `keybindingTable.headerBackground`, else `tree.tableOddRowsBackground`, for the header; `list.activeSelectionBackground`, `list.activeSelectionForeground` and `list.inactiveSelectionBackground`; `list.focusOutline` or `focusBorder`; `input.placeholderForeground`, else `foreground` at half opacity, for NULL; `editorLineNumber.foreground` for row numbers; `tree.tableColumnsBorder` for grid lines; `keybindingTable.rowsBackground`, else `tree.tableOddRowsBackground`, for alternate rows; booleans from the token rules for SQL `TRUE` and `FALSE` | | Row changes | `diffEditor.insertedLineBackground` and `diffEditor.removedLineBackground`, and the `gitDecoration` modified and deleted colors, made translucent, for modified rows and deleted text | -A color the file does not set stays unset and draws as [Colors a theme leaves out](#colors-a-theme-leaves-out) describes. A translucent window, editor or grid background is flattened over the editor background. +A color the file does not set stays unset and draws as [Colors a theme leaves out](#colors-a-theme-leaves-out) describes. A translucent window, editor, grid or header background is flattened over the editor background. ### What is left out @@ -126,7 +126,6 @@ A color the file does not set stays unset and draws as [Colors a theme leaves ou - `semanticTokenColors` and `semanticHighlighting`. - Rules scoped to other languages, such as `source.json`. Syntax colors are read from SQL scopes only. - Colors TablePro has no place for: the inactive editor selection, selected text in the editor, the active line number, find matches and word highlights. -- List selection, focus outline and table header colors. A grid's header and selection keep the system look in every theme. ### How the file is read @@ -150,7 +149,7 @@ A custom theme is one JSON file in `~/Library/Application Support/TablePro/Theme | `appearance` | `light` or `dark`. Decides which popup lists the theme | | `window` | Window background, under `background` | | `editor` | Editor colors, with syntax colors nested under `syntax` | -| `dataGrid` | Data grid colors, the Changes section of the Theme Editor included | +| `dataGrid` | Data grid colors, the Selection and Changes sections of the Theme Editor included | ```json { @@ -165,11 +164,11 @@ A custom theme is one JSON file in `~/Library/Application Support/TablePro/Theme "text": "#D8DEE9", "syntax": { "keyword": "#81A1C1", "string": "#A3BE8C" } }, - "dataGrid": { "background": "#2E3440", "alternateRow": "#3B4252" } + "dataGrid": { "background": "#2E3440", "selection": "#434C5E" } } ``` -A color is sRGB hex, `#RRGGBB`, or `#RRGGBBAA` for a translucent wash such as the editor selection. The window, editor and data grid backgrounds are always opaque: an alpha value there is dropped. Every color is optional. +A color is sRGB hex, `#RRGGBB`, or `#RRGGBBAA` for a translucent wash such as a selection. The window, editor, data grid and header backgrounds are always opaque: an alpha value there is dropped. Every color is optional. ### Colors a theme leaves out @@ -188,7 +187,7 @@ A file in the themes folder that breaks one of these is listed under **Not Loade - It is not plain JSON. Comments are refused here; a VS Code theme goes through **Import…** instead. - It has no `schema`, or a `schema` other than `3`. A theme file from TablePro 0.80 or earlier needs to be made again. - It lacks `id`, `name` or `appearance`, or a field breaks the rules in the table. -- It holds a key TablePro does not use, or a value that is not a `#RRGGBB` or `#RRGGBBAA` string. The six data grid keys earlier versions wrote for the header and the selection, `headerBackground`, `headerText`, `selection`, `selectionText`, `inactiveSelection` and `focusBorder`, are the exception: a file that has them loads, and those keys are dropped. +- It holds a key TablePro does not use, or a value that is not a `#RRGGBB` or `#RRGGBBAA` string. - Its `id` is one another file in the folder already uses. The first file by name loads. ## Connection colors diff --git a/features/data-grid.mdx b/features/data-grid.mdx index efc302df..b7072282 100644 --- a/features/data-grid.mdx +++ b/features/data-grid.mdx @@ -180,7 +180,7 @@ Click a cell to select its row and put the cell cursor on that cell. Drag or `Sh For a whole column, `Cmd`-click its header or right-click the header and choose **Select Column**; `Cmd`-`Shift`-click another header to take every column between the two. A plain click on a header sorts. The row numbers stay at the left edge on a table wider than the window, so whole rows are still selectable when the columns have scrolled past them. `Shift+Space` widens whatever is selected to every row it touches. -The selection draws in your Accent color, and the cell the cursor is on carries a focus border. A right-click never changes the selection: inside it, the menu acts on the whole selection; outside it, on the cell or row you clicked. +The selection draws in your Accent color, or in the theme's selection color when it sets one, and the cell the cursor is on carries a focus border. A right-click never changes the selection: inside it, the menu acts on the whole selection; outside it, on the cell or row you clicked. After a plain click on a cell, `Cmd+C` copies the value of the cell under the cursor. Rows selected by their row numbers or with `Cmd+A` copy in the **Copy rows as** format from [Settings > Data](/customization/data-settings#copying). A range of cells copies as tab-separated cells.