✦ Terminal Text Editor · v0.0.23 · Python · Textual

SuperNanno

Nano, but modern. With UI, syntax highlighting, and a real developer workflow.

A modern terminal text editor built on Textual and Tree-sitter. Modular architecture with event-driven design, state management, dedicated services, and structured JSON logging — all within the terminal.

Python 3.10+ Textual 8.2.3 Tree-sitter 0.25.2 16 Languages BSD-3-Clause

Project Screenshots

Visual overview of SuperNanno's main features and interface

Main Editor

Main Editor — Overview da interface principal do SuperNanno

Full-featured text editor based on Textual's TextArea widget. Advanced cursor support, text selection, smooth scrolling, current line highlighting, and configurable cursor_style: block.

Search + Replace

Search + Replace — Funcionalidades de busca e substituição do SuperNanno

Strategic Search Engine: Advanced search architecture.

Sidebar Explorer

Animation Timeline do SuperNanno

DirectoryTree integrated into the sidebar.
Navigate the filesystem, open files with a click, toggle with CTRL+B. Configurable width and root directory with automatic refresh.

Syntax Highlighting

Syntax Highlighting do SuperNanno

High-performance highlighting powered by Tree-sitter with intelligent fallback to Pygments. Automatic language detection by file extension using an internal language_map. Supports 16 languages.

Status Bar

Status Bar do SuperNanno

StatusService with five visual levels, persistent message locking, deduplication, and automatic reset. Displays file info, language, encoding, EOL, cursor position, and document metrics.

Everything you need in the terminal

SuperNanno is built with a modular, event-driven architecture powered by services and robust state management. Every feature is implemented with comprehensive resilience, structured logging, and intelligent recovery mechanisms.

Editor Core (TextArea)
Full-featured text editor based on Textual's TextArea widget. Advanced cursor support, text selection, smooth scrolling, current line highlighting, and configurable cursor_style: block.
Syntax Highlighting
High-performance highlighting powered by Tree-sitter with intelligent fallback to Pygments. Automatic language detection by file extension using an internal language_map. Supports 16 languages.
Robust File Manager
FileManager with atomic writes (write-then-rename via .tmp), intelligent encoding fallbacks, resilient backup systems, and comprehensive handling of filesystem operations.
Strategic Search Engine
Advanced search architecture using the Strategy Pattern: SearchEngine + SearchRegistry + SearchStrategy. Supports literal, case-sensitive, and regex queries. Individual and global replace with smooth match navigation.
Save, Save As & Read-Only
Reliable save operations (CTRL+S) with atomic writes. Inline Save As with path input. Read-only mode (-v/--view). Real-time dirty state detection and automatic directory tree refresh.
Session Manager
SessionManager with atomic JSON persistence, recent files history (last 10), automatic restoration of the last session, and intelligent backup of corrupted session files.
Diagnostic Service & Correlation IDs
DiagnosticService assigns unique correlation_id (8 hex chars) to operations. Automatic categorization and MD5 fingerprinting for precise observability and issue deduplication.
Report Service — Direct Feedback
Press CTRL+X to generate a comprehensive diagnostic report and open a GitHub issue directly from the editor. Includes editor state, readable logs, and a bundled ZIP for streamlined contribution.
Async Config Watcher
Asynchronous worker that monitors .supernannorc and applies changes in real-time without restart. Exponential backoff with graceful degradation for maximum stability.
Sidebar File Explorer
DirectoryTree integrated into the sidebar. Navigate the filesystem, open files with a click, toggle with CTRL+B. Configurable width and root directory with automatic refresh.
Structured JSON Logging
StructuredLogger produces rich JSON entries with ISO timestamps, correlation IDs, context, and editor state. Daily log rotation with best-effort reliability that never impacts editor stability.
Backup & Recovery
Automatic pre-save backups via -B/--backup or set backup. Configurable backup directory. Non-blocking operation ensures primary save performance is never affected.
Data Loss Protection
Proactive check_dirty_before system prevents destructive actions on unsaved changes. Double confirmation for quit with clear status bar guidance and preserved pending actions.
Intelligent Status Bar
StatusService with five visual levels, persistent message locking, deduplication, and automatic reset. Displays file info, language, encoding, EOL, cursor position, and document metrics.
Async Cursor Watcher
Dedicated asynchronous worker tracks cursor position for real-time status updates. Adaptive polling with intelligent backoff ensures smooth performance and stability.
Settings Screen (F1)
Dedicated SettingsScreen with clean grid layout. Supports session restore, auto-save, line numbers and more. Changes saved safely through ConfigManager with per-field validation.
Insert File at Cursor (CTRL+R)
Insert content from another file at the exact cursor position. Replaces selection if active. Full encoding support with automatic fallbacks and clear success feedback.
Signature System
Automatic file header insertion powered by config.json. Configurable fields including author, dates, copyright, and disclaimers. Fully toggleable per file type.
Word Wrap & Auto Indent
Configurable word wrap, intelligent auto-indent, and flexible tab behavior. Adjustable tab size and indent type (spaces or tabs) for precise workflow control.

