Markdown & CSV table editor for Neovim — structural editing, pure text, always valid.
Supports Markdown and CSV out of the box, and can be extended to other formats via custom parsers.
Edit Markdown tables structurally.
Raw → aligned → edit → back to raw (lossless).
Raw → aligned → edit → back to raw (lossless).
- Vim-first
- Text-only buffer
- Structurally safe
- Fully reversible transformation
- No hidden metadata
- Always valid
Markdown and CSV are text — but they represent structure.
Tirenvi lets you edit tabular data structurally, while staying in Vim’s native editing model.
You edit text. Tirenvi preserves structure.
At the center is: TIR — Tabular Intermediate Representation
flat (gfm markdown, csv, tsv, ...)
↓ external parser
TIR (intermediate representation)
↓ tirenvi
tir-vim (structured buffer view)
Editing happens in tir-vim format.
On save:
tir-vim → TIR → original flat format
Key principles:
- The buffer contains only text
- No hidden state
- No shadow buffer
- No custom buffer type
- Transformations are reversible
- The buffer is always structurally valid
Edit tables directly in Vim — without breaking structure.
- Render CSV/TSV/GFM into an aligned structured view
- Preserve original file format on save
- Toggle raw ↔ structured view
- Automatic structural correction
- Multiline cell support with preserved line breaks
- Column width control with wrapping support
- Grid-aware join that preserves column structure
- Column text objects for structural editing
- Works with all native Vim motions and operators
- External parser architecture (extensible)
- No learning curve
Tirenvi is a strict editor.
- Invalid structural edits are detected
- In Normal mode: corrected immediately
- In Insert mode: corrected after leaving Insert
- Undo tree integrity is preserved
- Only leaf undo states are auto-corrected
Structural integrity is preserved in the current editing state.
Tirenvi respects Vim’s undo tree. Historical undo states are not modified, even if they contain temporary structural inconsistencies.
{
"kibi2/tirenvi.nvim",
dependencies = {
"tpope/vim-repeat", -- optional: enables '.' repeat for column width operations
},
config = function()
require("tirenvi").setup {}
end,
}Plug 'kibi2/tirenvi.nvim'
" Optional: enables '.' repeat for column width operations
Plug 'tpope/vim-repeat'- Neovim >= 0.9
- UTF-8 environment
Install parsers:
pip install tir-gfm-lite
pip install tir-csv
pip install tir-pukiwikiAutomatically activates based on filetype (via parser_map):
csvtsvmarkdownpukiwiki
Custom parser mapping:
require("tirenvi").setup({
parser_map = {
csv = { executable = "tir-csv", required_version = "0.1.4" },
tsv = { executable = "tir-csv", options = { "--delimiter", "\t" }, required_version = "0.1.4" },
markdown = { executable = "tir-gfm-lite", allow_plain = true, required_version = "0.1.6" },
pukiwiki = { executable = "tir-pukiwiki", allow_plain = true, required_version = "0.1.1" },
}
})| Command | Description |
|---|---|
:Tir redraw |
Normalize table layout (trim padding and re-align cells) |
:Tir toggle |
Switch raw ↔ structured table view |
:Tir width[=+-][count] |
Adjust column width by count (=: set, +/-: increment/decrement) |
All native Vim editing works.
dd,yy,p,D,o,R,J, and more- Command-line command
- Visual mode command
No special editing mode.
Columns are structural units.
To modify a column:
- Select a column using text objects (
vil,val,v3al) - Apply standard operators (
d,p, etc.)
require("tirenvi").setup({
textobj = {
column = "l",
},
})Operations that would break structure are automatically corrected.
Column width operations support . repeat when
vim-repeat is installed.
Fast horizontal navigation across cells.
vim.keymap.set({ 'n', 'o', 'x' }, '<leader>tf', require('tirenvi').motion.f, { expr = true })
vim.keymap.set({ 'n', 'o', 'x' }, '<leader>tF', require('tirenvi').motion.F, { expr = true })
vim.keymap.set({ 'n', 'o', 'x' }, '<leader>tt', require('tirenvi').motion.t, { expr = true })
vim.keymap.set({ 'n', 'o', 'x' }, '<leader>tT', require('tirenvi').motion.T, { expr = true })They behave like Vim’s f/F/t/T,
but target table separators.
; and , continue to repeat as usual.
Note: There are two types of pipes (continuation and non-continuation), so motions may behave differently across lines.
- Not a spreadsheet
- Not a new editing mode
- Not a hidden AST editor
- Not a file-format converter
It is a structured text editor layer.
- Text objects (table, row, column, cell)
- Column formatting presets
- Outline mode
- Optional non-strict mode (experimental)
| Feature | Tirenvi | csv.vim | Spreadsheet tools |
|---|---|---|---|
| Native Vim editing | ✅ | ❌ | |
| Always structurally valid | ✅ | ❌ | |
| No file format change | ✅ | ❌ | ❌ |
| No custom buffer type | ✅ | ❌ | ❌ |
| Toggle raw view | ✅ | ❌ | ❌ |
| Markdown | ✅ | ❌ | ❌ |
| Automatic wrapping | ✅ | ❌ | |
| Grid-aware join | ✅ | ❌ | ❌ |
Tirenvi prioritizes structural safety with Vim purity.
The architecture centers around:
- flat ↔ TIR (external)
- TIR ↔ tir-vim (internal)
Large changes should respect this separation.
Please open an issue before major design proposals.
MIT License.

