I’m working on a module to add OctoPrint status to my zsh prompt, which I’ll probably write about in the future as a bigger post about my prompt customizations.
To start with that though, I need to play around with accessing the API via curl.
So here’s my super alpha version that will request the current status via HTTP and output it:
#!/bin/bash
OCTOPRINT_API="hunter2"
BASE_URL="http://octoprint.example.com"
JOB_ENDPOINT="${BASE_URL}/api/job"
CURL_TIMEOUT="0.5"# Fetch the JSON from OctoPrint
response="$(curl --max-time ${CURL_TIMEOUT} --silent --fail \
--header "X-Api-Key: ${OCTOPRINT_API}" \
"${JOB_ENDPOINT}")"# Extract fields with jq
file_name=$(jq -r '.job.file.display' <<< "$response")
completion=$(jq -r '.progress.completion' <<< "$response")
state=$(jq -r '.state' <<< "$response")
time_elapsed=$(jq -r '.progress.printTime' <<< "$response")
time_left=$(jq -r '.progress.printTimeLeft' <<< "$response")
# Round the completion percentage to two decimals
completion_str=$(printf"%.2f""$completion")
# Convert seconds to H:MM:SSfunctionfmt_time() {
local total_seconds="$1"local hours=$((total_seconds / 3600))
local minutes=$(((total_seconds % 3600) / 60))
local seconds=$((total_seconds % 60))
printf"%02d:%02d:%02d""$hours""$minutes""$seconds"
}
# Convert the times
time_elapsed_str=$(fmt_time "$time_elapsed")
time_left_str=$(fmt_time "$time_left")
# Print a readable summaryecho"File: ${file_name}"echo"State: ${state}"echo"Completion: ${completion_str}%"echo"Time Elapsed: ${time_elapsed_str}"echo"Time Left: ${time_left_str}"Code language:Bash(bash)
I often SSH into servers to get some work done, and one of the things I discovered recently is that I may not always know or remember if I’m in a screen session.
So I had the bright idea to just add it to my shell prompt!
Simply just add one of these to your RC file of choice:
Bash
# Add Screen name to PS1 if we're in a screen.if [ -n "$STY" ]; then
PS1="\[\e[1m\](Screen: $STY)\[\e[0m\]\n$PS1"
fiCode language:PHP(php)
ZSH
# Add Screen name to PROMPT if we're in a screen.if [[ -n "$STY" ]]; then
PROMPT="%B(Screen: $STY)%b"$'\n'"$PROMPT"
fiCode language:PHP(php)
And remember, if you’re asking yourself if you should run something in a screen, you’re already too late!
As a power user of my Macbook, I’ve found that I often overlook the small battery icon on my menu bar, especially when I’m immersed in a fun project. This minor inconvenience sparked a thought: why not incorporate the battery status directly into my terminal prompt? Thus, I embarked on a fun exploration into ZSH scripting. With a bit of coding magic, I was able to enhance my terminal prompt to dynamically display my Macbook’s battery percentage. Let me guide you through the process.
We start by loading the ZSH hook module. This module allows us to add functions that run before and/or after each command, giving us the ability to update our battery status prompt in real-time.
autoload -U add-zsh-hookCode language:Bash(bash)
The Battery Status Function
Next, I crafted a function, terminal_battery_stats, that retrieves battery information and displays it in the terminal prompt. Here’s how it works:
function terminal_battery_stats {
# Retrieve battery statistics using the pmset command. This is a macOS# command that allows power management and battery status retrieval.# The awk command is used to format the output into a useful string.
bat_info=$(pmset -g batt | awk 'NR==2 {gsub(/;/,""); print $3 " " $4}')
# Extract the battery percentage and state from the bat_info string.
bat_percent=$(echo$bat_info | cut -d' ' -f1 | tr -d '%')
bat_state=$(echo$bat_info | cut -d' ' -f2)
# Check if the battery is charging or on AC power.if [ $bat_state = 'charging' ] || [ $bat_state = 'AC' ] || [ $bat_state = 'charged' ] || [ $bat_state = 'finishing' ]; then# If the battery is over 66%, don't display a battery prompt.if [ $bat_percent -gt 66 ]; then
bat_prompt=""else# Otherwise, set the battery icon to a plug, and the color to green.
bat_icon='🔌'
bat_color='%F{green}'# Format the prompt with the battery color, percentage, and icon.
bat_prompt="〔$bat_color$bat_percent%% $bat_icon%f〕"fielse# If the battery is discharging, choose a battery icon and color based on the battery level.if [ $bat_percent -le 33 ]; then
bat_icon='🪫'
bat_color='%F{red}'elif [ $bat_percent -gt 66 ]; then
bat_icon='🔋'
bat_color='%F{green}'else
bat_icon='🔋'
bat_color='%F{yellow}'fi# Format the prompt with the battery color, percentage, and icon.
bat_prompt="〔$bat_color$bat_percent%% $bat_icon%f〕"fi# Check if the current prompt already contains a battery status.if [[ "$PROMPT" == *"〔"* ]]; then# If it does, remove the existing battery status from the prompt.
PROMPT=${PROMPT#*"〕"}fi# Add the new battery status to the prompt.
PROMPT="${bat_prompt}${PROMPT}"
}Code language:Bash(bash)
To get some basic understanding of the magic behind ZSH scripting and manipulating the terminal prompt, check this helpful resource.
Applying the Battery Status Function
After creating the function, I added terminal_battery_stats to the command prompt via ZSH’s pre-command hook. Now, my function runs before each command entered in the terminal, keeping the battery stats up-to-date.
All the above code is added to my ~/.zshrc file, turning my terminal prompt into a dynamic display of my Macbook’s battery status. The resulting terminal prompt looks like this:
Conclusion
Through the power of ZSH scripting magic, my terminal now offers real-time updates of my Macbook’s battery status after every command. I set it to disappear once the battery reaches 67%, a level I consider to be within the safe zone. This is an excellent example of how minor inconveniences can lead to innovative solutions that enhance productivity.
Here’s the full script ready to drop in to your own ~/.zshrc file:
# Load the zsh hook module. This is a module that allows adding functions# that get run before and/or after each command.autoload -U add-zsh-hook
# Function to retrieve and display battery statistics in the terminal prompt.# Uses the pmset command to retrieve battery information, and awk to format# it into a useful string. Depending on the battery's state and level, # different icons and colors will be displayed in the terminal prompt.# # @return voidfunction terminal_battery_stats {
# Retrieve battery statistics using the pmset command. This is a macOS# command that allows power management and battery status retrieval.# The awk command is used to format the output into a useful string. bat_info=$(pmset -g batt | awk 'NR==2 {gsub(/;/,""); print $3 " " $4}')
# Extract the battery percentage and state from the bat_info string. bat_percent=$(echo$bat_info | cut -d' ' -f1 | tr -d '%')
bat_state=$(echo$bat_info | cut -d' ' -f2)
# Check if the battery is charging or on AC power.if [ $bat_state = 'charging' ] || [ $bat_state = 'AC' ] || [ $bat_state = 'charged' ] || [ $bat_state = 'finishing' ]; then# If the battery is over 66%, don't display a battery prompt.if [ $bat_percent -gt 66 ]; then bat_prompt=""else# Otherwise, set the battery icon to a plug, and the color to green. bat_icon='🔌' bat_color='%F{green}'# Format the prompt with the battery color, percentage, and icon. bat_prompt="〔$bat_color$bat_percent%% $bat_icon%f〕"fielse# If the battery is discharging, choose a battery icon and color based on the battery level.if [ $bat_percent -le 33 ]; then bat_icon='🪫' bat_color='%F{red}'elif [ $bat_percent -gt 66 ]; then bat_icon='🔋' bat_color='%F{green}'else bat_icon='🔋' bat_color='%F{yellow}'fi# Format the prompt with the battery color, percentage, and icon. bat_prompt="〔$bat_color$bat_percent%% $bat_icon%f〕"fi# Check if the current prompt already contains a battery status.if [[ "$PROMPT" == *"〔"* ]]; then# If it does, remove the existing battery status from the prompt. PROMPT=${PROMPT#*"〕"}fi# Add the new battery status to the prompt. PROMPT="${bat_prompt}${PROMPT}"}
# Adds the function terminal_battery_stats to the command prompt # meaning it will be run before each command entered in the terminal. add-zsh-hook precmd terminal_battery_stats
Code language:Bash(bash)
I’ve had a few snippets in my .zshrc file for a while now that will output how long a command takes to process.
First off, I’d like to say that I did not come up with this idea, and I didn’t really write the code. I’ve snipped it from somewhere and modified it over time, so I am very sorry to the original author for not being able to give full credit. I didn’t save where I got it from–so if anyone comes across this in the future and might know where the idea came from, drop it in the comments.
Now, on to the fun:
The original script only went down to the second, but I wanted more granularity than that, so I went down to the millisecond.
You’ll likely need to install gdate (brew install gdate) for this to work properly.
The code (added to ~/.zshrc):
functionpreexec(){
timer=$(($(gdate +%s%0N)/1000000))
}
functionprecmd(){
if [ "$timer" ]; then
now=$(($(gdate +%s%0N)/1000000))
elapsed=$now-$timer
reset_color=$'\e[00m'
RPROMPT="%F{cyan} $(converts "$elapsed") %{$reset_color%}"
export RPROMPT
unset timer
fi
}
converts() {
local t=$1
local d=$((t/1000/60/60/24))
local h=$((t/1000/60/60%24))
local m=$((t/100/60%60))
local s=$((t/1000%60))
local ms=$((t%1000))
if [[ $d -gt 0 ]]; then
echo -n " ${d}d"
fi
if [[ $h -gt 0 ]]; then
echo -n " ${h}h"
fi
if [[ $m -gt 0 ]]; then
echo -n " ${m}m"
fi
if [[ $s -gt 0 ]]; then
echo -n " ${s}s"
fi
if [[ $ms -gt 0 ]]; then
echo -n " ${ms}ms"
fi
echo
}Code language:PHP(php)
HyperDock, a macOS tool that provides windows previews like modern versions of Windows, seems to have problems on macOS Catalina for me. At random times, it will stop working and I need to go to System Preferences and disable and re-enable it; sometimes many times a day.
I’ve tried contacting the author and so far I’ve not gotten any response. The last update was quite a while ago, and … just radio silence.
To help fix this, I’ve fiddled around enough to figure out what program to run to get HyperDock to work again, and have built a really janky daemon for it using a Login Item.
I have this script that runs every time I log in, which will (re)start the HyperDock Helper, and restart it every time it dies:
#/bin/zsh
until "/Users/username/Library/PreferencePanes/HyperDock.prefpane/Contents/Resources/HyperDock Helper.app/Contents/MacOS/HyperDock Helper"; doecho"HyperDock Helper crashed with exit code $?. Respawning.." >&2 | tee /Users/username/.hh.log
sleep 1
doneCode language:PHP(php)