Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Inspect a row

Press Space at the table to see every field of the current row, and the focused field’s whole value. It opens on the field of the column cursor’s column. Esc or Space closes it.

Enter, or a double-click on the row, opens it too, except on a row of a by query or a SQL GROUP BY, where Enter drills down into the group and Space inspects. Where Enter drills, the footer says Enter Drill.

The title counts the rows: Row 3 of 60. Inside a drill-down it counts the group’s rows and names the group, Row 3 of 20 · region=north, since the inspector covers the breadcrumb.

The list takes the rows its fields need and the value the rest; when they do not all fit, the value keeps the lines it needs, up to half the height, and the list scrolls, with … 5 above and … 12 more at its ends. At 140 columns and wider the fields and the value sit side by side at full height, and the fields flow into as many columns as fit: a row with more fields than the screen has rows narrows the value to make room for them. At 240 columns and wider, a row with a binary field gives the value room for a hex dump of 32 bytes a line. The fields’ rule counts them, 14 · 2 null · 1 empty, and the footer offers only the keys that act now.

The table cuts long text at the edge of its column and rounds floats to its preview. The inspector shows what is stored:

ValueShown as
FloatThe shortest decimal that reads back to the stored value: 1000000.125, not the table’s 1.0000e6. -0.0, NaN, inf and -inf as they are
IntegerEvery digit. When the table groups digits, a line under it says what the table shows
DatetimeEvery digit of its unit and the zone’s offset: 2024-01-02 04:04:05.000120 +01:00. One past the calendar’s range shows its stored number: -9223372036854775807 us since 1970-01-01 UTC
TextWhole, wrapped between words, a line per line break; its length, line count and any spaces at either end are named on the rule above it. Over 1 KB, the list’s preview ends with its size: … · 2.1 MB
JSON textIndented, with json on the rule. e shows it raw or escaped
Empty text"" in the list; empty string in the pane, or "" escaped
Empty bytes0 bytes · empty in the list; empty binary in the pane
Null∅ null; · absent or ≠ conflicting where the dataset’s files differ
List, structOne item per line, text quoted
BinaryIts size, 1.0 MB (1,048,576 bytes), and what the first bytes say it is: PNG, JPEG or GIF with its dimensions, PDF, gzip, zstd, zip, Parquet, Arrow. UTF-8 bytes read as text; others as a hex dump

Exact means the value as Polars stored it, not the spelling in a CSV file: a 1.50 read from CSV is the float 1.5.

A dataset a catalog documents says more under the value: what the field means, and what the value stands for when the documentation lists it. In NOAA’s weather data, AWDR under ELEMENT reads AWDR = Average daily wind direction (degrees), and a blank Q_FLAG reads blank = did not fail any quality assurance check.

Keys

KeyAction
← → or h lPrevious and next row; the table’s cursor moves with it
Tab Shift+TabInto the value (below)
EnterOpen a struct, a list or JSON text (below), read a field the table’s rows do not hold, or on a group’s row drill down
y YCopy the value; copy the row as JSON (below)
e wThe value’s next view; word or hard wrap
c mCompare with the next row; pin this one
oOpen the value elsewhere
f s /Nulls shown or hidden; field order; find a field

The keyboard reference has every key.

Read a long value

Tab or Shift+Tab moves the focus, and the ▎ rail, into the value. Nothing moves: the list and the value are split by what they hold, so a long value already has its room.

KeyAction
↑ ↓ or j kScroll a line
PgUp PgDnScroll a page
Home EndThe top and the end
/Find in the value; n N go to the next and the last place. Lowercase text ignores case
e w y oAs in the fields
← → or h lPrevious and next row
Esc TabBack to the fields; Esc clears a find first

Only what is on screen is wrapped, so the end of a 2 MiB string or a 1 MiB binary is as near as its start: Tab End. The rule says where the pane is: lines 41-73 of 4,000 · 1% for text, 0x0-0x1ff of 0x100000 for bytes.

Word wrap breaks between words and after / & ? , ; | -, so a URL wraps at its separators. A long run with no spaces, such as base64, fills each row instead. w switches to hard wrap, at the pane’s edge, for every value until pressed again.

Views

e cycles the views that apply to the value, and the rule names the one shown. The footer offers e only where there is more than one.

ValueViews
Text that parses as JSON (up to 1 MiB)JSON (indented), Raw, Escaped
Other textRaw, Escaped
UTF-8 bytesText, Hex, Escaped
gzip or zstd holding textHex, Text (the first 64 KB decompressed), Escaped
Other bytesHex, Escaped

