Skip to main content

curses_components

A reusable Python terminal UI library built on curses. Provides a grid viewer for tabular data and a vi-like text editor popup. Both components focus purely on the user interface and accept data in a canonical format.

Components

GridComponent Displays tabular data (e.g. CSV, database result sets) in a scrollable, interactive grid. Supports filtering, sorting, searching, column navigation, and CSV export.

EditorPopup A vi-like modal text editor shown as a popup window. Suitable for editing small text files such as SQL scripts. Supports insert mode, normal mode commands, search, substitute, and sort.

ScrollablePopup Base class for bordered, scrollable popup windows. Subclass to build custom help screens or information panels.

Installation

Install as an editable local package (recommended for development):

pip install -e /path/to/curses_component

Or add as a git submodule in another project:

git submodule add <repo-url> libs/curses_component
pip install -e libs/curses_component

Usage

GridComponent:

import curses
from curses_components import GridComponent

data = [
    {'name': 'Alice', 'age': 30},
    {'name': 'Bob',   'age': 25},
]

def main(stdscr):
    grid = GridComponent(data, fg_color='green', bg_color='black')
    grid.display(stdscr)

curses.wrapper(main)

EditorPopup:

import curses
from curses_components import EditorPopup

def main(stdscr):
    editor = EditorPopup(stdscr, title='Edit', fg_color='green',
                         bg_color='black', bold=True)
    result = editor.edit(text='', filename='script.sql')
    if result is not None:
        print(result)

curses.wrapper(main)

See examples/ for runnable demos:

python examples/grid_editor.py
python examples/text_editor.py
python examples/text_editor.py <file>
python examples/text_editor.py --size 120x40 <file>

GridComponent key bindings

Grid extensions can display reusable popups through show_popup:

grid.show_popup('Messages', lines=['first line', 'second line'])
grid.show_popup('Results', rows=[('Name', 'Alice'), ('State', 'Active')])

The popup inherits the grid's configured colors.

Commands can be added with a handler that receives the grid and parsed arguments:

def show_current_column(grid, args):
    column = grid.columns[grid.col_idx]
    grid.show_popup(column, lines=[str(row.get(column, ''))
                                   for row in grid.data])

grid.register_command('values', show_current_column)

Number formatting uses thousands separators by default. The global formatter and individual column formatters can be changed from Python or command mode:

grid.set_default_formatter('commas')
grid.set_column_formatter('amount', 'off')
grid.set_column_formatter('ratio', 'percent')

Custom formatters receive the raw cell value and return display text:

grid.register_formatter('percent', lambda value: f'{value:.1%}')

Interactive commands are :format, :format commas, :format off, :format all commas, and :format amount off. Use inherit for a column to return it to the global formatter.

Navigation: j/k/h/l or arrow keys, Home/End, Page Up/Down, ^/$ Search: / (substring), r/

EditorPopup key bindings

Normal mode: h/j/k/l or arrow keys, w/b (word), 0/$ (line), gg/G (file) Editing: i/a (insert), o/O (new line), x (delete char), dw (delete word), dd (delete line), yy (yank), p (paste), u (undo) Search: / (enter), n/N (next/previous) Command mode: :w [file], :q, :q!, :wq, :x, : (jump to line) Substitute: :s/pat/rep[/g], :%s/pat/rep[/g] Sort: :sort[!][ u] Help: :help

Color options (both components)

Both GridComponent and EditorPopup accept fg_color, bg_color, and border_color as constructor arguments. Valid color names:

black  blue  cyan  green  magenta  red  white  yellow

EditorPopup also accepts bold=True (bright text) and bold_background=True.

Dependencies

  • Python 3.8+
  • pyperclip (for copy/copyrow commands in GridComponent)

License

MIT

Metadata

Release files for curses-components 26.10.1

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

Source distribution (sdist)

Source distribution for curses-components 26.10.1
File Size Uploaded
curses_components-26.10.1.tar.gz 30.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for curses-components 26.10.1
File Interpreter ABI Platform
curses_components-26.10.1-py3-none-any.whl Python 3 none any Details

Total release size: 62.7 kB

Release files / curses_components-26.10.1.tar.gz

Download URL curses_components-26.10.1.tar.gz
Size 30.6 kB
Tags Source
SHA-256 checksum
How to use checksums
fd6bab173c64dc3a307e93970daae30175cd8cb586f9ba3367be52468b345219
BLAKE2b-256 checksum
How to use checksums
3a7b6e400f13b0eba91510e2b2a357fc813f71c69aa43cbfd3d718e65482f8d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release files / curses_components-26.10.1-py3-none-any.whl

Download URL curses_components-26.10.1-py3-none-any.whl
Size 32.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fb17a27af5e1e092df7d3127bc7765baa6dce858b7aff1ef450a74045d6a1521
BLAKE2b-256 checksum
How to use checksums
bd74324e9d0c2d4bd87243778030cb344861a44b8d6b115b59aa852fb3459354
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.15

Release history Release notifications | RSS feed

This release

26.10.1 This release

2 release files

26.9.5

2 release files

26.9.4

2 release files

26.9.2

2 release files

26.7.2

2 release files

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