5 Visual Status Levels

The StatusService provides rich visual feedback with message persistence, deduplication, and configurable auto-reset.

(Editor): main.py | python | UTF-8 | LF | Ln 42, Col 8 | 1.2k chars
(File): Saved "app_context.py"
(Session): Restored "handlers/file.py"
(Editor): Unsaved changes — press again to confirm
[a3f2b1c9] Operation completed with diagnostic info
StatusService Flow:
1
Direct Calls
ctx.status.success("(File): Saved") — typed message with automatic 2s timeout
2
Deduplication
Identical messages are intelligently skipped to reduce visual noise
3
Persistent Locking
ctx.status.persist("(Search): Find mode") — locks state until explicitly cleared
4
Async Auto-reset
Background worker restores default state after configured delay

Control at your fingertips

All shortcuts defined in ui/bindings.py and registered through Textual's BINDINGS system.

File & Editor
CTRL+N New file action_new_file → handlers/file.new()
CTRL+O Open file Opens path input for quick navigation
CTRL+R Insert file at cursor action_read_file → handlers/file.read()
CTRL+S Save file action_save → atomic write with optional backup
CTRL+Q Quit action_quit with smart unsaved changes protection
Search, UI & System
CTRL+F Search in file action_search → ctx.set_state(SearchState())
CTRL+B Toggle Sidebar action_show_hide_sidebar → toggle_sidebar(ctx)
CTRL+X Generate Report action_report_issue → ctx.report.open_report()
F1 Open Settings action_show_settings → push_screen(SettingsScreen)
ESC Cancel / Close panel Closes search, path input or active state
Search: Navigation & Replace
Enter Next match state.next_match(ctx)
Shift+Enter Previous match state.prev_match(ctx)
Enter Replace mode Shows replace input in SearchBar
Return to Find mode Hides replace input
CTRL+H Replace All state.replace_all(ctx)
Settings Screen (F1)
CTRL+S Save Settings action_save in SettingsScreen
ESC Close Settings action_dismiss → returns to editor

Complete CLI Arguments

Full parser in cli/parser.py · Models in cli/models.py · Constants in cli/constants.py. Compatible with original nano syntax.

