Editing Cells
VisiData's cell editor lets you modify values directly in any sheet. Edits are held in memory — nothing reaches disk until you explicitly save with Ctrl+S.
Think of it like this: VisiData is always working on a live copy in RAM. Your original file is untouched until you consciously press Save.
Understand the edit lifecycle: enter edit mode (e), modify, accept or cancel, then optionally save (Ctrl+S). Nothing is written to disk unless you explicitly save. To copy a cell value to another cell, use zy → zp (see Copying and Pasting Rows). For bulk column editing commands, see Column Editing.
Your source file is unchanged until you press Ctrl+S and confirm overwrite or provide a new filename.
Sample Data Used in This Lesson
cat > ~/github/practice-folder/visidata/04-cleaning/01-dirty_orders.csv << 'EOF'
order_id,customer,status,amount,region
1001,Alice,active,250,sg
1002,Bob,pending,150,kl
1003,Carol,actve,400,sg
1004,Dave,error,0,
1005,Eve,pending,320,kl
EOF
vd ~/github/practice-folder/visidata/04-cleaning/01-dirty_orders.csv
Inside VisiData:
order_id customer status amount region
1001 Alice active 250 sg
1002 Bob pending 150 kl
1003 Carol actve 400 sg ← typo: "actve"
1004 Dave error 0 ← missing region
1005 Eve pending 320 kl
Fix a Typo in a Cell
Carol's status has a typo: actve instead of active.
# Move cursor to Carol's 'status' cell (row 3, status column)
e
# Edit field opens — shows current value: actve
# Use Backspace to delete, type: active
Enter
Result:
order_id customer status amount region
1001 Alice active 250 sg
1002 Bob pending 150 kl
1003 Carol active 400 sg ← fixed
1004 Dave error 0
1005 Eve pending 320 kl
Inside Edit Mode — Keyboard Shortcuts
| Key | Action |
|---|---|
Enter | Accept the edit |
Ctrl+C | Cancel and discard the edit |
Ctrl+A | Move cursor to beginning of field |
Ctrl+E | Move cursor to end of field |
Ctrl+K | Clear from cursor to end of line |
Ctrl+U | Clear from cursor to beginning of line |
Ctrl+O | Open this cell value in external $EDITOR |
Tab | Accept edit and move cursor right |
Shift+Tab | Accept edit and move cursor left |
Up / Down | Accept edit and use previous/next input history |
Bulk Set Column Value for Selected Rows (ge)
Instead of editing each cell one by one, use ge to set the same value for all selected rows in the current column.
# Select all 'pending' rows
|
# Enter: pending
# Bulk-set their status to 'PENDING' (uppercase)
ge
# Enter: PENDING
Before:
order_id customer status amount region
1002 Bob pending 150 kl
1005 Eve pending 320 kl
After ge → PENDING:
order_id customer status amount region
1002 Bob PENDING 150 kl
1005 Eve PENDING 320 kl
Fill Null Cells Downward (f)
If a column has blank/null cells, press f to fill each null with the non-null value from the row above.
Before (region column has a blank for Dave):
order_id customer status amount region
1001 Alice active 250 sg
1002 Bob pending 150 kl
1003 Carol active 400 sg
1004 Dave error 0 ← blank
1005 Eve pending 320 kl
# Move cursor to 'region' column
f
After — Dave's region is filled from Carol's row above:
order_id customer status amount region
1001 Alice active 250 sg
1002 Bob pending 150 kl
1003 Carol active 400 sg
1004 Dave error 0 sg ← filled from above
1005 Eve pending 320 kl
f fills from the nearest non-null value above. It's perfect for spreadsheets where a category label only appears in the first row of a group.
Undo and Redo
# After making a change:
U # undo the last change
R # redo (reapply the undone change)
To enable undo, add this to ~/.visidatarc:
options.undo = True
Edit a Single Cell in an External Editor (e, then Ctrl+O)
For long text, descriptions, or JSON content that is hard to edit inline, hand one cell value to your system $EDITOR. No row selection is needed.
# 1. Move the cursor onto the cell (do NOT select any rows)
# 2. Enter edit mode
e # or i
# 3. With the input line open, launch the external editor
Ctrl+O # opens just this one value in $EDITOR (vim, nvim, nano, ...)
# 4. Edit the value, save, and quit the editor
# → the text returns to the input line and is applied to the cell
^O in VisiData help and cheat sheets means Ctrl+O — the ^ is the standard caret notation for the Ctrl key. A lowercase g before it is a separate keypress, so g^O = press g, then Ctrl+O.
o is not Ctrl+OPlain o runs open-file (it prompts for a path and opens a new sheet). That is not the external editor. Only Ctrl+O — pressed while a cell's input line is open — launches $EDITOR.
$EDITOR must be set and exported in the shell that launched VisiData:
export EDITOR=nvim # put in ~/.bashrc to make it permanent
Local Common-Config Shortcuts (zn, zq)
The shared local VisiData config adds two shortcuts that are not built-in VisiData defaults:
| Key | Action |
|---|---|
zn (z, then n) | Open the current cell directly in Neovim, without first entering VisiData's inline editor. Use :wq in Neovim to apply the edited value and return. |
zq (z, then q) | Force-save the current sheet to its default save path without a filename or overwrite prompt, then quit after saving succeeds. |
zq overwrites without askingzq may replace the original source file. It bypasses the overwrite confirmation and does not ask for another filename. Use Ctrl+S instead when you want VisiData's normal save-path and overwrite prompts. If the forced save fails, zq leaves the sheet open.
These bindings are specific to the local common-config setup and require its .visidatarc.d configuration to be loaded.
Bulk Edit Rows with an External Editor (g^O)
g^O (press g, then Ctrl+O) opens all currently visible columns of the selected rows in $EDITOR as a single temporary TSV file — one row per line, one column per tab. When you save and quit, VisiData writes the edited values back into the selected rows.
It edits whole rows, not a single column. To edit just one column, hide the other columns first so the target is the only visible one.
# 1. Select the rows you want to edit
s # select current row
gs # or select ALL rows
t / gt # or toggle current / all rows
# 2. (optional) hide the columns you do NOT want to edit
- # hide the current column
# 3. Launch the editor on the selected rows
g Ctrl+O # g, then Ctrl+O
# VisiData prompts: "edit N rows as filetype:" → Enter to accept 'tsv'
# 4. In the temp TSV: edit the values, then save and quit
Example — fix only the status column:
# Move to the 'status' column, then hide every other column with '-'
# (there is no single-column mode for g^O; hiding is how you scope it)
gs # select all rows
g Ctrl+O # Enter to accept the 'tsv' filetype
# edit each status value in the editor, save, quit
U # undo if needed (requires options.undo = True)
With nothing selected, g^O stops with a status message such as no rows selected. Select rows with s or gs first.
In the editor, do not delete or add lines, and leave the header row in place. VisiData maps the file back to the rows by position, so changing the number of lines or the header can misalign the values.
External-editor changes live in memory like any other edit. Press Ctrl+S to write the sheet to disk.
Renaming Columns
^ rename current column (opens input prompt)
g^ rename all unnamed columns to content of selected rows
z^ rename current column to content of current cell
# Move cursor to 'order_id' column
^
# Enter: id
# Column header changes from 'order_id' to 'id'
Saving Changes
Ctrl+S save current sheet to file (prompts for filename)
g Ctrl+S save all open sheets to files
z Ctrl+S save current column only
If you save back to the original file, VisiData will prompt for confirmation. Always use a new filename first if you are unsure about overwriting.
# Save changes to a new file
Ctrl+S
# Enter: /tmp/orders_cleaned.csv
# Original file is untouched
# Save to original (with confirmation)
Ctrl+S
# Enter: ~/github/practice-folder/visidata/04-cleaning/01-dirty_orders.csv
# VisiData prompts: "overwrite?" → yes
Complete Edit Commands Reference
| Key | Action |
|---|---|
e | Enter edit mode on current cell |
zn (custom) | Open current cell directly in Neovim |
ge | Set current column for all selected rows |
Ctrl+O | While editing a cell, open that cell value in external $EDITOR |
g Ctrl+O | Edit all visible columns of selected rows in external $EDITOR (temp TSV) |
f | Fill null cells with value from above |
^ | Rename current column |
zm | Copy cell to tmux buffer (custom) |
U | Undo most recent modification |
R | Redo most recent undo |
Ctrl+S | Save current sheet |
zq (custom) | Force-save to default path without prompts, then quit |
Copy Cell to Tmux Buffer (Custom)
The zm keybinding copies the current cell value to the tmux paste buffer, enabling cross-pane pasting.
zm # copy current cell to tmux buffer
# Switch to another tmux pane
Ctrl+b ] # cell value is pasted
This uses cursorDisplay (same as zY for system clipboard) and pipes to tmux load-buffer. Requires tmux to be running. See Plugins for details.
Hands-On Practice
vd ~/github/practice-folder/visidata/04-cleaning/01-dirty_orders.csv
# 1. Move to Carol's 'status' cell (row with 'actve'), press e → fix to 'active'
# 2. Press U → undo the change (confirm it reverts)
# 3. Select rows where status = 'pending': | → Enter: pending
# 4. Bulk-set status: ge → Enter: PENDING
# 5. Press U → undo
# 6. Move to 'region' column where Dave has no region → press f (fill from above)
# 7. Press Ctrl+S → save as /tmp/orders_edited.csv