A Blocks bundle is a folder whose name ends in .lnb,
treated as a single item in the tree (double-click opens it). Each block is a
real file on disk; the order lives in a blocks.json at the bundle
root. It works like a notebook: stacked cells of code or text. A Jupyter notebook comes in this way: right-click an .ipynb in the tree and choose Import as Blocks (.lnb). Each cell becomes a real file — versionable and read by search — and the .ipynb stays where it was, because importing is not converting. The outputs stored in the notebook do not come along: running the cell here produces the real result, with its time and command. If blocks.json is unreadable (a Git conflict or an interrupted write), the notebook warns you and does not rewrite it: the order, the connection and the session are saved again only after you fix it.
Cells, notebook bar and shortcuts
Each cell has a name, a type button (markdown, python, javascript, sql, shell, powershell, bat, r, julia, http, ai, mermaid, latex and the text types) and buttons to copy, insert (click: below; the arrow: above and duplicate), delete, move up and down and run (the arrow offers Run up to here). A new cell inherits the type of its neighbour. The button on the right collapses the cell, leaving only its first line in the header, and the [n] counter tells the order in which the cells ran in this session. Create a notebook from the tree (New) or via File → New.
The notebook bar, at the top, acts on the whole notebook: Run all runs the code cells in order; Stop interrupts the running one and empties the queue (the run goes to the history with exit code -1); Clear outputs closes the panels without deleting anything; the More menu exports the notebook and deletes the history. The timeoutSec key in blocks.json sets a time limit per cell (0, the default, is no limit).
Shortcuts, with the focus in a cell: Ctrl+Enter runs and stays; Shift+Enter runs and moves to the next cell (on the last one, it creates a new one); Alt+Enter runs and inserts a cell right below. In a text cell, running means rendering: it opens rendered when it has content, and a double-click (or Enter on it) goes back to editing.
Saved results, attachments and history
Results are saved (like a lab notebook): when a run finishes it becomes a
.md file under saida/<cell>/ inside the bundle —
with the timestamp, exit code, duration, command and the output itself. Being
Markdown, it reads in any editor, versions in Git alongside the notebook, and is
picked up by AI Chat. Reopening the bundle
brings back the Last run strip above the panel: click it to see the result
without running again.
Attachments: each run gets a folder of its own, next to the .md, and its path reaches the program in the LN_RUN_DIR environment variable. Whatever the cell writes there — a matplotlib chart, a CSV — appears below the output (images drawn, the rest as a link to the folder) and is listed in the history file. Output that is already Markdown (the table of a SELECT, the AI answer, a diagram) opens rendered; the Text/Render button on the strip switches.
History: the History button next to that strip lists the previous
runs of that cell (timestamp and exit code) — handy to compare what the same cell
returned over time. We keep the 10 most recent per cell; to change that, edit
the historyLimit key in the bundle's blocks.json
(0 turns saving off, and attachments with it). Very large output is cut (the file says
truncated: true). Renaming a cell or changing its type takes the
history along; deleting the cell sends its history to the Recycle Bin.
Persistent session
By default each cell is a new process: what one defines, the next does not see. With the persistent session on (the Session button on the bar; the session key in blocks.json), Python, JavaScript, shell and PowerShell cells run in a process that stays alive between runs — variables, functions and imports from one cell are valid in the next, as in Jupyter. In Python, matplotlib figures left open at the end of the cell are saved to the attachments folder on their own. Restart session forgets everything; so does Stop, because interrupting means ending the process. In JavaScript, declare with var (or with no declaration): top-level let, const and class cannot be declared again — not even by running the same cell twice.
SQL cells
With no connection set, an sql cell runs on the notebook's own DuckDB (in memory): tables created in one cell are valid in the next, and read_csv('data/sales.csv') reads the files in the notebook folder — keep the data in a subfolder, because every loose file in the notebook folder is a cell. For a real database, point the notebook at an .lnc connection from the connection strip (it lists the workspace connections): the cells start running on the database, through the same connection as the Connections panel — remembered password, SSH tunnel, re-reading of the .lnc and the production confirmation before any write. A SELECT result becomes a table in the output file; INSERT/UPDATE and friends report how many rows changed, and an error stops the script and records the statement that failed. We fetch up to 100 rows per query (sqlMaxRows in blocks.json; the file says when there were more).
@set name = value defines a variable with notebook scope, and :name (or ?) is a parameter asked at run time, as in the SQL editor. The last SELECT also writes resultado.csv to the attachments folder (the same rows as the table, up to sqlMaxRows), and the following cells receive its path in LN_LAST_SQL — in Python, pd.read_csv(os.environ["LN_LAST_SQL"]). The connection lives in blocks.json as a relative path; an .lnc kept inside the bundle counts as configuration, not as a cell.
HTTP, AI, Mermaid and LaTeX
Four types run inside LightNote itself, with no interpreter: the http cell is an .lnh test executed by the same runner as the API tester (the report goes to the history; the environment is the one named by the httpEnv key in blocks.json, and a file the request sends must be inside the workspace); the ai cell sends the prompt to the default assistant with the notebook context — the source of the previous cells and the last output of each, except the http cells, which may carry credentials — and the answer arrives rendered; the mermaid and latex cells draw the diagram or the formula into an image in the attachments. Stop cancels the first two.
Exporting the notebook
The More menu on the bar exports the whole notebook: as Markdown (text cells inline, code in fences with the language, the last output right below and the images linked) or as a Jupyter notebook (.ipynb, with the last output of each cell and the images embedded; a cell of another language carries the mark that VS Code reads). It is a copy to share — the notebook is still the folder.
Index
Editing
- Overview
- Getting started
- Workspace and windows
- Activities panel: tasks and messages
- Code editor
- Markdown and wikilinks
- Diagrams (Mermaid)
- Mathematics and chemistry (LaTeX)
- Calendar in a note
- Numbering and cross-references
- Citations and references
- Academic paper standard
- Connections graph
- Tables (Parquet, CSV, JSON, Excel)
- Analysis area: pivot table and several charts
- PDF and images
- Images: marking up a screenshot
- HTML pages (.html)
- Printing
- Zip as a folder (.zip)
- Blocks (.lnb)
- Tasks (Kanban / Gantt)
- Custom table (.lnd)
- Bases (saved queries over your notes)
Tools
- Search in files and Pending items
- Versioning (easy Git)
- Snapshots and backup
- Review changes (checkpoints)
- Compare files (diff)
- Run code (F5)
- Terminal and AI CLIs
- AI assistant on the selection (Ctrl+K / Ctrl+I)
- AI on your computer
- AI sessions
- AI Chat
- Test HTTP APIs (.lnh)
- Databases (.lnc)
- SSH connection (.lns)
- Security: Passphrase, PIN and Secure Markdown
- Daily notes, quick capture and tray
- Resurface old notes
- Your notes on your phone
- Record audio (voice, meeting) with AI transcription
- Sticky notes
- Calendar
- Command palette
Automation (AI / scripts)
Reference