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:
| Value | Shown as |
|---|---|
| Float | The 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 |
| Integer | Every digit. When the table groups digits, a line under it says what the table shows |
| Datetime | Every 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 |
| Text | Whole, 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 text | Indented, with json on the rule. e shows it raw or escaped |
| Empty text | "" in the list; empty string in the pane, or "" escaped |
| Empty bytes | 0 bytes · empty in the list; empty binary in the pane |
| Null | ∅ null; · absent or ≠ conflicting where the dataset’s files differ |
| List, struct | One item per line, text quoted |
| Binary | Its 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
| Key | Action |
|---|---|
| ← → or h l | Previous and next row; the table’s cursor moves with it |
| Tab Shift+Tab | Into the value (below) |
| Enter | Open 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 Y | Copy the value; copy the row as JSON (below) |
| e w | The value’s next view; word or hard wrap |
| c m | Compare with the next row; pin this one |
| o | Open 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.
| Key | Action |
|---|---|
| ↑ ↓ or j k | Scroll a line |
| PgUp PgDn | Scroll a page |
| Home End | The 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 o | As in the fields |
| ← → or h l | Previous and next row |
| Esc Tab | Back 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.
| Value | Views |
|---|---|
| Text that parses as JSON (up to 1 MiB) | JSON (indented), Raw, Escaped |
| Other text | Raw, Escaped |
| UTF-8 bytes | Text, Hex, Escaped |
| gzip or zstd holding text | Hex, Text (the first 64 KB decompressed), Escaped |
| Other bytes | Hex, 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.
| Key | Action |
|---|---|
| Enter or → l | Open the focused item |
| Esc or ← h | Up a level; at the row, Esc closes |
| ↑ ↓ or j k, Home End | Move between items |
| y | Copy the focused item; a JSON object or array as indented JSON |
| Space | Close |
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 | |
|---|---|
| Items | Only the items on screen are read: a list of a million items opens at once, and End reaches the last |
| JSON text | Up 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 |
| Depth | JSON 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:
| Value | Opened 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 PDFs | The 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.