Show HN: A terminal spreadsheet editor with Vim keybindings | Hacker News
| Hacker Newsnew | past | comments | ask | show | jobs | submit| login
Show HN: A terminal spreadsheet editor with Vim keybindings (github.com/garritfra)
126 points by garritfra 44 days ago | hide | past | favorite | 50 comments While speccing out this spreadsheet tool, I realized that I never had to think about the keybindings. It all just came naturally from Vim. Normal/insert/visual modes, hjkl navigation, dd/yy/p, :w, :q. The usual muscle memory works.It supports CSV/TSV import and export, and a native .cell format that preserves formulas. The formula engine handles SUM, AVERAGE, COUNT, MIN, MAX, and IF with range references.The codebase is a Cargo workspace: a pure cell-sheet-core library (no TUI dependency) and a cell-sheet-tui crate on top of ratatui. Early days, but it's usable.To try it out: cargo install cell-sheet-tuiFeedback of any kind is greatly appreciated!
| freedomben 44 days ago | next [–]
Very neat, a tool like this is badly needed. Also cool to see it's in rust (that means I can hack on it).To be really useful to me though (and I would imagine others), it will need to be able to at least view (but probably edit) xlsx and/or open document format spreadsheets. I know that's a huge task, but it would add immense value to the project. I'm not asking for it and I don't feel "entitled" to it (lest the inevitable replies of "add it youself" come flying in), just trying to provide some helpful feedback.Question: is this a project you see yourself staying committed to long term? (Obviously life events happen and things change, but at least for now, do you enjoy it? Do you use it as part of your workflow? Do you feel like it's something you'll want to own long term?)
| garritfra 44 days ago | parent | next [–]
Thank you!XLSX and ODS support won't be trivial, but I see the value of having it. I added it to the roadmap: https://github.com/garritfra/cell/issues/22Regarding your question: This idea has been sitting on my todo list [1] for over 3 years now. I don't usually work with large data files in my dayjob, but occasionally working with the odd CSV on macOS frustrated me enough to put it on the list. And now that spec-driven development has matured enough to be actually useful, there's no real excuse not to build this.I genuinely see myself caring for this long-term. I'm comfortable with the scope, and there seems to be some real interest from the community.[1]: https://garrit.xyz/todo
| rpassos 44 days ago | prev | next [–]
I've been using https://github.com/medialab/xan for anything csv. It's the best tool there is for reading and analyzing csv files, but not for writing them. Something like cell-sheet-tui would fit my workflow very well, since I am using neovim to edit csv files manually (as well as some csv merging features offered by xan to simplify the process).The reason why I find your software promising is because dealing with csv in plain text is very disorienting with the inconsistent horizontal cell space. A csv-aware text editor would help a lot there with two issues in particular:- not having to set commas manually, especially not having to count them between empty cells- being able to navigate using h/j/k/l between cells instead of having to get creative with vim-motions on plain textOP, if you're reading this:I would greatly appreciate if this tool could focus on the writing experience and less with anything formula engine related, since xan is already a very performant tool for that, even at large data sets. Replacing or even competing with xan seems very difficult in my eyes, considering both tools are targeting a similar audience (rust, minimalist, and performance), which makes me think cell could focus more on the writing experience, like I said.There are some bugs I countered right away and I'll get to open issues in due time. Thanks for making this and I hope I can replace neovim with cell for anything csv in the future!
| ranger_danger 42 days ago | parent | next [–]
It's the best tool there is for reading and analyzing csv filesIt does not appear to support the file types I regularly work with: https://www.fda.gov/medical-devices/medical-device-reporting...These files have a field delimiter of '|' with a line delimiter of '\r\n', as individual fields also contain '\n' characters.I prefer visidata as the program stays running while searching and navigating through large files, making subsequent searches and filtering much faster, plus editing/writing is also supported, as well as Excel and other formats I regularly use.
| garritfra 44 days ago | parent | prev | next [–]
Author here - thanks for bringing this up!Cell is very much tailored towards what you're looking for. My vision was "Excel but it's (Neo)Vim". Editing files should feel just as smooth as looking at the data. I believe Xan and Cell could actually pipe into each other quite nicely for rendering more complex data.I'd really appreciate your time to report the bugs you encountered. Looking forward to them.
| nanis 44 days ago | prev | next [–]
This looks good, but, I noticed:> Supported Functions (v1) > SUM, AVERAGE, COUNT, MIN, MAX, IFI would recommend switching to numerically stable algorithms for adding numbers and taking their averages sooner rather than later.Looking at the code[1], it looks like you are simply summing the numbers and dividing by count. If that is indeed the case, please switch to a stable average[2]. See also [3].Additionally, I tried to test the executable[4] on Windows, but there is something wrong with input. Using Windows Terminal Version: 1.24.10921.0, characters are doubled on input. Regular Vim compiled using Visual C++ does not have this issue.When I press :, I get :: in the COMMAND line. Then, every key I press gets doubled. This means I cannot :q!. :-)[1]: https://github.com/garritfra/cell/blob/99b0afc7a60a871b27452...[2]: https://www.nu42.com/2015/03/how-you-average-numbers.html[3]: https://en.wikipedia.org/wiki/Algorithms_for_calculating_var...[4]: https://github.com/garritfra/cell/releases/tag/v0.2.0
| garritfra 44 days ago | parent | next [–]
This is valuable feedback. I opened two issues to track this:Use numerically stable algorithms for SUM and AVERAGE: https://github.com/garritfra/cell/issues/43Keystrokes doubled in Windows Terminal: https://github.com/garritfra/cell/issues/44Thanks!
| nanis 38 days ago | root | parent | next [–]
I was able to test the keystroke-doubling and that works well in Windows Terminal now. I am going to try out the formulas later.
| sev_verso 42 days ago | parent | prev | next [–]
Interesting. Last time I dealt with currency in SQL (which was well over a decade ago admittedly), we used a fixed point format for those fields.What do you recon Excel does, floating point math for regular entries and lossless point math for currency? Or just does not rely on floats at all?
| marcyb5st 44 days ago | prev | next [–]
Pretty cool project! Congrats.QQ: does it support programmatic cell access/modifications?Eg cell file.cell --write A2 "42" or cell file.cell --read "=SUM(A1:A10)"? Couldn't surmise that from the glimpse I gave the README, but it would be pretty cool for scripting stuff.
| garritfra 44 days ago | parent | next [–]
Love this idea! I created a GH issue for this: https://github.com/garritfra/cell/issues/6I'll try to add this ASAP. :)
| garritfra 44 days ago | parent | prev | next [–]
Update: This just landed in v0.1.7. Thanks again for bringing this up!
| marcyb5st 44 days ago | root | parent | next [–]
My pleasure!
| slu 44 days ago | prev | next [–]
Nice. I've been using https://github.com/andmarti1424/sc-im for a while now. It would be great with a comparison.
| garritfra 44 days ago | parent | next [–]
Cell is heavily inspired by this project. FWIW, I added a comparison chart to the README: https://github.com/garritfra/cell#comparison-with-sc-im
| k2enemy 44 days ago | prev | next [–]
Looks terrific! I have a suggestion as you continue to add features and think about scripting. sc-im has lua external functions, but you cannot pass a range of cells, only the value of one cell. This severely limits the usefulness of external lua scripts. If/when you add scripting, hopefully you can overcome this limitation. If so, you'll have at least one more user!
| garritfra 44 days ago | parent | next [–]
I see the value, but I'm not sure if I'd be confident enough to add proper scripting yet, as this requires a lot of attention towards a stable API.Nonetheless, I think it's an intersting discussion to put on the roadmap: https://github.com/garritfra/cell/issues/23 (RFC sketched out by AI)Thanks!
| cassepipe 44 days ago | parent | prev | next [–]
https://github.com/andmarti1424/sc-imSaved you all a search: It seems like it is similar software written in C
| daft_pink 44 days ago | prev | next [–]
It’s really amazing how spreadsheet started in the terminal and have come full circle back to the terminal.This is fantastic thanks for your work
| WillAdams 44 days ago | prev | next [–]
Was initially hopeful that this would rather than have A..B..C... and 1..2..3... for columns and rows would instead have one creating categories à la Javelin/Lotus Improv/Quantrix/Flexisheet --- give me that, and have a dynamic system for displaying a pane of formulae and one would have a very nice tool.
| garritfra 44 days ago | parent | next [–]
Huh, I haven't thought about that yet, but I like it. I opened an issue to track this: https://github.com/garritfra/cell/issues/11I'd have to look into the tools you mentioned to really understand all the details. Thanks!
| WillAdams 44 days ago | root | parent | next [–]
Thanks! I'm gratified!I made a comment on that issue which hopefully will inform this --- I will note that while on the surface it's a great idea, the UI will be very challenging and not being able to address it may make it not worth pursuing.Alternately, maybe the correct approach would be some sort of hybrid where columns/rows can be named and then referred to using said names....I really miss Lotus Improv, and can't afford Quantrix, and don't have the programming chops to resurrect Flexisheet, so I keep pestering folks about this, but in the meanwhile, I use pyspread....
| adilkhanovkz 43 days ago | parent | prev | next [–]
Dimensions over A1/B2 is the right move. Rust is a good base for the engine — formula propagation in dimensional models needs to be fast. Curious whether the bigger challenge is the engine or the UI layer
| pca2 44 days ago | prev | next [–]
Very cool, I was just wishing for a tool like this today. A small feature request I would love to see: Support for custom delimiters. I sometimes work with CSVs that actually use pipe (|) as the delimiter to avoid issues with cells that contain commas as content.
| garritfra 44 days ago | parent | next [–]
Thank you! I fully agree with your request. Added it to the roadmap: https://github.com/garritfra/cell/issues/20
| cassepipe 44 days ago | parent | prev | next [–]
Do you save them as .psv ? :)
| ximm 44 days ago | prev | next [–]
I was working on something similar a while back (https://github.com/xi/spreadsheet) but ended up not using it. I just didn't end up being the first tool that came to mind when I was reaching for a spreadsheet. Not sure why.I will definitely try out your tool and check if it works better to me.Two random thoughts:- In excel I often use the dragging feature, i.e. use a formula like $A2 + B$1 and then drag it in both directions. Does your tool have something similar?- Another nice feature are visualizations. In my tool I added a bar() function that renders a value between 0 and 1 as a bar in the cell. Not sure how flexible that is, but I did have some fun with it.
| garritfra 44 days ago | parent | next [–]
Thanks for trying it, and the spreadsheet repo is great prior art — I'll dig through it.Drag-fill. Not yet, but the parts are mostly there. The formula layer already carries abs_col/abs_row through tokenization → AST → eval, so $A2 + B$1 parses correctly today; what's missing is the editing op that copies a formula across a range and shifts only the relative components. Opened #17 for it. The tricky part isn't the rewrite, it's the keybinding — Vim doesn't have an obvious idiom for "drag," so I'm leaning toward a visual-selection + fill-from-anchor key (Y is a candidate) or a :fill command. Open to suggestions if you have a feel for what works in a modal editor. It also needs to land on top of the bulk-undo work in #8/#9 so a fill is one undo step instead of N.bar() / inline visualizations. Love it, opened #18. The interesting design call is whether BAR returns a CellValue::Visual { … } that the renderer dispatches on (correct under column resizes, but ripples into CSV export, copy/paste, and how SUM treats a visual cell), or whether it just returns a string of block-drawing chars at eval time (trivial to add, but width gets baked in at compute time which is wrong). The first is the right answer; the second is a tempting MVP. SPARKLINE(range) is the natural follow-up once the abstraction settles.#17 — https://github.com/garritfra/cell/issues/17 #18 — https://github.com/garritfra/cell/issues/18
| teo_zero 44 days ago | root | parent | next [–]
Vim doesn't have an obvious idiom for "drag," so I'm leaning toward a visual-selection + fill-from-anchor key (Y is a candidate)Better I or A, to mimick vim's multiple insert after a block selection.
| iammrpayments 44 days ago | prev | next [–]
I wonder if you can beat the excel world champions with that: https://youtu.be/QwNoFOUiSiE?si=4tKFWCAuFtWFHo34
| akshayKMR 43 days ago | prev | next [–]
Looks cool! Reminded me of ironcalc - rust based project that aims to have full excel parity. Linking it in case you might want to reuse/contribute to that engine.- https://www.ironcalc.com - Also found a tui interface for it - https://github.com/zaphar/sheetsui
| PaulBunch 43 days ago | prev | next [–]
This is really cool. The cell alignment and overall scannability are excellent.One thing I’ve noticed in many TUI tools is that even small inconsistencies in character width or icon rendering quickly become annoying. Did you run into any tricky rendering/alignment issues while building on ratatui?
| immccc 44 days ago | prev | next [–]
The kind of stuff that once you see it, you think "how didn't come the idea up to me?" :)Only thing is that it would be great to have it as a vim plugin, so that after opening a .csv file or similar, you can make use of the spreadsheet tooling.
| Theaetetus 44 days ago | prev | next [–]
This is great. I often want a low-latency, minimal-feeling option for this sort of thing. (And I get to use my Vim muscle memory less and less often these days!)Really, thanks for making and sharing this; so far, I feel calm and happy when I'm using it.
| garritfra 44 days ago | parent | next [–]
Glad to hear that. Thanks for trying it out! If you have any feedback, I'd be more than happy to hear it.
| reagle 44 days ago | prev | next [–]
visidata is vim influenced.
| self_awareness 43 days ago | prev | next [–]
A Lotus 1-2-3 "clone" is also trending now:https://github.com/duane1024/l123
| jzer0cool 44 days ago | prev | next [–]
Looks great something I want to check out. For comparison anyone share some built-in tools to pretty print-only the csv? Usually what I need to start but formatting is quite off.
| bewuethr 44 days ago | parent | next [–]
csvkit (https://github.com/wireservice/csvkit) has a "csvlook" command, and yq (https://github.com/mikefarah/yq) supports CSV as an input format.
| lydericlandry 44 days ago | prev | next [–]
This is very nice!See also: https://github.com/maaslalani/sheets
| bytejanitor 44 days ago | prev | next [–]
Looks very nice at first glance.I have been looking for something like this for a long time. Maybe this has some potential to become somewhat popular.
| unlikelyusernam 44 days ago | prev | next [–]
forgive me if I'm missing something obvious, but is there any plan to add jumping to a specific row? Usually when I scroll and find the row I'm looking for, I'll just nG there (where n is the row I found), which in vi-esque editors will jump to that specific line.
| garritfra 44 days ago | parent | next [–]
I fully agree that this should be on the roadmap: https://github.com/garritfra/cell/issues/21Thanks for bringing this up!
| teo_zero 44 days ago | prev | next [–]
The equal operator should work on strings, too. It would allow formulas like IF(A1=C3,A2,0)
| Keyframe 44 days ago | prev | next [–]
Lotus 1-2-3 flashbacks kicking in. I'll try it out for sure.
| tpoacher 44 days ago | prev | next [–]
i'll try this next time i'm on my laptop, but for now, how does it compare to visidata (which is a long standing peoject already?)
| solarized 43 days ago | prev | next [–]
hi, did your claude.md files always works consistently?
| voidtools 44 days ago | prev | next [–]
Good luck
|
| SilentEditor 44 days ago | prev [3 more]
[flagged]
| garritfra 44 days ago | parent [–]
Thanks!Honestly, the current implementations are pretty naive — they pass the tests and feel snappy on the small sheets I work with, but they'd buckle pretty quickly under real load. Most of what you're asking about is already on the tracker; I opened a batch of issues citing your comment as the prompt.Recalculation. Right now it's a full recalc on every edit: recalculate collects all formula cells, computes in-degrees across the whole formula set, topo-sorts, and evaluates top to bottom. The dirty flag gets propagated by mark_dirty but isn't actually used to prune work. It's also re-parsing every formula from its raw string on every pass. Two issues cover this: #8 introduces a batch boundary so paste/fill/CSV import trigger one recalc instead of N, and #7 adds criterion benches so we can actually tell whether the parser, the BFS, or the topo sort is the hotspot before optimizing. AST caching on Cell is the obvious next step once #7 confirms parsing dominates.https://github.com/garritfra/cell/issues/8 https://github.com/garritfra/cell/issues/7Dependency tracking. The bigger smell is in extract_deps — a range like SUM(A1:A1000) literally enumerates 1000 cell positions into the dep graph, with a HashSet per cell on each side. Fine at hundreds of cells, a disaster at hundreds of thousands. Range expansion is one of the bench cases in #7; the proper fix (interval-keyed deps so ranges stay first-class instead of fanning out) doesn't have its own issue yet — I should open one, since #7 only measures the problem.Undo/redo. This is the worst offender right now. UndoEntry only had a single-cell variant until very recently; #12 added MultiCellEdit, but #13 tracks two destructive paths I missed — visual-mode d and p/P paste — that still don't push undo entries at all. #9 is the broader coalescing story (one dd = one undo, CSV import = one undo, etc.), tied to the batch mechanism from #8 so a single transaction produces a single undo entry. sort_by_column is also non-undoable today and belongs in that bucket.https://github.com/garritfra/cell/issues/13 https://github.com/garritfra/cell/issues/9Larger CSVs. Storage is HashMap
| s_suiindik 44 days ago | root | parent [–]
Range as first-class is the right priority. Pattern that works: keep ranges as single AST nodes (one dep edge per range, not N), then use interval trees on the reverse side so a cell change at C5 becomes "find intervals covering (C, 5)" instead of scanning all formulas. Pairs well with column-oriented storage if you go thereOn the AST caching point, worth caching by structural hash of the parsed expression, not the source string. Copy paste with relative references produces different strings but identical AST shape, which hits a lot in financial-model-style workbooks where parallel columns share structureAlso worth a look: the "сalculation chain" docs in Microsot's OOXML SpreadsheetML spec describe how they serialize the dep order in xlsx files. Different problem (persistence vs runtime) but the data model is informative for what level of granularity ends up being practical

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact
Search: