/

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)

# Download the latest .deb from GitHub Releases, then: $ 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 # welcome screen $ asat budget.csv # open a CSV file $ asat report.xlsx # open an Excel file

Welcome Screen Keys

KeyAction
nNew empty spreadsheet
fOpen file finder (fuzzy search)
rRecent files list
tTheme browser
cOpen configuration file
?Open help screen
q / EscQuit

# File Formats

FormatReadWriteNotes
.csvYesYesComma-separated values
.xlsxYesYesExcel (calamine / rust_xlsxwriter)
.odsYesYesOpenDocument Spreadsheet
.asatYesYesNative binary format (bincode + zstd)

Save with :w to save to the current file, or :w filename.xlsx to save as a different format. The format is determined by the file extension.

# 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

KeyAction
h j k lMove left / down / up / right (count prefix supported)
w / bNext / previous non-empty cell horizontally
W / BNext / previous non-empty cell vertically
eNext non-empty cell horizontally (alias for w)
} / {Next / previous paragraph (empty row boundary)
ggJump to first row
GJump to last row
0 / HomeJump to first column
$ / EndJump to last column
H / M / LTop / middle / bottom of visible area
Ctrl+d / Ctrl+uPage down / up
Ctrl+f / Ctrl+bPage down / up (alias)
PgDn / PgUpPage down / up
zz / zt / zbScroll 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 / BackTabMove right / left one cell

Entering Edit

KeyAction
i / Enter / F2Edit cell (cursor at end of content)
aEdit cell in append mode (cursor at end)
s / ccClear cell content and start editing
ci"Change inner: select text between " delimiters and edit. Also works with ( [ { < '
rReplace mode — edit cell, then return to Normal on confirm
oInsert row below and start editing
OInsert row above and start editing

Cell Operations

KeyAction
x / D / DelClear cell content (yanks to register first)
ddDelete entire row (count prefix: 3dd deletes 3 rows). Yanks first.
dcClear cell content (alias for x)
dCDelete entire column
dj / dkDelete row below / above (count prefix supported)
~Toggle case of text cell content
Ctrl+aIncrement: add 1 to number, cycle date/weekday/month forward
Ctrl+xDecrement: subtract 1 from number, cycle backward
JJoin cell below into current cell (concatenate)
UUnmerge cell under cursor
gwToggle line-wrap on cell
.Repeat last change

Undo / Redo

KeyAction
uUndo last change
Ctrl+rRedo

# 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.

KeyAction
Confirm / Exit
EnterConfirm edit, move down one row
TabConfirm edit, move right one cell
EscConfirm edit, stay in place
Cursor Movement
Left / RightMove edit cursor within cell text
Ctrl+aJump to start of edit buffer
Ctrl+eJump to end of edit buffer
Editing
BackspaceDelete character to the left
DeleteDelete character to the right
Ctrl+wDelete word backward
Ctrl+uDelete from cursor to start of buffer
Ctrl+kDelete from cursor to end of buffer
Ctrl+vPaste from system clipboard into edit buffer
Formula Features (when editing =...)
Tab / BackTabCycle through function name completions
Ctrl+rEnter 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
KeyAction
Extend Selection
hjkl, arrowsExtend selection in direction
w/b/W/BExtend by non-empty cell
} / {Extend by paragraph
0 / $Extend to first / last column
gg / GExtend to first / last row
Actions
d / x / DelDelete selection (yanks to register first)
c / sClear selection and enter insert mode
yYank (copy) selection to register + clipboard
MMerge selection into one cell
SInsert =SUM() formula below/right of selection
Ctrl+dFill down — copy anchor row to all selected rows
Ctrl+rFill right — copy anchor column to all selected columns
Ctrl+fAuto-fill series — smart direction detection from anchor to cursor
> / <Widen / narrow columns (count prefix supported)
:Enter command mode with selection range pre-filled
Mode
v / VSwap between visual sub-modes, or exit
EscExit 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

KeyAction
/Search forward (from Normal mode)
?Search backward
n / NNext / previous match (count prefix supported)
*Search for the content of the cell under cursor
EscClear 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)

KeyAction
yy / yrYank entire row (count prefix: 3yy yanks 3 rows)
ycYank cell
yCYank entire column
yj / ykYank row below / above
ySCopy cell style to style clipboard

Paste

KeyAction
pPaste after cursor position
PPaste before cursor position
pSPaste 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

KeyAction
>> / <<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 NSet column width to exactly N characters
:rh NSet row height to exactly N

Insert / Delete

Key / CommandAction
:irInsert row below cursor
:drDelete current row
:icInsert column to the left
:icrInsert column to the right
:dcDelete current column
ddDelete row (Normal mode)
dCDelete column (Normal mode)

# Formatting & Styles

CommandAction
Text Style
:boldToggle bold on cell / selection
:italicToggle italic
:underlineToggle underline (text characters only)
:underline fullToggle full-width underline (entire cell including padding)
:strikeToggle strikethrough
Colors
:fg <color>Set foreground color (hex #rrggbb or name: red, blue, green...)
:bg <color>Set background color
:hl <color>Highlight: set background + auto-contrast foreground
:hlClear highlight (remove bg and fg colors)
Layout
:align l/c/rSet text alignment: left, center, right
:wrapToggle line-wrap on cell/selection
Number Format
:fmt %Percentage format (0.15 → 15%)
:fmt $Currency format ($1,234.56)
:fmt 0.00Fixed decimal places
:fmt intInteger (no decimals)
:fmt dateDate format
:fmt datetimeDate + time format
:fmt noneClear number format
Style Clipboard
:copystyleCopy current cell style
:pastestylePaste style to cell / selection
ySCopy cell style (Normal mode)
pSPaste style (Normal mode)
:csClear all styles from cell / selection

# Formulas

Start a formula with = in any cell. Formulas are automatically recalculated every frame.

Cell References

SyntaxMeaning
A1Relative reference — adjusts on paste
$A$1Absolute row and column — never adjusts
$A1Absolute column, relative row
A$1Relative column, absolute row
A1:C10Range reference
Sheet1!A1Cross-sheet reference
'Sheet Name'!A1:B5Quoted sheet name with spaces

Operators

OperatorMeaning
+ - * /Arithmetic
^Exponentiation (power)
&String concatenation
= <>Equal / not equal
< <= > >=Comparison

Editing Features

  • Tab completion: While typing a function name after =, press Tab to cycle through matching function names
  • Reference picker: Press Ctrl+r to enter F-REF mode and pick cells/ranges by navigating the grid
  • Auto-recalculation: All formulas update automatically every frame

# Formula Functions

Math

SUM
SUM(number1, [number2, ...])
Sum of all values in a range or list
AVERAGE
AVERAGE(number1, [number2, ...])
Arithmetic mean; empty cells ignored
MIN / MAX
MIN(range) / MAX(range)
Smallest / largest value
ABS
ABS(number)
Absolute (positive) value
ROUND
ROUND(number, digits)
Round to N decimal places
ROUNDUP / ROUNDDOWN
ROUNDUP(n, digits)
Round away from / toward zero
FLOOR / CEILING
FLOOR(n, significance)
Round down/up to nearest multiple
MOD
MOD(number, divisor)
Remainder after division
POWER
POWER(base, exp)
Raise to exponent (same as ^)
SQRT
SQRT(number)
Square root
LN / LOG / LOG10
LOG(number, [base])
Logarithm: natural, arbitrary base, base-10
EXP
EXP(number)
e raised to the power
INT / TRUNC
INT(n) / TRUNC(n, [digits])
Integer part: floor vs. truncate
SIGN
SIGN(number)
Returns -1, 0, or 1
PI
PI()
Returns 3.14159265...

Statistics

COUNT / COUNTA
COUNT(range) / COUNTA(range)
Count numeric / non-empty cells
SUMIF
SUMIF(range, criteria, [sum_range])
Conditional sum
COUNTIF
COUNTIF(range, criteria)
Count cells matching criteria
AVERAGEIF
AVERAGEIF(range, criteria, [avg_range])
Conditional average
SUMPRODUCT
SUMPRODUCT(array1, [array2, ...])
Sum of element-wise products
MEDIAN
MEDIAN(number1, ...)
Middle value (robust to outliers)
STDEV / VAR
STDEV(range) / VAR(range)
Sample standard deviation / variance
LARGE / SMALL
LARGE(range, k)
k-th largest / smallest value
RANK
RANK(value, range, [order])
Rank of value in range
PERCENTILE
PERCENTILE(range, k)
k-th percentile (k = 0..1)
QUARTILE
QUARTILE(range, quart)
Quartile (0=min, 2=median, 4=max)
MAXIFS / MINIFS
MAXIFS(range, crit_range, criteria)
Max/min with criteria

Text

LEN
LEN(text)
Character count
LEFT / RIGHT / MID
LEFT(text, n) / MID(text, start, n)
Extract substring from start / end / middle
TRIM
TRIM(text)
Remove extra whitespace
UPPER / LOWER / PROPER
UPPER(text)
Case conversion: upper / lower / title
CONCATENATE
CONCATENATE(t1, t2, ...)
Join text strings (or use &)
TEXT
TEXT(value, format)
Format number as text string
VALUE
VALUE(text)
Parse text to number
FIND / SEARCH
FIND(needle, haystack)
Position of text (FIND=case-sensitive, SEARCH=insensitive)
SUBSTITUTE
SUBSTITUTE(text, old, new, [nth])
Replace text by content
REPLACE
REPLACE(text, start, len, new)
Replace text by position
REPT
REPT(text, n)
Repeat text n times

Logic

IF
IF(cond, val_true, [val_false])
Conditional: return different values based on test
AND / OR / NOT
AND(c1, c2, ...) / OR(c1, c2, ...)
Logical operators
IFERROR
IFERROR(value, fallback)
Return fallback if value is an error
ISNUMBER / ISTEXT / ISBLANK
ISNUMBER(value)
Type-checking functions
ISERROR / ISLOGICAL
ISERROR(value)
Error and boolean checks
TRUE / FALSE
TRUE / FALSE
Boolean constants

Lookup

XLOOKUP
XLOOKUP(val, lookup, return, [missing])
Modern flexible lookup — replaces VLOOKUP/HLOOKUP
VLOOKUP / HLOOKUP
VLOOKUP(val, table, col, FALSE)
Vertical / horizontal lookup
INDEX / MATCH
INDEX(range, row, [col])
Return value at position / find position
OFFSET
OFFSET(ref, rows, cols, [h], [w])
Shifted reference for dynamic ranges
CHOOSE
CHOOSE(index, val1, val2, ...)
Pick value by index number

Finance

PV / FV
PV(rate, nper, pmt)
Present value / future value
PMT
PMT(rate, nper, pv)
Periodic payment for a loan
NPER / RATE
NPER(rate, pmt, pv)
Number of periods / interest rate
NPV / IRR / MIRR
NPV(rate, cashflows...)
Net present value / internal rate of return
IPMT / PPMT
IPMT(rate, per, nper, pv)
Interest / principal portion of payment
CUMIPMT / CUMPRINC
CUMIPMT(rate, nper, pv, s, e, type)
Cumulative interest / principal
SLN / DDB
SLN(cost, salvage, life)
Straight-line / double-declining depreciation
EFFECT / NOMINAL
EFFECT(nominal_rate, npery)
Effective / nominal annual interest rate conversion

Date & Time

NOW
NOW()
Current date + time (volatile, recalculates every frame)
TODAY
TODAY()
Today's date as serial number
DATE
DATE(year, month, day)
Construct date from components
YEAR / MONTH / DAY
YEAR(date)
Extract year / month / day from date

Random (Volatile)

RAND
RAND()
Random float in [0, 1) — changes every frame
RANDBETWEEN
RANDBETWEEN(lo, hi)
Random integer in [lo, hi]

# Data Operations

CommandAction
:sort asc/descSort all rows by the cursor column (ascending or descending)
:filter A >100Filter: show only rows where column A value > 100
:filter offClear active row filter
:transposeTranspose visual selection (swap rows and columns)
:dedupRemove duplicate rows (by cursor column)
:filldownFill selection down from the top row
:fillrightFill selection right from the leftmost column
:merge / :unmergeMerge visual selection into one cell / unmerge
:name sales A1:C10Define a named range
:colfmt >100 redConditional formatting rule for column
:note HelloSet cell note (:note to view, :note! to clear)
:s/pat/repl/gFind and replace across all text cells
:JJoin 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, 23, 4, 5, ... or 10, 2030, 40, 50, ...
  • Weekday names (short): Mon, TueWed, Thu, Fri, ...
  • Weekday names (full): Monday, TuesdayWednesday, Thursday, ...
  • Month names (short): Jan, FebMar, Apr, May, ...
  • Month names (full): January, FebruaryMarch, April, ...
  • Cyclic repeat: Any other values repeat cyclically
Case Preservation: The output preserves the case style of your seed. montue, wed; MONTUE, WED; MonTue, Wed; MONDAYTUESDAY, 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 / CommandAction
gtSwitch to next sheet tab
gTSwitch to previous sheet tab
:tabnew / :tabeditCreate a new sheet
:tabcloseClose 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.

KeyAction
q{a-z}Start recording into register (e.g. qa)
qStop 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

KeyAction
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 / CommandAction
/Search forward
?Search backward
n / NNext / previous match (count prefix supported)
*Search for cell content under cursor
EscClear search highlights
:s/pattern/replacement/gFind and replace across all text cells

# Freeze Panes

CommandAction
:freeze rows NFreeze top N rows (they stay visible while scrolling)
:freeze cols NFreeze left N columns
:freeze offClear 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).

CommandAction
:pluginsOpen the plugin manager panel
:plugin reloadReload init.py
:plugin listList 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.

CommandDescription
File
:wSave to current file
:w <file>Save to a new file (format by extension)
:qQuit (warns if unsaved changes)
:q!Force quit without saving
:wq / :xSave and quit
:e <file>Open a file
:homeReturn to welcome screen
Sheets
:tabnew / :tabeditCreate new sheet
:tabcloseClose current sheet
Rows & Columns
:irInsert row below cursor
:drDelete current row
:icInsert column to the left
:icrInsert column to the right
:dcDelete current column
:cw <N>Set column width to N characters
:rh <N>Set row height to N
Formatting
:boldToggle bold on cell / selection
:italicToggle italic
:underlineToggle underline (text characters only)
:underline fullToggle full-width underline (entire cell including padding)
:strikeToggle strikethrough
:fg <color>Set foreground colour (hex or name)
:bg <color>Set background colour
:hl <color>Highlight: set bg + auto-contrast fg
:hlClear highlight
:align l/c/rSet alignment
:fmt <spec>Number format: %, $, 0.00, int, date, datetime, none
:copystyleCopy current cell style
:pastestylePaste style to cell / selection
:csClear all styles
:wrapToggle line-wrap
Data
:sort asc/descSort rows by cursor column
:s /pat/repl/gFind & replace in text cells
:filter <c> <op> <v>Filter rows (e.g. :filter A >100)
:filter offClear row filter
:transposeTranspose visual selection
:dedupRemove duplicate rows
:filldown / :fillrightFill selection from anchor
:merge / :unmergeMerge / unmerge cells
:name <n> <range>Define named range
:colfmt <op> <v> <color>Conditional format rule
:note <text>Set cell note (:note view, :note! clear)
:JJoin cell below into current
Navigation & UI
:goto <cell>Jump to cell (e.g. :goto B15)
:help / :hOpen searchable help screen
:homeReturn to welcome screen
:themeOpen 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 offClear freeze panes
:plugin reloadReload init.py
:pluginsOpen plugin manager

# Keybinding Quick Reference

Normal Mode

KeyAction
hjklMove cursor
w/b/W/B/eJump non-empty cells
}/{Next/prev paragraph
gg/GFirst/last row
0/$First/last column
H/M/LScreen top/mid/bottom
^d/^u/^f/^bPage scroll
zz/zt/zbCenter/top/bottom
g{A-Z}/f{c}Jump to column
i/Enter/a/s/ccEdit cell
r/o/OReplace/open row
ci{d}Change inner delim
x/D/dd/dc/dCDelete cell/row/col
dj/dkDelete row below/above
~/^a/^xToggle case / inc / dec
J/U/gwJoin/unmerge/wrap
yy/yc/yC/yj/yk/ySYank operations
p/P/pSPaste
u/^rUndo/redo
.Repeat last change
v/V/^vVisual modes
:Command mode
//?/n/N/*Search
gt/gT/gdSheets/goto def
m{c}/'{c}/''Marks
q{c}/@{c}/@@Macros
>>/<</=Column sizing
+/-/_Row sizing

Visual Mode

KeyAction
d/xDelete
c/sClear + edit
yYank
M/SMerge / SUM
^d/^r/^fFill down/right/auto
>/<Resize columns

Insert Mode

KeyAction
Enter/Tab/EscConfirm (down/right/stay)
^a/^eStart/end of buffer
^w/^u/^kDelete word/to-start/to-end
^vPaste clipboard
^rFormula ref picker