ublx 0.1.3

TUI to index once, enrich with metadata, and browse a flat snapshot in a 3-pane layout with multiple modes.
Documentation

UBLX

Crates.io docs.rs Build Rust

Ublx ... Safe when taken as directed.

UBLX is a TUI that turns any directory into a flat, navigable catalog — categories, previews, metadata, and templates in the terminal. (Driven by nefaxer and zahirscan)

Currently in development, expect breaking changes.

Before you start

  • a terminal emulator with truecolor (24-bit color) & image support
  • Strongly recommend using a terminal with a Nerd Font

Optional:

Tool Role
tree Directory preview in the Viewer when on PATH
Poppler (pdftoppm) or MuPDF (mutool) PDF page raster preview
ffmpeg Video frame preview

Install

cargo install ublx

# or compile from source
cargo build --release

What it does

  • Index once, then browse — One run updates the catalog; the prior index enables fast diffs. Per-root SQLite under your user cache (ubli/; stem is sanitized dir name plus path hash; extension matches the ublx package name). Config file names and paths: Configuration.
  • Path catalog vs full metadata — By default, indexing records paths and filetype/category hints (fast, lightweight). ZahirScan adds the rich Zahir JSON used for deep previews, Templates, Writing stats, and Metadata tables. Batch that with enable_enhance_all, scope it with [[enhance_policy]], or run Enhance with ZahirScan on demand (quick actions / multi-select). Keys and behavior: Configuration.
  • TUI — Main tabs (left to right when all are shown): Snapshot | Lenses | Delta | Duplicates | SettingsLenses and Duplicates appear only when the DB has lenses or duplicate groups. Three-pane layout and keys: Modes and Panes overview. Search across & within files, vim motions, theme selector, quick actions menu, command mode, toast notifications, fullscreen toggle.
  • Snapshot-only — Index without the TUI (-s / --snapshot-only; Usage).
  • Export — Pretty-printed Zahir JSON (Usage); Lenses converted to markdown.

Use case

Looking for a file manager? Use yazi for that; where UBLX comes in:

  • Best for navigating and handling project directories that you frequent
  • Preview & extract filetype specific metadata without having to open a file
  • For large directories: can still get a quick understanding of filetypes contained without metadata enhancement

Modes

Tab Description
Snapshot From the current index: categories and file list; right pane shows Templates / Viewer / Metadata / Writing for the selected row.
Delta Added / Mod / Removed since last snapshot; same 3-pane layout with overview in the right pane.
Lenses Saved lists of items with a specific focus (e.g. a “lens” on a subset of files); left = lens names, middle = paths in the selected lens. Shown when the DB has at least one lens.
Duplicates Groups of duplicate files by content hash; left = group names, middle = paths in the group. Run duplicate detection from Command Mode to populate; tab appears when groups exist.
Settings Global vs local ublx.toml: theme, layout, bg_opacity, bool toggles (e.g. show_hidden_files, run_snapshot_on_startup), and more; e opens the active scope's file in $EDITOR.

Cycle main tabs with ~.

Panes overview

The right pane shows Viewer, Templates, Metadata, or Writing for the selected item. Tab switches focus between the left (categories) and middle (contents) panes; h / l also focus left or middle.

  • Focus a right-pane tabv (Viewer), t (Templates), m (Metadata), w (Writing). Shift+Tab cycles through right-pane tabs.
  • Scroll in the previewShift+b / Shift+e (jump to top/bottom), Shift+↑ / Shift+↓ or Shift+K / Shift+J (line by line).
  • Viewer fullscreenShift+F toggles fullscreen for the Viewer tab.
  • Viewer searchShift+S opens literal in-pane search in the preview (see in-app help for n/N and Esc).
  • Catalog search/ fuzzy-filters the category and content lists (left and middle) by path/category. Press Esc to clear filter.
Tab Content
Viewer Previews for the selected file — details in Viewer. Footer: size and last-modified when available.
Templates Extracted template/structure snippet (e.g. document outline) when zahirscan provides it.
Metadata Enrichment metadata as tables: key/value pairs, and for supported types things like CSV column metadata, XLSX sheet stats (rows/columns per sheet), SQLite schema/table info, zip/archive “Contents” tables, and schema trees. Sections are parsed from the stored zahirscan result and rendered with headers and scroll.
Writing Writing stats (writing footprint): word count, character counts, and similar stats when zahirscan has computed them. Shown in the same table layout as Metadata.

Viewer

  • Markdown — formatted preview (headings, lists, code blocks, tables inside the doc).
  • CSV-style files — pretty table layout for .csv, .tsv, .tab, .psv when the index says so or the path matches (so previews still work if a row’s category label is off).
  • Images — terminal preview via ratatui-image (downscaled for the pane; larger files may decode off the UI thread; recent previews cached for quick navigation).
  • Code and structured textsyntect highlighting via sublime_syntaxes; grammar from path/extension; colors match theme light/dark. Large buffers are cached for smooth scrolling.
  • Other text — raw text (length-capped).
  • Binaries — short label instead of dumping bytes.
  • Directoriestree when available.

