From f9cffabebbc47a3129d71c4a6f5c9acecc50335a Mon Sep 17 00:00:00 2001 From: 2art <2art@pm.me> Date: Wed, 5 Jun 2024 00:32:23 +0300 Subject: [PATCH] feat(nanotimer): New nanotimer plugin --- plugins/nanotimer/nanotimer.plugin.zsh | 70 ++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 plugins/nanotimer/nanotimer.plugin.zsh diff --git a/plugins/nanotimer/nanotimer.plugin.zsh b/plugins/nanotimer/nanotimer.plugin.zsh new file mode 100644 index 000000000..cb26c1cd8 --- /dev/null +++ b/plugins/nanotimer/nanotimer.plugin.zsh @@ -0,0 +1,70 @@ +#!/usr/bin/env zsh + +## nanotimer - Oh-My-Zsh plugin +## +## Utilizes the 'preexec' and 'precmd' hooks. Timer is setup during 'preexec', and stopped at +## 'precmd'. This time difference is very accurate, and is displayed in the right prompt. +## +## More information about hooks like 'preexec' and 'precmd', and many others: +## https://zsh.sourceforge.io/Doc/Release/Functions.html#index-hook-functions + +## * __exectimer_preexec() +## Executed just after a command has been read and is about to be executed. This hook is used to +## start a high-precision timer before command execution. Additional tasks can be completed in this +## function; for example, update active network interface. By doing that here, it ensures the +## network interface stays updated. +__exectimer_preexec() { + timer=$(($(date +%s%0N))) +} + +## * __exectimer_precmd() +## Executed before each prompt, or in other words, after previous command. Stops the timer from +## 'preexec', and updates rprompt with elapsed time. This is modified for higher precision from the +## following code snippet: https://gist.github.com/knadh/123bca5cfdae8645db750bfb49cb44b0 +__exectimer_precmd() { + if [ $timer ]; then + now=$(($(date +%s%0N))) + elapsed=$(($now-$timer)) + + # Unset elapsed variables to make below syntax work (work-around to prevent more work) + unset elns elmcs elms els + + # Depending on digits in nanoseconds, set the elapsed milliseconds, seconds etc. + # I should document this more later as ZSH syntax is kinda weird sometimes. + case ${#elapsed} in + [0-3]) + elns=$elapsed + ;; + [4-6]) + elapsed=${elapsed%${elns=${elapsed:(-3):3}}} + elmcs=$elapsed + ;; + [7-9]) + elapsed=${elapsed%${elns=${elapsed:(-3):3}}} + elapsed=${elapsed%${elmcs=${elapsed:(-3):3}}} + elms=$elapsed + ;; + *) + elapsed=${elapsed%${elns=${elapsed:(-3):3}}} + elapsed=${elapsed%${elmcs=${elapsed:(-3):3}}} + elapsed=${elapsed%${elms=${elapsed:(-3):3}}} + els=$elapsed + ;; + esac + + # Zero values for all, when e.g. under a second execution. + for v in elns elmcs elms els; do + [[ ! "${(P)v}" =~ ^[0-9]+$ ]] && read $v <<< $((0)) + done + + # Set right prompt and reset timer. + export RPROMPT="%(?.%F{195}[%?].%S%B%F{009}[%?]%b%s) %F{215}%B${els}%b%F{250}s %F{192}%B${elms}%b%F{250}ms %F{194}%B${elmcs}%b%F{250}μs %F{231}%B${elns}%b%F{250}ns%{$reset_color%}" + + unset timer + fi +} + +# Add functions to Zsh hooks. +autoload -U add-zsh-hook +add-zsh-hook preexec __exectimer_preexec +add-zsh-hook precmd __exectimer_precmd