Skip to content

Instantly share code, notes, and snippets.

@InTEGr8or
Created April 3, 2026 21:00
Show Gist options
  • Select an option

  • Save InTEGr8or/7c23d1a091d8b5098d812a6706cb5644 to your computer and use it in GitHub Desktop.

Select an option

Save InTEGr8or/7c23d1a091d8b5098d812a6706cb5644 to your computer and use it in GitHub Desktop.
A lightweight interactive select list installer. Store your favorte items in the tools.list Interactive select the needed items on any new machine or instance.
#!/usr/bin/env bash
LIST_FILE="$HOME/tools.list"
STATE_FILE="$HOME/.mstouffer_setup_state.json"
BLUE='\033[0;34m'; GREEN='\033[0;32m'; RED='\033[0;31m'; YELLOW='\033[1;33m'; NC='\033[0m'; BOLD='\033[1m'
if [[ ! -f "$LIST_FILE" ]]; then
echo -e "${RED}Error: $LIST_FILE not found.${NC}"
exit 1
fi
TOOL_NAMES=()
declare -A TOOL_DESC
declare -A TOOL_CMD
while IFS="|" read -r name desc cmd; do
[[ -z "$name" || "$name" == "#"* ]] && continue
TOOL_NAMES+=("$name")
TOOL_DESC["$name"]="$desc"
TOOL_CMD["$name"]="$cmd"
done < "$LIST_FILE"
declare -A SELECTED
[[ -f "$STATE_FILE" ]] && while read -r line; do SELECTED["$line"]=1; done < "$STATE_FILE"
save_state() { > "$STATE_FILE"; for n in "${!SELECTED[@]}"; do [[ ${SELECTED[$n]} -eq 1 ]] && echo "$n" >> "$STATE_FILE"; done; }
current_idx=0
draw_ui() {
printf "\033[H\033[J"
echo -e "${BLUE}${BOLD}=== mstouffer Multi-Tool Installer ===${NC}"
echo -e "Loading from: ${YELLOW}$LIST_FILE${NC}"
echo "-----------------------------------------------------------------------"
for i in "${!TOOL_NAMES[@]}"; do
local name="${TOOL_NAMES[$i]}"
local prefix=" "; [[ $i -eq $current_idx ]] && prefix="${YELLOW}> ${NC}"
local mark="[ ]"; local color=$NC; [[ ${SELECTED[$name]} -eq 1 ]] && { mark="[x]"; color=$GREEN; }
printf "%b%b %-15s %b ${NC}%s\n" "$prefix" "$color" "$name" "$mark" "${TOOL_DESC[$name]}"
done
}
apply_changes() {
echo -e "\n\n${YELLOW}${BOLD}--- Installing Selected Items ---${NC}"
export PATH="$HOME/.local/bin:$PATH"
if command -v mise &>/dev/null; then eval "$(mise activate bash)"; fi
for name in "${TOOL_NAMES[@]}"; do
if [[ ${SELECTED[$name]} -eq 1 ]]; then
echo -e "${BLUE}Running: $name...${NC}"
eval "${TOOL_CMD[$name]}"
fi
done
echo -e "\n${GREEN}${BOLD}Done! Press any key.${NC}"
read -n 1 -s
}
hide_cursor() { printf "\033[?25l"; }
show_cursor() { printf "\033[?25h"; }
hide_cursor; trap show_cursor EXIT
while true; do
draw_ui
read -rsn1 key
[[ "$key" == "" ]] && key=" "
case "$key" in
k) ((current_idx--)); [[ $current_idx -lt 0 ]] && current_idx=$((${#TOOL_NAMES[@]} - 1)) ;;
j) ((current_idx++)); [[ $current_idx -ge ${#TOOL_NAMES[@]} ]] && current_idx=0 ;;
" ") name="${TOOL_NAMES[$current_idx]}"; [[ ${SELECTED[$name]} -eq 1 ]] && SELECTED[$name]=0 || SELECTED[$name]=1; save_state ;;
i) apply_changes ;;
q) break ;; # FIXED: Use break instead of exit
esac
done
show_cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment