[← README](../../README.md) · [Docs index](../README.md) · [The preview pane](README.md) # Data: trees, spreadsheets, databases and certificates Structured files are shown by their structure: JSON, YAML and TOML as a collapsible tree, JSON Lines, CSV and workbooks as tables, SQLite, Parquet and DuckDB as their tables and schema, and certificates as the facts that matter, with expiry coloured. ![Four previews: mission.yaml as a tree with counts per level, launches.db with its tables and row counts, a certificate expiring in 20 days shown in yellow, and an e-mail](../screenshots/gui-previews-data.png) *A YAML tree (**Tree** on), a SQLite database, a certificate chain's facts.* ## Contents - [How to use it](#how-to-use-it) - [Formats](#formats) - [What you see](#what-you-see) - [Coxswain's own index and store](#coxswains-own-index-and-store) - [Settings and config.toml](#settings-and-configtoml) - [In the terminal app](#in-the-terminal-app) - [Questions](#questions) ## How to use it 1. Put the cursor on the file and press **Space** or **F3**. 2. In a tree, click a ▶ to open a level; the first two levels open by themselves. 3. **Tree / Source** (JSON, YAML, TOML) switches to the text. 4. A workbook with several sheets gets a button per sheet above the table. 5. In a SQLite database, click a table's name for its schema (`CREATE TABLE …`) and its first rows; a Parquet file has **Schema** under its rows. | Key | Desktop app | Terminal app | |---|---|---| | **Space** / **F3** | Shows or hides the pane | **F3** opens the file in the built-in viewer; a database or Parquet file as its tables and first rows, a workbook as its sheets' text | | **Enter** | Opens the file in its program | The same | ## Formats | Files | Preview | Done by | |---|---|---| | `.json`, `.geojson`, `.yaml`, `.yml`, `.toml` | A tree with counts per level (`{12}` keys, `[3]` items); strings, numbers, booleans and `null` coloured; at most 500 entries per level, then *… 120 more* | Built in, [yaml](https://eemeli.org/yaml/), [smol-toml](https://github.com/squirrelchat/smol-toml) | | `.jsonl`, `.ndjson` | Every line in the [log view](logs.md): a column per key (**Columns**), coloured by a `level` field, filtered by a key's value, followed as it is written | Built in, the same in both apps | | `.csv`, `.tsv`, `.xlsx`, `.xlsm`, `.xlsb`, `.xls`, `.ods` | The first 200 rows as a table, a button per sheet | [SheetJS](https://sheetjs.com/) | | `.dbf` | A dBase table: its fields and first 200 records | Built in: [Old pictures and files](old-formats.md#dbase-tables) | | `.db`, `.sqlite`, `.sqlite3`, `.db3` | Every table and view (*name (view)*) with its row count; click a name for its schema and first rows (open already when there are three tables or fewer) | [SQLite](https://sqlite.org/), opened read-only | | `.parquet`, `.pq` | Row and column counts, the first 200 rows, and **Schema** (column, type, repetition) | [hyparquet](https://github.com/hyparam/hyparquet), with Snappy, Gzip, Zstd, Brotli and LZ4 | | `.duckdb`, `.ddb` | Schema, table, estimated rows and column count per table | DuckDB, installed or in a container ([Previews made by tools](tools.md)) | | `.pem`, `.crt`, `.cer`, `.der` | Each certificate in the file (a chain shows all): *Subject*, *Issuer* (*(CA)* for an authority), *Valid*, *Expires*, *Names*, *Serial* | Read in Rust | | `.plist` | Binary or XML property lists, as highlighted XML | [plist](https://crates.io/crates/plist) | | Coxswain's `index.bin` and `search.db`, wherever they are | What the name index or the search store holds ([below](#coxswains-own-index-and-store)) | Read in Rust, the store opened read-only | ## What you see - **Trees:** keys in one colour, values in the colour of their type. - **Tables:** a header row, then the rows; *Showing the first 200 rows* when there are more. - **SQLite:** a *Table* / *Rows* table; *–* where a count took too long or the row is a view. - **Certificates:** *Expires* says *in 20 days* or *expired 3 days ago*; yellow within 30 days, red once expired. - **DuckDB:** the **Read tables** button when it cannot run by itself (an image to pull), the table otherwise. - A spreadsheet over 25 MB, or a Parquet file over 500 MB, says *Too large to preview*. ## Coxswain's own index and store The name index (`index.bin`) and the search store (`search.db`) are shown as what they hold, not as bytes or tables. Each is known by what is inside it (the index by its first eight bytes, the store by its tables), so a copy elsewhere, under another name, is shown too; *Where* then says *a copy; Coxswain uses …* and names the one in use. ![The desktop app with ~/.cache/coxswain open and index.bin under the cursor: the preview says Coxswain's name index, with the buttons Settings at Disk use and Clear, Entries 674: 317 files, 357 folders, Inside archives, Built 2026-10-08 14:56, Size, Where, Folders indexed /home/demo, and Folders with the most entries](../screenshots/preview-index-bin.png) | `index.bin` | Shows | |---|---| | *Entries* | All names, and how many are files and folders | | *Inside archives* | Archives looked into, and the entries inside them (when search inside archives is on) | | *Built* | When the index was last built, and how long it took (*not noted* for an index from before 2.16) | | *Size*, *Where* | The file's size, its path, and whether it is the one Coxswain uses | | *Folders indexed* | `[search] name_roots`, or `/` (every drive on Windows) | | *Folders with the most entries* | The ten with the most names below them; a folder that is mostly one of its own folders gives way to that one | | *Left out* | `[search] name_exclude`; each folder with a `.nosearch` file (named, its text not read); files only in the cloud (named, their text not read) | ![The preview of search.db: Coxswain's search store with Files known 129, Files read for their text 112, Waiting to be read 0, Without text to read 42, Only in the cloud 0, Last read, Size 1.5 MB, Where, then Files read, by kind: .java 44, .md 8, .json 5 …](../screenshots/preview-search-db.png) | `search.db` | Shows | |---|---| | The first part | Files known, files read for their text, waiting to be read, without text to read, only in the cloud (not read), when a file was last read, the size with the write-ahead log, where | | *Files read, by kind* | The twelve extensions with the most files read, then *N other kinds*, git commits and files inside archives | | *Meaning* | Passages with their vectors and the files they are of (a long file with the vectors of the part read in time counts too), the model that made them, files waiting for theirs | | *Size per part* | Text, vectors, duplicate hashes, files and sizes, the rest: SQLite's own count of each table's pages | | *Latest errors* | The last ten, newest first: when, the file, what (a server that refused a file, a scan that failed, *took too long*, *could not be read to its end*, *read only in part*), the store's own words in your language | Above them: **Settings at Disk use** opens Settings at *Privacy and updates* → *Disk use* ([Disk use](../reference/disk-use.md)), and on the one Coxswain uses **Clear** (a second click confirms; the store is emptied through the search helper while it runs). A copy has no **Clear**: delete it like any file. The store is opened read-only (SQLite's own read-only mode), so nothing is written to it, its write-ahead log or the helper's work, while you look; the index file is only read. In the terminal app, **F3** on either file shows the same in the built-in viewer, then *Settings at this: F9 → Disk use, or coxswain --settings=disk* and, for the one in use, *Clear it: Delete on its row there, or coxswain --disk clear index*. ![The terminal app's built-in viewer with index.bin.txt in Classic blue: line numbers, Coxswain's name index, Entries, Inside archives, Built, Size, Where, Folders indexed (/home/demo), Folders with the most entries, Left out, then Settings at this: F9 → Disk use, or coxswain --settings=disk, and the key line at the bottom](../screenshots/tui-index-bin.png) ## Settings and config.toml None for the built-in formats. DuckDB uses `[preview.images] duckdb` (default `ghcr.io/mwo-dk/coxswain-duckdb:latest`, pinned: Coxswain's own image of DuckDB's released command line, as DuckDB publishes none; `""` for no container, which takes *Container* out of its choices) and the rest of [`[preview]`](tools.md#settings-and-configtoml). ## In the terminal app No preview pane (tables and trees are drawn by the desktop app's webview). **F3** shows the text of JSON, YAML, TOML, CSV and PEM files in the built-in viewer. A workbook (`.xlsx`, `.xlsm`, `.xlsb`, `.xls`, `.ods`) shows as text, as search reads it: each sheet's name on a line, then a line per row with its cells apart by a tab, values and not formulas, then the notes on the cells (the first 4 MB of text). Coxswain's own `index.bin` and `search.db` as [what they hold](#coxswains-own-index-and-store). On a SQLite database (`.db`, `.sqlite`, `.sqlite3`, `.db3`) it pages its tables instead: each with its row count, its `CREATE` statement and its first 20 rows as aligned columns. On a Parquet file: its row count, its columns with their types, and its first 20 rows; a file compressed with zstd shows its columns and count, and says *Its rows are compressed with zstd, which only the desktop app's preview reads.* For DuckDB the command line does the job: `duckdb file.duckdb -c "SHOW TABLES"`. ## Questions #### My JSON file shows as text, not as a tree. It does not parse, or it is over 512 KB and was cut off, which breaks the JSON. Then the source is shown instead. Fix the error (the source view shows where) or open it with **F4**. #### Why do only 200 rows show? The pane is for a look at the data, and a table of 200 rows draws at once. Open the file with **Enter** for the rest. #### Is it safe to preview a database another program is writing to? Yes. SQLite files are opened read-only, and counting and reading rows stop after two and a half seconds for the whole database: the tables not reached by then show their name and schema with the count as *–* and no rows, so a huge database does not hold up the pane (or the terminal app, which waits for it on **F3**). #### Why does search.db not show its tables like other databases? It is Coxswain's own search store, so its preview says what it holds (files read, vectors, errors, size per part) instead. Any other SQLite file shows its tables. A copy of the store is known by its tables too, and shown the same way. #### Does looking at index.bin or search.db slow the search helper? Hardly: the index file is read once, the store with a read-only connection that writes nothing. On a store of a million files counting by kind takes a second or two, after which the preview shows. #### Why does a DuckDB file need a program, when SQLite does not? SQLite is built into the app; DuckDB's file format needs DuckDB itself. Install `duckdb`, or pull Coxswain's DuckDB image (Settings → Previews → Preview tools, **Pull** on the *DuckDB databases* row, about 25 MB; terminal app: **P** there), or press **Read tables** in the preview, which pulls it the first time. With `[preview.images] duckdb = ""` that row says *Used now: nothing: install duckdb* and *Container: no image; name one under [preview.images] duckdb in config.toml* with **Open config.toml** (terminal app: **O**), *Container (no image)* is greyed out, and a *Container* choice made before uses the installed `duckdb`. #### Why is a certificate shown in yellow? It expires within 30 days. Red means it has expired. A `.pem` with a chain shows every certificate in it, the server's first. #### Which compressions can Parquet files use? Snappy, Gzip, Zstd, Brotli and LZ4 are all read in the desktop app; nothing to install. The terminal app's **F3** reads all but Zstd, whose files show their columns and row count. #### Can I edit a cell in the table? No, previews only read. Open the file with **Enter** in its program. --- [← Previous: PowerPoint and Office](office.md) · [Next: Cryptography bills of materials →](bom.md)