Skip to main content

nanoCode

A Textual-based TUI editor/workspace with tabs, project search, git controls, markdown preview, and an integrated terminal.

Features

  • File explorer sidebar with git-aware decorations and context-menu file actions
  • Project text search sidebar with clickable file/line results
  • Git control sidebar for staging, unstaging, discard, commit, sync, and branch checkout
  • Tabbed editor with preview tabs, persistent tabs, and git status badges
  • Markdown source/rendered preview workflow
  • External formatter framework with Ruff-backed Python formatting
  • Footer language selector for syntax overrides and footer branch selector for quick checkout
  • Integrated PTY terminal with session handoff support
  • Quick switcher for open tabs and recent files
  • Workspace session restore for open files and key UI state
  • Mouse support for splitters, tabs, search results, recent files, and git controls

Installation

Install from PyPI:

pip install nanoc

This installs the nanoc command and textual[syntax], which includes tree-sitter support for syntax highlighting.

Usage

Launch the app from the current directory:

nanoc

Launch against a specific workspace:

nanoc /path/to/project

Run through the Python module entry point:

python -m nanocode.app /path/to/project

Keyboard Shortcuts

Key Action
Ctrl+S Save file
Ctrl+Shift+S Save file as
Ctrl+P Quick open files and tabs
Ctrl+Shift+P Open command palette
Ctrl+Shift+M Toggle Markdown preview
Ctrl+/ Toggle line comment
Ctrl+Shift+F Format document
Ctrl+O Focus file tree
Ctrl+E Focus editor
Ctrl+Option+Left Switch to tab on the left
Ctrl+Option+Right Switch to tab on the right
Ctrl+T Toggle terminal
Ctrl+N New untitled file
Ctrl+Q Quit

Additional actions such as Editor: Format Document, Editor: Toggle Format On Save, View: Search, View: Git, Settings: Keybindings, and theme switching are available from the command palette.

App-level shortcuts can be overridden with ~/.config/nanoCode/keybindings.json. Only NanoCode app bindings are configurable; widget and modal bindings keep their built-in defaults. Use the command palette and run Settings: Keybindings to create or open that file in the editor. Modifier names in overrides use Textual syntax; macOS-friendly aliases like command and option are also accepted.

Example:

{
  "bindings": {
    "file.save": "ctrl+alt+s",
    "view.files": "ctrl+shift+o"
  }
}

UI Overview

  • Sidebar tabs switch between Explorer, Search, and Git Control.
  • The editor area shows recent files when no tabs are open.
  • Files normally open as preview tabs first; editing or double-clicking promotes them to regular tabs.
  • The bottom panel hosts the integrated terminal and can be toggled with Ctrl+T.
  • The footer exposes the current branch and language mode. Both controls are clickable.
  • The footer branch selector labels local-only branches as local, labels same-name tracking branches that are no longer on the remote as not on remote, and marks branches whose changes are already present on the default branch as in main. If the remote cannot be reached, it falls back to local tracking state such as Git's [gone] marker.
  • The footer branch selector hides old branch groups by default, can show them on demand, asks before switching to one, and can create and switch to a new branch from its New Branch button.

Search, Git, and Markdown Workflows

  • Project search scans the workspace, skips common generated directories, and jumps the cursor to the selected match.
  • The git sidebar shows staged and unstaged changes, supports file-level and bulk actions, and can switch its primary button from Commit to Sync Changes when the tree is clean but ahead of remote.
  • Some discard operations are intentionally destructive and may remove untracked files as part of restoring the worktree.
  • Clicking a changed file in the git sidebar opens it and can show an inline fullscreen diff view.
  • Markdown preview opens a rendered companion tab for Markdown files rather than replacing the source tab.

Terminal

The terminal is a built-in PTY emulator based on pyte.

Features:

  • Interactive shell support (bash, zsh, etc.)
  • 256-color ANSI rendering
  • Mouse tracking support
  • Running interactive terminal programs
  • Session handoff: when a file is opened with nanoc path/to/file from inside the integrated terminal, the request is forwarded into the already-running app session instead of spawning a second instance

Persistence & Config

nanoCode stores user state under ~/.config/nanoCode/.

Current files:

  • recent.json: recent files shown on startup and used by the quick switcher
  • recent_actions.json: recent command-palette actions
  • sessions.json: per-workspace open tabs, active tab, explorer state, selected sidebar panel, and terminal visibility
  • keybindings.json: app-level keybinding overrides
  • settings.json: app-level editor settings such as format_on_save

Workspace restore intentionally skips untitled tabs, but it does restore file-backed tabs and rendered Markdown tabs.

Supported Languages

Syntax highlighting is supported for Textual's built-in languages:

  • Bash (.sh, .bash, .zsh, .command)
  • Go (.go)
  • Java (.java)
  • JavaScript (.js, .mjs, .cjs, .jsx)
  • Python (.py)
  • HTML (.html, .htm)
  • CSS (.css)
  • JSON (.json)
  • Markdown (.md)
  • Regex (.regex, .regexp)
  • Rust (.rs)
  • YAML (.yaml, .yml)
  • TOML (.toml)
  • SQL (.sql)
  • XML (.xml, .xsd, .xsl, .xslt, .svg)

Use the footer language selector to override the active tab's language for the current tab session. Choose Auto to return to extension-based detection, or Plain Text to disable syntax highlighting.

Comment toggling is implemented for common languages including Bash, Go, HTML, Java, JavaScript, Markdown, Python, Rust, SQL, TOML, XML, and YAML.

Formatting is provided through external tools. Python formatting uses Ruff to organize imports and then run ruff format, so install Ruff separately and make sure ruff is on PATH before running Editor: Format Document or pressing Ctrl+Shift+F. Format-on-save is off by default and can be toggled from the command palette with Editor: Toggle Format On Save.

Development

Install development dependencies:

pip install -e ".[dev]"

Run the full test suite:

python -m pytest

Run a focused test module while iterating:

python -m pytest tests/test_workspace_sessions.py -q

Publishing

The PyPI project and distribution name is nanoc; the app name remains nanoCode, the import package remains nanocode, and the installed command is nanoc.

PyPI releases are published by .github/workflows/publish.yml using PyPI Trusted Publishing. Configure a pending GitHub Actions publisher on PyPI with:

  • PyPI project name: nanoc
  • Owner: mmcguffi
  • Repository name: nanoCode
  • Workflow name: publish.yml
  • Environment name: pypi

Version numbers use a major-only scheme: 0, 1, 2, and so on. The first release is 0.

Create the initial 0 release manually after the major-only version and publishing workflow changes are on main. After version 0 is available on PyPI, .github/workflows/release.yml handles normal releases without bypassing branch rules. When a non-release pull request is merged into main, GitHub Actions opens a release/N pull request that bumps version in pyproject.toml and nanocode.__version__ to the next major number. When that release pull request is merged, GitHub Actions creates a GitHub release with the same numeric tag and generated notes, then dispatches publish.yml.

The repository Actions setting must allow workflows to read and write repository contents so the release workflow can create release branches, open release pull requests, create releases, and dispatch publish runs. If GitHub Actions pull request creation is disabled in repository settings, the workflow leaves the release/N branch in place and logs a warning instead of failing. publish.yml runs the tests, builds the source and wheel distributions, and uploads them to PyPI without a PYPI_TOKEN secret. It can also be run manually from GitHub Actions if a failed publish needs to be retried before files have reached PyPI.

Metadata

Release files for nanoc 0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nanoc 0
File Size Uploaded Provenance
nanoc-0.tar.gz 114.1 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for nanoc 0
File Interpreter ABI Platform
nanoc-0-py3-none-any.whl Python 3 none any Details

Total release size: 231.5 kB

Release files / nanoc-0.tar.gz

Download URL nanoc-0.tar.gz
Size 114.1 kB
Tags Source
SHA-256 checksum
How to use checksums
18bda9a773f34c06aec05c79718d9922309e5ab50693178352c923d93a9af4ea
BLAKE2b-256 checksum
How to use checksums
47da55ab905893bc5f19965db4e4a00661d5a15757cc83b81bbba405d45f1df8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 26, 2026.

Transparency log

Release files / nanoc-0-py3-none-any.whl

Download URL nanoc-0-py3-none-any.whl
Size 117.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5ddd7d454729b9a7acb553ba8ea1a346f41cc32c781e176780d853b97e3d4a7c
BLAKE2b-256 checksum
How to use checksums
8e1754c17c9b5afcd857d0184df1fd13304784f9936786c06bdfd6fb93a858f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 26, 2026.

Transparency log

Security for nanoc 0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for nanoc-0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 26, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page