# Zsh Command Execution Time Notification Plugin A Zsh plugin that automatically calculates the execution time of commands. If a command runs longer than a given threshold, it notifies you with the command's name (arg0), execution time, and exit code. Notifications are delivered via: 1. **OSC Escape Sequences** (OSC 9 and OSC 777), which are natively supported by modern terminal emulators like iTerm2, Windows Terminal, Kitty, WezTerm, foot, and urxvt to show native system notifications. 2. An **External Command** (configured via `ET_NOTIFY_COMMAND`), which is executed asynchronously in the background. ## Features - **Automatic Hooking**: Seamlessly integrates using standard Zsh hooks (`preexec` and `precmd`). - **Precision Time Measurement**: Uses `$EPOCHREALTIME` to measure duration with microsecond precision. - **Smart Command Parsing**: Extracts the exact executable name (`arg0` only) by skipping environment variable overrides and stripping path prefixes. - **Custom Threshold**: Configurable notification threshold in milliseconds. - **Asynchronous External Notifications**: Run custom notifications, Slack hooks, or scripts without locking up your shell prompt. ## Installation ### Manual 1. Clone or download this repository. 2. Add the following line to your `~/.zshrc`: ```zsh source /path/to/execution-time.plugin.zsh ``` ### Using Oh My Zsh 1. Clone this repository into your custom plugins directory: ```bash git clone https://github.com/yourusername/execution-time.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/execution-time ``` 2. Enable it by adding `execution-time` to your plugins list in `~/.zshrc`: ```zsh plugins=(... execution-time) ``` ## Configuration You can configure the behavior of the plugin by setting the following environment variables in your `~/.zshrc` before or after loading the plugin: ### `ET_NOTIFY_TIMEOUT` (msec) The threshold duration in milliseconds. A notification is triggered only if the command runs longer than this threshold. - **Default**: `5000` (5 seconds) - **Example**: ```zsh # Notify for commands taking longer than 2 seconds (2000 ms) ET_NOTIFY_TIMEOUT=2000 ``` ### `ET_NOTIFY_OSC9` and `ET_NOTIFY_OSC777` Notify the user via OSC9 and OSC777 escape sequence. The terminal should support it. - **Default**: empty; no notifications through OSC9 and OSC777 - **Example**: ```zsh # Notify the user via OSC9 escape sequence ET_NOTIFY_OSC9=yes ``` ### `ET_NOTIFY_COMMAND` An optional external shell command/command string to run when a command exceeds the threshold. This command is executed asynchronously (non-blocking) in a background subshell. To allow custom notification formats, the plugin exports the following environment variables to the command context: - `ET_COMMAND`: The name of the command executed (`arg0` only). - `ET_ELAPSED`: The exact duration in milliseconds (integer). - `ET_EXIT_CODE`: The exit status of the command. - `ET_DURATION_STR`: The duration formatted cleanly (e.g. `2.50s` or `450ms`). - `ET_MESSAGE`: A pre-formatted message: `: Took (exit: )`. #### Examples **Using `notify-send` (Linux):** ```zsh ET_NOTIFY_COMMAND='notify-send "Command Finished: $ET_COMMAND" "Took $ET_DURATION_STR (exit: $ET_EXIT_CODE)"' ``` **Using `osascript` (macOS):** ```zsh ET_NOTIFY_COMMAND='osascript -e "display notification \"Took $ET_DURATION_STR (exit: $ET_EXIT_CODE)\" with title \"Finished: $ET_COMMAND\""' ``` **Triggering a script with arguments:** ```zsh ET_NOTIFY_COMMAND='/path/to/my-notifier.sh "$ET_COMMAND" "$ET_ELAPSED" "$ET_EXIT_CODE"' ``` ## Testing To run the plugin's test suite, execute: ```bash zsh test_plugin.zsh ```