Context Menu, Multi-select, & Command Mode

Feature Keys Notes
Quick actions (context menu) Space Actions for the current row: open, reveal in folder, enhance / lens / copy / rename / delete — depends on tab and row type.
Multi-select Ctrl+Space Toggles multi-select on the contents pane (Snapshot or Lenses only). While on: Space toggles selection on the current row; a opens the bulk menu; Esc leaves multi-select.
Command Mode Ctrl+A “Leader” — press a second key for a global action, or wait briefly to see a centered menu listing the letters below. Not available while the catalog search bar is active.

Command Mode second key (after Ctrl+A):

Key Action
d Run duplicate detection (background)
t Theme selector (writes theme to local config on confirm)
s Take snapshot (background)
r Reload config from disk
x Export Zahir JSON to ublx-export/
l Export lenses as Markdown to ublx-lenses/
p Switch indexed project (recents / ubli/ roots)

Press ? to open the full keybinding help.

Configuration

Config is optional. If present, global config is applied first, then local overrides from the indexed directory.

Platform Global config Config Cache
macOS / Linux ~/.config/ublx/ublx.toml ~/.local/share/ublx/configs/
Windows %APPDATA%\ublx\ublx.toml %LOCALAPPDATA%\ublx\configs\

Local config (same on all platforms): .ublx.toml (default) or ublx.toml in the directory you index. Only keys present in each file override defaults.

Global-only keys:

Key Type Allowable values / notes
opacity_format string (optional) When bg_opacity < 1: OSC 11 payload style — rgba (default) or hex8 (#RRGGBBAA). Some terminals prefer one or the other.
ask_enhance_on_new_root bool (optional) If false, skip the first-run “Enhance all files?” prompt and apply enable_enhance_all from config immediately. If true or omitted (default), show the prompt for a newly indexed root.

Configurable keys (global and/or local unless noted):

Key Type Allowable values / notes
theme string See Themes.
layout table Pane widths: left_pct, middle_pct, right_pct (each 0–100; must sum to 100). Default: left_pct = 10, middle_pct = 30, right_pct = 60.
bg_opacity float (optional) Page background opacity 0.01.0: main pane uses terminal default fill (OSC 11) below 1.0 so wallpaper can show through; omitted or 1.0 = solid theme background. Adjustable in Settings.
show_hidden_files bool If true, include hidden files (e.g. .*) in the index.
hash bool If true, compute blake3 hash per file (slower; used for duplicate detection and change detection).
exclude array of strings Extra path patterns to exclude from indexing (startup only; not hot-reloadable).
editor_path string Path to editor for “Open (Terminal)” (e.g. "vim", "nvim"). When unset, uses $EDITOR.
enable_enhance_all bool If true, full metadata for all files on snapshot. If false (default), only get path plus file-type/category until Enhance with ZahirScan per file.
run_snapshot_on_startup bool (optional) Default true (omit = true): spawn a background snapshot when the TUI opens (unless first-run defers it) and when switching indexed roots in-session. Set false to skip those automatic runs and use the existing DB until you take a snapshot.
[[enhance_policy]] TOML array of tables Optional per-subtree rules (see below). Hot-reloadable with the rest of the overlay.

All of the above except exclude are hot-reloadable when set in a file that UBLX loads (global and/or local). The global-only keys in the previous table are hot-reloadable only via global config edits, not from local project files.

[[enhance_policy]] — Each row has path (relative to the indexed directory, / separators, e.g. src or photos/2024) and policy:

  • auto — ZahirScan runs for files under that prefix when you take a snapshot (same idea as enable_enhance_all = true, but only for this subtree).
  • manual — No batch Zahir on snapshot for that subtree (same idea as enable_enhance_all = false): the catalog is path-only there until you Enhance with ZahirScan on specific files.

The longest path prefix that matches a file wins. If no row matches, enable_enhance_all applies globally.

Live reload — A file watcher monitors both the indexed directory’s local config and the global config path; saving either file triggers a debounced reload. A successful parse applies the new merged settings immediately, and the valid merged overlay is written to the per-directory config cache. If the file is invalid, an error is shown and the last successful config saved in cache is used.

Usage

Usage: ublx [OPTIONS] <DIR>

Arguments:
  <DIR>  Directory to index (default: current directory)

Options:
  -s, --snapshot-only  Headless snapshot. Writes a local config file when this dir has none
  -e, --enhance-all    With `--snapshot-only`: set `enable_enhance_all = true` in new local config and use it for this run
  -f, --full-snapshot  Same as `--snapshot-only --enhance-all`
  -x, --export         Headless: write each Zahir JSON to `ublx-export/` as flat `{path}.json` files. Recommended to run with `--full-snapshot` to get most complete & recent results. Adjust enhance policy in config to fine-tune which paths get ZahirScan
      --dev            Dev mode: tui-logger drain + `move_events` + trace-level default filter
      --themes         Print available themes grouped by appearance
  -h, --help           Print help

License

Dual-licensed under MIT or Apache-2.0.