# TUI A small keyboard-driven terminal UI for browsing directories and executing ordinary shell commands defined in `.tui` files. The important design choice is that **TUI does not execute actions inside a Python subprocess**. It hands the generated commands back to the Bash process that started `tui`. This keeps the commands visible in Bash history and gives actions the normal shell environment. ## Requirements - Debian/Linux with Bash - Python 3 - PyYAML (`python3-yaml` on Debian) - `curses` from the normal Python installation Install the Debian dependency if necessary: ```bash sudo apt install python3-yaml ``` ## Installation Unpack the project and run: ```bash ./install.sh ``` The installer installs TUI under: ```text ~/.local/lib/tui/ ``` and adds the shell integration to: ```text ~/.bashrc ``` The integration is therefore loaded automatically for interactive Bash sessions, including the normal Debian login/terminal startup path. After installation, start a new terminal/login session, or run: ```bash source ~/.bashrc ``` Then: ```bash tui ``` Use `-a` to include hidden files and directories: ```bash tui -a ``` The installer does not overwrite an existing `~/.tui`. `-a` / `--all` is a command-line option, so the shell integration preserves it when the TUI restarts after an action. ## `.tui` configuration TUI searches for the nearest `.tui` starting in the current directory and walking upwards, but never above `$HOME`. A configuration contains `keys` and `actions`: ```yaml keys: up: up down: down left: parent right: folder: enter file: - "*.zip": list-zip ctrl-k: b: mark-begin k: mark-end m: file: - "*": move actions: list-zip: command: - unzip -l - read -rp "Tryck Enter för att fortsätta..." move: command: mv -v ``` Rules are evaluated from top to bottom; the first matching glob wins. ### Substitutions | Token | Meaning | |---|---| | `` | basename of the target | | `` | full path of the target | | `` | directory currently displayed by TUI, with trailing `/` | ## Navigation The default example configuration uses: - `↑` / `↓` — move cursor - `Enter` / `→` — execute the configured action - `../` — synthetic parent-directory entry at the top of every listing - `←` — move the cursor to `../`; pressing `←` again enters the parent directory - `Enter` on `../` — enter the parent directory - navigation cannot move above the directory containing the applicable `.tui` file - hidden files and directories are hidden by default; `tui -a` shows them - file and directory colors follow the usual GNU `ls --color=yes` conventions for common file types - `Ctrl-K B` — set selection start - `Ctrl-K K` — set selection end - `Ctrl-K C` — copy marked files/folders - `Ctrl-K M` — move marked files - `Ctrl-K Y` — delete marked files/folders - `Ctrl-C` — quit ## Marking Marks are stored as absolute paths and belong to the TUI session, not to the current directory. For example: ```text /home/joakim/notes/ A.txt * B.txt * work/ ``` Entering `work/` does not clear the marks. Returning to the parent directory shows `A.txt` and `B.txt` as marked again. Marks in different directories can coexist. If `A.txt` is marked, then TUI is moved to `work/`, `Ctrl-K M` operates on the original absolute path while using the **current directory** as the destination: ```bash mv -v /home/joakim/notes/A.txt . ``` A mark is removed automatically only when its target no longer exists. `Ctrl-K B` and `Ctrl-K K` define a contiguous selection in the directory being viewed. Changing directory clears the temporary selection endpoints but does not clear the already marked paths. ## Shell integration When an action is triggered, TUI writes the generated commands to a temporary file and exits with a private handoff status. The `tui()` Bash function then executes them. For example: ```yaml actions: list-zip: command: - unzip -l - read -rp "Tryck Enter för att fortsätta..." ``` The flow is: ```text TUI ↓ unzip -l archive.zip ↓ read -rp "Tryck Enter..." ↓ TUI ``` TUI is **not redrawn between commands belonging to the same action**. Every command is also inserted into Bash history. If one command fails, the remaining commands in that action are not executed. TUI prints the exit code and waits for: ```text Tryck Enter för att fortsätta... ``` before returning to TUI, so an error cannot disappear immediately. The shell wrapper uses `pushd`/`popd` so the command runs in the directory shown by TUI without permanently changing the user's Bash working directory. ## Security note Action strings are intentionally ordinary Bash commands and are executed with `eval` by the user's Bash shell. `.tui` files should therefore be treated as executable configuration and only used from directories/configurations you trust. ## Development Run a syntax check with: ```bash python3 -m py_compile tui/tui.py ``` For development without installing: ```bash source tui/tui-shell.bash tui ``` The example configuration is in `tui/example.tui`. ### Version Use `tui -v` or `tui --version` to verify the installed TUI version.