From 662a9e6300f89eaf590ec9151589634f2ff48d00 Mon Sep 17 00:00:00 2001 From: Jona Date: Mon, 19 Oct 2026 10:01:08 -0400 Subject: [PATCH] Add numeric selection totals to the status bar --- README.md | 200 ++++------------- docs/user-guide.md | 208 ++++++++++++++++++ images/selection-statistics.png | Bin 0 -> 294579 bytes media/main.js | 55 ++++- src/CsvEditorProvider.ts | 68 +++++- src/selection-statistics.ts | 83 +++++++ src/test/default-ignore-rows.test.ts | 8 +- src/test/edit-integrity-harness.ts | 9 + src/test/editor-switch.test.ts | 6 +- src/test/frozen-panes.test.ts | 4 +- src/test/selection-statistics.test.ts | 50 +++++ src/test/webview-navigation-scroll.test.ts | 11 +- src/test/webview-selection-statistics.test.ts | 185 ++++++++++++++++ 13 files changed, 713 insertions(+), 174 deletions(-) create mode 100644 docs/user-guide.md create mode 100644 images/selection-statistics.png create mode 100644 src/selection-statistics.ts create mode 100644 src/test/selection-statistics.test.ts create mode 100644 src/test/webview-selection-statistics.test.ts diff --git a/README.md b/README.md index 6b54e6a..82576c2 100644 --- a/README.md +++ b/README.md @@ -1,195 +1,77 @@ # CSV -View and edit `.csv`, `.tsv`, `.tab`, and `.psv` files as tables in VS Code. CSV supports multiline cells, selection and clipboard operations, column filters, frozen panes, and a text-view switch for working with the underlying file. +**Find the rows that matter. Make the fix. Stay in VS Code.** -Actual CSV table webview with example data, captured in Chromium. +A data export, a test fixture, a lookup table: sometimes you just need to check a few values and fix them. CSV gives you an editable table in the same workspace as your code, with visual filters, selection totals, and cell-by-cell comparisons. Open the file, work on the data, and save. -![CSV table in a dark theme](images/marketplace-dark.png) -![CSV table in a light theme](images/marketplace-light.png) +CSV, TSV, TAB & PSV · No account required -## Open and edit a file +![CSV table with aligned columns, datatype colors, and multiline notes in a dark theme](images/marketplace-dark.png) -Install **CSV** by **ReprEng** from the Extensions view, then open a supported file. CSV opens it as a table unless your editor associations select another editor. The default separators are comma for `.csv`, tab for `.tsv` and `.tab`, and pipe for `.psv`. +## Why choose CSV? -1. Click a cell to select it. Type to start a quick edit, or press Enter or double-click for detail editing. -2. Press Enter or Tab, click outside the cell, or move focus away to commit its text to the VS Code document. In quick edit, arrow keys also commit and move to the adjacent cell. In detail edit, arrows move the text caret; Shift+Enter inserts a line break. -3. Press Ctrl/Cmd+S to commit the active cell and save the document. Committing a cell alone does **not** write the file to disk; VS Code's autosave can save committed document changes if enabled. +Choose CSV when your next step is to **inspect and fix the data in place**. -Escape cancels the active cell draft. If VS Code rejects an edit, its draft stays available: retry it or press Escape to discard it before structural operations, switching views, or disabling the table. Changes remain unsaved until a save succeeds. - -An empty file can be edited immediately. The extra bottom row is an append affordance; entering a value creates source data, while leaving it empty does not. Disable `csv.showTrailingEmptyRow` to hide it. - -CSV declares support for VS Code **1.70 or later**. Saved-file table/text replacement requires **1.100** for clean documents and **1.120** for documents with unsaved changes. Older hosts show update guidance for that action. - -## Select, copy, paste, and arrange data - -Selection is visible as soon as you press the mouse button. Drag or Shift+click to select a range. Click a header to select its column; a second separate click on the same header selects only the header cell. Double-click edits the header. Click the serial index to select a row, or the top-left corner to select the table. Shift+click extends whole-row or whole-column selections. - -Use Ctrl/Cmd+C or X, or the selection's right-click **Copy** or **Cut** action. Clipboard data uses the active separator and quotes each value only when needed, preserving separators, line breaks, literal quotes, surrounding whitespace, and real empty cells. The serial index and extra append row are excluded. Selecting only the append row leaves the clipboard unchanged. Clipboard shortcuts inside cell edits, Find, Replace, and filter inputs keep their normal text-editing behavior. - -Paste with Ctrl/Cmd+V in selection mode or the right-click **Paste** action. A single value fills a selected rectangle; a copied matrix starts at the selection. With filters active, copying, cutting, filling, and matrix paste use matching source rows. Additional pasted rows append at the physical end of the file. Nonmatching rows stay intact, and saving includes the full file. - -Right-click cells to insert or delete rows and columns. Multi-selection actions use the selected count. Drag selected headers or row indices to reorder a column/row or selected group. Right-click a header to sort ascending or descending; with filters active, sorting rearranges matching rows within their source positions and leaves hidden rows in place. These operations change the document and require saving like other edits. Unchanged field quoting and existing line endings are preserved; new values follow a consistent existing column quote style where available. - -Context menus open toward the available space, flip above or left when needed, and scroll in small panes. Resizing the editor or changing CSV zoom dismisses an open menu. - -## Headers, metadata rows, widths, and frozen panes - -- **Header:** Right-click a cell in the first visible source row and choose **Use first row as header** or **Treat first row as data**. Hidden leading metadata is skipped; filtering does not promote an arbitrary matching row to the header. The Command Palette also provides **CSV: Toggle First Row as Header**. -- **Serial index:** Right-click an index cell or its top-left corner and choose **Hide serial index column**. Restore it with **CSV: Toggle Serial Index Column**. The numbers identify source rows and can have gaps while filtering. -- **Metadata:** **CSV: Hide First N Rows** hides leading records without deleting them. Blank input inherits `csv.defaultIgnoreRows`; an explicit `0` shows them even if the configured default is nonzero. -- **Widths:** Automatic column widths account for the longest line in multiline cells. Drag close to a column boundary to resize, including with headers off. Double-click the boundary to restore automatic sizing. Manual widths are remembered per file; narrow columns retain a selectable center. Drag the bottom edge of a serial-index cell to adjust its row height. -- **Word wrap:** Word wrap starts **off** for each file, showing single-line cutoff with an ellipsis. Use the wrap icon beside the table/text switch in the editor title bar to toggle it; hover for **Enable Word Wrap** or **Disable Word Wrap**. Automatic widths remain capped at 100 characters; manual widths and row heights stay intact. Cutoff lets long rows collapse or be resized shorter. The selected cell/range stays selected and its active cell stays in view. Editing always shows the full value, and copying, searching and saving use the complete text. The display choice is remembered with the table's webview state. -- **Frozen panes:** Right-click to freeze through a visible row or data column, or use **CSV: Freeze Leading Rows/Columns**. Enter `0` to unfreeze an axis. Counts are remembered per file. By default, the header stays frozen; with headers off, no rows freeze until requested. Hidden metadata and the append row do not count. Frozen rows follow measured multiline/zoomed heights and paint their divider seams; the serial index stays alongside frozen data columns. - -Header, serial-index, separator, hidden-row, manual-width, and frozen-pane preferences do not change CSV contents and are stored per file URI in VS Code workspace state. Scroll, selection, row heights, and zoom use webview state. Column colors follow the selected datatype palette (`default`, `cool`, or `warm`) or the theme foreground mode. Light, dark, and high-contrast themes retain that choice. CSV's zoom changes the table's text size independently of global editor zoom. - -## Live column filters - -Right-click a data column and choose **Filter this column** to add a condition above the table. Choose a column and operator, then type a value; results update as you type without replacing the focused input. **Add filter** and repeated context actions add conditions, including multiple conditions on the same column. All conditions combine with **AND**. Remove one condition or use **Clear all filters** to remove them all. - -![Two live column conditions combined with AND](images/marketplace-filters.png) - -Every column offers Contains, Does Not Contain, Regular Expression, Equals, Does Not Equal, Is Empty, and Is Not Empty. Number and date columns also offer `>`, `>=`, `<`, and `<=`. Types are inferred from the original body rows, excluding the effective header and hidden metadata, before any filters apply. A text column whose nonblank cells all parse as supported dates also offers date comparisons without changing its column colors. - -- Text comparisons ignore case. Numbers accept finite decimal/scientific values and consistent thousands grouping, and compare without rounding away significant digits. -- Boolean equality accepts `true/false`, `t/f`, `yes/no`, `y/n`, `on/off`, and `1/0`. -- Dates accept ISO/year-first forms, numeric dates with four-digit years, and English month names, with optional times and timezone offsets. Unzoned values use UTC. Ambiguous numeric dates use month/day/year: `03/04/2026` means March 4; `13/04/2026` is unambiguously April 13. Use ISO dates or month names to avoid ambiguity. Supported timestamps compare exactly, including sub-millisecond fractions. -- Regular Expression uses [RE2 syntax](https://github.com/google/re2/wiki/Syntax). Plain patterns ignore case; `/pattern/flags` supports `i`, `m`, and `s`. An explicit empty flag list (`/pattern/`) is case-sensitive. Lookaround and backreferences are unsupported. +| If you currently use: | What CSV will add for you: | +| --- | --- | +| **Editing raw CSV in VS Code** | Work with cells, rows, and columns directly. Paste a block, move a column, or edit a multiline value while CSV handles the separators and escaping. | +| **[Rainbow CSV](https://marketplace.visualstudio.com/items?itemName=mechatroner.rainbow-csv)** for colored columns and SQL-like queries | Use a visual grid with point-and-click filters, range editing, and selection totals. Narrow down a dataset and correct the matching cells without writing a query. | +| **[Edit CSV](https://marketplace.visualstudio.com/items?itemName=janisdd.vscode-edit-csv)** for a grid with an Apply workflow | Cell edits commit directly to the VS Code document, source edits refresh the table, and Ctrl/Cmd+S saves. Switch between table and text as the task changes. | -A zero-length value leaves a draft condition inactive, except Is Empty/Is Not Empty, which need no value. Literal spaces are valid text searches. Invalid or incomplete values show an inline error and retain the last valid results. Blank or invalid cell values do not match typed comparisons, including Does Not Equal; use Is Empty for empty cells. Incomplete IME text is not applied automatically after a view refresh. +## Find the few rows that need attention -Filtering scans the full editable document, retains source row identities, and does not delete source rows. Valid conditions are remembered per file and can contain sensitive data; see [Privacy and data handling](PRIVACY.md). Blank or invalid drafts are not persisted. +An export has thousands of rows; you need the overdue orders, missing IDs, or unusually large amounts. Right-click a column, choose **Filter this column**, and build the conditions visually. Results update as you type. Combine text, number, date, and empty-cell conditions across columns, or use a regular expression when you need one. -## Find, native search, and text view +Filters search the full editable document, including rows beyond the screen. Copy the matches, fill a selected range, or use Find and Replace to clean them up. **Filtering keeps the other rows in your file**, and range operations on the filtered view leave nonmatching rows intact. -Ctrl/Cmd+F opens table Find; Ctrl/Cmd+H opens Find and Replace. Match case, whole-word, regular expression, selection-only search, and single/all replacement are available. Table Find includes later chunks. With filters active, Find and Replace All use matching displayed rows and the header; hidden metadata and nonmatching rows are excluded. +![CSV narrowing a table with two live column filters combined with AND](images/marketplace-filters.png) -Ctrl/Cmd+Shift+F and Ctrl/Cmd+Shift+H remain VS Code's native Find/Replace in Files shortcuts. Alt-modified variants also stay outside the table overlay. +## Make one correction or clean up a whole range -Use the toolbar switch or **CSV: Switch Between Table and Text** to edit the same document as source text. For saved files, the target opens before the source view is replaced, so one representation remains in that editor group. Live cell edits commit first, unsaved changes remain unsaved, and unrelated tabs/groups are retained. If the file already has a table in another group, switch from that group. +Click a cell and type. Tab to the next one. Paste a block of data, fill a rectangle with one value, or drag selected rows and columns into the order you need. Right-click to insert, delete, or sort. -For a saved local `file:` URI without an authority, query, or fragment, choosing Text also installs a reversible file-path editor association. Native Find in Files can then open that file in text at the selected result while CSV remains enabled. The choice survives restart and Off/On; switching successfully back to Table restores only CSV's owned association. Other files keep their normal editor choice. Intervening user choices are preserved. Patterns use VS Code's case-insensitive matching, so case-distinct paths are not independently isolated. CSV reports longer/conflicting associations or settings restrictions that prevent native routing. +For long notes, double-click to edit the full value and use Shift+Enter for line breaks. CSV handles quoted separators and multiline cells, so you can concentrate on the content. Familiar copy, cut, paste, Find, and Replace shortcuts work in the table. -**Search boundary:** this does not add native search navigation inside a table. A cold search into a file still associated with the table may open the table without revealing the match. Remote/virtual URIs that cannot be isolated by these patterns can switch views, but need CSV turned off for native text search routing. **CSV: Toggle Extension On/Off** temporarily routes CSV's four selectors and explicit CSV associations to native text while off, then restores owned preferences when enabled again. It honors an explicit workspace `csv.enabled` value, otherwise it toggles the global value. Re-enabling upgrades the invoking saved text tab when its restored editor choice is CSV; other already-open text tabs keep their current view until reopened or explicitly switched. +## Check totals without writing a formula -## Untitled CSV and TSV +Select numeric cells and read **Sum, Average, and Count** in the VS Code status bar. Check a column total, compare a group of values, or sanity-check a filtered export without opening a spreadsheet or writing a script. -Choose CSV or TSV language mode in a new untitled text document to open a table before saving. The native text tab remains its unsaved owner. Switching the table to text commits the live cell and closes only the temporary table; switching back recreates a table against that same document. Language changes preserve pending edits before refreshing the table. +Totals follow your selection and committed edits. With filters active, they include only matching data rows; whole-column selections also include matching rows beyond the screen. Count is the number of selected numeric cells, with text, blanks, and headers excluded. -Use the table toolbar's **Save Untitled Document As…** action or Ctrl/Cmd+S in selection or editing mode. CSV commits the active cell, reveals the native owner, and invokes VS Code's normal Save As flow. The temporary table closes when the untitled document becomes a saved file. Cancelling Save As retains the unsaved owner and table. Native **File > Save** cannot directly target a standalone table panel; switch to text before using that native action. +## Keep your changes easy to review -Separator, header, serial-index, metadata, and filter controls work before saving. File encoding can be changed after saving. Untitled documents are not switched with the saved-file native replacement operation because associated-path untitled buffers require their existing owner. +A small data fix should be easy to spot in version control. CSV preserves unchanged field quoting and existing line endings, so surrounding formatting stays intact. Datatype detection helps with colors and filters while stored values remain text: an ID such as `00123` keeps its leading zeros. -## Large File Preview +Use the title-bar switch to inspect or edit the same document as raw text, then return to the table. Pending changes stay unsaved until you save, or VS Code autosave saves committed edits. -The normal editable view uses a full VS Code text document; chunked rendering does not bound source-memory use. To inspect a very large saved file without first allocating that document, right-click it in Explorer and choose **CSV: Open Large File Preview (Read-only)**, or run that command and pick a file. Opening the preview after an editable tab does not undo memory already allocated by VS Code. +Need to compare two exports? Select them in Explorer and choose **CSV: Compare Files as Table**. See changed cells side by side, navigate between changes, and keep both panes aligned as you scroll. This read-only comparison is a separate command; use VS Code's text diff for native Git/PR review. [Comparison details and size limits](docs/user-guide.md#compare-two-files-as-tables). -The preview reads bounded saved-file blocks and displays one page at a time. **Next**, **Previous**, and **Back to Start** navigate complete records, including quoted multiline fields. The first record is data. There is no editing, global search, sorting, or filtering, and unsaved edits in another view are not included. +## Keep context as you scroll -It supports valid **UTF-8**, an optional UTF-8 BOM, a single ASCII separator, and host-local `file:` URIs. It reads directly in the extension host; arbitrary remote filesystem-provider URIs and other encodings are unsupported. Use a per-file separator override or `extension`/`default` separator mode; automatic detection without an override produces an actionable error. +Freeze the identifier columns and leading rows you need to keep in sight. Resize columns, toggle word wrap for long notes, or hide leading metadata without deleting it. CSV remembers per-file preferences such as column widths, frozen panes, and filters so you can return to the same working view. -`csv.largeFilePreviewRows` sets a maximum of 1–10,000 records per page (default 1,000). Independent limits are 512 KiB of source records and 20,000 cells per page, 256 KiB per record, and 1,000 columns. Pages may be smaller. Malformed/oversized records produce errors instead of truncated data. Only the current page and up to 32 page positions are retained; **Previous** reaches that retained history. If the saved file changes, use **Back to Start**. +Datatype colors, table zoom, and support for light, dark, and high-contrast themes help you read the data comfortably. [See the light theme](images/marketplace-light.png). -## Compare two files as tables +## Try it on your next export -Select two files in Explorer and choose **CSV: Compare Files as Table**, or run the command from an active CSV/text document and select the modified file. With no active source, choose original and modified files. Both panes are read-only and use VS Code's decoded document text, including unsaved edits; editing a source refreshes the comparison. +1. **[Install CSV by ReprEng](https://marketplace.visualstudio.com/items?itemName=ReprEng.csv)** from the VS Code Marketplace, or search for `ReprEng.csv` in Extensions. +2. **Open a `.csv`, `.tsv`, `.tab`, or `.psv` file.** It opens as a table unless you have chosen another editor association. If needed, right-click the editor tab and choose **Reopen Editor With… → CSV**. +3. **Make a change and press Ctrl/Cmd+S.** Click a cell and type, or right-click a column to filter first. Escape cancels the active cell draft. -The comparison aligns records around insertions/deletions, highlights changed cells, and shows placeholders for missing records or fields. Both scroll axes stay synchronized and paired rows share their height. Use **Previous/Next Change** and **Previous/Next Page**. The first record is data; comparison uses parsed values and field presence, not quoting or line-ending formatting. +Working from scratch? Create an untitled document and choose CSV or TSV as its language mode to start a table before saving. Need a different delimiter? Run **CSV: Change CSV Separator**. -The existing `csv.maxFileSizeMB` limit applies. Hard per-input limits are 10 MiB of saved bytes before a new document opens, 5 MiB of decoded text, 10,000 records, 100,000 cells, and 1,000 columns; values are limited to 64 Ki characters and records to 256 Ki characters. A provider without size information must already have the document open. Pages are capped at 200 aligned records, 20,000 body cells, and 512 Ki characters. Oversized/malformed inputs show errors without truncation. Bounded alignment falls back to positional pairing with a visible notice when necessary. +CSV supports VS Code 1.70+. Switching saved files between table and text requires 1.100+, or 1.120+ when there are unsaved changes. [Editing and compatibility details](docs/user-guide.md#open-and-edit-a-file). -This command is a separate table comparison. It does not provide native Git/PR custom-editor diff navigation; stable APIs do not reliably expose both input URIs for that flow. +## Your files stay in your workspace -## File encoding +CSV requires no account or upload service and has no extension-specific analytics client. Processing runs in your VS Code environment, including the remote extension host when you use a remote workspace. [Privacy and data handling](PRIVACY.md). -Editable views use Unicode text decoded by VS Code. Run **CSV: Change File Encoding**, choose **Reopen with Encoding**, and select the original file's encoding to correct incorrectly displayed characters. Check the text before saving. Cancelling the unsaved-changes prompt stops the command without discarding your edits. **Save with Encoding** changes how the current text is written; it cannot repair characters already decoded incorrectly. Use the original file or a backup if a corrupted version was saved. +For a very large saved file, use **CSV: Open Large File Preview (Read-only)** from Explorer to inspect it a page at a time. The preview reads bounded blocks of host-local UTF-8 files; normal editing loads the full document. [Preview capabilities and limits](docs/user-guide.md#large-file-preview). -A nonmodal warning appears once per opened document containing the replacement character `�`, offering the encoding action. This is a possible decoding mismatch, not automatic encoding detection: `�` can be legitimate text, and other incorrect decodings may not produce it. CSV does not guess, transcode, or repair bytes automatically. The read-only preview's UTF-8 restriction is separate from this editable-view workflow. +**Ready to make your next CSV fix in place? [Install CSV](https://marketplace.visualstudio.com/items?itemName=ReprEng.csv).** -## Commands +## Help and reference -Run these from the Command Palette. Commands that change a view preference target the active CSV table unless noted. +[User guide](docs/user-guide.md) · [Keyboard shortcuts](docs/user-guide.md#keyboard-and-mouse-reference) · [Commands](docs/user-guide.md#commands) · [Settings](docs/user-guide.md#settings) · [Changelog](CHANGELOG.md) · [Report an issue](https://github.com/jonaraphael/csv/issues) -| Command | Purpose | -| --- | --- | -| **CSV: Switch Between Table and Text** (`csv.toggleEditor`) | Switch the active supported table/text view. | -| **CSV: Enable/Disable Word Wrap** (`csv.enableWordWrap` / `csv.disableWordWrap`) | Toggle wrapping in the active editable table; also available beside the table/text switch. | -| **CSV: Save Untitled Document As…** (`csv.saveUntitled`) | Commit and save the active untitled table through the native owner. | -| **CSV: Toggle Extension On/Off** (`csv.toggleExtension`) | Enable/disable CSV and synchronize native editor routing. | -| **CSV: Toggle First Row as Header** (`csv.toggleHeader`) | Change the file's header preference. | -| **CSV: Toggle Serial Index Column** (`csv.toggleSerialIndex`) | Show/hide the file's serial index. | -| **CSV: Change CSV Separator** (`csv.changeSeparator`) | Override the separator; blank input inherits configured rules. Enter `\t` for tab. | -| **CSV: Reset CSV Separator (Inherit)** (`csv.resetSeparator`) | Clear the file's separator override. | -| **CSV: Hide First N Rows** (`csv.changeIgnoreRows`) | Override the metadata-row count; blank input inherits the default. | -| **CSV: Freeze Leading Rows** (`csv.changeFrozenRows`) | Set the number of leading visible rows to freeze; `0` unfreezes. | -| **CSV: Freeze Leading Columns** (`csv.changeFrozenColumns`) | Set leading data columns to freeze; `0` unfreezes. | -| **CSV: Change File Encoding** (`csv.changeEncoding`) | Open VS Code's encoding picker for a saved file. | -| **CSV: Change Font Family** (`csv.changeFontFamily`) | Pick an extension-host font or inherit `editor.fontFamily`. | -| **CSV: Toggle Clickable Links** (`csv.toggleClickableLinks`) | Toggle link interaction globally. | -| **CSV: Open Large File Preview (Read-only)** (`csv.openLargeFilePreview`) | Open a saved host-local file in the bounded preview. | -| **CSV: Compare Files as Table** (`csv.compareFilesAsTable`) | Choose two source files for read-only table comparison. | - -## Settings - -All settings are under `csv.*` in VS Code Settings or `settings.json`. Font and mouse-wheel zoom settings are application-scoped. Per-file commands override the relevant inherited view defaults. - -| Setting | Default | Behavior | -| --- | --- | --- | -| `csv.enabled` | `true` | Enable the custom editor; the toggle command also manages reversible native routing. | -| `csv.fontFamily` | `""` | Inherit `editor.fontFamily`, or use the specified font family. | -| `csv.fontSize` | `0` | Inherit `editor.fontSize`, or use a positive pixel size. | -| `csv.mouseWheelZoom` | `true` | Allow Ctrl/Cmd+mouse wheel table zoom. | -| `csv.mouseWheelZoomInvert` | `false` | Reverse the table zoom direction. | -| `csv.cellPadding` | `4` | Vertical cell padding in pixels. | -| `csv.columnColorMode` | `"type"` | `type` uses datatype colors; `theme` uses theme foreground. | -| `csv.columnColorPalette` | `"default"` | `default`, `cool`, or `warm` when color mode is `type`. | -| `csv.diffUseThemeForeground` | `true` | Use theme foreground for CSV views recognized as diff contexts. | -| `csv.clickableLinks` | `true` | Enable Ctrl/Cmd+click on recognized links. | -| `csv.showTrailingEmptyRow` | `true` | Show the extra append row. | -| `csv.separatorMode` | `"extension"` | `extension` uses extension mapping, `auto` detects from content first, `default` uses the configured default. Per-file overrides take precedence. | -| `csv.defaultSeparator` | `","` | Fallback separator. Use `"\t"` in JSON for a tab character, or `"\\t"` for the supported literal escape. | -| `csv.separatorByExtension` | CSV comma; TSV/TAB tab; PSV pipe | Extension mapping; keys accept `.ext` or `ext`. | -| `csv.maxFileSizeMB` | `10` | Editable-view size prompt. `0` disables it; **Ignore Forever** sets it to `0`. This is not a memory cap. | -| `csv.defaultIgnoreRows` | `0` | Hidden leading metadata records when no per-file override exists. | -| `csv.largeFilePreviewRows` | `1000` | Preview records per page, from `1` to `10000`, subject to byte/cell caps. | - -Header mode, serial-index visibility, separator overrides, hidden rows, widths, frozen panes, and valid filter conditions are remembered per file. They change the view, except operations such as sorting, editing, and structural changes that explicitly modify document data. - -## Keyboard and mouse reference - -Ctrl/Cmd means Ctrl on Windows/Linux and Command on macOS. Table shortcuts apply outside text inputs unless noted. - -| Action | Shortcut or gesture | -| --- | --- | -| Select a cell/range | Click / drag / Shift+click | -| Select a row or column | Click its serial index or header; Shift+click extends the range | -| Select only a header cell | A second separate click on the same header | -| Select the table | Ctrl/Cmd+A, or click the top-left corner | -| Move selection | Arrow keys; holding a key keeps the target visible | -| Extend selection | Shift+Arrow | -| Jump to a table edge | Ctrl/Cmd+Arrow | -| Extend to an edge | Ctrl/Cmd+Shift+Arrow, retaining the starting anchor and row/column shape | -| Next/previous cell | Tab / Shift+Tab; wraps across data rows | -| Quick edit | Type on a selected cell; arrows commit and move | -| Detail edit | Enter or double-click; arrows move the caret | -| Commit and move while editing | Enter moves down; Tab/Shift+Tab moves across | -| Insert a cell line break | Shift+Enter | -| Cancel a draft | Escape; a failed edit restores its current source value | -| Save | Ctrl/Cmd+S commits the active cell, then saves (Save As for untitled) | -| Copy / cut / paste | Ctrl/Cmd+C / X / V, or right-click actions | -| Clear selected values | Delete / Backspace | -| Table Find / Replace | Ctrl/Cmd+F / H | -| Native Find / Replace in Files | Ctrl/Cmd+Shift+F / H | -| Next/previous Find match | F3 / Shift+F3; Enter/Shift+Enter in Find; Ctrl/Cmd+G/Shift+G while Find is open | -| Resize / reset a column | Drag / double-click near its boundary | -| Resize a row | Drag the bottom edge of its serial-index cell | -| Reorder rows/columns | Drag selected serial indices/headers | -| Zoom in / out / reset | Ctrl/Cmd+plus / minus / 0; Ctrl/Cmd+mouse wheel if enabled | -| Open a recognized link | Ctrl/Cmd+click | - -## Privacy and development - -See [Privacy and data handling](PRIVACY.md) for local/remote processing, clipboard and link actions, diagnostics, and saved preferences. CSV has no upload service or extension-specific analytics client. Remote workspaces can process files in the remote extension host. - -For development, use Node 20 and run `npm ci`, `npm test`, and `npm run lint`. `npm run package` creates the VSIX. See [the changelog](CHANGELOG.md) for release history and [REVIEW.md](REVIEW.md) for repository priorities. +For local development and verification, see the [development notes](docs/user-guide.md#privacy-and-development) and [repository priorities](REVIEW.md). diff --git a/docs/user-guide.md b/docs/user-guide.md new file mode 100644 index 0000000..d937fa8 --- /dev/null +++ b/docs/user-guide.md @@ -0,0 +1,208 @@ +# CSV user guide + +For an overview and installation, see [CSV for VS Code](../README.md). + +Use this guide for editing behavior, commands, settings, and compatibility details. + +- [Open and edit a file](#open-and-edit-a-file) +- [Select, copy, paste, and arrange data](#select-copy-paste-and-arrange-data) +- [Headers, metadata rows, widths, and frozen panes](#headers-metadata-rows-widths-and-frozen-panes) +- [Live column filters](#live-column-filters) +- [Find, native search, and text view](#find-native-search-and-text-view) +- [Untitled CSV and TSV](#untitled-csv-and-tsv) +- [Large File Preview](#large-file-preview) +- [Compare two files as tables](#compare-two-files-as-tables) +- [File encoding](#file-encoding) +- [Commands](#commands) +- [Settings](#settings) +- [Keyboard and mouse reference](#keyboard-and-mouse-reference) +- [Privacy and development](#privacy-and-development) + +## Open and edit a file + +Install **CSV** by **ReprEng** from the Extensions view, then open a supported file. CSV opens it as a table unless your editor associations select another editor. The default separators are comma for `.csv`, tab for `.tsv` and `.tab`, and pipe for `.psv`. + +1. Click a cell to select it. Type to start a quick edit, or press Enter or double-click for detail editing. +2. Press Enter or Tab, click outside the cell, or move focus away to commit its text to the VS Code document. In quick edit, arrow keys also commit and move to the adjacent cell. In detail edit, arrows move the text caret; Shift+Enter inserts a line break. +3. Press Ctrl/Cmd+S to commit the active cell and save the document. Committing a cell alone does **not** write the file to disk; VS Code's autosave can save committed document changes if enabled. + +Escape cancels the active cell draft. If VS Code rejects an edit, its draft stays available: retry it or press Escape to discard it before structural operations, switching views, or disabling the table. Changes remain unsaved until a save succeeds. + +An empty file can be edited immediately. The extra bottom row is an append affordance; entering a value creates source data, while leaving it empty does not. Disable `csv.showTrailingEmptyRow` to hide it. + +CSV declares support for VS Code **1.70 or later**. Saved-file table/text replacement requires **1.100** for clean documents and **1.120** for documents with unsaved changes. Older hosts show update guidance for that action. + +## Select, copy, paste, and arrange data + +Selection is visible as soon as you press the mouse button. Drag or Shift+click to select a range. Click a header to select its column; a second separate click on the same header selects only the header cell. Double-click edits the header. Click the serial index to select a row, or the top-left corner to select the table. Shift+click extends whole-row or whole-column selections. + +The VS Code status bar shows **Sum**, **Average**, and **Count** for selected numeric data cells. Count includes only numbers; blanks, text, headers, the serial index, hidden rows, and the extra append row are excluded. Decimal/scientific values and consistent thousands grouping are supported. Whole-column and whole-table totals include matching rows that have not loaded on screen yet. The summary updates with selection and committed edits, and hides when no numeric cells are selected or another editor is active. + +Use Ctrl/Cmd+C or X, or the selection's right-click **Copy** or **Cut** action. Clipboard data uses the active separator and quotes each value only when needed, preserving separators, line breaks, literal quotes, surrounding whitespace, and real empty cells. The serial index and extra append row are excluded. Selecting only the append row leaves the clipboard unchanged. Clipboard shortcuts inside cell edits, Find, Replace, and filter inputs keep their normal text-editing behavior. + +Paste with Ctrl/Cmd+V in selection mode or the right-click **Paste** action. A single value fills a selected rectangle; a copied matrix starts at the selection. With filters active, copying, cutting, filling, and matrix paste use matching source rows. Additional pasted rows append at the physical end of the file. Nonmatching rows stay intact, and saving includes the full file. + +Right-click cells to insert or delete rows and columns. Multi-selection actions use the selected count. Drag selected headers or row indices to reorder a column/row or selected group. Right-click a header to sort ascending or descending; with filters active, sorting rearranges matching rows within their source positions and leaves hidden rows in place. These operations change the document and require saving like other edits. Unchanged field quoting and existing line endings are preserved; new values follow a consistent existing column quote style where available. + +Context menus open toward the available space, flip above or left when needed, and scroll in small panes. Resizing the editor or changing CSV zoom dismisses an open menu. + +## Headers, metadata rows, widths, and frozen panes + +- **Header:** Right-click a cell in the first visible source row and choose **Use first row as header** or **Treat first row as data**. Hidden leading metadata is skipped; filtering does not promote an arbitrary matching row to the header. The Command Palette also provides **CSV: Toggle First Row as Header**. +- **Serial index:** Right-click an index cell or its top-left corner and choose **Hide serial index column**. Restore it with **CSV: Toggle Serial Index Column**. The numbers identify source rows and can have gaps while filtering. +- **Metadata:** **CSV: Hide First N Rows** hides leading records without deleting them. Blank input inherits `csv.defaultIgnoreRows`; an explicit `0` shows them even if the configured default is nonzero. +- **Widths:** Automatic column widths account for the longest line in multiline cells. Drag close to a column boundary to resize, including with headers off. Double-click the boundary to restore automatic sizing. Manual widths are remembered per file; narrow columns retain a selectable center. Drag the bottom edge of a serial-index cell to adjust its row height. +- **Word wrap:** Word wrap starts **off** for each file, showing single-line cutoff with an ellipsis. Use the wrap icon beside the table/text switch in the editor title bar to toggle it; hover for **Enable Word Wrap** or **Disable Word Wrap**. Automatic widths remain capped at 100 characters; manual widths and row heights stay intact. Cutoff lets long rows collapse or be resized shorter. The selected cell/range stays selected and its active cell stays in view. Editing always shows the full value, and copying, searching and saving use the complete text. The display choice is remembered with the table's webview state. +- **Frozen panes:** Right-click to freeze through a visible row or data column, or use **CSV: Freeze Leading Rows/Columns**. Enter `0` to unfreeze an axis. Counts are remembered per file. By default, the header stays frozen; with headers off, no rows freeze until requested. Hidden metadata and the append row do not count. Frozen rows follow measured multiline/zoomed heights and paint their divider seams; the serial index stays alongside frozen data columns. + +Header, serial-index, separator, hidden-row, manual-width, and frozen-pane preferences do not change CSV contents and are stored per file URI in VS Code workspace state. Scroll, selection, row heights, and zoom use webview state. Column colors follow the selected datatype palette (`default`, `cool`, or `warm`) or the theme foreground mode. Light, dark, and high-contrast themes retain that choice. CSV's zoom changes the table's text size independently of global editor zoom. + +## Live column filters + +Right-click a data column and choose **Filter this column** to add a condition above the table. Choose a column and operator, then type a value; results update as you type without replacing the focused input. **Add filter** and repeated context actions add conditions, including multiple conditions on the same column. All conditions combine with **AND**. Remove one condition or use **Clear all filters** to remove them all. + +![Two live column conditions combined with AND](../images/marketplace-filters.png) + +Every column offers Contains, Does Not Contain, Regular Expression, Equals, Does Not Equal, Is Empty, and Is Not Empty. Number and date columns also offer `>`, `>=`, `<`, and `<=`. Types are inferred from the original body rows, excluding the effective header and hidden metadata, before any filters apply. A text column whose nonblank cells all parse as supported dates also offers date comparisons without changing its column colors. + +- Text comparisons ignore case. Numbers accept finite decimal/scientific values and consistent thousands grouping, and compare without rounding away significant digits. +- Boolean equality accepts `true/false`, `t/f`, `yes/no`, `y/n`, `on/off`, and `1/0`. +- Dates accept ISO/year-first forms, numeric dates with four-digit years, and English month names, with optional times and timezone offsets. Unzoned values use UTC. Ambiguous numeric dates use month/day/year: `03/04/2026` means March 4; `13/04/2026` is unambiguously April 13. Use ISO dates or month names to avoid ambiguity. Supported timestamps compare exactly, including sub-millisecond fractions. +- Regular Expression uses [RE2 syntax](https://github.com/google/re2/wiki/Syntax). Plain patterns ignore case; `/pattern/flags` supports `i`, `m`, and `s`. An explicit empty flag list (`/pattern/`) is case-sensitive. Lookaround and backreferences are unsupported. + +A zero-length value leaves a draft condition inactive, except Is Empty/Is Not Empty, which need no value. Literal spaces are valid text searches. Invalid or incomplete values show an inline error and retain the last valid results. Blank or invalid cell values do not match typed comparisons, including Does Not Equal; use Is Empty for empty cells. Incomplete IME text is not applied automatically after a view refresh. + +Filtering scans the full editable document, retains source row identities, and does not delete source rows. Valid conditions are remembered per file and can contain sensitive data; see [Privacy and data handling](../PRIVACY.md). Blank or invalid drafts are not persisted. + +## Find, native search, and text view + +Ctrl/Cmd+F opens table Find; Ctrl/Cmd+H opens Find and Replace. Match case, whole-word, regular expression, selection-only search, and single/all replacement are available. Table Find includes later chunks. With filters active, Find and Replace All use matching displayed rows and the header; hidden metadata and nonmatching rows are excluded. + +Ctrl/Cmd+Shift+F and Ctrl/Cmd+Shift+H remain VS Code's native Find/Replace in Files shortcuts. Alt-modified variants also stay outside the table overlay. + +Use the toolbar switch or **CSV: Switch Between Table and Text** to edit the same document as source text. For saved files, the target opens before the source view is replaced, so one representation remains in that editor group. Live cell edits commit first, unsaved changes remain unsaved, and unrelated tabs/groups are retained. If the file already has a table in another group, switch from that group. + +For a saved local `file:` URI without an authority, query, or fragment, choosing Text also installs a reversible file-path editor association. Native Find in Files can then open that file in text at the selected result while CSV remains enabled. The choice survives restart and Off/On; switching successfully back to Table restores only CSV's owned association. Other files keep their normal editor choice. Intervening user choices are preserved. Patterns use VS Code's case-insensitive matching, so case-distinct paths are not independently isolated. CSV reports longer/conflicting associations or settings restrictions that prevent native routing. + +**Search boundary:** this does not add native search navigation inside a table. A cold search into a file still associated with the table may open the table without revealing the match. Remote/virtual URIs that cannot be isolated by these patterns can switch views, but need CSV turned off for native text search routing. **CSV: Toggle Extension On/Off** temporarily routes CSV's four selectors and explicit CSV associations to native text while off, then restores owned preferences when enabled again. It honors an explicit workspace `csv.enabled` value, otherwise it toggles the global value. Re-enabling upgrades the invoking saved text tab when its restored editor choice is CSV; other already-open text tabs keep their current view until reopened or explicitly switched. + +## Untitled CSV and TSV + +Choose CSV or TSV language mode in a new untitled text document to open a table before saving. The native text tab remains its unsaved owner. Switching the table to text commits the live cell and closes only the temporary table; switching back recreates a table against that same document. Language changes preserve pending edits before refreshing the table. + +Use the table toolbar's **Save Untitled Document As…** action or Ctrl/Cmd+S in selection or editing mode. CSV commits the active cell, reveals the native owner, and invokes VS Code's normal Save As flow. The temporary table closes when the untitled document becomes a saved file. Cancelling Save As retains the unsaved owner and table. Native **File > Save** cannot directly target a standalone table panel; switch to text before using that native action. + +Separator, header, serial-index, metadata, and filter controls work before saving. File encoding can be changed after saving. Untitled documents are not switched with the saved-file native replacement operation because associated-path untitled buffers require their existing owner. + +## Large File Preview + +The normal editable view uses a full VS Code text document; chunked rendering does not bound source-memory use. To inspect a very large saved file without first allocating that document, right-click it in Explorer and choose **CSV: Open Large File Preview (Read-only)**, or run that command and pick a file. Opening the preview after an editable tab does not undo memory already allocated by VS Code. + +The preview reads bounded saved-file blocks and displays one page at a time. **Next**, **Previous**, and **Back to Start** navigate complete records, including quoted multiline fields. The first record is data. There is no editing, global search, sorting, or filtering, and unsaved edits in another view are not included. + +It supports valid **UTF-8**, an optional UTF-8 BOM, a single ASCII separator, and host-local `file:` URIs. It reads directly in the extension host; arbitrary remote filesystem-provider URIs and other encodings are unsupported. Use a per-file separator override or `extension`/`default` separator mode; automatic detection without an override produces an actionable error. + +`csv.largeFilePreviewRows` sets a maximum of 1–10,000 records per page (default 1,000). Independent limits are 512 KiB of source records and 20,000 cells per page, 256 KiB per record, and 1,000 columns. Pages may be smaller. Malformed/oversized records produce errors instead of truncated data. Only the current page and up to 32 page positions are retained; **Previous** reaches that retained history. If the saved file changes, use **Back to Start**. + +## Compare two files as tables + +Select two files in Explorer and choose **CSV: Compare Files as Table**, or run the command from an active CSV/text document and select the modified file. With no active source, choose original and modified files. Both panes are read-only and use VS Code's decoded document text, including unsaved edits; editing a source refreshes the comparison. + +The comparison aligns records around insertions/deletions, highlights changed cells, and shows placeholders for missing records or fields. Both scroll axes stay synchronized and paired rows share their height. Use **Previous/Next Change** and **Previous/Next Page**. The first record is data; comparison uses parsed values and field presence, not quoting or line-ending formatting. + +The existing `csv.maxFileSizeMB` limit applies. Hard per-input limits are 10 MiB of saved bytes before a new document opens, 5 MiB of decoded text, 10,000 records, 100,000 cells, and 1,000 columns; values are limited to 64 Ki characters and records to 256 Ki characters. A provider without size information must already have the document open. Pages are capped at 200 aligned records, 20,000 body cells, and 512 Ki characters. Oversized/malformed inputs show errors without truncation. Bounded alignment falls back to positional pairing with a visible notice when necessary. + +This command is a separate table comparison. It does not provide native Git/PR custom-editor diff navigation; stable APIs do not reliably expose both input URIs for that flow. + +## File encoding + +Editable views use Unicode text decoded by VS Code. Run **CSV: Change File Encoding**, choose **Reopen with Encoding**, and select the original file's encoding to correct incorrectly displayed characters. Check the text before saving. Cancelling the unsaved-changes prompt stops the command without discarding your edits. **Save with Encoding** changes how the current text is written; it cannot repair characters already decoded incorrectly. Use the original file or a backup if a corrupted version was saved. + +A nonmodal warning appears once per opened document containing the replacement character `�`, offering the encoding action. This is a possible decoding mismatch, not automatic encoding detection: `�` can be legitimate text, and other incorrect decodings may not produce it. CSV does not guess, transcode, or repair bytes automatically. The read-only preview's UTF-8 restriction is separate from this editable-view workflow. + +## Commands + +Run these from the Command Palette. Commands that change a view preference target the active CSV table unless noted. + +| Command | Purpose | +| --- | --- | +| **CSV: Switch Between Table and Text** (`csv.toggleEditor`) | Switch the active supported table/text view. | +| **CSV: Enable/Disable Word Wrap** (`csv.enableWordWrap` / `csv.disableWordWrap`) | Toggle wrapping in the active editable table; also available beside the table/text switch. | +| **CSV: Save Untitled Document As…** (`csv.saveUntitled`) | Commit and save the active untitled table through the native owner. | +| **CSV: Toggle Extension On/Off** (`csv.toggleExtension`) | Enable/disable CSV and synchronize native editor routing. | +| **CSV: Toggle First Row as Header** (`csv.toggleHeader`) | Change the file's header preference. | +| **CSV: Toggle Serial Index Column** (`csv.toggleSerialIndex`) | Show/hide the file's serial index. | +| **CSV: Change CSV Separator** (`csv.changeSeparator`) | Override the separator; blank input inherits configured rules. Enter `\t` for tab. | +| **CSV: Reset CSV Separator (Inherit)** (`csv.resetSeparator`) | Clear the file's separator override. | +| **CSV: Hide First N Rows** (`csv.changeIgnoreRows`) | Override the metadata-row count; blank input inherits the default. | +| **CSV: Freeze Leading Rows** (`csv.changeFrozenRows`) | Set the number of leading visible rows to freeze; `0` unfreezes. | +| **CSV: Freeze Leading Columns** (`csv.changeFrozenColumns`) | Set leading data columns to freeze; `0` unfreezes. | +| **CSV: Change File Encoding** (`csv.changeEncoding`) | Open VS Code's encoding picker for a saved file. | +| **CSV: Change Font Family** (`csv.changeFontFamily`) | Pick an extension-host font or inherit `editor.fontFamily`. | +| **CSV: Toggle Clickable Links** (`csv.toggleClickableLinks`) | Toggle link interaction globally. | +| **CSV: Open Large File Preview (Read-only)** (`csv.openLargeFilePreview`) | Open a saved host-local file in the bounded preview. | +| **CSV: Compare Files as Table** (`csv.compareFilesAsTable`) | Choose two source files for read-only table comparison. | + +## Settings + +All settings are under `csv.*` in VS Code Settings or `settings.json`. Font and mouse-wheel zoom settings are application-scoped. Per-file commands override the relevant inherited view defaults. + +| Setting | Default | Behavior | +| --- | --- | --- | +| `csv.enabled` | `true` | Enable the custom editor; the toggle command also manages reversible native routing. | +| `csv.fontFamily` | `""` | Inherit `editor.fontFamily`, or use the specified font family. | +| `csv.fontSize` | `0` | Inherit `editor.fontSize`, or use a positive pixel size. | +| `csv.mouseWheelZoom` | `true` | Allow Ctrl/Cmd+mouse wheel table zoom. | +| `csv.mouseWheelZoomInvert` | `false` | Reverse the table zoom direction. | +| `csv.cellPadding` | `4` | Vertical cell padding in pixels. | +| `csv.columnColorMode` | `"type"` | `type` uses datatype colors; `theme` uses theme foreground. | +| `csv.columnColorPalette` | `"default"` | `default`, `cool`, or `warm` when color mode is `type`. | +| `csv.diffUseThemeForeground` | `true` | Use theme foreground for CSV views recognized as diff contexts. | +| `csv.clickableLinks` | `true` | Enable Ctrl/Cmd+click on recognized links. | +| `csv.showTrailingEmptyRow` | `true` | Show the extra append row. | +| `csv.separatorMode` | `"extension"` | `extension` uses extension mapping, `auto` detects from content first, `default` uses the configured default. Per-file overrides take precedence. | +| `csv.defaultSeparator` | `","` | Fallback separator. Use `"\t"` in JSON for a tab character, or `"\\t"` for the supported literal escape. | +| `csv.separatorByExtension` | CSV comma; TSV/TAB tab; PSV pipe | Extension mapping; keys accept `.ext` or `ext`. | +| `csv.maxFileSizeMB` | `10` | Editable-view size prompt. `0` disables it; **Ignore Forever** sets it to `0`. This is not a memory cap. | +| `csv.defaultIgnoreRows` | `0` | Hidden leading metadata records when no per-file override exists. | +| `csv.largeFilePreviewRows` | `1000` | Preview records per page, from `1` to `10000`, subject to byte/cell caps. | + +Header mode, serial-index visibility, separator overrides, hidden rows, widths, frozen panes, and valid filter conditions are remembered per file. They change the view, except operations such as sorting, editing, and structural changes that explicitly modify document data. + +## Keyboard and mouse reference + +Ctrl/Cmd means Ctrl on Windows/Linux and Command on macOS. Table shortcuts apply outside text inputs unless noted. + +| Action | Shortcut or gesture | +| --- | --- | +| Select a cell/range | Click / drag / Shift+click | +| Select a row or column | Click its serial index or header; Shift+click extends the range | +| Select only a header cell | A second separate click on the same header | +| Select the table | Ctrl/Cmd+A, or click the top-left corner | +| Move selection | Arrow keys; holding a key keeps the target visible | +| Extend selection | Shift+Arrow | +| Jump to a table edge | Ctrl/Cmd+Arrow | +| Extend to an edge | Ctrl/Cmd+Shift+Arrow, retaining the starting anchor and row/column shape | +| Next/previous cell | Tab / Shift+Tab; wraps across data rows | +| Quick edit | Type on a selected cell; arrows commit and move | +| Detail edit | Enter or double-click; arrows move the caret | +| Commit and move while editing | Enter moves down; Tab/Shift+Tab moves across | +| Insert a cell line break | Shift+Enter | +| Cancel a draft | Escape; a failed edit restores its current source value | +| Save | Ctrl/Cmd+S commits the active cell, then saves (Save As for untitled) | +| Copy / cut / paste | Ctrl/Cmd+C / X / V, or right-click actions | +| Clear selected values | Delete / Backspace | +| Table Find / Replace | Ctrl/Cmd+F / H | +| Native Find / Replace in Files | Ctrl/Cmd+Shift+F / H | +| Next/previous Find match | F3 / Shift+F3; Enter/Shift+Enter in Find; Ctrl/Cmd+G/Shift+G while Find is open | +| Resize / reset a column | Drag / double-click near its boundary | +| Resize a row | Drag the bottom edge of its serial-index cell | +| Reorder rows/columns | Drag selected serial indices/headers | +| Zoom in / out / reset | Ctrl/Cmd+plus / minus / 0; Ctrl/Cmd+mouse wheel if enabled | +| Open a recognized link | Ctrl/Cmd+click | + +## Privacy and development + +See [Privacy and data handling](../PRIVACY.md) for local/remote processing, clipboard and link actions, diagnostics, and saved preferences. CSV has no upload service or extension-specific analytics client. Remote workspaces can process files in the remote extension host. + +For development, use Node 20 and run `npm ci`, `npm test`, and `npm run lint`. `npm run package` creates the VSIX. See [the changelog](../CHANGELOG.md) for release history and [REVIEW.md](../REVIEW.md) for repository priorities. diff --git a/images/selection-statistics.png b/images/selection-statistics.png new file mode 100644 index 0000000000000000000000000000000000000000..5c92e9863461d87e08138b467627c5d8bb259f03 GIT binary patch literal 294579 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%0Aei)7pFK&M_DAaWLMcVSZG{yJJQn}rYDsd+v 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 DNKTkE literal 0 HcmV?d00001 diff --git a/media/main.js b/media/main.js index 61cc43b..349362b 100644 --- a/media/main.js +++ b/media/main.js @@ -465,7 +465,35 @@ window.addEventListener('wheel', handleZoomWheel, { passive: false }); let hasHeader = document.querySelector('thead') !== null; let headerEnabled = root?.dataset?.headerenabled === '1'; const getCellCoords = cell => ({ row: parseInt(cell.getAttribute('data-row')), col: parseInt(cell.getAttribute('data-col')) }); -const clearSelection = () => { currentSelection.forEach(c => c.classList.remove('selected')); currentSelection = []; }; +let numericSelectionScope = null; +let selectionReportScheduled = false; +const scheduleSelectionReport = () => { + if (selectionReportScheduled) return; + selectionReportScheduled = true; + requestAnimationFrame(() => { + selectionReportScheduled = false; + let selection = editingCell ? null : numericSelectionScope; + if (!selection && !editingCell) { + let minRow = Infinity, maxRow = -1, minCol = Infinity, maxCol = -1; + for (const cell of currentSelection) { + if (!cell.classList.contains('selected')) continue; + const { row, col } = getCellCoords(cell); + if (row < 0 || col < 0) continue; + minRow = Math.min(minRow, row); maxRow = Math.max(maxRow, row); + minCol = Math.min(minCol, col); maxCol = Math.max(maxCol, col); + } + selection = maxRow >= 0 && maxCol >= 0 ? { kind: 'cells', minRow, maxRow, minCol, maxCol } : null; + } + vscode.postMessage({ type: 'selectionChanged', selection, session: filterSession, filterEpoch }); + }); +}; +const clearSelection = () => { + currentSelection.forEach(c => c.classList.remove('selected')); + currentSelection = []; + numericSelectionScope = null; + // Read the final selection after synchronous mouse/keyboard handlers finish. + scheduleSelectionReport(); +}; const contextMenu = document.getElementById('contextMenu'); /* ──────── UPDATED showContextMenu ──────── */ @@ -1163,6 +1191,7 @@ const selectRange = (start, end) => { clearSelection(); const minRow = Math.min(start.row, end.row), maxRow = Math.max(start.row, end.row); const minCol = Math.min(start.col, end.col), maxCol = Math.max(start.col, end.col); + numericSelectionScope = { kind: 'cells', minRow, maxRow, minCol: Math.max(0, minCol), maxCol }; const selectedRows = visibleRowOrder.length ? visibleRowOrder.filter(row => row >= minRow && row <= maxRow) : Array.from({ length: maxRow - minRow + 1 }, (_, index) => minRow + index); for (const r of selectedRows) { for(let c = minCol; c <= maxCol; c++){ @@ -1176,6 +1205,7 @@ const selectRange = (start, end) => { const selectFullColumnRange = (col1, col2) => { clearSelection(); const minCol = Math.min(col1, col2), maxCol = Math.max(col1, col2); + numericSelectionScope = { kind: 'columns', minCol: Math.max(0, minCol), maxCol }; table.querySelectorAll('tr').forEach(row => { Array.from(row.children).forEach(cell => { const cellCol = cell.getAttribute('data-col'); @@ -1189,6 +1219,7 @@ const selectFullColumnRange = (col1, col2) => { const selectFullRowRange = (row1, row2) => { clearSelection(); const minRow = Math.min(row1, row2), maxRow = Math.max(row1, row2); + numericSelectionScope = { kind: 'rows', minRow, maxRow }; table.querySelectorAll('tr').forEach(row => { Array.from(row.children).forEach(cell => { const r = cell.getAttribute('data-row'); @@ -1199,6 +1230,19 @@ const selectFullRowRange = (row1, row2) => { }); }; +// Newly loaded cells belong to an existing whole-column/table or range selection. +window.addEventListener('csvChunkLoaded', () => { + const scope = numericSelectionScope; + if (!scope || editingCell) return; + table.querySelectorAll('td:not(.selected), th:not(.selected)').forEach(cell => { + const { row, col } = getCellCoords(cell); + if ('minRow' in scope && (row < scope.minRow || row > scope.maxRow)) return; + if ('minCol' in scope && (col < scope.minCol || col > scope.maxCol)) return; + cell.classList.add('selected'); + currentSelection.push(cell); + }); +}); + const extendSelectionTo = target => { rangeEndCell = target; const start = getCellCoords(anchorCell); @@ -2075,7 +2119,11 @@ document.addEventListener('paste', e => { }); }); -const selectAllCells = () => { clearSelection(); document.querySelectorAll('td, th').forEach(cell => { cell.classList.add('selected'); currentSelection.push(cell); }); }; +const selectAllCells = () => { + clearSelection(); + numericSelectionScope = { kind: 'all' }; + table.querySelectorAll('td, th').forEach(cell => { cell.classList.add('selected'); currentSelection.push(cell); }); +}; const setCursorToEnd = cell => { const range = document.createRange(); range.selectNodeContents(cell); range.collapse(false); @@ -2184,6 +2232,8 @@ const editCell = (cell, event, mode = 'detail') => { cell.classList.remove('selected'); originalCellValue = cell.textContent; editingCell = cell; + numericSelectionScope = null; + scheduleSelectionReport(); vscode.postMessage({ type: 'cellEditStarted' }); editMode = mode; cell.classList.add('editing'); @@ -2199,6 +2249,7 @@ const editCell = (cell, event, mode = 'detail') => { cell.removeAttribute('contenteditable'); cell.classList.remove('editing'); editingCell = null; + scheduleSelectionReport(); editMode = null; cell.removeEventListener('blur', onBlurHandler); }; diff --git a/src/CsvEditorProvider.ts b/src/CsvEditorProvider.ts index 7fabbe3..640c9f4 100644 --- a/src/CsvEditorProvider.ts +++ b/src/CsvEditorProvider.ts @@ -4,6 +4,7 @@ import * as path from 'path'; import { parseClipboardMatrix, serializeClipboardMatrix } from './clipboard'; import { ColumnFilter, normalizeColumnFilters, compileColumnFilters, visibleSourceRows, remapColumnFilters, getFilterOperatorChoices, validateColumnFilterInput, MAX_COLUMN_FILTERS, MAX_FILTER_VALUE_LENGTH } from './column-filters'; import { FilterDataType, parseFilterDate } from './filter-values'; +import { NumericSelection, computeSelectionStatistics, formatSelectionStatistics, parseNumericSelection } from './selection-statistics'; type FrozenPanes = { rows: number; columns: number }; @@ -121,6 +122,11 @@ class CsvEditorController { private filterSessionUri = ''; private filterColumnsRevision = 0; private pendingFilterDraft: { uri: string; draft: FilterDraft } | undefined; + private numericSelection: NumericSelection | undefined; + private selectionStatusBar: vscode.StatusBarItem | undefined; + private selectionStatusText: string | undefined; + private selectionStatisticsVersion = -1; + private selectionData: { version: number; data: string[][] } | undefined; constructor(private readonly context: vscode.ExtensionContext) {} @@ -138,6 +144,9 @@ class CsvEditorController { // Register before remote stat/prompt awaits: a closed panel stays closed. webviewPanel.onDidDispose(() => { this.disposed = true; + this.selectionStatusBar?.dispose(); + this.selectionStatusBar = undefined; + this.selectionData = undefined; changeDocumentSubscription?.dispose(); saveDocumentSubscription?.dispose(); CsvEditorProvider.editors = CsvEditorProvider.editors.filter(ed => ed !== this); @@ -183,6 +192,7 @@ class CsvEditorController { if (webviewPanel.active) { CsvEditorProvider.currentActive = this; this.updateWordWrapContext(); + this.updateSelectionStatusBar(); } void this.warnAboutPossibleDecoding().catch(error => { console.warn('CSV: Encoding warning action failed', error); @@ -203,10 +213,12 @@ class CsvEditorController { e.webviewPanel.webview.postMessage({ type: 'focus' }); CsvEditorProvider.currentActive = this; this.updateWordWrapContext(); + this.updateSelectionStatusBar(); } else if (CsvEditorProvider.currentActive === this) { CsvEditorProvider.currentActive = undefined; void vscode.commands.executeCommand('setContext', 'csv.wordWrapEnabled', false); } + if (!e.webviewPanel.active) { this.selectionStatusBar?.hide(); } }); webviewPanel.webview.onDidReceiveMessage(e => { @@ -240,6 +252,12 @@ class CsvEditorController { return; } switch (e.type) { + case 'selectionChanged': + if (e.session === this.filterSession && e.filterEpoch === this.filterEpoch) { + this.numericSelection = parseNumericSelection(e.selection); + this.refreshSelectionStatistics(true); + } + break; case 'webviewReady': { if (this.viewCommitRequested) { this.postViewCommitRequest(); @@ -388,7 +406,10 @@ class CsvEditorController { private enqueueOperation(operation: () => void | Promise): Promise { // Event listeners are not awaited by VS Code. Serialize mutations, reads and // saves so every command sees the result of the preceding document edit. - this.pendingOperation = this.pendingOperation.then(operation).catch(error => { + this.pendingOperation = this.pendingOperation.then(async () => { + await operation(); + this.refreshSelectionStatistics(); + }).catch(error => { console.error('CSV: Editor operation failed', error); }); return this.pendingOperation; @@ -955,6 +976,7 @@ class CsvEditorController { this.currentFilterView = view; this.currentHeader = view.headerEnabled; this.filterEpoch = rawRevision; + this.resetSelectionStatistics(data); reply({}); } @@ -1038,6 +1060,49 @@ class CsvEditorController { } } + private resetSelectionStatistics(data: string[][]): void { + this.selectionData = { version: this.document.version, data }; + this.numericSelection = undefined; + this.selectionStatusText = undefined; + this.selectionStatisticsVersion = -1; + this.selectionStatusBar?.hide(); + } + + private refreshSelectionStatistics(force = false): void { + if (this.disposed || (!force && this.selectionStatisticsVersion === this.document.version)) { return; } + this.selectionStatisticsVersion = this.document.version; + const view = this.currentFilterView; + if (!this.numericSelection || !view) { + this.selectionStatusText = undefined; + } else { + if (this.selectionData?.version !== this.document.version) { + this.selectionData = { + version: this.document.version, + data: this.trimTrailingEmptyRows(Papa.parse(this.document.getText(), { delimiter: this.getSeparator() }).data) + }; + } + const stats = computeSelectionStatistics(this.selectionData.data, this.numericSelection, + view.firstVisibleRow + (view.headerEnabled ? 1 : 0), view.filters.length ? view.visibleRowIds : undefined); + this.selectionStatusText = stats.count ? formatSelectionStatistics(stats) : undefined; + } + this.updateSelectionStatusBar(); + } + + private updateSelectionStatusBar(): void { + if (!this.isActive() || !this.selectionStatusText || this.disposed) { + this.selectionStatusBar?.hide(); + return; + } + if (!this.selectionStatusBar) { + this.selectionStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100); + this.selectionStatusBar.name = 'CSV Numeric Selection'; + this.selectionStatusBar.tooltip = 'Sum, average, and count of selected numeric data cells. Headers, hidden rows, blanks, and text are excluded.'; + this.context.subscriptions.push(this.selectionStatusBar); + } + this.selectionStatusBar.text = this.selectionStatusText; + this.selectionStatusBar.show(); + } + public setWordWrap(enabled: boolean): void { void this.currentWebviewPanel?.webview.postMessage({ type: 'setWordWrap', enabled }); } @@ -2181,6 +2246,7 @@ class CsvEditorController { this.filterEpoch = 0; this.filterSession = this.getNonce(); this.filterSessionUri = this.document.uri.toString(); + this.resetSelectionStatistics(data); const mouseWheelZoomEnabled = config.get('mouseWheelZoom', true); const mouseWheelZoomInvert = config.get('mouseWheelZoomInvert', false); const { tableHtml, chunksJson, colorCss, nextChunkStart, hasRemoteChunks } = view; diff --git a/src/selection-statistics.ts b/src/selection-statistics.ts new file mode 100644 index 0000000..2309b43 --- /dev/null +++ b/src/selection-statistics.ts @@ -0,0 +1,83 @@ +import { parseFilterNumber } from './filter-values'; + +export type NumericSelection = + | { kind: 'cells'; minRow: number; maxRow: number; minCol: number; maxCol: number } + | { kind: 'rows'; minRow: number; maxRow: number } + | { kind: 'columns'; minCol: number; maxCol: number } + | { kind: 'all' }; + +export interface SelectionStatistics { + sum: number; + average: number; + count: number; +} + +/** Validate the compact selection message before using its bounds. */ +export function parseNumericSelection(raw: unknown): NumericSelection | undefined { + if (!raw || typeof raw !== 'object' || Array.isArray(raw)) { return undefined; } + const value = raw as Record; + const validRange = (min: unknown, max: unknown): boolean => + typeof min === 'number' && typeof max === 'number' && Number.isSafeInteger(min) && Number.isSafeInteger(max) && min >= 0 && max >= min; + if (value.kind === 'all') { return { kind: 'all' }; } + if (value.kind === 'cells' || value.kind === 'rows') { + if (!validRange(value.minRow, value.maxRow)) { return undefined; } + if (value.kind === 'rows') { return { kind: 'rows', minRow: value.minRow as number, maxRow: value.maxRow as number }; } + } + if ((value.kind === 'cells' || value.kind === 'columns') && validRange(value.minCol, value.maxCol)) { + const columns = { minCol: value.minCol as number, maxCol: value.maxCol as number }; + return value.kind === 'columns' ? { kind: 'columns', ...columns } + : { kind: 'cells', minRow: value.minRow as number, maxRow: value.maxRow as number, ...columns }; + } + return undefined; +} + +/** Aggregate source values, including unloaded rows, within the displayed selection. */ +export function computeSelectionStatistics( + data: readonly (readonly string[])[], + selection: NumericSelection, + firstDataRow: number, + visibleRowIds?: readonly number[] +): SelectionStatistics { + const minRow = Math.max(firstDataRow, 'minRow' in selection ? selection.minRow : 0); + const maxRow = Math.min(data.length - 1, 'maxRow' in selection ? selection.maxRow : data.length - 1); + const minCol = 'minCol' in selection ? selection.minCol : 0; + const maxCol = 'maxCol' in selection ? selection.maxCol : Infinity; + let count = 0, sum = 0, correction = 0, scale = 0; + const addRow = (rowId: number) => { + if (rowId < minRow || rowId > maxRow) { return; } + const row = data[rowId]; + for (let col = minCol; col <= Math.min(maxCol, row.length - 1); col++) { + const value = parseFilterNumber(row[col]); + if (value === undefined) { continue; } + count++; + // Scale before compensated summation so intermediate totals cannot overflow. + // This also keeps the average finite when a valid sum exceeds Number.MAX_VALUE. + const magnitude = Math.abs(value); + if (magnitude > scale) { + const ratio = scale / magnitude; + sum *= ratio; + correction *= ratio; + scale = magnitude; + } + const normalized = scale ? value / scale : 0; + const next = sum + normalized; + correction += Math.abs(sum) >= Math.abs(normalized) ? (sum - next) + normalized : (normalized - next) + sum; + sum = next; + } + }; + if (visibleRowIds) { + for (const rowId of visibleRowIds) { addRow(rowId); } + } else { + for (let rowId = minRow; rowId <= maxRow; rowId++) { addRow(rowId); } + } + const total = sum + correction; + return { sum: total * scale, average: count ? (total / count) * scale : 0, count }; +} + +export function formatSelectionStatistics(stats: SelectionStatistics): string { + const format = (value: number) => { + if (!Number.isFinite(value)) { return 'Overflow'; } + return Number.isSafeInteger(value) ? String(value) : String(Number(value.toPrecision(15))); + }; + return `Sum: ${format(stats.sum)} Average: ${format(stats.average)} Count: ${stats.count}`; +} diff --git a/src/test/default-ignore-rows.test.ts b/src/test/default-ignore-rows.test.ts index 4a0da63..bfdf824 100644 --- a/src/test/default-ignore-rows.test.ts +++ b/src/test/default-ignore-rows.test.ts @@ -68,9 +68,9 @@ describe('Default hidden rows', () => { assert.strictEqual(setting.default, 0); assert.strictEqual(setting.minimum, 0); assert.strictEqual(setting.scope, 'resource'); - const readme = fs.readFileSync(path.join(process.cwd(), 'README.md'), 'utf8'); - assert.ok(readme.includes('csv.defaultIgnoreRows')); - assert.ok(readme.includes('blank')); - assert.ok(readme.includes('explicit `0`')); + const guide = fs.readFileSync(path.join(process.cwd(), 'docs', 'user-guide.md'), 'utf8'); + assert.ok(guide.includes('csv.defaultIgnoreRows')); + assert.ok(guide.includes('blank')); + assert.ok(guide.includes('explicit `0`')); }); }); diff --git a/src/test/edit-integrity-harness.ts b/src/test/edit-integrity-harness.ts index bcae523..13de15d 100644 --- a/src/test/edit-integrity-harness.ts +++ b/src/test/edit-integrity-harness.ts @@ -24,7 +24,15 @@ const vscodeStub = { replace(_uri: unknown, _range: unknown, text: string) { this.text = text; } }, ColorThemeKind: { Dark: 1 }, + StatusBarAlignment: { Right: 2 }, window: { + createStatusBarItem: () => { + const item = { text: '', name: '', tooltip: '', visible: false, disposed: false, + show() { this.visible = true; }, hide() { this.visible = false; }, + dispose() { this.disposed = true; this.visible = false; } }; + activeHarness.statusBarItems.push(item); + return item; + }, activeColorTheme: { kind: 1 }, onDidChangeActiveTextEditor: () => ({ dispose() {} }), showTextDocument: async (document: any) => { @@ -255,6 +263,7 @@ export async function createEditorHarness(options: { commands: new Map unknown>(), executedCommands: [] as Array<{ name: string; args: unknown[] }>, contextUpdates: [] as unknown[][], + statusBarItems: [] as Array<{ text: string; name: string; tooltip: string; visible: boolean; disposed: boolean }>, registerCommands() { const { registerCsvCommands } = require('../commands') as typeof import('../commands'); registerCsvCommands(context as any); diff --git a/src/test/editor-switch.test.ts b/src/test/editor-switch.test.ts index 604113c..6971716 100644 --- a/src/test/editor-switch.test.ts +++ b/src/test/editor-switch.test.ts @@ -302,9 +302,9 @@ describe('single-view CSV table/text switching', () => { assert.ok(action.when.includes('!isInDiffEditor')); assert.ok(action.when.includes('resourceScheme != untitled')); assert.ok(!action.when.includes('workbench.editors.textEditor')); - const readme = fs.readFileSync(path.join(root, 'README.md'), 'utf8'); - assert.ok(!readme.includes('Both representations may remain open')); - assert.ok(readme.includes('one representation remains')); + const guide = fs.readFileSync(path.join(root, 'docs', 'user-guide.md'), 'utf8'); + assert.ok(!guide.includes('Both representations may remain open')); + assert.ok(guide.includes('one representation remains')); }); }); diff --git a/src/test/frozen-panes.test.ts b/src/test/frozen-panes.test.ts index bc82ca0..81e93f3 100644 --- a/src/test/frozen-panes.test.ts +++ b/src/test/frozen-panes.test.ts @@ -340,11 +340,11 @@ describe('Frozen panes', () => { it('adds documented command contributions and opaque sticky theme surfaces', () => { const manifest = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf8')); - const readme = fs.readFileSync(path.join(process.cwd(), 'README.md'), 'utf8'); + const guide = fs.readFileSync(path.join(process.cwd(), 'docs', 'user-guide.md'), 'utf8'); for (const command of ['csv.changeFrozenRows', 'csv.changeFrozenColumns']) { assert.ok(manifest.contributes.commands.some((item: any) => item.command === command)); assert.ok(manifest.activationEvents.includes(`onCommand:${command}`)); - assert.ok(readme.includes(command)); + assert.ok(guide.includes(command)); } const provider = fs.readFileSync(path.join(process.cwd(), 'src', 'CsvEditorProvider.ts'), 'utf8'); assert.ok(provider.includes('background-color: var(--vscode-editor-background,')); diff --git a/src/test/selection-statistics.test.ts b/src/test/selection-statistics.test.ts new file mode 100644 index 0000000..39fc131 --- /dev/null +++ b/src/test/selection-statistics.test.ts @@ -0,0 +1,50 @@ +import assert from 'assert'; +import { describe, it } from 'node:test'; +import { computeSelectionStatistics, formatSelectionStatistics, parseNumericSelection } from '../selection-statistics'; + +describe('Numeric selection statistics', () => { + it('counts finite numeric values, including zero, independently of column type', () => { + const data = [['0', ' -2.5 ', '.5', '1e2', '1,000', "2'000", '3\u202f000', '4 000'], + ['', ' ', 'text', '12px', '$20', '20%', 'NaN', 'Infinity', '0x10', '12,34', '1e309']]; + const stats = computeSelectionStatistics(data, { kind: 'all' }, 0); + assert.strictEqual(formatSelectionStatistics(stats), 'Sum: 10098 Average: 1262.25 Count: 8'); + }); + + it('respects row/column bounds, hidden metadata, numeric headers, filters, and ragged rows', () => { + const data = [['999'], ['2026', '99'], ['2', '3'], ['100', '200'], ['4'], ['6', '7']]; + const visibleRows = [1, 2, 4, 5, 6]; + assert.strictEqual(formatSelectionStatistics(computeSelectionStatistics(data, { kind: 'all' }, 2, visibleRows)), + 'Sum: 22 Average: 4.4 Count: 5'); + assert.strictEqual(formatSelectionStatistics(computeSelectionStatistics(data, { kind: 'columns', minCol: 1, maxCol: 1 }, 2, visibleRows)), + 'Sum: 10 Average: 5 Count: 2'); + assert.strictEqual(formatSelectionStatistics(computeSelectionStatistics(data, { kind: 'rows', minRow: 2, maxRow: 4 }, 2, visibleRows)), + 'Sum: 9 Average: 3 Count: 3'); + assert.strictEqual(formatSelectionStatistics(computeSelectionStatistics(data, { kind: 'cells', minRow: 2, maxRow: 4, minCol: 0, maxCol: 0 }, 2, visibleRows)), + 'Sum: 6 Average: 3 Count: 2'); + assert.deepStrictEqual(computeSelectionStatistics(data, { kind: 'rows', minRow: 6, maxRow: Number.MAX_SAFE_INTEGER }, 2), + { sum: 0, average: 0, count: 0 }); + }); + + it('formats decimal sums cleanly and preserves cancellation and very small values', () => { + const stats = (values: string[]) => computeSelectionStatistics([values], { kind: 'all' }, 0); + assert.strictEqual(formatSelectionStatistics(stats(['0.1', '0.2'])), 'Sum: 0.3 Average: 0.15 Count: 2'); + assert.strictEqual(stats(['1e16', '1', '-1e16']).sum, 1); + assert.strictEqual(stats(['1e-20']).average, 1e-20); + assert.strictEqual(formatSelectionStatistics(stats(['9007199254740991'])), + 'Sum: 9007199254740991 Average: 9007199254740991 Count: 1'); + assert.strictEqual(formatSelectionStatistics(stats(['-0', '0'])), 'Sum: 0 Average: 0 Count: 2'); + assert.strictEqual(formatSelectionStatistics(stats(['1e308', '1e308'])), 'Sum: Overflow Average: 1e+308 Count: 2'); + assert.strictEqual(stats(['1e308', '1e308', '-1e308']).sum, 1e308); + }); + + it('rejects malformed selection messages and clamps valid large bounds to the data', () => { + for (const raw of [null, [], 'all', { kind: 'unknown' }, { kind: 'rows', minRow: 2, maxRow: 1 }, + { kind: 'cells', minCol: 0, maxCol: 1 }, { kind: 'columns', minCol: -1, maxCol: 0 }, + { kind: 'columns', minCol: 0, maxCol: Infinity }, { kind: 'rows', minRow: '0', maxRow: 1 }]) { + assert.strictEqual(parseNumericSelection(raw), undefined); + } + const selection = parseNumericSelection({ kind: 'cells', minRow: 0, maxRow: Number.MAX_SAFE_INTEGER, minCol: 0, maxCol: Number.MAX_SAFE_INTEGER }); + assert.ok(selection); + assert.deepStrictEqual(computeSelectionStatistics([['2']], selection!, 0), { sum: 2, average: 2, count: 1 }); + }); +}); diff --git a/src/test/webview-navigation-scroll.test.ts b/src/test/webview-navigation-scroll.test.ts index a2d844d..ee12778 100644 --- a/src/test/webview-navigation-scroll.test.ts +++ b/src/test/webview-navigation-scroll.test.ts @@ -128,7 +128,7 @@ async function fixture(options: { separator?: string; rowCount?: number; columnC assert.ok(rect.left >= viewport.left + leftInset && rect.right <= viewport.right, `column ${target.getAttribute('data-col')} must remain in the usable viewport`); }; return { host, window, container, table, messages, scrollCalls, focusCalls, cell, select, key, flush, finishSmooth, visible, - get state() { return state; }, get pendingSmooth() { return pendingSmooth; }, get frameCount() { return frames.size; }, + get state() { return state; }, get pendingSmooth() { return pendingSmooth; }, anchor: () => window.navigationTestApi.anchor(), endpoint: () => window.navigationTestApi.endpoint(), close: () => window.close() }; } @@ -157,11 +157,16 @@ describe('Keyboard navigation viewport reveal', () => { const view = await fixture(); try { view.select(1, 0); + view.messages.length = 0; for (let column = 1; column <= 10; column++) { view.key('ArrowRight', { repeat: true }); } assert.strictEqual(view.window.document.activeElement, view.cell(1, 10)); - assert.strictEqual(view.frameCount, 1, 'one pending reveal for the newest target'); + assert.strictEqual(view.scrollCalls.length, 0, 'reveals wait for the next paint'); view.flush(); - assert.strictEqual(view.scrollCalls.length, 1); + assert.strictEqual(view.scrollCalls.length, 1, 'one reveal for the newest target'); + const selections = view.messages.filter(message => message.type === 'selectionChanged'); + assert.strictEqual(selections.length, 1, 'selection reporting also coalesces the burst'); + assert.strictEqual(selections[0].selection.minCol, 10); + assert.strictEqual(selections[0].selection.maxCol, 10); view.visible(view.cell(1, 10)); for (let column = 9; column >= 1; column--) { view.key('ArrowLeft', { repeat: true }); diff --git a/src/test/webview-selection-statistics.test.ts b/src/test/webview-selection-statistics.test.ts new file mode 100644 index 0000000..ebbe920 --- /dev/null +++ b/src/test/webview-selection-statistics.test.ts @@ -0,0 +1,185 @@ +import assert from 'assert'; +import { describe, it } from 'node:test'; +import { createEditorHarness, createWebviewDom } from './edit-integrity-harness'; + +type Host = Awaited>; +type View = ReturnType; +const paint = (view: View) => new Promise(resolve => view.window.requestAnimationFrame(() => resolve())); +const status = (host: Host) => host.statusBarItems.find(item => item.visible)?.text; +const deliver = async (host: Host, view: View) => { + await paint(view); + for (const message of view.messages.splice(0)) { await host.receive(message); } +}; +const click = (view: View, row: number, col: number, options: Record = {}) => { + const cell = view.cell(row, col); + for (const type of ['mousedown', 'mouseup', 'click']) { + cell.dispatchEvent(new view.window.MouseEvent(type, { button: 0, detail: 1, bubbles: true, cancelable: true, clientX: 60, clientY: 45, ...options })); + } +}; + +describe('Selection statistics in the native status bar', () => { + for (const separator of [',', '\t']) { + it(`updates mouse, keyboard, row and rectangular selections (${JSON.stringify(separator)})`, async () => { + const host = await createEditorHarness({ separator, rows: [['2026', 'Value'], ['2', 'text'], ['4', '6'], ['', '0']] }); + const view = createWebviewDom(host.panel.webview.html); + try { + await deliver(host, view); + assert.strictEqual(status(host), undefined); + click(view, 1, 0); + await deliver(host, view); + assert.strictEqual(status(host), 'Sum: 2 Average: 2 Count: 1'); + click(view, 2, 1, { shiftKey: true }); + await deliver(host, view); + assert.strictEqual(status(host), 'Sum: 12 Average: 4 Count: 3'); + click(view, 2, -1); + await deliver(host, view); + assert.strictEqual(status(host), 'Sum: 10 Average: 5 Count: 2'); + click(view, 1, 0); + view.key('ArrowDown', { shiftKey: true }); + await deliver(host, view); + assert.strictEqual(status(host), 'Sum: 6 Average: 3 Count: 2'); + view.key('a', { ctrlKey: true }); + await deliver(host, view); + assert.strictEqual(status(host), 'Sum: 12 Average: 3 Count: 4'); + view.key('Escape'); + await deliver(host, view); + assert.strictEqual(status(host), undefined); + click(view, 1, 1); + await deliver(host, view); + assert.strictEqual(status(host), undefined, 'text does not count'); + click(view, 4, 0); + await deliver(host, view); + assert.strictEqual(status(host), undefined, 'the append row does not count'); + click(view, 0, 0); + await deliver(host, view); + assert.strictEqual(status(host), 'Sum: 6 Average: 3 Count: 2'); + click(view, 0, 0); + await deliver(host, view); + assert.strictEqual(status(host), undefined, 'a numeric header selected on its own does not count'); + } finally { view.close(); host.dispose(); } + }); + } + + it('ignores hidden rows and restores a numeric selection with headers and serial index off', async () => { + const host = await createEditorHarness({ rows: [['100'], ['2'], ['4'], ['6']], header: false, serialIndex: false, hiddenRows: 1, + filters: [{ column: 0, operator: 'notEquals', value: '4', dataType: 'number' }] }); + const view = createWebviewDom(host.panel.webview.html, { anchorRow: 1, anchorCol: 0 }); + try { + await deliver(host, view); + assert.strictEqual(status(host), 'Sum: 2 Average: 2 Count: 1'); + click(view, 3, 0, { shiftKey: true }); + await deliver(host, view); + assert.strictEqual(status(host), 'Sum: 8 Average: 4 Count: 2'); + view.key('a', { ctrlKey: true }); + await deliver(host, view); + assert.strictEqual(status(host), 'Sum: 8 Average: 4 Count: 2'); + } finally { view.close(); host.dispose(); } + }); + + it('includes remote chunks in column/table totals without loading them into the webview', async () => { + const host = await createEditorHarness({ rows: [['Value'], ...Array.from({ length: 1200 }, () => ['2'])] }); + const view = createWebviewDom(host.panel.webview.html); + try { + await deliver(host, view); + assert.strictEqual(view.cell(1200, 0), null); + click(view, 0, 0); + await deliver(host, view); + assert.strictEqual(status(host), 'Sum: 2400 Average: 2 Count: 1200'); + view.key('a', { ctrlKey: true }); + await deliver(host, view); + assert.strictEqual(status(host), 'Sum: 2400 Average: 2 Count: 1200'); + assert.strictEqual(view.cell(1200, 0), null); + view.window.__csvLoadNextChunk(); + await deliver(host, view); + const chunk = host.messages.find(message => message.type === 'chunkData'); + assert.ok(chunk); + view.window.dispatchEvent(new view.window.MessageEvent('message', { data: chunk })); + assert.ok(view.cell(1200, 0).classList.contains('selected'), 'later chunks inherit the selection represented by the totals'); + await deliver(host, view); + assert.strictEqual(status(host), 'Sum: 2400 Average: 2 Count: 1200'); + } finally { view.close(); host.dispose(); } + }); + + it('updates committed edits and hides while editing, inactive, or disposed', async () => { + const host = await createEditorHarness({ rows: [['Value'], ['2'], ['4']], untitled: true }); + const view = createWebviewDom(host.panel.webview.html); + try { + await deliver(host, view); + click(view, 0, 0); + await deliver(host, view); + assert.strictEqual(status(host), 'Sum: 6 Average: 3 Count: 2'); + await host.receive({ type: 'editCell', row: 1, col: 0, value: '10' }); + assert.strictEqual(status(host), 'Sum: 14 Average: 7 Count: 2'); + await host.view(false, true); + assert.strictEqual(status(host), undefined); + await host.view(true, true); + assert.strictEqual(status(host), 'Sum: 14 Average: 7 Count: 2'); + view.start(view.cell(1, 0)); + await deliver(host, view); + assert.strictEqual(status(host), undefined, 'uncommitted cell drafts are not selection totals'); + view.cell(1, 0).textContent = '8'; + view.key('Tab', { shiftKey: true }); + await deliver(host, view); + click(view, 0, 0); + await deliver(host, view); + assert.strictEqual(status(host), 'Sum: 12 Average: 6 Count: 2'); + host.dispose(); + assert.strictEqual(status(host), undefined); + assert.ok(host.statusBarItems.every(item => item.disposed)); + } finally { view.close(); if (!host.panel.disposed) { host.dispose(); } } + }); + + it('rejects stale messages after filter changes and full refreshes', async () => { + const host = await createEditorHarness({ rows: [['Value'], ['2'], ['4']] }); + const view = createWebviewDom(host.panel.webview.html); + try { + await deliver(host, view); + click(view, 0, 0); + await paint(view); + const selected = view.messages.find(message => message.type === 'selectionChanged'); + assert.ok(selected); + await deliver(host, view); + await host.receive({ type: 'updateColumnFilters', session: selected.session, revision: 1, + filters: [{ column: 0, operator: 'equals', value: '2' }] }); + assert.strictEqual(status(host), undefined); + await host.receive(selected); + assert.strictEqual(status(host), undefined, 'the old filter epoch cannot restore stale totals'); + await host.receive({ ...selected, filterEpoch: 1 }); + assert.strictEqual(status(host), 'Sum: 2 Average: 2 Count: 1'); + await host.view(false, false); + await host.view(true, true); + assert.strictEqual(status(host), undefined); + await host.receive({ ...selected, filterEpoch: 1 }); + assert.strictEqual(status(host), undefined, 'the old webview session cannot restore stale totals'); + } finally { view.close(); host.dispose(); } + }); + + it('keeps status values owned by the active editor when a background editor reports a selection', async () => { + const first = await createEditorHarness({ rows: [['Value'], ['2']], fileName: '/test/first.csv' }); + const firstView = createWebviewDom(first.panel.webview.html); + let second: Host | undefined; + let secondView: View | undefined; + try { + await deliver(first, firstView); + click(firstView, 1, 0); + await deliver(first, firstView); + assert.strictEqual(status(first), 'Sum: 2 Average: 2 Count: 1'); + await first.view(false, true); + second = await createEditorHarness({ rows: [['Value'], ['10']], fileName: '/test/second.csv' }); + secondView = createWebviewDom(second.panel.webview.html); + await deliver(second, secondView); + click(secondView, 1, 0); + await deliver(second, secondView); + assert.strictEqual(status(first), undefined); + assert.strictEqual(status(second), 'Sum: 10 Average: 10 Count: 1'); + click(firstView, 0, 0); + await deliver(first, firstView); + assert.strictEqual(status(first), undefined); + assert.strictEqual(status(second), 'Sum: 10 Average: 10 Count: 1'); + await second.view(false, true); + await first.view(true, true); + assert.strictEqual(status(first), 'Sum: 2 Average: 2 Count: 1'); + assert.strictEqual(status(second), undefined); + } finally { firstView.close(); first.dispose(); secondView?.close(); second?.dispose(); } + }); +});