doc: Add install guide instructions.
This commit is contained in:
24
README.md
24
README.md
@@ -95,6 +95,30 @@ or at all:
|
||||
overlay on Wayland (layer-shell) and X11. Auto-detects your
|
||||
environment.
|
||||
|
||||
## Install
|
||||
|
||||
See [docs/guides/install.md](docs/guides/install.md) for full details.
|
||||
The short version:
|
||||
|
||||
```sh
|
||||
cargo install pikl
|
||||
```
|
||||
|
||||
Or from source:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/maplecool/pikl-menu.git
|
||||
cd pikl-menu
|
||||
cargo install --path .
|
||||
```
|
||||
|
||||
## Guides
|
||||
|
||||
- **[Install](docs/guides/install.md):** cargo install, building from source
|
||||
- **[App Launcher](docs/guides/app-launcher.md):** set up pikl as a
|
||||
keyboard-driven app launcher on Hyprland, i3, macOS (Raycast), or
|
||||
in a terminal
|
||||
|
||||
## Building
|
||||
|
||||
```sh
|
||||
|
||||
@@ -275,6 +275,36 @@ navigate directories without spawning new processes.
|
||||
query, or the viewport to do a lookup after each filter
|
||||
pass.
|
||||
|
||||
- **Confirm-with-arguments (Shift+Enter).** Select an item
|
||||
and also pass free-text arguments alongside it. Primary
|
||||
use case: app launcher where you select `ls` and want to
|
||||
pass `-la` to it. The output would include both the
|
||||
selected item and the user-supplied arguments.
|
||||
|
||||
Open questions:
|
||||
- UX flow: does the filter text become the args on
|
||||
Shift+Enter? Or does Shift+Enter open a second input
|
||||
field for args after selection? The filter-as-args
|
||||
approach is simpler but conflates filtering and
|
||||
argument input. A two-step flow (select, then type
|
||||
args) is cleaner but adds a mode.
|
||||
- Output format: separate field in the JSON output
|
||||
(`"args": "-la"`)? Second line on stdout? Appended to
|
||||
the label? Needs to be unambiguous for scripts.
|
||||
- Should regular Enter with a non-empty filter that
|
||||
matches exactly one item just confirm that item (current
|
||||
behaviour), or should it also treat any "extra" text
|
||||
as args? Probably not, too implicit.
|
||||
- Keybind: Shift+Enter is natural, but some terminals
|
||||
don't distinguish it from Enter. May need a fallback
|
||||
like Ctrl+Enter or a normal-mode keybind.
|
||||
|
||||
This is a core feature (new keybind, new output field),
|
||||
not just a launcher script concern. Fits naturally after
|
||||
phase 4 (multi-select) since it's another selection
|
||||
mode variant. The launcher script would assemble
|
||||
`{selected} {args}` for execution.
|
||||
|
||||
## Future Ideas (Unscheduled)
|
||||
|
||||
These are things we've talked about or thought of. No
|
||||
@@ -306,3 +336,11 @@ commitment, no order.
|
||||
(optionally into a tmux session). Needs GUI frontend
|
||||
(phase 8) and frecency sorting.
|
||||
See `docs/use-cases/app-launcher.md`.
|
||||
Setup guides: `docs/guides/app-launcher.md`.
|
||||
- App description indexing: a tool or subcommand that
|
||||
builds a local cache of binary descriptions from man
|
||||
pages (`whatis`), .desktop file Comment fields, and
|
||||
macOS Info.plist data. Solves the "whatis is too slow
|
||||
to run per-keystroke" problem for the app launcher.
|
||||
Could be a `pikl index` subcommand or a standalone
|
||||
helper script.
|
||||
|
||||
286
docs/guides/app-launcher.md
Normal file
286
docs/guides/app-launcher.md
Normal file
@@ -0,0 +1,286 @@
|
||||
# App Launcher Setup
|
||||
|
||||
Use pikl as a keyboard-driven application launcher. Bind
|
||||
a hotkey, type a few characters, hit Enter, and your app
|
||||
launches. This guide covers terminal, Hyprland, i3, and
|
||||
macOS setups.
|
||||
|
||||
For the design rationale and feature roadmap, see
|
||||
[the app launcher use case](../use-cases/app-launcher.md).
|
||||
|
||||
## Quick start: terminal
|
||||
|
||||
The simplest version. No GUI, no hotkeys, just an alias:
|
||||
|
||||
```sh
|
||||
# ~/.bashrc or ~/.zshrc
|
||||
alias launch='compgen -c | sort -u | pikl | xargs -I{} sh -c "{} &"'
|
||||
```
|
||||
|
||||
Run `launch`, type to filter, Enter to run the selection
|
||||
in the background. That's it.
|
||||
|
||||
### With descriptions (experimental)
|
||||
|
||||
You can pull one-line descriptions from man pages using
|
||||
`whatis`. This is noticeably slow on systems with
|
||||
thousands of binaries (it shells out per binary), so treat
|
||||
it as a nice-to-have rather than the default:
|
||||
|
||||
```sh
|
||||
launch-rich() {
|
||||
compgen -c | sort -u | while IFS= read -r cmd; do
|
||||
desc=$(whatis "$cmd" 2>/dev/null | head -1 | sed 's/.*- //')
|
||||
printf '{"label":"%s","sublabel":"%s"}\n' "$cmd" "$desc"
|
||||
done | pikl --format '{label} <dim>{sublabel}</dim>' \
|
||||
| jq -r '.label' \
|
||||
| xargs -I{} sh -c '{} &'
|
||||
}
|
||||
```
|
||||
|
||||
This works, but it's slow. Caching the output of the
|
||||
`whatis` loop to a file and refreshing it periodically
|
||||
would make it usable day-to-day. A built-in indexing
|
||||
solution is on the roadmap but not built yet.
|
||||
|
||||
## Hyprland
|
||||
|
||||
Hyprland is a first-class target. pikl uses
|
||||
`iced_layershell` to render as a Wayland layer-shell
|
||||
overlay, so it floats above your desktop like rofi does.
|
||||
|
||||
### The launcher script
|
||||
|
||||
Save this somewhere in your PATH (e.g.
|
||||
`~/.local/bin/pikl-launch`):
|
||||
|
||||
```sh
|
||||
#!/bin/sh
|
||||
# pikl-launch: open pikl as a GUI app launcher
|
||||
|
||||
compgen -c | sort -u \
|
||||
| pikl --mode gui \
|
||||
| xargs -I{} sh -c '{} &'
|
||||
```
|
||||
|
||||
```sh
|
||||
chmod +x ~/.local/bin/pikl-launch
|
||||
```
|
||||
|
||||
### Keybinding
|
||||
|
||||
Add to `~/.config/hypr/hyprland.conf`:
|
||||
|
||||
```
|
||||
bind = SUPER, SPACE, exec, pikl-launch
|
||||
```
|
||||
|
||||
Reload with `hyprctl reload` or restart Hyprland.
|
||||
|
||||
### With .desktop files (future)
|
||||
|
||||
When pikl gains .desktop file parsing (or a helper
|
||||
script emits structured JSON from XDG desktop entries),
|
||||
you'll get proper app names, descriptions, and categories
|
||||
instead of raw binary names. The keybinding and workflow
|
||||
stay the same, only the input to pikl changes.
|
||||
|
||||
## i3
|
||||
|
||||
i3 runs on X11, so pikl opens as an override-redirect
|
||||
window rather than a layer-shell overlay. Same launcher
|
||||
script, different keybinding syntax.
|
||||
|
||||
### The launcher script
|
||||
|
||||
Same `pikl-launch` script as Hyprland above. pikl
|
||||
auto-detects X11 vs Wayland, so no changes needed.
|
||||
|
||||
### Keybinding
|
||||
|
||||
Add to `~/.config/i3/config`:
|
||||
|
||||
```
|
||||
bindsym $mod+space exec --no-startup-id pikl-launch
|
||||
```
|
||||
|
||||
Reload with `$mod+Shift+r`.
|
||||
|
||||
### Notes
|
||||
|
||||
- `--no-startup-id` prevents the i3 startup notification
|
||||
cursor from spinning while pikl is open.
|
||||
- If pikl doesn't grab focus automatically, you may need
|
||||
to add an i3 rule:
|
||||
```
|
||||
for_window [class="pikl"] focus
|
||||
```
|
||||
|
||||
## macOS with Raycast
|
||||
|
||||
Raycast is the best way to bind a global hotkey to pikl
|
||||
on macOS. You create a script command that Raycast can
|
||||
trigger from its search bar or a direct hotkey.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [Raycast](https://raycast.com) installed
|
||||
- pikl installed (`cargo install pikl`)
|
||||
- pikl in your PATH (cargo's bin directory is usually
|
||||
`~/.cargo/bin`, make sure it's in your shell PATH)
|
||||
|
||||
### Create the script command
|
||||
|
||||
Raycast script commands are shell scripts with a special
|
||||
header. Create this file in your Raycast script commands
|
||||
directory (usually `~/.config/raycast/scripts/` or
|
||||
wherever you've configured it):
|
||||
|
||||
**`pikl-launch.sh`:**
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# Required parameters:
|
||||
# @raycast.schemaVersion 1
|
||||
# @raycast.title App Launcher (pikl)
|
||||
# @raycast.mode silent
|
||||
# @raycast.packageName pikl
|
||||
|
||||
# Optional parameters:
|
||||
# @raycast.icon :rocket:
|
||||
|
||||
# Scan /Applications for .app bundles, pipe to pikl, open the result
|
||||
find /Applications ~/Applications -maxdepth 2 -name '*.app' 2>/dev/null \
|
||||
| sed 's|.*/||; s|\.app$||' \
|
||||
| sort -u \
|
||||
| pikl --mode gui \
|
||||
| xargs -I{} open -a "{}"
|
||||
```
|
||||
|
||||
```sh
|
||||
chmod +x pikl-launch.sh
|
||||
```
|
||||
|
||||
The `silent` mode tells Raycast not to show any output
|
||||
window. pikl handles its own GUI.
|
||||
|
||||
### Assign a hotkey
|
||||
|
||||
1. Open Raycast preferences (Cmd+,)
|
||||
2. Go to Extensions
|
||||
3. Find "App Launcher (pikl)" under Script Commands
|
||||
4. Click the hotkey field and press your preferred combo
|
||||
(e.g. Ctrl+Space, Opt+Space, etc.)
|
||||
|
||||
### With structured JSON input
|
||||
|
||||
For a richer experience with app metadata, you can parse
|
||||
the `Info.plist` files inside .app bundles:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# Required parameters:
|
||||
# @raycast.schemaVersion 1
|
||||
# @raycast.title App Launcher (pikl)
|
||||
# @raycast.mode silent
|
||||
# @raycast.packageName pikl
|
||||
|
||||
for app in /Applications/*.app ~/Applications/*.app; do
|
||||
[ -d "$app" ] || continue
|
||||
name=$(basename "$app" .app)
|
||||
# Pull the bundle identifier for metadata
|
||||
bundle_id=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" \
|
||||
"$app/Contents/Info.plist" 2>/dev/null)
|
||||
printf '{"label":"%s","meta":{"bundle":"%s","path":"%s"}}\n' \
|
||||
"$name" "$bundle_id" "$app"
|
||||
done \
|
||||
| pikl --mode gui \
|
||||
| jq -r '.meta.path' \
|
||||
| xargs -I{} open "{}"
|
||||
```
|
||||
|
||||
This version gives pikl structured data to work with.
|
||||
When pikl gains frecency sorting, your most-launched apps
|
||||
will float to the top automatically.
|
||||
|
||||
### Alternative: skhd
|
||||
|
||||
If you don't use Raycast, [skhd](https://github.com/koekeishiya/skhd)
|
||||
is a standalone hotkey daemon:
|
||||
|
||||
```
|
||||
# ~/.config/skhd/skhdrc
|
||||
ctrl + space : pikl-launch-mac.sh
|
||||
```
|
||||
|
||||
Where `pikl-launch-mac.sh` is the same script as above,
|
||||
minus the Raycast header comments.
|
||||
|
||||
## Customizing the launcher
|
||||
|
||||
These tips apply to all platforms.
|
||||
|
||||
### Filter fields
|
||||
|
||||
If your input includes structured JSON with metadata,
|
||||
tell pikl which fields to search:
|
||||
|
||||
```sh
|
||||
# Search both label and sublabel when filtering
|
||||
pikl --filter-fields label,sublabel
|
||||
```
|
||||
|
||||
### Hooks
|
||||
|
||||
Run something when the launcher opens or when an item
|
||||
is selected:
|
||||
|
||||
```sh
|
||||
pikl --mode gui \
|
||||
--on-select-exec 'jq -r .label >> ~/.local/state/pikl-launch-history'
|
||||
```
|
||||
|
||||
This logs every launch to a history file, which could
|
||||
feed into frecency sorting later.
|
||||
|
||||
### Starting in normal mode
|
||||
|
||||
If you prefer to land in vim normal mode (navigate first,
|
||||
then `/` to filter):
|
||||
|
||||
```sh
|
||||
pikl --mode gui --start-mode normal
|
||||
```
|
||||
|
||||
## What's not built yet
|
||||
|
||||
A few things mentioned in this guide depend on features
|
||||
that are still in development:
|
||||
|
||||
- **GUI frontend** (phase 8): the `--mode gui` flag and
|
||||
layer-shell/X11 rendering. Until this ships, you can use
|
||||
the TUI versions in a drop-down terminal (like tdrop,
|
||||
kitty's `--single-instance`, or a quake-mode terminal).
|
||||
- **Frecency sorting:** tracking launch frequency and
|
||||
boosting common picks. On the roadmap.
|
||||
- **.desktop file parsing:** structured input from XDG
|
||||
desktop entries with proper names, icons, and categories.
|
||||
On the roadmap.
|
||||
- **Description caching/indexing:** a way to build and
|
||||
maintain a local index of binary descriptions so the
|
||||
launcher can show what each app does without the slow
|
||||
`whatis` loop. On the roadmap.
|
||||
|
||||
## GNOME, KDE, and other desktops
|
||||
|
||||
These aren't supported as app launcher environments right
|
||||
now. Hyprland, i3, and macOS are the environments the dev
|
||||
team uses daily, so that's where the effort goes. The
|
||||
main blocker for GNOME on Wayland is the lack of
|
||||
layer-shell support, which means pikl can't render as an
|
||||
overlay the same way it does on wlroots-based compositors.
|
||||
|
||||
If you use one of these environments and want to help,
|
||||
PRs and discussion are welcome.
|
||||
60
docs/guides/install.md
Normal file
60
docs/guides/install.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Installing pikl
|
||||
|
||||
## From crates.io (recommended)
|
||||
|
||||
```sh
|
||||
cargo install pikl
|
||||
```
|
||||
|
||||
This builds the unified `pikl` binary with both TUI and
|
||||
GUI frontends. You'll need a working Rust toolchain. If
|
||||
you don't have one, [rustup](https://rustup.rs) is the
|
||||
way to go.
|
||||
|
||||
### TUI only
|
||||
|
||||
If you only want the terminal interface and don't want to
|
||||
pull in GUI dependencies:
|
||||
|
||||
```sh
|
||||
cargo install pikl --no-default-features --features tui
|
||||
```
|
||||
|
||||
## From source
|
||||
|
||||
```sh
|
||||
git clone https://github.com/maplecool/pikl-menu.git
|
||||
cd pikl-menu
|
||||
cargo install --path .
|
||||
```
|
||||
|
||||
This builds and installs the `pikl` binary into your
|
||||
cargo bin directory (usually `~/.cargo/bin/`).
|
||||
|
||||
## Package managers
|
||||
|
||||
We'd like pikl to be available in package managers like
|
||||
the AUR and Homebrew, but honestly haven't set that up
|
||||
before and aren't sure when we'll get to it. TBD.
|
||||
|
||||
If you package pikl for a distro or package manager, open
|
||||
an issue and we'll link it here.
|
||||
|
||||
## Verify it works
|
||||
|
||||
```sh
|
||||
echo -e "hello\nworld\ngoodbye" | pikl
|
||||
```
|
||||
|
||||
You should see a filterable list in insert mode. Type to
|
||||
filter, use arrow keys to navigate, Enter to select,
|
||||
Escape to quit. The selected item prints to stdout.
|
||||
|
||||
pikl starts in insert mode by default (type to filter
|
||||
immediately). Press Ctrl+N to switch to normal mode for
|
||||
vim-style navigation (j/k, gg, G, Ctrl+D/U). Ctrl+E
|
||||
switches back to insert mode. You can also start in
|
||||
normal mode with `--start-mode normal`.
|
||||
|
||||
Note: Ctrl+I is not the same as Tab. pikl treats these
|
||||
as distinct inputs.
|
||||
Reference in New Issue
Block a user