Terminal UI for browsing and filtering JSON/CSV data with keyboard navigation.
dv-tui (data viewer - terminal user interface) is a curses-based terminal UI for viewing and interacting with JSON and CSV data. It provides a fast, keyboard-driven interface for browsing, searching, and filtering structured data.
Key features include:
- Multi-tab browsing - Load multiple files and switch between tabs
- Vim keybindings - Navigate with j/k, h/l for tabs and cells
- Fuzzy search - Real-time filtering with smart character-distance scoring
- Auto-reload - Detects and reloads modified files
- Color-coded display - Dynamic color cycling for statuses and types
- Type handling - Supports string types and integer durations (shown as minutes)
- Smart sanitization - Cleans control characters and truncates long strings
- Tab indicators - Shows item counts; search mode shows filtered vs. total count
- Multiple file formats - Supports JSON and CSV data files
- Drill-down navigation - Navigate into nested lists and objects
- Enum cell editing - Cycle through pre-defined values in cells
- Custom keybindings - Configure keys via CLI or config file
- Trigger system - Execute commands on row/cell selection and navigation events
pip install dv-tui# Clone the repository
git clone https://github.com/YlanAllouche/dv-tui.git
cd dv-tui
# Install in development mode
pip install -e .dv --helpdv-tui has no external dependencies - it uses only Python standard library modules:
curses- Terminal UI (included with Python on most systems)json- JSON parsingcsv- CSV parsingargparse- Command line argument parsing
On some Linux distributions, you may need to install curses separately:
- Ubuntu/Debian:
sudo apt-get install python3-curses - Fedora:
sudo dnf install python3-curses - macOS: Included with Python
Basic usage:
# View a JSON file
dv file.json
# View a CSV file
dv data.csv
# View multiple files as tabs
dv file1.json file2.json
# View data from stdin
cat data.json | dv
# View data from a command output
query.sh | dvSingle-select mode (exit after selecting):
dv -s file.jsonCustom column display:
dv --columns "name,status,age" file.jsonGlobal on-enter trigger:
dv --on-enter "open_task.sh $DV_SELECTED_INDEX" file.jsonAuto-refresh from command:
dv -c "query.sh" --refresh --refresh-interval 5Use dv-tui as a tmux popup window:
bind-key e run-shell "tmux display-popup -w 90% -h 80% -E ~/.local/bin/dv -s ~/share/_tmp/query1.json"Prompt for file from directory:
# Interactive selection from ~/share/_tmp/
dv
# Custom directory
dv ~/data/*.jsondv-tui supports configuration through multiple sources:
- Config file:
~/.config/dv/config.jsonor custom path via--config - Inline JSON: Configuration embedded in first data item via
_configfield - Command line: Override via flags like
--columns,--bind, etc.
Configuration priority: CLI flags > inline JSON > config file > defaults
For detailed configuration options, see CONFIG.md.
| Key | Action |
|---|---|
j / ↓ |
Move down |
k / ↑ |
Move up |
h / ← |
Previous tab (or left cell in cell mode) |
l / → |
Next tab (or right cell in cell mode) |
/ |
Enter search mode |
c |
Toggle row/cell selection mode |
Enter |
Select row/cell |
q |
Quit |
| Key | Action |
|---|---|
| Type | Filter results |
Tab / ↓ |
Next result |
Shift+Tab / ↑ |
Previous result |
Esc |
Exit search (restores position) |
Backspace |
Delete search character |
Enter |
Select result |
| Key | Action |
|---|---|
e |
Cycle to next enum value |
E |
Cycle to previous enum value |
Ctrl+E |
Open enum picker dialog |
For detailed keybinding customization, see KEYBINDS.md.
dv-tui can be used as a Python library in your applications:
from dv_tui import TableUI
data = [
{"name": "Alice", "status": "active", "age": 30},
{"name": "Bob", "status": "inactive", "age": 25},
]
# Create TUI
tui = TableUI(data)
# Handle selections
def on_enter(selected_row):
print(f"Selected: {selected_row}")
tui.bind_key('Enter', on_enter)
# Run
selected = tui.run()For detailed API documentation and examples, see LIBRARY.md.
dv-tui expects JSON data as an array of objects:
[
{
"type": "work",
"status": "active",
"summary": "Task description",
"file": "path/to/file",
"line": 42,
"locator": "url_or_id"
}
]_config: Embedded configuration (see CONFIG.md)- Any field with nested objects/arrays is drillable
CSV files are automatically converted to JSON objects:
name,status,age
Alice,active,30
Bob,inactive,25Press Enter on cells containing arrays or nested objects to drill into them. Use Esc to go back.
Configure enum fields to cycle through values:
{
"_config": {
"enum": {
"status": {
"source": "inline",
"values": ["todo", "in-progress", "done"]
}
}
}
}Execute commands on events:
{
"_config": {
"triggers": {
"table": {
"on_enter": "echo $DV_SELECTED_ROW | jq",
"on_select": "open_file $DV_SELECTED_INDEX"
}
}
}
}Bind custom actions via config or CLI:
dv --bind "v:view_details"See the examples/ directory for complete example scripts:
basic_library_usage.py- Basic Python library usagecustom_keybindings.py- Custom keybinding configurationprogrammatic_updates.py- Updating data programmatically
pytest tests/Sample test data is provided in tests/data/:
dv tests/data/work_tasks.json
dv tests/data/study_tasks.json
dv tests/data/mixed_tasks.csvSee tests/data/README.md for more testing examples.
Contributions are welcome! Please open an issue or submit a pull request.
MIT License - see LICENSE file for details
