Metadata-Version: 2.4
Name: nanoc
Version: 0
Summary: A Textual TUI coding workspace with file explorer and syntax highlighting
Project-URL: Homepage, https://github.com/mmcguffi/nanoCode
Project-URL: Repository, https://github.com/mmcguffi/nanoCode
Project-URL: Issues, https://github.com/mmcguffi/nanoCode/issues
Requires-Python: >=3.10
Requires-Dist: pyte>=0.8.0
Requires-Dist: textual[syntax]>=0.47.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# 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:

```bash
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:

```bash
nanoc
```

Launch against a specific workspace:

```bash
nanoc /path/to/project
```

Run through the Python module entry point:

```bash
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:

```json
{
  "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](https://github.com/selectel/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:

```bash
pip install -e ".[dev]"
```

Run the full test suite:

```bash
python -m pytest
```

Run a focused test module while iterating:

```bash
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.