Full Usage
$ supernanno [OPTIONS] [[+LINE[,COLUMN] | +/SEARCH] FILE]
All arguments are optional. Without arguments, opens a blank editor (or restores session if enabled).
Available Options — CLIArgs (cli/models.py) + cli/constants.py
FILE str | None
Path to the file to open on startup. Relative or absolute.
$ supernanno my_file.py
+LINE int | None
Positions cursor at the specified line on open. Inspired by nano syntax.
$ supernanno +25 main.py
+LINE,COL int, int
Positions cursor at specific line and column. Safe parsing with sensible fallbacks.
$ supernanno +25,8 main.py
+/SEARCH str | None
Opens file and initiates search for the term automatically.
$ supernanno +/TODO app.py
-v / --view bool
Opens in read-only mode (ctx.read_only = True).
$ supernanno -v config.json
-B / --backup bool
Enables automatic backups before each save.
$ supernanno -B file.py
-C <dir> / --backupdir str | None
Sets backup directory. Supports ~/ expansion.
$ supernanno -B -C ~/Backups/ file.py
-h / --help bool
Displays complete help text and exits.
$ supernanno --help
-V / --version bool
Displays version and exits.
$ supernanno --version
$ supernanno # opens blank (restores session if enabled)
$ supernanno file.txt # opens file directly
$ supernanno +42 app.py # opens at line 42
$ supernanno +42,10 app.py # opens at line 42, column 10
$ supernanno +/TODO app.py # opens and searches for "TODO"
$ supernanno -v config.json # read-only mode
$ supernanno -B -C ~/bak/ main.py # backup to ~/bak/ before saving
$ supernanno --version # show version
$ supernanno --help # show help

File .supernannorc

The .supernannorc file in your project root defines editor preferences. Parsed by services/rc_parser.py with smart encoding fallbacks. Monitored in real-time by the asynchronous Config Watcher.

Current .supernannorc content:
# SuperNanno configuration

set backup
set backupdir ~/.config/Bisneto/SuperNanno/Backup
set configwatcher
set configwatcherinterval 1
set indenttype spaces
set operatingdir ~/
set pathdisplay full
set restoresession
set sidebar
set sidebarwidth 35
set tabbehavior indent
set tabsize 4

# To disable an option:
unset backup
Complete Reference — ConfigApplier
.supernannorc
backup flag (bool) Enables automatic backup before saving. Creates .bak in backupdir.
backupdir ~/path/ Directory for backups. Supports ~/. Default: ~/.config/Bisneto/SuperNanno/Backup.
configwatcher flag (bool) Monitors .supernannorc and applies changes live.
configwatcherinterval int (seconds) Interval between config watcher checks. Minimum: 1s.
indenttype spaces | tabs Indentation type applied to editor.
operatingdir ~/path/ Root directory for sidebar. Ignored if file opened via CLI.
pathdisplay full | name Controls path display in status bar: full path or filename only.
restoresession flag (bool) Automatically restores last session on startup.
sidebar flag (bool) Controls sidebar visibility on startup.
sidebarwidth int (20–80) Sidebar width in columns. Clamped between 20 and 80.
tabbehavior indent | ... Tab key behavior in editor.
tabsize int Tab/indent width. Default: 4.
debug flag (bool) Enables debug output in StatusService.
config.json — Additional Settings
JSON
auto_save false Periodic auto-save (interval controlled by auto_save_interval).
highlight_current_line true Visual highlight for the current cursor line.
mouse_support true Enables mouse support in Textual.
smooth_scrolling true Animated scrolling in the editor.
trim_trailing_whitespace true Automatically trims trailing whitespace on save.
highlight_all_matches true Highlights all search matches in the document.

Module Structure

SuperNanno follows clean layer separation: app → handlers → services → core. Each module has a single responsibility and communicates through the central AppContext.