JSON text over 64 KB is indented in the background; until then it shows raw, with json, indenting... on the rule. gzip and zstd are decompressed in the background when their Text view is chosen, with decompressing... on the rule until then; bytes that turn out to hold no text go back to Hex, and the rule says not text. Escaped text tells a line break (\n) from a backslash followed by n (\\n), and shows invisible characters such as a no-break space as \u{a0}.

Compare two rows

c adds a column with the next row’s values, and Δ (* in an ASCII terminal) marks each field whose values differ. The rule counts them, 14 · 5 differ, and the title names the other row: Row 2 of 60 · compare with 3. At 240 columns and wider the row before is shown as well, in row order (previous, this, next), each named over its column, and the title says compare with 1 and 3; a field is marked when it differs from either. f then lists only the fields that differ.

m pins the current row: Compare then shows it beside each row you move to with ← →, and the title says compare with pinned 3. m on the pinned row lets it go. Esc or c leaves Compare; the next Esc closes the inspector.

Drill down into nested values

Enter on a struct, a list or an array opens it one level down: a struct’s fields, or a list’s items as [0], [1], … with their types and previews. Text that holds a JSON object or array opens the same way, its keys in the document’s order. The footer says Enter Open where it applies.

KeyAction
Enter or → lOpen the focused item
Esc or ← hUp a level; at the row, Esc closes
↑ ↓ or j k, Home EndMove between items
yCopy the focused item; a JSON object or array as indented JSON
SpaceClose

The title is the path from the row: Row 42 of 60 › customer › address. On a narrow terminal the middle steps give way to …. A list of structs, or a JSON array of objects, shows as a table with a column per field (the first object’s keys); +3 after the header counts the columns that do not fit, and the focused item’s whole value is under the table.

Limit
ItemsOnly the items on screen are read: a list of a million items opens at once, and End reaches the last
JSON textUp to 64 KB is parsed on the key; longer text in the background, with the spinner. Text over 4 MiB is not opened; Tab reads it in the value
DepthJSON nested deeper than 128 levels does not open

Text that does not parse stays where it is, and the footer says why: Not JSON: key must be a string at line 1 column 2. From then on Enter leaves it as text, read in the value like any other.

Copy a field or the row

y copies the focused value through the same clipboard as the copy dialog, as its view shows it: numbers exact, lists and structs as JSON, indented JSON in the JSON view, the text bytes hold in their Text view, other bytes as base64 (the footer says y Copy base64), a null as nothing.

Y copies the whole row as one JSON object, field names as keys and values exact, without leaving the inspector. Hidden and binary fields are included once read; otherwise the message counts them: Copied row 3: 12 fields, 2 not read.

A copy over an osc52 clipboard’s osc52_limit_kb is refused.

Open a value elsewhere

o writes the focused value, as its view shows it, to a read-only temporary file named for the field, the row and its kind (.json, .xml, .txt, .png, .pdf, .bin, …), and opens it:

ValueOpened with
Text, JSON, bytes with no known kind$VISUAL, $EDITOR or $PAGER, else less (on Windows, the system’s opener). It has the terminal until it exits, and the file is removed then
Images and PDFsThe system’s opener: xdg-open, open, or Windows’ start, which asks for a program when none is set. The file stays until datui quits

A program named with arguments, such as code --wait, runs with them. Nothing is read back into the dataset.

Hidden and binary columns

The table reads only the columns it shows, and reads a binary column as a ‹binary› placeholder. In the inspector, columns hidden in Sort & Filter are listed after the others with a ⊘ mark, and they and binary columns read not read. Enter on one reads those fields for this row, in the background. From then on, while the focus stays on that field, each row moved to is read too, without holding the keys. The read also checks the row’s other fields: if a query’s sort with ties put another row there on reading again, the pane says so instead of showing that row’s values. A sort from Sort & Filter or a SQL ORDER BY keeps tied rows in order, and a SQL result comes back in one order, so a second read finds the same row.

In the table

The table keeps a row on one line. A line break in a value shows as , a tab as » and another control character or a direction mark (such as U+202E, which would turn the rest of the row around) as ¤ ($, > and ? in an ASCII terminal), so line1\nline2 reads line1¶line2 instead of line1line2.

A date or datetime past the calendar’s range, such as a sentinel of i64::MIN + 1 microseconds, shows its stored number: -9223372036854775807 us since 1970-01-01 UTC, 2147483647 days since 1970-01-01. So do Describe, Data Quality and copies.