# selectui A terminal UI for selecting and searching through items with a clean, split-pane interface. ## Features - **Search Bar**: Filter items in real-time as you type - **Split View**: - Left pane: List of items showing title and subtitle - Right pane: Detailed view of selected item (all keys/values) - **Fuzzy Search**: Toggle with `f` key for flexible matching - **Case Sensitivity**: Toggle with `i` key for exact case matching - **Readline Controls**: Support for common shortcuts (^A, ^E, ^W, ^U) - **Status Bar**: Shows total entries, matched entries, and active flags - **Help**: Press `?` to see keybindings - **Oneshot Mode**: Use `-o` flag to exit after first selection ## Installation This project uses [uv](https://github.com/astral-sh/uv) for dependency management. ```bash cd selectui uv sync ``` Or install as a library: ```bash pip install -e . ``` ## Usage ### As a CLI Tool The script reads JSON objects line-by-line from stdin (JSONL format). Each line should be a valid JSON object with at least a `title` key (and optionally a `subtitle` key). Items are loaded asynchronously, so the UI updates as new objects arrive. ### Basic usage: ```bash cat example.jsonl | uv run selectui ``` ### Oneshot mode (exit after selection): ```bash cat example.jsonl | uv run selectui --oneshot ``` or ```bash cat example.jsonl | uv run selectui -o ``` ### Example with jq: ```bash # Select from a list of files (convert to JSONL) find . -type f | while read f; do echo "{\"title\": \"$f\"}"; done | uv run selectui # Or using jq to output JSONL (one object per line) cat data.json | jq -c '.[]' | uv run selectui ``` ### Streaming example: ```bash # Simulate streaming data - items appear one by one for i in 1 2 3 4 5; do echo "{\"title\": \"Item $i\", \"subtitle\": \"Description $i\"}"; sleep 0.5; done | uv run selectui ``` ### Custom title/subtitle keys: ```bash # Use 'name' as title and 'description' as subtitle cat data.jsonl | uv run selectui -t name -s description # Use 'filename' as title, no subtitle cat files.jsonl | uv run selectui --title filename ``` ### As a Library SelectUI can be used as a library in your Python applications: ```python from selectui import SelectUI items = [ {"title": "Python", "subtitle": "High-level language"}, {"title": "Rust", "subtitle": "Systems language"}, {"title": "Go", "subtitle": "Concurrent language"}, ] app = SelectUI(items=items, oneshot=True) app.run() if app.selected_item: print(f"You selected: {app.selected_item['title']}") ``` ### With Pydantic Models (Type Safety) ```python from selectui import SelectUI, SelectItem # Type-safe items with validation items = [ SelectItem(title="Python", subtitle="High-level language", info="1991"), SelectItem(title="Rust", subtitle="Systems language", info="2010"), ] app = SelectUI(items=items, oneshot=True) app.run() ``` ### Converting from JSON with Custom Keys ```python from selectui import SelectItem # Convert JSON/dict with custom field mappings data = {"name": "Alice", "role": "Engineer", "team": "Backend"} item = SelectItem.from_dict(data, title_key="name", subtitle_key="role", info_key="team") ``` See the [examples/](examples/) directory for more library usage examples: - `examples/minimal.py` - Simplest possible usage - `examples/simple_library_example.py` - Common patterns - `examples/library_usage.py` - Comprehensive feature demonstrations - `examples/pydantic_example.py` - Pydantic models with type safety - `examples/json_conversion.py` - JSON conversion with custom keys For detailed library documentation, see [examples/README.md](examples/README.md). ## Keybindings ### Navigation - `↑/↓` - Move selection up/down (works from search bar!) - `PgUp/PgDn` - Page up/down (works from search bar!) - `j/k` - Vim-style navigation (when list is focused) - `Enter` - Select item and output to stdout - `Esc`, `q`, or `^C` - Quit ### Search - Type to filter items - `^A` - Move cursor to start of line - `^E` - Move cursor to end of line - `^W` - Delete word backward - `^U` - Clear search line - `Backspace` - Delete character - `←/→` - Move cursor left/right in search box ### Toggles - `f` - Toggle fuzzy search (shows "F" in status bar when active) - `i` - Toggle case-sensitive search (shows "I" in status bar when active) ## Input Format The input should be JSONL (JSON Lines) - one JSON value per line. Each line can be either: - A single JSON object - A JSON array of objects (all items will be added to the list) ```jsonl {"title": "Item 1", "subtitle": "Description of item 1"} {"title": "Item 2", "subtitle": "Description of item 2"} [{"title": "Item 3"}, {"title": "Item 4"}] ``` - `title`: Displayed as the main text (configurable with `-t/--title`) - `subtitle`: Displayed below the title (configurable with `-s/--subtitle`) - Other keys: All keys and values are shown in the detail pane The UI loads items asynchronously as they arrive, showing a "..." indicator in the status bar while streaming is in progress. ## Command Line Options | Option | Description | |--------|-------------| | `-o, --oneshot` | Exit after first selection | | `-t, --title KEY` | Key to use for item title (default: `title`) | | `-s, --subtitle KEY` | Key to use for item subtitle (default: `subtitle`) | | `-i, --info KEY` | Key to display as right-aligned info in each entry | | `-e, --events` | Enable events mode (see below) | ## Events Mode When `--events` is enabled, pressing CTRL+key combinations will emit a JSONL event to stdout containing the pressed key and the currently selected item: ```bash cat items.jsonl | selectui --events ``` Output format when CTRL+x is pressed: ```json {"key":"ctrl+x","item":{"title":"Selected Item","subtitle":"..."}} ``` This allows building interactive workflows where different CTRL keys trigger different actions on the selected item. Reserved keys (like CTRL+C for quit) are not emitted. ## Output When an item is selected (by pressing Enter), the complete JSON object is output to stdout. In non-oneshot mode, the UI continues running after output. In oneshot mode, the program exits after the first selection. ## Example See `example.jsonl` for a sample data file with job listings. ```bash cat example.jsonl | uv run selectui ``` ## Dependencies - Python 3.8+ - textual (for the TUI framework) - thefuzz (for fuzzy searching) ## License MIT