diff --git a/README.md b/README.md index ed360a8..1550895 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![Rust](https://img.shields.io/badge/rust-2021_edition-orange.svg)](https://www.rust-lang.org/) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![Platform](https://img.shields.io/badge/platform-macOS%20%7C%20Linux-lightgrey.svg)](https://github.com/IamShreshth/Tman) -[![Shell](https://img.shields.io/badge/shell-zsh%20%7C%20bash-green.svg)](https://github.com/IamShreshth/Tman) +[![Shell](https://img.shields.io/badge/shell-zsh%20%7C%20bash%20%7C%20fish-green.svg)](https://github.com/IamShreshth/Tman) [![Dependencies](https://img.shields.io/badge/dependencies-zero_runtime-brightgreen.svg)](docs/requirements.txt)
@@ -39,59 +39,121 @@ Press `Ctrl+Shift+T` (or `Ctrl+Space`) anywhere in your shell, or run `tman`. --- +## macOS Installation (Apple Silicon & Intel) + +### Option 1: Single-Step Installer (Recommended) +Automatically detects Apple Silicon (`arm64`) or Intel (`x86_64`), installs `tman`, signs the binary (`codesign`) so Gatekeeper never prompts, and configures `~/.zshrc`: + +```bash +curl -fsSL https://raw.githubusercontent.com/IamShreshth/Tman/main/files/install.sh | bash +source ~/.zshrc +``` + +### Option 2: Homebrew + Cargo (Build from Source) +```bash +# 1. Ensure Xcode Command Line Tools & Rust are installed +xcode-select --install 2>/dev/null || true +brew install rust # OR: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh + +# 2. Install tman via Cargo +cargo install --git https://github.com/IamShreshth/Tman.git --locked + +# 3. Activate in your shell (Zsh is default on macOS): +echo 'eval "$(tman init zsh)"' >> ~/.zshrc && source ~/.zshrc +# Bash: echo 'eval "$(tman init bash)"' >> ~/.bash_profile && source ~/.bash_profile +# Fish: mkdir -p ~/.config/fish && echo 'tman init fish | source' >> ~/.config/fish/config.fish +``` + +> **Note on macOS integration:** `pbcopy` (clipboard) and `open` (Finder / default app opener) work out of the box on macOS with zero extra packages. For `Ctrl+Shift+T` in iTerm2, Warp, Kitty, Alacritty, or WezTerm, you can also use `Ctrl+Space` at any time. + +--- + ## Linux Installation -### Universal (All Distros) +### Universal One-Liner (All Distros) + +Automatically detects your architecture (`x86_64` / `aarch64`), libc (`glibc` / `musl`), downloads the pre-built binary (or builds via Cargo if needed), and configures your shell: ```bash curl -fsSL https://raw.githubusercontent.com/IamShreshth/Tman/main/files/install.sh | bash ``` -### Fedora +--- + +### 1. Arch Linux (Manjaro, EndeavourOS, CachyOS) ```bash -# Install Rust toolchain (required to build from source) -sudo dnf install -y cargo rust +# 1. Install build prerequisites & optional clipboard/desktop helpers +sudo pacman -S --needed --noconfirm base-devel git rust wl-clipboard xclip xdg-utils -# Install tman +# 2. Install tman (via installer script or Cargo) curl -fsSL https://raw.githubusercontent.com/IamShreshth/Tman/main/files/install.sh | bash +# OR build directly via Cargo: +# cargo install --git https://github.com/IamShreshth/Tman.git --locked -# Activate (add to ~/.bashrc or ~/.zshrc) -echo 'eval "$(tman init bash)"' >> ~/.bashrc -source ~/.bashrc +# 3. Activate in your shell: +source ~/.bashrc # Bash +# source ~/.zshrc # Zsh +# tman init fish | source # Fish (append to ~/.config/fish/config.fish) ``` -### Arch Linux +--- + +### 2. Fedora (RHEL, CentOS Stream, Nobara) ```bash -# Install Rust toolchain -sudo pacman -S --noconfirm rust +# 1. Install Rust toolchain & optional clipboard/desktop helpers +sudo dnf install -y gcc git cargo rust wl-clipboard xclip xdg-utils -# Install tman +# 2. Install tman (via installer script or Cargo) curl -fsSL https://raw.githubusercontent.com/IamShreshth/Tman/main/files/install.sh | bash +# OR build directly via Cargo: +# cargo install --git https://github.com/IamShreshth/Tman.git --locked -# Activate (add to ~/.bashrc or ~/.zshrc) -echo 'eval "$(tman init bash)"' >> ~/.bashrc -source ~/.bashrc +# 3. Activate in your shell: +source ~/.bashrc # Bash +# source ~/.zshrc # Zsh +# tman init fish | source # Fish (append to ~/.config/fish/config.fish) ``` -> **AUR users:** If an AUR package becomes available, you can also use `yay -S tman` or `paru -S tman`. +--- -### Ubuntu / Debian +### 3. Ubuntu / Debian (Linux Mint, Pop!_OS, Kali) ```bash -# Install Rust toolchain -sudo apt update && sudo apt install -y cargo rustc +# 1. Install build tools, Rust toolchain & optional clipboard/desktop helpers +sudo apt update && sudo apt install -y build-essential curl git cargo rustc wl-clipboard xclip xdg-utils -# Install tman +# 2. Install tman (via installer script or Cargo) curl -fsSL https://raw.githubusercontent.com/IamShreshth/Tman/main/files/install.sh | bash +# OR build directly via Cargo: +# cargo install --git https://github.com/IamShreshth/Tman.git --locked -# Activate (add to ~/.bashrc or ~/.zshrc) -echo 'eval "$(tman init bash)"' >> ~/.bashrc -source ~/.bashrc +# 3. Activate in your shell: +source ~/.bashrc # Bash +# source ~/.zshrc # Zsh +# tman init fish | source # Fish (append to ~/.config/fish/config.fish) ``` -> **Note on keybindings:** Most Linux terminal emulators intercept `Ctrl+Shift+T` (e.g., GNOME Terminal uses it to open a new tab). Use `Ctrl+Space` instead by setting `open = "ctrl-space"` in your tman config (`~/.config/tman/config.toml`). +> **Tip for older Ubuntu/Debian releases:** If the `apt` Rust version is older than `1.70`, install the latest toolchain via `rustup`: +> ```bash +> curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y +> source "$HOME/.cargo/env" +> ``` + +--- + +### Manual Shell Hook Setup (If Installing via Cargo) + +If you installed via `cargo install` instead of `install.sh`, add the shell hook for your shell: + +| Shell | Command | +| :--- | :--- | +| **Bash** | `echo 'eval "$(tman init bash)"' >> ~/.bashrc && source ~/.bashrc` | +| **Zsh** | `echo 'eval "$(tman init zsh)"' >> ~/.zshrc && source ~/.zshrc` | +| **Fish** | `mkdir -p ~/.config/fish && echo 'tman init fish \| source' >> ~/.config/fish/config.fish && source ~/.config/fish/config.fish` | + +> **Note on Linux keybindings:** Most Linux terminal emulators intercept `Ctrl+Shift+T` to open a new tab. `tman` automatically binds **`Ctrl+Space`** alongside `Ctrl+Shift+T` so you can press `Ctrl+Space` out of the box on GNOME Terminal, Konsole, XFCE Terminal, Alacritty, Kitty, and WezTerm. --- @@ -115,8 +177,10 @@ source ~/.bashrc | `Left` / `h` / `Backspace` | Submenus | Navigate to parent directory / previous view | | `b` | Menu / Files | Bookmark current directory or highlighted folder | | `d` or `x` | Bookmarks | Delete highlighted bookmark | +| `Space` | Git Changed Files | Stage / unstage highlighted file in-place | +| `Q` | File Browser | Quit HUD and `cd` shell into the browsed directory | | `Tab` | Browser / Runners | Open action menu (`Open with app`, `Open file manager`, copy path) | -| `/` | Lists | Filter items with fuzzy search | +| `/` | Lists | Filter items with multi-word fuzzy search | | `.` | File Browser | Toggle hidden dotfiles | | `m` | Submenus | Return to main menu | | `Esc` | Any View | Clear search / close modal / exit HUD | @@ -131,10 +195,10 @@ source ~/.bashrc | Component | Requirement | | :--- | :--- | | **Operating System** | macOS (Apple Silicon & Intel) or Linux (x86_64, aarch64, musl/glibc) | -| **Supported Shells** | Zsh (v5.0+) or Bash (v4.0+) | +| **Supported Shells** | Zsh (v5.0+), Bash (v4.0+), or Fish (v3.4+) | | **Build Toolchain** | Rust 1.70+ and Cargo (only when building from source) | -See [docs/linux.md](docs/linux.md) for Linux-specific details and [docs/requirements.txt](docs/requirements.txt) for technical specifications. +See [linux.md](linux.md) for Linux-specific details and [docs/requirements.txt](docs/requirements.txt) for technical specifications. --- diff --git a/docs/app.js b/docs/app.js index 4615dc0..2253161 100644 --- a/docs/app.js +++ b/docs/app.js @@ -72,79 +72,109 @@ document.addEventListener('DOMContentLoaded', () => { const simList = document.getElementById('sim-list'); const dynTitle = document.getElementById('dyn-block-title'); const dynContent = document.getElementById('dyn-content'); + const rightPanelTitle = document.getElementById('right-panel-title'); + + const themeColors = { + cyan: '#46d7e6', + blue: '#5aa0ff', + green: '#50dc96', + magenta: '#c878ff', + peach: '#ffb48c' + }; const actionStates = { navigate: { - title: 'DIRECTORY CONTENTS', + panel: 'MISSION CONTROL', + title: '━━━ DIRECTORY CONTENTS ━━━━━━━━━━━━━━━', items: [ '▸ src/', '▸ tests/', - '· Cargo.toml', - '· Dockerfile', - '· README.md' + ' Cargo.toml', + ' Dockerfile', + ' README.md' ] }, bookmarks: { - title: 'PINNED BOOKMARKS', + panel: 'PREVIEW BOOKMARKS', + title: '━━━ PINNED & RECENT (ZOXIDE) ━━━━━━━━━', items: [ '* ~/projects/tman', '* ~/code/dotfiles', - '* ~/.config/nvim', - '* ~/work/backend-api' + '↺ ~/.config/nvim [recent]', + '↺ ~/work/backend-api [recent]' ] }, history: { - title: 'LIVE SHELL HISTORY (DEDUPLICATED)', + panel: 'PREVIEW HISTORY', + title: '━━━ LIVE SHELL HISTORY (DEDUPLICATED) ━', items: [ - '↺ cargo test --release', - '↺ git status -sb', - '↺ docker compose up -d', - '↺ nvim src/main.rs', - '↺ git push origin main' + '· cargo test --release', + '· git status -sb', + '· docker compose up -d', + '· nvim src/main.rs', + '· git push fork linux_ins' ] }, search: { - title: 'FUZZY MATCHES (QUERY: "sys")', + panel: 'PREVIEW SEARCH', + title: '━━━ GITIGNORE-AWARE FUZZY MATCHES ━━━━', items: [ - '· src/sys.rs (kernel telemetry)', - '· tests/test_sys.rs', - '· src/safety.rs' + '· src/sys.rs', + '· src/safety.rs', + '· src/git.rs', + '· files/install.sh' ] }, git: { - title: 'GIT ACTIONS & STATUS', + panel: 'PREVIEW GIT', + title: '━━━ INTERACTIVE GIT WORKFLOWS ━━━━━━━━', items: [ - '⎇ Status: 2 staged, 1 modified, 0 untracked', - '⎇ Commit: "feat: add linux support"', - '⎇ Diff: unstaged changes in src/sys.rs', - '⎇ Pull (fast-forward preview)', - '⎇ Push (origin/main)' + '⎇ Changed files (Space to stage/unstage)', + '⎇ Branches (git switch + log preview)', + '⎇ Stashes (git stash pop + diff)', + '+185 -79 in src/app.rs, src/git.rs' ] }, run: { - title: 'DISCOVERED WORKFLOW TARGETS', + panel: 'PREVIEW RUN', + title: '━━━ DISCOVERED PROJECT TARGETS ━━━━━━━', + items: [ + '▶ cargo build Cargo.toml', + '▶ cargo test Cargo.toml', + '▶ docker compose up -d Docker Compose', + '▶ ${EDITOR:-vi} .env .env (DATABASE_URL = ***)' + ] + }, + ports: { + panel: 'PREVIEW ACTIVE PORTS', + title: '━━━ LISTENING TCP PORTS (LSOF / SS) ━━', items: [ - '▶ cargo build', - '▶ cargo run -- ui', - '▶ cargo test', - '▶ cargo clippy', - '▶ docker build -t app .' + '◈ :3000 node PID 41230', + '◈ :5432 postgres PID 1892', + '◈ :8080 cargo-watch PID 50211' ] }, theme: { - title: 'ACCENT COLOR PALETTE', + panel: 'PREVIEW THEMES', + title: '━━━ CLICK A THEME TO PREVIEW ━━━━━━━━━', items: [ - '# Cyan (active default)', - '# Blue (Tokyo Night)', - '# Green (Matrix)', - '# Magenta (Synthwave)', - '# Peach (Catppuccin)' + '# cyan Futuristic high-tech cyan [active]', + '# blue Electric royal blue', + '# green Matrix / terminal emerald green', + '# magenta Cyberpunk neon magenta', + '# peach Soft warm aesthetic peach' ] } }; if (simList && dynTitle && dynContent) { const items = simList.querySelectorAll('.hud-item'); + let hudHovered = false; + + if (interactiveView) { + interactiveView.addEventListener('mouseenter', () => { hudHovered = true; }); + interactiveView.addEventListener('mouseleave', () => { hudHovered = false; }); + } function selectAction(item) { items.forEach(i => { @@ -152,13 +182,27 @@ document.addEventListener('DOMContentLoaded', () => { i.querySelector('.item-pointer').textContent = ' '; }); item.classList.add('active'); - item.querySelector('.item-pointer').textContent = '›'; + item.querySelector('.item-pointer').textContent = '❯'; const actionKey = item.getAttribute('data-action'); const state = actionStates[actionKey]; if (state) { + if (rightPanelTitle) rightPanelTitle.textContent = state.panel; dynTitle.textContent = state.title; - dynContent.innerHTML = state.items.map(text => `
${escapeHtml(text)}
`).join(''); + dynContent.innerHTML = state.items.map(text => { + const themeMatch = actionKey === 'theme' ? text.match(/^#\s+(\w+)/) : null; + const attr = themeMatch ? ` data-theme-color="${themeMatch[1]}" style="cursor:pointer"` : ''; + return `
${escapeHtml(text)}
`; + }).join(''); + + if (actionKey === 'theme') { + dynContent.querySelectorAll('[data-theme-color]').forEach(el => { + el.addEventListener('click', () => { + const c = themeColors[el.getAttribute('data-theme-color')]; + if (c) document.documentElement.style.setProperty('--cyan-primary', c); + }); + }); + } } } @@ -166,17 +210,19 @@ document.addEventListener('DOMContentLoaded', () => { item.addEventListener('click', () => selectAction(item)); }); - // Keyboard navigation (Up / Down) when focusing on the simulator + // Keyboard navigation (Up/Down or j/k) only when hovering or focusing the simulator window.addEventListener('keydown', (e) => { - if (e.key === 'ArrowDown' || e.key === 'ArrowUp') { + const focused = document.activeElement === interactiveView || (interactiveView && interactiveView.contains(document.activeElement)); + if (!hudHovered && !focused) return; + if (e.key === 'ArrowDown' || e.key === 'ArrowUp' || e.key === 'j' || e.key === 'k') { const activeItem = simList.querySelector('.hud-item.active'); if (!activeItem) return; const all = Array.from(items); const idx = all.indexOf(activeItem); - if (e.key === 'ArrowDown' && idx < all.length - 1) { + if ((e.key === 'ArrowDown' || e.key === 'j') && idx < all.length - 1) { e.preventDefault(); selectAction(all[idx + 1]); - } else if (e.key === 'ArrowUp' && idx > 0) { + } else if ((e.key === 'ArrowUp' || e.key === 'k') && idx > 0) { e.preventDefault(); selectAction(all[idx - 1]); } diff --git a/docs/index.html b/docs/index.html index e6881b3..821f171 100644 --- a/docs/index.html +++ b/docs/index.html @@ -28,25 +28,30 @@ - +