app.py
SuperNanno(App) main application
BINDINGS registered shortcuts
action_* 9 actions
on_* events 6 event handlers
__watch_config__ async worker
Entry point. Coordinates all subsystems via AppContext.
core/
__version__.py v0.0.23
editor.py EditorState
file_manager.py FileManager
status.py StatusService
logger.py Logger facade
structured_logger.py JSON logger
Core business logic. Independent of Textual UI layer.
services/
app_context.py central facade
config_manager.py config.json
config_applier.py applies rc
diagnostic_service.py correlation IDs
report_service.py GitHub reports
log_service.py logging API
rc_parser.py parser rc
session_manager.py JSON session
paths.py platformdirs
Service layer. AppContext provides unified access to all services.
handlers/
__init__.py public exports
file.py new/open/load/read/save
toggle_sidebar.py toggle visibility
quit.py quit with dirty check
User action logic. Receives context and executes operations.
events/
button_pressed.py next/prev/replace
cursor_watcher.py async worker
directory_tree_selected.py sidebar click
input_changed.py search input
input_submitted.py path/open
key.py key events
list_view_selected.py list navigation
mount.py on_mount
text_area_changed.py dirty/stats
unmount.py shutdown
Textual event handlers, each in its own focused module.
search/
controller.py SearchController
engine.py SearchEngine
models.py SearchQuery/Result
registry.py SearchRegistry
strategies.py Strategy Pattern
Extensible search subsystem using Strategy Pattern.
ui/
bindings.py BINDINGS + WELCOME
layout.py create_layout()
search_bar.py SearchBar widget
startup_view.py StartupView
settings/screen.py SettingsScreen
Textual UI components. Layout assembled in create_layout().
cli/
models.py CLIArgs dataclass
parser.py parse_cli_args()
constants.py VERSION/HELP_TEXT
Pure Python CLI parser. CLIArgs is a comprehensive dataclass.
states/
base.py BaseState
search.py SearchState
State machine for managing editor modes (normal, search, replace, etc.).
style.tcss
$primary: #7c84ec primary color
$accent: #454990 accent color
$background: #1F1F1F background
status classes success/warn/info/error
Textual CSS (.tcss). Defines palette, layout and all widget styles.
tests/
test_report_service.py pytest unit tests
TestDiagnosticBundle ZIP bundle
TestReportService report flow
TestDiagnosticContext log excerpt
UI-independent tests. Run with: python -m pytest tests/ -v.

Syntax Highlighting via Tree-sitter

SuperNanno uses Tree-sitter for precise AST-based parsing and highlighting. Automatic detection by file extension via internal language_map. Smart fallback to Pygments (guess_lexer()) when needed.

Python .py JavaScript .js TypeScript .ts Bash .sh CSS .css HTML .html Go .go Java .java Rust .rs SQL .sql JSON .json TOML .toml YAML .yaml/.yml Markdown .md XML .xml Regex C .c C++ .cpp C# .cs
Languages detected by extension in app_context.py → set_language(). When Tree-sitter parser is unavailable, pygments.lexers.guess_lexer() automatically analyzes file content.

Get Started with SuperNanno

Install SuperNanno using the included dev.sh script or via pipx (recommended for production use).

Global Installation (Recommended)
$ pipx install supernanno

After installation, you can run:

$ supernanno
$ supernanno myfile.py
Development / Local Install
$ git clone https://github.com/hbisneto/SuperNanno.git
$ cd SuperNanno
$ bash dev.sh

The dev.sh script offers multiple installation modes:

  • 1) Stable Channel (PyPI) — Recommended
  • 2) Local Developer Mode (editable install)
  • 3) Dev Channel (TestPyPI)
  • 4 & 5) Specific version
Useful Commands
$ supernanno --help
$ supernanno --version
$ supernanno +25 file.py
Configuration directory
  • Linux: ~/.config/Bisneto/SuperNanno/
  • macOS: ~/Library/Application Support/Bisneto/SuperNanno/
  • Windows: %APPDATA%\Bisneto\SuperNanno\
Core Dependencies (requirements.txt)
textual 8.2.3 rich 14.3.3 tree-sitter 0.25.2 tree-sitter-python 0.25.0 tree-sitter-javascript 0.25.0 tree-sitter-bash 0.25.1 tree-sitter-rust 0.24.0 tree-sitter-go 0.25.0 tree-sitter-json 0.24.8 tree-sitter-yaml 0.7.2 tree-sitter-toml 0.7.0 tree-sitter-markdown 0.5.1 tree-sitter-html 0.23.2 tree-sitter-css 0.25.0 tree-sitter-java 0.23.5 tree-sitter-sql 0.3.11 tree-sitter-xml 0.7.0 tree-sitter-regex 0.25.0 Pygments 2.19.2 httpx 0.28.1 platformdirs 4.9.4 markdown-it-py 4.0.0 anyio 4.12.1 linkify-it-py 2.1.0
Unit Tests
$ python -m pytest tests/ -v # runs all tests
$ python -m pytest tests/test_report_service.py -v # tests ReportService