ASAT Documentation
Complete reference for A Spreadsheet And Terminal — the Vim-inspired terminal spreadsheet editor.
# Installation
Arch Linux (AUR)
$ yay -S asat
Homebrew (macOS / Linux)
$ brew tap okt4v/tap
$ brew install asat
Debian / Ubuntu (.deb)
$ sudo dpkg -i asat_*.deb
Build from source
$ git clone https://github.com/okt4v/ASAT.git
$ cd ASAT
$ cargo install --path crates/asat
Pre-built binaries
Download pre-compiled binaries for Linux (x86_64, aarch64), macOS (x86_64, aarch64), and Windows from the GitHub Releases page.
# First Launch
Run asat with no arguments to see the welcome screen, or open a file directly:
$ asat
$ asat budget.csv
$ asat report.xlsx
Welcome Screen Keys
| Key | Action |
| n | New empty spreadsheet |
| f | Open file finder (fuzzy search) |
| r | Recent files list |
| t | Theme browser |
| c | Open configuration file |
| ? | Open help screen |
| q / Esc | Quit |
# Normal Mode
The default mode. Navigate the grid, trigger actions, and enter other modes. Most keys accept a count prefix — type a number before the key to repeat it (e.g. 5j moves 5 rows down).
Navigation
| Key | Action |
| h j k l | Move left / down / up / right (count prefix supported) |
| w / b | Next / previous non-empty cell horizontally |
| W / B | Next / previous non-empty cell vertically |
| e | Next non-empty cell horizontally (alias for w) |
| } / { | Next / previous paragraph (empty row boundary) |
| gg | Jump to first row |
| G | Jump to last row |
| 0 / Home | Jump to first column |
| $ / End | Jump to last column |
| H / M / L | Top / middle / bottom of visible area |
| Ctrl+d / Ctrl+u | Page down / up |
| Ctrl+f / Ctrl+b | Page down / up (alias) |
| PgDn / PgUp | Page down / up |
| zz / zt / zb | Scroll cursor row to center / top / bottom |
| g{A-Z} | Jump to column by letter (gA = col A, gZ = col Z) |
| f{char} | Jump to column by letter |
| Tab / BackTab | Move right / left one cell |
Entering Edit
| Key | Action |
| i / Enter / F2 | Edit cell (cursor at end of content) |
| a | Edit cell in append mode (cursor at end) |
| s / cc | Clear cell content and start editing |
| ci" | Change inner: select text between " delimiters and edit. Also works with ( [ { < ' |
| r | Replace mode — edit cell, then return to Normal on confirm |
| o | Insert row below and start editing |
| O | Insert row above and start editing |
Cell Operations
| Key | Action |
| x / D / Del | Clear cell content (yanks to register first) |
| dd | Delete entire row (count prefix: 3dd deletes 3 rows). Yanks first. |
| dc | Clear cell content (alias for x) |
| dC | Delete entire column |
| dj / dk | Delete row below / above (count prefix supported) |
| ~ | Toggle case of text cell content |
| Ctrl+a | Increment: add 1 to number, cycle date/weekday/month forward |
| Ctrl+x | Decrement: subtract 1 from number, cycle backward |
| J | Join cell below into current cell (concatenate) |
| U | Unmerge cell under cursor |
| gw | Toggle line-wrap on cell |
| . | Repeat last change |
Undo / Redo
| Key | Action |
| u | Undo last change |
| Ctrl+r | Redo |
# Insert Mode
Entered with i, Enter, F2, a, s, cc, o, or O. The formula bar shows an edit cursor. Type to edit the cell value.
| Key | Action |
| Enter | Confirm edit, move down one row |
| Tab | Confirm edit, move right one cell |
| Esc | Confirm edit, stay in place |
| Left / Right | Move edit cursor within cell text |
| Ctrl+a | Jump to start of edit buffer |
| Ctrl+e | Jump to end of edit buffer |
| Backspace | Delete character to the left |
| Delete | Delete character to the right |
| Ctrl+w | Delete word backward |
| Ctrl+u | Delete from cursor to start of buffer |
| Ctrl+k | Delete from cursor to end of buffer |
| Ctrl+v | Paste from system clipboard into edit buffer |
| Tab / BackTab | Cycle through function name completions |
| Ctrl+r | Enter F-REF mode — navigate the grid to pick a cell or range reference interactively |
F-REF Mode: While editing a formula, press Ctrl+r to enter reference picker mode. Navigate with hjkl. Press Enter to insert a single cell reference. Press v to anchor a range start, then navigate to the end cell and press Enter to insert the range reference (e.g. A1:C5). Press Esc to cancel.
# Visual Mode
Select a range of cells to operate on. Three sub-modes:
- v — cell selection (rectangular range)
- V — V-ROW: full row selection
- Ctrl+v — V-COL: full column selection
| Key | Action |
| hjkl, arrows | Extend selection in direction |
| w/b/W/B | Extend by non-empty cell |
| } / { | Extend by paragraph |
| 0 / $ | Extend to first / last column |
| gg / G | Extend to first / last row |
| d / x / Del | Delete selection (yanks to register first) |
| c / s | Clear selection and enter insert mode |
| y | Yank (copy) selection to register + clipboard |
| M | Merge selection into one cell |
| S | Insert =SUM() formula below/right of selection |
| Ctrl+d | Fill down — copy anchor row to all selected rows |
| Ctrl+r | Fill right — copy anchor column to all selected columns |
| Ctrl+f | Auto-fill series — smart direction detection from anchor to cursor |
| > / < | Widen / narrow columns (count prefix supported) |
| : | Enter command mode with selection range pre-filled |
| v / V | Swap between visual sub-modes, or exit |
| Esc | Exit visual mode |
# Command Mode
Entered with :. Type an ex-command and press Enter to execute. Tab cycles through completions. See the Ex-Commands Reference for all available commands.
# Search Mode
| Key | Action |
| / | Search forward (from Normal mode) |
| ? | Search backward |
| n / N | Next / previous match (count prefix supported) |
| * | Search for the content of the cell under cursor |
| Esc | Clear search highlights |
# Cell Editing
ASAT provides multiple ways to enter and modify cell content, mirroring Vim's editing philosophy.
Entering Edit Mode
- i / Enter / F2 — Edit existing content (cursor at end)
- a — Append mode (cursor at end)
- s / cc — Clear cell and start editing from scratch
- r — Replace mode: edit cell, automatically return to Normal on confirm
- o / O — Insert a new row below/above and start editing in it
- ci{delim} — Change inner: select content between delimiters (
" ' ( [ { <) and edit
Cell Arithmetic
Ctrl+a increments the value under the cursor. For numbers, it adds 1. For dates, it advances by one day. For weekday names (Mon, Tuesday, etc.) and month names (Jan, February, etc.), it cycles to the next one. Ctrl+x does the reverse.
Repeat & Dot Command
Press . to repeat the last editing operation. This works for cell edits, deletes, style changes, and more — just like Vim's dot command.
# Yank & Paste
Yank (Copy)
| Key | Action |
| yy / yr | Yank entire row (count prefix: 3yy yanks 3 rows) |
| yc | Yank cell |
| yC | Yank entire column |
| yj / yk | Yank row below / above |
| yS | Copy cell style to style clipboard |
Paste
| Key | Action |
| p | Paste after cursor position |
| P | Paste before cursor position |
| pS | Paste style from style clipboard to current cell |
Formula-Aware Paste: When you paste cells containing formulas, relative references (like A1) are adjusted based on the offset from the source to the destination. Absolute references (like $A$1, $A1, A$1) remain unchanged.
Style-Aware: Yank operations copy both cell values AND cell styles (bold, italic, colors, etc.). Delete operations (dd, x, visual d) yank to the register before clearing, so you can always paste what you just deleted.
System Clipboard: Yanking also copies to the system clipboard as TSV (tab-separated values). In Insert mode, Ctrl+v pastes from the system clipboard.
# Columns & Rows
Sizing
| Key | Action |
| >> / << | Widen / narrow column by 1 char (count prefix supported) |
| = | Auto-fit column width to content |
| + / - | Increase / decrease row height (count prefix supported) |
| _ | Reset row height to auto-fit |
:cw N | Set column width to exactly N characters |
:rh N | Set row height to exactly N |
Insert / Delete
| Key / Command | Action |
:ir | Insert row below cursor |
:dr | Delete current row |
:ic | Insert column to the left |
:icr | Insert column to the right |
:dc | Delete current column |
| dd | Delete row (Normal mode) |
| dC | Delete column (Normal mode) |
# Data Operations
| Command | Action |
:sort asc/desc | Sort all rows by the cursor column (ascending or descending) |
:filter A >100 | Filter: show only rows where column A value > 100 |
:filter off | Clear active row filter |
:transpose | Transpose visual selection (swap rows and columns) |
:dedup | Remove duplicate rows (by cursor column) |
:filldown | Fill selection down from the top row |
:fillright | Fill selection right from the leftmost column |
:merge / :unmerge | Merge visual selection into one cell / unmerge |
:name sales A1:C10 | Define a named range |
:colfmt >100 red | Conditional formatting rule for column |
:note Hello | Set cell note (:note to view, :note! to clear) |
:s/pat/repl/g | Find and replace across all text cells |
:J | Join cell below into current cell |
# Auto-Fill Series
Select a range in Visual mode with some seed values, then press Ctrl+f to extend the pattern. Direction is detected automatically from the anchor (where you started the selection) to the cursor.
Supported Patterns
- Numeric sequences:
1, 2 → 3, 4, 5, ... or 10, 20 → 30, 40, 50, ...
- Weekday names (short):
Mon, Tue → Wed, Thu, Fri, ...
- Weekday names (full):
Monday, Tuesday → Wednesday, Thursday, ...
- Month names (short):
Jan, Feb → Mar, Apr, May, ...
- Month names (full):
January, February → March, April, ...
- Cyclic repeat: Any other values repeat cyclically
Case Preservation: The output preserves the case style of your seed. mon → tue, wed; MON → TUE, WED; Mon → Tue, Wed; MONDAY → TUESDAY, WEDNESDAY; etc.
Direction Detection
The fill direction depends on where you started the selection (anchor) vs. where the cursor is when you press Ctrl+f:
- Anchor above cursor → fills down (seed from top)
- Anchor below cursor → fills up (seed from bottom)
- Anchor left of cursor → fills right (seed from left)
- Anchor right of cursor → fills left (seed from right)
# Multi-Sheet
| Key / Command | Action |
| gt | Switch to next sheet tab |
| gT | Switch to previous sheet tab |
:tabnew / :tabedit | Create a new sheet |
:tabclose | Close current sheet |
Sheet tabs appear at the bottom of the screen. Cross-sheet formula references use Sheet1!A1 syntax.
# Macros
Record a sequence of keystrokes into a register and replay it.
| Key | Action |
| q{a-z} | Start recording into register (e.g. qa) |
| q | Stop recording (while recording) |
| @{a-z} | Play macro from register (count prefix: 5@a replays 5 times) |
| @@ | Replay the last-used macro (count prefix supported) |
Tip: Macros record all keystrokes including mode changes (Normal → Insert → Normal). They survive mode transitions and can be replayed with a count prefix for bulk operations.
# Marks
| Key | Action |
| m{a-z} | Set a mark at the current cursor position |
| '{a-z} | Jump to the cell where mark was set |
| '' | Jump to previous position (before last jump) |
# Search & Replace
| Key / Command | Action |
| / | Search forward |
| ? | Search backward |
| n / N | Next / previous match (count prefix supported) |
| * | Search for cell content under cursor |
| Esc | Clear search highlights |
:s/pattern/replacement/g | Find and replace across all text cells |
# Freeze Panes
| Command | Action |
:freeze rows N | Freeze top N rows (they stay visible while scrolling) |
:freeze cols N | Freeze left N columns |
:freeze off | Clear all freeze panes |
# Themes
:theme — open the interactive theme picker
:theme <name> — apply a theme by name directly
- t from the welcome screen — browse and preview themes
- Custom themes can be defined in
~/.config/asat/config.toml
# Plugins
ASAT supports Python plugins via PyO3 (opt-in feature).
| Command | Action |
:plugins | Open the plugin manager panel |
:plugin reload | Reload init.py |
:plugin list | List installed plugins |
# Configuration
Configuration file is at ~/.config/asat/config.toml. Press c from the welcome screen to open it.
:set <option> — set options at runtime
- Theme, keybindings, default column width, scroll padding, and more can be configured
# Ex-Commands Reference
All commands are entered with : from Normal mode. Tab auto-completes.
| Command | Description |
:w | Save to current file |
:w <file> | Save to a new file (format by extension) |
:q | Quit (warns if unsaved changes) |
:q! | Force quit without saving |
:wq / :x | Save and quit |
:e <file> | Open a file |
:home | Return to welcome screen |
:tabnew / :tabedit | Create new sheet |
:tabclose | Close current sheet |
:ir | Insert row below cursor |
:dr | Delete current row |
:ic | Insert column to the left |
:icr | Insert column to the right |
:dc | Delete current column |
:cw <N> | Set column width to N characters |
:rh <N> | Set row height to N |
:bold | Toggle bold on cell / selection |
:italic | Toggle italic |
:underline | Toggle underline (text characters only) |
:underline full | Toggle full-width underline (entire cell including padding) |
:strike | Toggle strikethrough |
:fg <color> | Set foreground colour (hex or name) |
:bg <color> | Set background colour |
:hl <color> | Highlight: set bg + auto-contrast fg |
:hl | Clear highlight |
:align l/c/r | Set alignment |
:fmt <spec> | Number format: %, $, 0.00, int, date, datetime, none |
:copystyle | Copy current cell style |
:pastestyle | Paste style to cell / selection |
:cs | Clear all styles |
:wrap | Toggle line-wrap |
:sort asc/desc | Sort rows by cursor column |
:s /pat/repl/g | Find & replace in text cells |
:filter <c> <op> <v> | Filter rows (e.g. :filter A >100) |
:filter off | Clear row filter |
:transpose | Transpose visual selection |
:dedup | Remove duplicate rows |
:filldown / :fillright | Fill selection from anchor |
:merge / :unmerge | Merge / unmerge cells |
:name <n> <range> | Define named range |
:colfmt <op> <v> <color> | Conditional format rule |
:note <text> | Set cell note (:note view, :note! clear) |
:J | Join cell below into current |
:goto <cell> | Jump to cell (e.g. :goto B15) |
:help / :h | Open searchable help screen |
:home | Return to welcome screen |
:theme | Open theme picker |
:theme <name> | Apply theme directly |
:set <option> | Set an option |
:freeze rows <N> | Freeze top N rows |
:freeze cols <N> | Freeze left N columns |
:freeze off | Clear freeze panes |
:plugin reload | Reload init.py |
:plugins | Open plugin manager |
# Keybinding Quick Reference
Normal Mode
| Key | Action |
| hjkl | Move cursor |
| w/b/W/B/e | Jump non-empty cells |
| }/{ | Next/prev paragraph |
| gg/G | First/last row |
| 0/$ | First/last column |
| H/M/L | Screen top/mid/bottom |
| ^d/^u/^f/^b | Page scroll |
| zz/zt/zb | Center/top/bottom |
| g{A-Z}/f{c} | Jump to column |
| i/Enter/a/s/cc | Edit cell |
| r/o/O | Replace/open row |
| ci{d} | Change inner delim |
| x/D/dd/dc/dC | Delete cell/row/col |
| dj/dk | Delete row below/above |
| ~/^a/^x | Toggle case / inc / dec |
| J/U/gw | Join/unmerge/wrap |
| yy/yc/yC/yj/yk/yS | Yank operations |
| p/P/pS | Paste |
| u/^r | Undo/redo |
| . | Repeat last change |
| v/V/^v | Visual modes |
| : | Command mode |
| //?/n/N/* | Search |
| gt/gT/gd | Sheets/goto def |
| m{c}/'{c}/'' | Marks |
| q{c}/@{c}/@@ | Macros |
| >>/<</= | Column sizing |
| +/-/_ | Row sizing |
Visual Mode
| Key | Action |
| d/x | Delete |
| c/s | Clear + edit |
| y | Yank |
| M/S | Merge / SUM |
| ^d/^r/^f | Fill down/right/auto |
| >/< | Resize columns |
Insert Mode
| Key | Action |
| Enter/Tab/Esc | Confirm (down/right/stay) |
| ^a/^e | Start/end of buffer |
| ^w/^u/^k | Delete word/to-start/to-end |
| ^v | Paste clipboard |
| ^r | Formula ref picker |