Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

turbobook

Jupyter notebooks in the terminal. Real vim. Live Python kernel.

turbobook notebook.tb

No browser. No Electron. A 30ms keystroke-to-render notebook that works like an editor.


Why

Web notebooks are slow and mouse-dependent. Most "vim mode" add-ons are keybinding shims — they don't compose operators with motions. Jupyter's wire protocol is overkill for local work.

turbobook is a terminal-first notebook editor built from scratch:

  • Vim that actually composes. d2w, c$, yip, ct) — operators + motions work the way vim users expect, with correct inclusive/exclusive/linewise semantics.
  • Persistent Python kernel. A subprocess connected over a Unix socket keeps all your globals alive across cell executions.
  • Git-friendly format. .tb files are versioned JSON with stable UUID cell IDs (not execution counts). They diff cleanly.
  • Execute anywhere. Ctrl+Enter runs the focused cell from normal, insert, or visual mode — no mode switching required.

Installation

Requires Go 1.21+ and Python 3.10+.

git clone https://github.com/fntune/turbobook
cd turbobook
go build -o turbobook .
sudo mv turbobook /usr/local/bin/   # optional

Usage

turbobook notebook.tb   # open an existing notebook
turbobook               # splash screen with recent files

Key bindings

Navigation (normal mode)

Key Action
j / k Move focus between cells
Ctrl+Enter Execute focused cell
o / O Insert cell below / above
dd Delete cell
gg / G First / last cell
: Command mode

Editor (insert mode, inside a cell)

Full vim editing — all motions, operators, and text objects work:

Pattern Examples
Motions w b e B E 0 ^ $ gg G { }
Operators d c y with any motion (d2w, c$, yip)
Find/till f F t T + char, then ; / , to repeat
Visual v (char), V (line) — then any operator
Replace r (single char), ~ (toggle case)
Search / forward, ? backward, n / N to cycle
Join J joins next line

Commands

Command Action
:w Save (source only)
:w! Save with outputs
:q Quit

Format

Notebooks are stored as .tb files — plain JSON, designed to diff cleanly:

{
  "version": "1",
  "cells": [
    {
      "id": "3f2a1c8b-...",
      "type": "code",
      "source": "import pandas as pd\ndf = pd.read_csv('data.csv')",
      "outputs": [],
      "meta": { "exec_count": 1, "exec_ms": 42, "collapsed": false }
    }
  ]
}

Cell IDs are UUIDs — reordering cells doesn't rewrite the whole file.


Architecture

turbobook (Go binary)
├── bubbletea TUI                 event loop, terminal rendering
├── vim layer (pure functions)    VimState × Buffer → VimState × Buffer × Action
│   ├── normal mode               operators, motions, counts, registers
│   ├── insert mode               text input, ctrl sequences
│   └── visual mode               inclusive/exclusive selection
├── kernel client                 Unix socket IPC to Python subprocess
│   ├── execute / interrupt       cell execution, cancellation
│   └── status / ready            kernel lifecycle events
└── .tb format                    versioned JSON, UUID cells, MIME outputs

Python runtime (subprocess)
└── Unix socket server            JSON-RPC, Content-Length framing
    ├── execute handler           eval in shared namespace, captures stdout/stderr
    └── ready / shutdown          lifecycle handshake

The vim layer is entirely pure: every key event is a function from (VimState, Buffer, key) to (VimState, Buffer, Action). No side effects, no global state — the UI drives side effects based on the returned Action.


Status

Working alpha. Core vim editing, kernel execution, cell management, and .tb format are complete. Planned: LSP code completion, SQL cells with remote DB connections, AI generation and fix commands.

About

Terminal notebook editor with vim keybindings and a live Python kernel

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages