nature_dotfiles/config/bash/prompt

325 lines
12 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/env bash
# folder names, change it depending on your language
documents="Documents"
music="Music"
pictures="Pictures"
videos="Videos"
downloads="Downloads"
declare -A PROJECT_ROOT_CACHE
export FIND_PROJECT_ROOT_DEBUG=0
find_project_root() {
local args=${@}
local cache_key="cache_$(echo -n $PWD | md5sum | cut -d' ' -f1)"
# args detection
for arg in ${args}; do
if [[ "${arg:0:2}" = "--" ]]; then
arg="${arg:2}"
case "${arg}" in
"help")
echo -e "Usage : find_project_root [OPTION(S)]\n"
echo "Find the folder that could be a project root."
echo "It is automatically called by the prompt generator but you can call it if you want to access or modify the cache.\n"
echo "The result is stocked in the env variable PROJECT_ROOT. The exit value is 0 when project root found or 1 if not."
echo "Options :"
echo " --print-cache print project root cache"
echo " --clear-cache clear project root cache ; WARNING : the cache is wiped automatically in new bash instances."
echo " --toggle-debug toggle debug mode"
echo " --help display this help"
return 0 ;;
"print-cache")
for key in ${!PROJECT_ROOT_CACHE[@]}; do
echo "[${key}]=${PROJECT_ROOT_CACHE[$key]}"
done ;;
"clear-cache")
PROJECT_ROOT_CACHE=() ;;
"toggle-debug")
FIND_PROJECT_ROOT_DEBUG=$((! FIND_PROJECT_ROOT_DEBUG)) ;;
*)
echo -e "Error : unrecognised parameter : --${arg}\n Try typing --help" ;;
esac
else
echo -e "Error : unrecognised parameter : ${arg}\n Try typing --help"
fi
done
# search cache for existing data
if [[ -n "${PROJECT_ROOT_CACHE[$cache_key]}" ]]; then
if [[ "${PROJECT_ROOT_CACHE[$cache_key]}" != "." ]]; then
PROJECT_ROOT="${PROJECT_ROOT_CACHE[$cache_key]}"
return 0
fi
PROJECT_ROOT=""
return 1
fi
# estimate probability of root dir
local depth=0
local current_dir="$PWD"
local current_max_score=0
local current_dir_score=0
local project_root="."
while (( depth < 10 )) && [[ "${current_dir}" != "/" ]]; do
current_dir_score=0
# 100% root
for path in README.md README.rst README LICENSE \
Dockerfile docker-compose.yml \
.git; do
if [[ -e "${current_dir}/${path}" ]]; then
(( FIND_PROJECT_ROOT_DEBUG )) && echo "${path}"
((current_dir_score += 100))
fi
done
# 90% root
for path in CMakeLists.txt \
Cargo.toml Cargo.lock \
go.mod go.sum \
pyproject.toml \
pom.xml \
package.json \
.csproj .sln; do
if [[ -e "${current_dir}/${path}" ]]; then
(( FIND_PROJECT_ROOT_DEBUG )) && echo "${path}"
((current_dir_score += 90))
fi
done
# 75% root
for path in Makefile \
requirements.txt \
build.gradle \
Gemfile \
tsconfig.json \
composer.json \
.gitignore; do
if [[ -e "${current_dir}/${path}" ]]; then
(( FIND_PROJECT_ROOT_DEBUG )) && echo "${path}"
((current_dir_score += 75))
fi
done
# 50% root
for path in webpack.config.js vite.config.js babel.config.js .babelrc rollup.config.js \
lib include config scripts bin src third_party 3rd_party vendor \
.env .env.local \
.dockerignore; do
if [[ -e "${current_dir}/${path}" ]]; then
(( FIND_PROJECT_ROOT_DEBUG )) && echo "${path}"
((current_dir_score += 50))
fi
done
# 25% root
for path in configure \
Gopkg.toml \
Pipfile Pipfile.lock setup.py tox.ini .python-version \
build.xml settings.gradle \
packages.config \
Directory.Build.props \
.htmlhintrc .stylelintrc \
Gemfile.lock \
composer.lock \
Rakefile; do
if [[ -e "${current_dir}/${path}" ]]; then
(( FIND_PROJECT_ROOT_DEBUG )) && echo "${path}"
((current_dir_score += 25))
fi
done
if (( current_dir_score >= current_max_score )) && (( current_dir_score > 50 )); then
current_max_score=${current_dir_score}
project_root=${current_dir}
fi
(( FIND_PROJECT_ROOT_DEBUG )) && echo -e "${depth} : ${current_dir}\n score : ${current_dir_score}"
current_dir=$(dirname "$current_dir")
((depth++))
done
# save data to cache
PROJECT_ROOT_CACHE[${cache_key}]="${project_root}"
if [[ "${project_root}" != "." ]]; then
PROJECT_ROOT="${project_root}"
return 0
fi
PROJECT_ROOT=""
return 1
}
declare -A DIR_MAJORITY_LANGUAGE_CACHE
export FIND_DIR_MAJORITY_LANGUAGE_DEBUG=0
find_dir_majority_language() {
local args=${@}
local cache_key="cache_$(echo -n $PWD | md5sum | cut -d' ' -f1)"
# args detection
for arg in ${args}; do
if [[ "${arg:0:2}" = "--" ]]; then
arg="${arg:2}"
case "${arg}" in
"help")
echo -e "Usage : find_dir_majority_language [OPTION(S)]\n"
echo "Find the majoritary language in the current and sub-folders."
echo "It is automatically called by the prompt generator but you can call it if you want to access or modify the cache.\n"
echo "The result is stocked in the env variable DIR_MAJORITY_LANGUAGE. The exit value is 0 when project root found or 1 if not."
echo "Options :"
echo " --print-cache print majority language cache"
echo " --clear-cache clear majority language cache ; WARNING : the cache is wiped automatically in new bash instances."
echo " --toggle-debug toggle debug mode"
echo " --help display this help"
return 0 ;;
"print-cache")
for key in ${!DIR_MAJORITY_LANGUAGE_CACHE[@]}; do
echo "[${key}]=${DIR_MAJORITY_LANGUAGE_CACHE[$key]}"
done ;;
"clear-cache")
DIR_MAJORITY_LANGUAGE_CACHE=() ;;
"toggle-debug")
FIND_DIR_MAJORITY_LANGUAGE_DEBUG=$((! FIND_DIR_MAJORITY_LANGUAGE_DEBUG)) ;;
*)
echo -e "Error : unrecognised parameter : --${arg}\n Try typing --help" ;;
esac
else
echo -e "Error : unrecognised parameter : ${arg}\n Try typing --help"
fi
done
# search cache for existing data
if [[ -n "${DIR_MAJORITY_LANGUAGE_CACHE[$cache_key]}" ]]; then
DIR_MAJORITY_LANGUAGE="${DIR_MAJORITY_LANGUAGE_CACHE[$cache_key]}"
return
fi
# in case of equal quantity of per-language file, the majoritary language is arbitrary selected
local C=0 Cpp=0 Rust=0 Go=0 Python=0 Java=0 Ruby=0 Javascript=0 PHP=0 CS=0 HTMLCSS=0 SQL=0
local ext=""
for file in "$PWD"/*.* "$PWD"/*/*.* "$PWD"/*/*/*.*; do
#[[ -f "$file" ]] || continue
local ext="${file##*.}"
[[ "${ext}" = "${file}" ]] && continue
case "${ext}" in
c|h) ((C++)) ;;
cpp|cxx|cc|hpp|hxx|hh|h) ((Cpp++)) ;;
rs|rlib) ((Rust++)) ;;
go) ((Go++)) ;;
py|pyw|pyc|pyo) ((Python++)) ;;
java|class|jar|war) ((Java++)) ;;
rb|erb|rake) ((Ruby++)) ;;
js|jsx|ts|tsx|mjs|cjs) ((Javascript++)) ;;
php|phtml) ((PHP++)) ;;
cs|csproj|sln) ((CS++)) ;;
html|htm|css|scss|sass|less)((HTMLCSS++)) ;;
esac
done
if (( FIND_DIR_MAJORITY_LANGUAGE_DEBUG )); then
echo "C: ${C}"
echo "C++: ${Cpp}"
echo "Rust: ${Rust}"
echo "Go: ${Go}"
echo "Python: ${Python}"
echo "Java: ${Java}"
echo "Ruby: ${Ruby}"
echo "Javascript: ${Javascript}"
echo "PHP: ${PHP}"
echo "C#: ${CS}"
echo "HTML/CSS: ${HTMLCSS}"
fi
local max_count=0
DIR_MAJORITY_LANGUAGE=""
(( C > max_count )) && max_count=${C} && DIR_MAJORITY_LANGUAGE="C"
(( Cpp > max_count )) && max_count=${Cpp} && DIR_MAJORITY_LANGUAGE="C++"
(( Rust > max_count )) && max_count=${Rust} && DIR_MAJORITY_LANGUAGE="Rust"
(( Go > max_count )) && max_count=${Go} && DIR_MAJORITY_LANGUAGE="Go"
(( Python > max_count )) && max_count=${Python} && DIR_MAJORITY_LANGUAGE="Python"
(( Java > max_count )) && max_count=${Java} && DIR_MAJORITY_LANGUAGE="Java"
(( Ruby > max_count )) && max_count=${Ruby} && DIR_MAJORITY_LANGUAGE="Ruby"
(( Javascript > max_count )) && max_count=${Javascript} && DIR_MAJORITY_LANGUAGE="Javascript"
(( PHP > max_count )) && max_count=${PHP} && DIR_MAJORITY_LANGUAGE="PHP"
(( CS > max_count )) && max_count=${CS} && DIR_MAJORITY_LANGUAGE="C#"
(( HTMLCSS > max_count )) && max_count=${HTMLCSS} && DIR_MAJORITY_LANGUAGE="HTML/CSS"
# save data to cache
DIR_MAJORITY_LANGUAGE_CACHE[${cache_key}]="${DIR_MAJORITY_LANGUAGE}"
}
gen_prompt() {
local LAST_EXIT_CODE=$?
local HOUR="\[\033[0;31m\]╭─\[\033[7;47m\]\A"
local USER="\[\033[45m\]\[\033[1;27;30m\]\u\[\033[7m\]"
local FOLDER="\[\033[0;36m\]\[\033[1;7m\]\w"
local INFO=" "
if find_project_root; then
find_dir_majority_language
local language_icon="󰡯 "
case "$DIR_MAJORITY_LANGUAGE" in
"C") language_icon=" " ;;
"C++") language_icon=" " ;;
"Rust") language_icon=" " ;;
"Go") language_icon="󰟓 " ;;
"Python") language_icon=" " ;;
"Java") language_icon=" " ;;
"Ruby") language_icon=" " ;;
"Javascript") language_icon=" " ;;
"PHP") language_icon="󰌟 " ;;
"C#") language_icon="󰌛 " ;;
"HTML/CSS") language_icon=" " ;;
esac
INFO="${language_icon}$(basename "${PROJECT_ROOT}")"
elif [ "$HOME" = "$PWD" ]; then
INFO="󱂵 "
elif [ "$HOME/${documents}" = "$PWD" ]; then
INFO="󱧶 "
elif [ "$HOME/${music}" = "$PWD" ]; then
INFO="󱍙 "
elif [ "$HOME/${pictures}" = "$PWD" ]; then
INFO="󰉏 "
elif [ "$HOME/${videos}" = "$PWD" ]; then
INFO="󰉏 "
elif [ "$HOME/${downloads}" = "$PWD" ]; then
INFO="󰉍 "
elif [ "$HOME/.config/" = "$PWD" ]; then
INFO="󱧼 "
elif [ "$HOME/.local/" = "$PWD" ]; then
INFO="󰉌 "
elif mount | grep -q "$PWD"; then
INFO="󰉉 "
fi
INFO="\[\033[45m\]\[\033[1;27;30m\]${INFO}\[\033[7m\]"
local ARROW_COLOR="35"
(( ${LAST_EXIT_CODE} != 0 )) && ARROW_COLOR="32"
local USER_PROMPT="\[\033[0;31m\]╰─\[\033[${ARROW_COLOR}m\]\[\033[0m\]"
PS1="\n${HOUR} ${USER} ${FOLDER} ${INFO}\n${USER_PROMPT} "
}
PROMPT_COMMAND=gen_prompt