diff --git a/plugins/README.md b/plugins/README.md index e7d1bb042..df691adee 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -55,6 +55,7 @@ By leveraging these plugins, you can streamline your workflow and tackle coding | tmux-autoattach | Plugin related to session management in the tmux terminal multiplexer. | | vagrant | Tool for creating and managing virtual development environments. | | virtualenvwrapper | A set of extensions to the virtualenv tool. | +| wake | This plugin provides a wrapper around the "wakeonlan" tool. | | xterm | Terminal emulator for X Window systems providing a graphical user interface for accessing the command line. | -| zellij-autoattach | Plugin related to session management in the zellij terminal multiplexer. | +| zellij-autoattach | Plugin related to session management in the zellij terminal multiplexer. | | zoxide | Utility for quickly navigating the filesystem based on visited directory history. | diff --git a/plugins/wake/README.md b/plugins/wake/README.md new file mode 100644 index 000000000..f50c90e7a --- /dev/null +++ b/plugins/wake/README.md @@ -0,0 +1,107 @@ +# wake + +This plugin provides a wrapper around the `wakeonlan` tool available from most +distributions' package repositories, or from [this website](https://github.com/jpoliv/wakeonlan). + +To use it, add `wake` to the plugins array in your **~/.bashrc**: + +```bash +plugins=(... wake) +``` + +## Configuration + +Create the `~/.wakeonlan` directory and place **one file per device** you want to wake. +The filename is the device name (used on the CLI and in completion). + +**Two file formats are supported** (comments and blank lines are ignored): + +**A) Single-line format** +``` + [broadcast-IP] [port] +``` + +**B) key=value format** +``` +MAC=aa:bb:cc:dd:ee:ff +BCAST=192.168.0.255 +PORT=9 +# comments allowed +``` + +**Defaults:** if `BCAST` is omitted → `255.255.255.255`; if `PORT` is omitted → `9`. + +**Example** (`~/.wakeonlan/server`): + +``` +00:11:22:33:44:55 192.168.0.255 9 +``` + +or + +``` +MAC=00:11:22:33:44:55 +BCAST=192.168.0.255 +PORT=9 +``` + +> Tip: device names can contain spaces, but you’ll need quotes when calling (e.g., `wake "my server"`). + +## Usage + +``` +wake [options] +``` + +### Options + +| Option | Description | Default | +|-------------------|---------------------------------------------|---------| +| `-l`, `--list` | List configured device names and exit | — | +| `-n`, `--dry-run` | Show the command that would be executed | — | +| `-p`, `--port N` | Override UDP port | `9` | +| `-h`, `--help` | Show usage | — | + +### Examples + +Wake a device: +```bash +wake server +``` + +List devices: +```bash +wake -l +``` + +Dry-run (don’t send a packet, just show the command): +```bash +wake -n server +# DRY-RUN: wakeonlan -p 9 -i 192.168.0.255 00:11:22:33:44:55 +``` + +Use a non-default port: +```bash +wake -p 7 server +``` + +**Autocompletion:** device names from `~/.wakeonlan` are autocompleted: +```bash +wake +``` + +**No-arg behavior:** running `wake` without arguments prints usage and shows available +devices (and exits with code 1). Use `wake -l` for a clean list and exit code 0. + +## Installing `wakeonlan` + +If your distro doesn’t provide `wakeonlan`, install it manually from GitHub: + +```bash +curl -RLOJ https://github.com/jpoliv/wakeonlan/raw/refs/heads/master/wakeonlan +chmod a+x wakeonlan +sudo install -o root -g root -m 755 wakeonlan /usr/local/bin/wakeonlan +rm wakeonlan +``` + +Enjoy! diff --git a/plugins/wake/wake.plugin.sh b/plugins/wake/wake.plugin.sh new file mode 100644 index 000000000..10b8328a8 --- /dev/null +++ b/plugins/wake/wake.plugin.sh @@ -0,0 +1,127 @@ +#!/usr/bin/env bash +# oh-my-bash.module: wake-on-lan wrapper + autocompletion +# wake.plugin.sh +# Author: hoek from 0ut3r.space +# Based on oh-my-zsh wakeonlan plugin @ commit 1d9eacb34f59f3bf82a9de0d7b474cb4c501e3fd +# +# Usage: wake [options] +# Options: +# -l, --list list configured devices +# -n, --dry-run show what would be executed (no packet sent) +# -p, --port UDP port (default 9) +# -h, --help usage +# +# Config dir: $HOME/.wakeonlan +# Device file format (either): +# " [broadcast-IP] [port]" +# first non-empty, non-# line +# or key=value lines: +# MAC=aa:bb:cc:dd:ee:ff +# BCAST=192.168.1.255 +# PORT=9 + +_wake_cfgdir="$HOME/.wakeonlan" + +_wake_usage() { + _omb_util_print 'Usage: wake [ -l | --list ] [ -n | --dry-run ] [ -p|--port N ] ' >&2 +} +Hyprland +_wake_collect_devices() { + local -n _out=$1 + _out=() + local f + shopt -s nullglob + for f in "$_wake_cfgdir"/*; do + [[ -f $f ]] && _out+=( "$(basename -- "$f")" ) + done + shopt -u nullglob +} + +_wake_read_config() { + local device=$1 cfgfile="$_wake_cfgdir/$device" + local -n _mac=$2 _bcast=$3 _port=$4 + _mac="" _bcast="" _port="" + + local line key val + while IFS= read -r line; do + [[ -z $line || $line =~ ^[[:space:]]*# ]] && continue + if [[ $line == *"="* ]]; then + key=${line%%=*}; val=${line#*=} + key=${key//[[:space:]]/}; val=${val##[[:space:]]} + case "${key^^}" in + MAC) _mac="$val" ;; + BCAST|BROADCAST) _bcast="$val" ;; + PORT) _port="$val" ;; + esac + else + read -r _mac _bcast _port <<<"$line" + fi + done <"$cfgfile" + + [[ -n $_mac ]] || return 1 + [[ -n $_bcast ]] || _bcast=255.255.255.255 + [[ -n $_port ]] || _port=9 + return 0 +} + +function wake { + local opt_list=0 opt_dry=0 opt_port="" + local device + + while (($#)); do + case "$1" in + -l|--list) opt_list=1 ;; + -n|--dry-run) opt_dry=1 ;; + -p|--port) shift; opt_port="${1-}" ;; + -h|--help) _wake_usage; return 0 ;; + --) shift; break ;; + -*) _wake_usage; return 2 ;; + *) device="$1"; break ;; + esac + shift + done + + if (( opt_list )); then + local -a devs; _wake_collect_devices devs + ((${#devs[@]})) && printf '%s\n' "${devs[@]}" || _omb_util_print "No devices configured in $_wake_cfgdir" >&2 + return 0 + fi + + local cfgfile="$_wake_cfgdir/${device-}" + if [[ -z ${device-} || ! -f $cfgfile ]]; then + _wake_usage + local -a devs; _wake_collect_devices devs + ((${#devs[@]})) && _omb_util_print "Available devices: ${devs[*]}" >&2 \ + || _omb_util_print "No devices configured. Create $_wake_cfgdir first." >&2 + return 1 + fi + + if ! _omb_util_command_exists wakeonlan; then + _omb_util_print "ERROR: 'wakeonlan' not found. Install it from https://github.com/jpoliv/wakeonlan." >&2 + return 1 + fi + + local mac bcast port + if ! _wake_read_config "$device" mac bcast port; then + _omb_util_print "ERROR: Invalid config in '$cfgfile'. Expected ' [BCAST] [PORT]' or key=value form." >&2 + return 1 + fi + [[ -n $opt_port ]] && port="$opt_port" + + if (( opt_dry )); then + _omb_util_print "DRY-RUN: wakeonlan -p $port -i $bcast $mac" >&2 + return 0 + fi + + wakeonlan -p "$port" -i "$bcast" "$mac" +} + +function _omb_plugin_wake_completion { + local cur=${COMP_WORDS[COMP_CWORD]} + local -a flags choices + flags=( -l --list -n --dry-run -p --port -h --help ) + [[ -d $_wake_cfgdir ]] && _wake_collect_devices choices || choices=() + local IFS=$'\n' + COMPREPLY=( $(compgen -W "$(printf '%s\n' "${flags[@]}" "${choices[@]}")" -- "$cur") ) +} +complete -F _omb_plugin_wake_completion wake