Compare commits

..

4 Commits

Author SHA1 Message Date
60cb952693 Fix: Show only ahead/behind symbols when working directory is clean
All checks were successful
CI Pipeline / shasums (push) Successful in 6s
git-sync-with-mirror / git-sync (push) Successful in 9s
CI Pipeline / build (push) Successful in 42s
CI Pipeline / tests (push) Successful in 28s
CI Pipeline / performance (push) Successful in 8s
2025-11-04 11:30:29 -05:00
aad97d949a Optimized git
Some checks failed
git-sync-with-mirror / git-sync (push) Failing after 5s
CI Pipeline / shasums (push) Successful in 17s
CI Pipeline / build (push) Successful in 51s
CI Pipeline / tests (push) Successful in 31s
CI Pipeline / performance (push) Successful in 8s
2025-11-03 16:27:38 -05:00
6185230dfd optimized _custom.sh 2025-11-03 15:14:19 -05:00
20decfa42a update themes 2025-08-13 10:12:57 -05:00
16 changed files with 995 additions and 496 deletions

View File

@@ -1,12 +1,15 @@
name: CI Pipeline
on: [push, pull_request]
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
workflow_dispatch:
jobs:
shasums:
runs-on: ubuntu-latest
container:
image: rusian/base-node
steps:
- uses: actions/checkout@v4
- name: Run shasums script
@@ -16,80 +19,170 @@ jobs:
cp -v ./hyperterm/_custom.sh "$HOME"
rm -rfv hyperterm/
(cd "$HOME/.hyperterm/" && sha512sum -c hyperterm.sha512)
(cd "$HOME" && bash -x .bashrc)
build:
runs-on: ubuntu-latest
needs: shasums
container:
image: rusian/base-node
steps:
- uses: actions/checkout@v4
- name: Set up locales
run: |
doas pacman -Syu --noconfirm
doas pacman -S --noconfirm glibc less
echo "es_ES.UTF-8 UTF-8" | doas tee -a /etc/locale.gen
echo "en_US.UTF-8 UTF-8" | doas tee -a /etc/locale.gen
doas locale-gen
export LANG=es_ES.UTF-8
export LANGUAGE=es_ES
sudo apt-get update -y
sudo apt-get install -y locales less
sudo sed -i 's/# \(es_ES.UTF-8 UTF-8\)/\1/' /etc/locale.gen
sudo sed -i 's/# \(en_US.UTF-8 UTF-8\)/\1/' /etc/locale.gen
sudo locale-gen es_ES.UTF-8
export LANG=es_ES.UTF-8 LANGUAGE=es_ES
# - name: Install dependencies for shellcheck
# run: pacman -S --noconfirm xz shellcheck
- name: Install dependencies for shellcheck
run: sudo apt-get install -y xz-utils shellcheck
# - name: Run shellcheck on bash profile
# run: |
# shellcheck .bash_profile
# shellcheck ./hyperterm/hyperterm.sh
# shellcheck ./hyperterm/_custom.sh
- name: Run shellcheck on bash profile
run: |
shellcheck .bash_profile
shellcheck ./hyperterm/hyperterm.sh
shellcheck ./hyperterm/_custom.sh
# - name: Run shellcheck on build script
# run: shellcheck build.sh
- name: Run shellcheck on build script
run: shellcheck build.sh
# - name: Run build script
# run: bash -x build.sh
- name: Run build script
run: bash -x build.sh
# - name: Run shellcheck on core scripts
# run: |
# shellcheck hyperterm/core/autocomplete.sh
# shellcheck hyperterm/core/colors.sh
# shellcheck hyperterm/core/git.sh
# shellcheck hyperterm/core/languages.sh
# shellcheck hyperterm/core/status.sh
# shellcheck hyperterm/core/update.sh
- name: Run shellcheck on core scripts
run: |
shellcheck hyperterm/core/autocomplete.sh
shellcheck hyperterm/core/colors.sh
shellcheck hyperterm/core/git.sh
shellcheck hyperterm/core/languages.sh
shellcheck hyperterm/core/status.sh
shellcheck hyperterm/core/update.sh
# - name: Run shellcheck on theme scripts
# run: |
# shellcheck hyperterm/themes/default.sh
# shellcheck hyperterm/themes/joy.sh
# shellcheck hyperterm/themes/light_theme.sh
# shellcheck hyperterm/themes/minterm.sh
# shellcheck hyperterm/themes/pure.sh
# shellcheck hyperterm/themes/simple.sh
# shellcheck hyperterm/themes/special.sh
- name: Run shellcheck on theme scripts
run: |
shellcheck hyperterm/themes/default.sh
shellcheck hyperterm/themes/joy.sh
shellcheck hyperterm/themes/light_theme.sh
shellcheck hyperterm/themes/minterm.sh
shellcheck hyperterm/themes/pure.sh
shellcheck hyperterm/themes/simple.sh
shellcheck hyperterm/themes/special.sh
# - name: Run shellcheck on tools scripts
# run: |
# shellcheck hyperterm/tools/aliases.sh
# shellcheck hyperterm/tools/compress.sh
# shellcheck hyperterm/tools/export.sh
# shellcheck hyperterm/tools/listuser.sh
# shellcheck hyperterm/tools/network.sh
# shellcheck hyperterm/tools/proxy.sh
# shellcheck hyperterm/tools/rar2zip.sh
# shellcheck hyperterm/tools/ruby.sh
# shellcheck hyperterm/tools/ssh-agent.sh
# shellcheck hyperterm/tools/sysinfo.sh
# shellcheck hyperterm/tools/virtualenv.sh
- name: Run shellcheck on tools scripts
run: |
shellcheck hyperterm/tools/aliases.sh
shellcheck hyperterm/tools/compress.sh
shellcheck hyperterm/tools/export.sh
shellcheck hyperterm/tools/listuser.sh
shellcheck hyperterm/tools/network.sh
shellcheck hyperterm/tools/proxy.sh
shellcheck hyperterm/tools/rar2zip.sh
shellcheck hyperterm/tools/ruby.sh
shellcheck hyperterm/tools/ssh-agent.sh
shellcheck hyperterm/tools/sysinfo.sh
shellcheck hyperterm/tools/virtualenv.sh
# - name: Run shellcheck on install script
# run: shellcheck install.sh
- name: Run shellcheck on test scripts
run: |
shellcheck tests/test_prompt.sh
shellcheck tests/quick_test.sh
# - name: Run install script
# run: bash -x install.sh -s
- name: Run shellcheck on install script
run: shellcheck install.sh
# - name: Run shellcheck on uninstall script
# run: shellcheck uninstall.sh
- name: Run install script
run: bash -x install.sh -s
# - name: Run uninstall script
# run: bash -x uninstall.sh -s
- name: Run shellcheck on uninstall script
run: shellcheck uninstall.sh
- name: Run uninstall script
run: bash -x uninstall.sh -s
tests:
runs-on: ubuntu-latest
needs: build
env:
CI: true
steps:
- uses: actions/checkout@v4
- name: Set up git configuration for tests
run: |
git config --global user.name "CI Test User"
git config --global user.email "ci-test@example.com"
- name: Install dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y git bash
- name: Run quick prompt test
run: |
echo "INFO: Running quick prompt test"
bash tests/quick_test.sh
- name: Run comprehensive prompt test
run: |
echo "INFO: Running comprehensive prompt test"
# Run in non-interactive mode for CI
bash tests/test_prompt.sh --non-interactive
- name: Test prompt in current repository
run: |
echo "INFO: Testing prompt in current git repository"
# Create test changes to verify git status detection
echo "test change for CI" >> README.md
echo "untracked CI test file" > ci_test_file.txt
# Test using our quick test (which already handles sourcing correctly)
echo "Running quick test to verify prompt works in CI environment..."
bash tests/quick_test.sh
- name: Validate optimizations
run: |
echo "INFO: Validating optimizations"
# Check that git_optimized.sh doesn't exist (should be integrated into git.sh)
if [[ -f "hyperterm/core/git_optimized.sh" ]]; then
echo "ERROR: git_optimized.sh should not exist (should be integrated)"
exit 1
fi
# Check that git.sh exists and is optimized
if [[ ! -f "hyperterm/core/git.sh" ]]; then
echo "ERROR: git.sh not found"
exit 1
fi
# Verify the optimized functions exist using bash
if ! bash -c 'source hyperterm/core/git.sh && command -v _get_git_status_fast >/dev/null 2>&1'; then
echo "ERROR: Optimized function _get_git_status_fast not found"
exit 1
fi
echo "SUCCESS: Optimizations validated"
performance:
runs-on: ubuntu-latest
needs: tests
steps:
- uses: actions/checkout@v4
- name: Set up git configuration
run: |
git config --global user.name "Performance Test"
git config --global user.email "perf-test@example.com"
- name: Performance benchmark
run: |
echo "INFO: Running performance benchmark using existing test suite"
# The comprehensive test already includes performance testing
# Run it again to get performance metrics in CI logs
bash tests/test_prompt.sh --non-interactive
echo "INFO: Performance benchmark completed"
echo "NOTE: Detailed performance metrics are included in the comprehensive test output above"

View File

@@ -7,42 +7,47 @@
#---------------
alias ac='clean && clear'
#---------------
# Theme's prompt
#---------------
if [[ -f $HOME/.hyperterm/themes/joy.sh ]]; then source "$HOME/.hyperterm/themes/joy.sh"; else true; fi
if [[ -f $HOME/.hyperterm/themes/light_theme.sh ]]; then source "$HOME/.hyperterm/themes/light_theme.sh"; else true; fi
if [[ -f $HOME/.hyperterm/themes/minterm.sh ]]; then source "$HOME/.hyperterm/themes/minterm.sh"; else true; fi
if [[ -f $HOME/.hyperterm/themes/pure.sh ]]; then source "$HOME/.hyperterm/themes/pure.sh"; else true; fi
if [[ -f $HOME/.hyperterm/themes/simple.sh ]]; then source "$HOME/.hyperterm/themes/simple.sh"; else true; fi
if [[ -f $HOME/.hyperterm/themes/special.sh ]]; then source "$HOME/.hyperterm/themes/special.sh"; else true; fi
#-----------------
# Theme Selection
#-----------------
HYPERTERM_THEME="default"
#---------------
# Set Theme
#---------------
unset prompt
prompt="${default}"
#prompt="${joy}"
#prompt="${light_theme}"
#prompt="${minterm}"
#prompt="${pure}"
#prompt="${simple}"
#prompt="${special}"
# Load only selected theme - optimized for speed
if [[ -f "$HOME/.hyperterm/themes/${HYPERTERM_THEME}.sh" ]]; then
source "$HOME/.hyperterm/themes/${HYPERTERM_THEME}.sh"
case "$HYPERTERM_THEME" in
"default") prompt="${default}" ;;
"joy") prompt="${joy}" ;;
"light_theme") prompt="${light_theme}" ;;
"minterm") prompt="${minterm}" ;;
"pure") prompt="${pure}" ;;
"simple") prompt="${simple}" ;;
"special") prompt="${special}" ;;
esac
fi
#---------------
#-------
# Tools
#---------------
if [[ -f $HOME/.hyperterm/tools/compress.sh ]]; then source "$HOME/.hyperterm/tools/compress.sh"; else true; fi
if [[ -f $HOME/.hyperterm/tools/export.sh ]]; then source "$HOME/.hyperterm/tools/export.sh"; else true; fi
if [[ -f $HOME/.hyperterm/tools/listuser.sh ]]; then source "$HOME/.hyperterm/tools/listuser.sh"; else true; fi
if [[ -f $HOME/.hyperterm/tools/network.sh ]]; then source "$HOME/.hyperterm/tools/network.sh"; else true; fi
if [[ -f $HOME/.hyperterm/tools/proxy.sh ]]; then source "$HOME/.hyperterm/tools/proxy.sh"; else true; fi
if [[ -f $HOME/.hyperterm/tools/rar2zip.sh ]]; then source "$HOME/.hyperterm/tools/rar2zip.sh"; else true; fi
if [[ -f $HOME/.hyperterm/tools/ruby.sh ]]; then source "$HOME/.hyperterm/tools/ruby.sh"; else true; fi
if [[ -f $HOME/.hyperterm/tools/ssh-agent.sh ]]; then source "$HOME/.hyperterm/tools/ssh-agent.sh"; else true; fi
if [[ -f $HOME/.hyperterm/tools/sysinfo.sh ]]; then source "$HOME/.hyperterm/tools/sysinfo.sh"; else true; fi
if [[ -f $HOME/.hyperterm/tools/virtualenv.sh ]]; then source "$HOME/.hyperterm/tools/virtualenv.sh"; else true; fi
# if [[ -f $HOME/.hyperterm/tools/vconverter.sh ]]; then source "$HOME/.hyperterm/tools/vconverter.sh"; else true; fi
#-------
# Uncomment only the tools you actually use for faster loading
HYPERTERM_TOOLS=(
"compress" # Archive extractor (ex function for .tar, .zip, .rar, etc)
# "export" # Export functions and environment variables
# "listuser" # User listing and management utilities
"network" # IP detection and network info functions
# "proxy" # Proxy configuration helpers
# "rar2zip" # RAR to ZIP conversion utilities
# "ruby" # Ruby development environment setup
"ssh-agent" # SSH key and agent management
# "sysinfo" # System information display functions
# "virtualenv" # Python virtual environment tools
# "vconverter" # Video conversion utilities
)
# Load only selected tools
for tool in "${HYPERTERM_TOOLS[@]}"; do
[[ -f "$HOME/.hyperterm/tools/${tool}.sh" ]] && source "$HOME/.hyperterm/tools/${tool}.sh"
done
#---------------
# Screenfetch

View File

@@ -10,9 +10,10 @@ function install_package() {
msg "El paquete $pkg no se encontró. Procediendo a instalar..." \
"$pkg not found. Attempting to install..."
local INSTALLER=""
local SUDO=""
local USER_CMD=$(command -v sudo || command -v doas)
local INSTALLER
local SUDO
local USER_CMD
USER_CMD=$(command -v sudo || command -v doas)=$(command -v sudo || command -v doas)
[[ "$(id -u)" -ne 0 ]] && SUDO="$USER_CMD"

View File

@@ -1,373 +1,173 @@
#!/bin/bash
# Set up symbols
function _symbols() {
# Cache symbols (generate once)
declare -A GIT_SYMBOLS
_init_git_symbols() {
[[ -n "${GIT_SYMBOLS[clean]:-}" ]] && return # Already initialized
# Import colors
_colors_bash "$@"
__ps="$(printf '%b%b%b' "${BOLD}${LEMON}" "\x7C" "${RESET}")" # |
__ss="$(printf '%b%b' "${BOLD}${CYAN}" "\xE2\x9C\x94")" # ✔
__dss="$(printf '%b%b' "${BOLD}${RED}" "\x2A")" #
__ahs="$(printf '%b%b' "${BOLD}${CYAN}" "\xE2\x86\x91")" # ↑
__bhs="$(printf '%b%b' "${BOLD}${RED}" "\xE2\x86\x93")" # ↓
__duphs="$(printf '%b%b' "${BOLD}${YELLOW}" "\xE2\x96\x82" )" # ▲
__duplls="$(printf '%b%b' "${BOLD}${RED}" "\xE2\x96\xBC")" # ▼
__duus="$(printf '%b%b%b' "${BOLD}${CYAN}" "\x64" "\x75")" # du
__upulls="$(printf '%b%b' "${BOLD}${GREEN}" "\xE2\x96\xBD")" # ▽
__sts="$(printf '%b%b%b' "${BOLD}${CYAN}" "\xE2\x86\x92" "\x4D")" # →M
__usts="$(printf '%b%b%b' "${BOLD}${RED}" "\xE2\x86\x90" "\x4D")" # ←M
__stusts="$(printf '%b%b%b%b' "${BOLD}${RED}" "\x3C" "\x4D" "\x3E")" # <M>
__uts="$(printf '%b%b' "${BOLD}${RED}" "\x3F")" # ?
__nfs="$(printf '%b%b' "${BOLD}${CYAN}" "\x2B")" # +
__dfs="$(printf '%b%b' "${BOLD}${RED}" "\x44")" # D
__rns="$(printf '%b%b%b' "${BOLD}${RED}" "\xE2\x8E\x87" "\x20")" # ⎇
GIT_SYMBOLS[pipe]="\x7C"
GIT_SYMBOLS[clean]="✔"
GIT_SYMBOLS[dirty]=""
GIT_SYMBOLS[ahead]="↑"
GIT_SYMBOLS[behind]="↓"
GIT_SYMBOLS[diverged]="⇅"
GIT_SYMBOLS[untracked]="?"
GIT_SYMBOLS[added]="+"
GIT_SYMBOLS[deleted]="D"
GIT_SYMBOLS[modified]="M"
GIT_SYMBOLS[renamed]="R"
GIT_SYMBOLS[staged]="●"
}
function _get_git_branch() {
# On branches, this will return the branch name
# On non-branches, (no branch)
ref="$(git symbolic-ref HEAD 2> /dev/null | sed -e 's/refs\/heads\///')"
if [[ -n $ref ]]; then
printf '%s' "$ref"
else
printf "(no branch)"
fi
_get_git_branch() {
git symbolic-ref --short HEAD 2>/dev/null || echo "(no branch)"
}
function _get_git_progress() {
# Detect in-progress actions (e.g. merge, rebase)
# https://github.com/git/git/blob/v1.9-rc2/wt-status.c#L1199-L1241
git_dir="$(git rev-parse --git-dir)"
_get_git_progress() {
local git_dir
git_dir="$(git rev-parse --git-dir 2>/dev/null)" || return 0
# git merge
if [[ -f "$git_dir/MERGE_HEAD" ]]; then
printf " [merge]"
elif [[ -d "$git_dir/rebase-apply" ]]; then
# git am
if [[ -f "$git_dir/rebase-apply/applying" ]]; then
printf " [am]"
# git rebase
else
printf " [rebase]"
[[ -f "$git_dir/MERGE_HEAD" ]] && echo " [merge]" && return 0
[[ -d "$git_dir/rebase-apply" ]] && echo " [rebase]" && return 0
[[ -d "$git_dir/rebase-merge" ]] && echo " [rebase]" && return 0
[[ -f "$git_dir/CHERRY_PICK_HEAD" ]] && echo " [cherry-pick]" && return 0
[[ -f "$git_dir/BISECT_LOG" ]] && echo " [bisect]" && return 0
[[ -f "$git_dir/REVERT_HEAD" ]] && echo " [revert]" && return 0
return 0
}
# Single git status call - parse everything at once
_parse_git_status() {
local status_output ahead_behind
# Single git status call
status_output="$(git status --porcelain=v1 2>/dev/null)"
# Get ahead/behind counts - use more reliable method
if git rev-parse --abbrev-ref "@{upstream}" >/dev/null 2>&1; then
# Use separate commands for more reliable parsing
GIT_STATUS[ahead]="$(git rev-list --count HEAD ^"@{upstream}" 2>/dev/null || echo 0)"
GIT_STATUS[behind]="$(git rev-list --count "@{upstream}" ^HEAD 2>/dev/null || echo 0)"
# Fallback to original method if separate commands fail
if [[ "${GIT_STATUS[ahead]}" == "0" && "${GIT_STATUS[behind]}" == "0" ]]; then
ahead_behind="$(git rev-list --left-right --count "@{upstream}"...HEAD 2>/dev/null)"
if [[ "$ahead_behind" =~ ^([0-9]+)[[:space:]]+([0-9]+)$ ]]; then
GIT_STATUS[behind]="${BASH_REMATCH[1]}"
GIT_STATUS[ahead]="${BASH_REMATCH[2]}"
fi
fi
elif [[ -d "$git_dir/rebase-merge" ]]; then
# git rebase --interactive/--merge
printf " [rebase]"
elif [[ -f "$git_dir/CHERRY_PICK_HEAD" ]]; then
# git cherry-pick
printf " [cherry-pick]"
else
GIT_STATUS[behind]=0
GIT_STATUS[ahead]=0
fi
if [[ -f "$git_dir/BISECT_LOG" ]]; then
# git bisect
printf " [bisect]"
fi
if [[ -f "$git_dir/REVERT_HEAD" ]]; then
# git revert --no-commit
printf " [revert]"
fi
}
_prompt_is_branch1_behind_branch2 () {
# $ git log origin/master..master -1
# commit 4a633f715caf26f6e9495198f89bba20f3402a32
# Author: Todd Wolfson <todd@twolfson.com>
# Date: Sun Jul 7 22:12:17 2013 -0700
#
# Unsynced commit
# Parse status output
GIT_STATUS[dirty]=0
GIT_STATUS[staged]=0
GIT_STATUS[untracked]=0
GIT_STATUS[modified]=0
GIT_STATUS[added]=0
GIT_STATUS[deleted]=0
GIT_STATUS[renamed]=0
# Find the first log (if any) that is in branch1 but not branch2
first_log="$(git log "$1..$2" -1 2> /dev/null)"
[[ -z "$status_output" ]] && return
# Exit with 0 if there is a first log, 1 if there is not
[[ -n "$first_log" ]]
}
local line
while IFS= read -r line; do
[[ -z "$line" ]] && continue
_prompt_branch_exists () {
# List remote branches | # Find our branch and exit with 0 or 1 if found/not found
git branch --remote 2> /dev/null | grep --quiet "$1"
}
local index_status="${line:0:1}"
local work_status="${line:1:1}"
_prompt_parse_git_ahead () {
# Grab the local and remote branch
branch="$(_get_git_branch)"
remote="$(git config --get "branch.${branch}.remote" || echo -n "origin")"
remote_branch="$remote/$branch"
# Count changes
((GIT_STATUS[dirty]++))
# $ git log origin/master..master
# commit 4a633f715caf26f6e9495198f89bba20f3402a32
# Author: Todd Wolfson <todd@twolfson.com>
# Date: Sun Jul 7 22:12:17 2013 -0700
#
# Unsynced commit
# If the remote branch is behind the local branch
# or it has not been merged into origin (remote branch doesn't exist)
if (_prompt_is_branch1_behind_branch2 "$remote_branch" "$branch" || ! _prompt_branch_exists "$remote_branch"); then echo -n "0"; else echo -n "1"; fi
}
_prompt_parse_git_behind() {
# Grab the branch
branch="$(_get_git_branch)"
remote="$(git config --get "branch.${branch}.remote" || echo -n "origin")"
remote_branch="$remote/$branch"
# $ git log master..origin/master
# commit 4a633f715caf26f6e9495198f89bba20f3402a32
# Author: Todd Wolfson <todd@twolfson.com>
# Date: Sun Jul 7 22:12:17 2013 -0700
#
# Unsynced commit
# If the local branch is behind the remote branch
if _prompt_is_branch1_behind_branch2 "$branch" "$remote_branch"; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_dirty() {
# If the git status has *any* changes (e.g. dirty), printf our character
if [[ -n "$(git status --porcelain 2> /dev/null)" ]]; then echo -n '0'; else echo -n '1'; fi
}
# start counter on git
function _git_dirty_count() {
local _dirty_status
local _git_status
_dirty_status="$(_prompt_parse_git_dirty)"
_git_status="$(git status --porcelain 2> /dev/null)"
if [[ "$_dirty_status" == 0 ]]; then
local change_count
change_count="$(echo "$_git_status" | wc -l | tr -d '[:space:]')"
case $change_count in
1) printf '%b\u2022%s' "${BOLD}${GREY}" "$change_count";;
2) printf '%b\u2236%s' "${BOLD}${GREY}" "$change_count";;
3) printf '%b\u2026%s' "${BOLD}${GREY}" "$change_count";;
*) printf '%b\u00BB%s' "${BOLD}${GREY}" "$change_count";;
# Index (staged) changes
case "$index_status" in
[MADRC]) ((GIT_STATUS[staged]++)) ;;
esac
fi
}
function _git_behind_count() {
local __behind_count
if git rev-parse --symbolic-full-name --abbrev-ref "@{upstream}" > /dev/null 2>&1; then
__behind_count="$(git rev-list --left-right --count "@{upstream}"...HEAD | cut -f1 2> /dev/null)"
case $__behind_count in
0) echo -n '';;
*) echo -n "$__behind_count";;
# Working tree changes
case "$work_status" in
M) ((GIT_STATUS[modified]++)) ;;
D) ((GIT_STATUS[deleted]++)) ;;
esac
fi
}
function _git_ahead_count() {
local __ahead_count
if git rev-parse --symbolic-full-name --abbrev-ref "@{upstream}" > /dev/null 2>&1; then
__ahead_count="$(git rev-list --left-right --count "@{upstream}"...HEAD | cut -f2 2> /dev/null)"
case $__ahead_count in
0) echo -n '';;
*) echo -n "$__ahead_count";;
# Special cases
case "$line" in
"??*") ((GIT_STATUS[untracked]++)) ;;
"A "*) ((GIT_STATUS[added]++)) ;;
"R "*) ((GIT_STATUS[renamed]++)) ;;
esac
done <<< "$status_output"
}
# Fast git status generation
_get_git_status_fast() {
_init_git_symbols "$@"
declare -A GIT_STATUS
_parse_git_status
local output=""
# Check if completely clean (no dirty files AND no ahead/behind)
if [[ ${GIT_STATUS[dirty]} -eq 0 && ${GIT_STATUS[ahead]} -eq 0 && ${GIT_STATUS[behind]} -eq 0 ]]; then
echo -n "${BOLD}${GREEN}${GIT_SYMBOLS[clean]}${RESET}"
return
fi
}
# ends counter on git
function _prompt_parse_git_untracked() {
local untracked
local evaltask
untracked="$(git status 2>&1 | tee)"
grep -E 'Untracked files:' <<<"$untracked" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
# Start with dirty indicator if there are dirty files
if [[ ${GIT_STATUS[dirty]} -gt 0 ]]; then
output="${BOLD}${YELLOW}${GIT_SYMBOLS[dirty]}${GIT_STATUS[dirty]}${RESET}"
fi
# Add ahead/behind status with semantic colors
if [[ ${GIT_STATUS[ahead]} -gt 0 && ${GIT_STATUS[behind]} -gt 0 ]]; then
output+="${BOLD}${ORANGE}${GIT_SYMBOLS[diverged]}${GIT_STATUS[ahead]}/${GIT_STATUS[behind]}${RESET}"
elif [[ ${GIT_STATUS[ahead]} -gt 0 ]]; then
output+="${BOLD}${GREEN}${GIT_SYMBOLS[ahead]}${GIT_STATUS[ahead]}${RESET}"
elif [[ ${GIT_STATUS[behind]} -gt 0 ]]; then
output+="${BOLD}${RED}${GIT_SYMBOLS[behind]}${GIT_STATUS[behind]}${RESET}"
fi
# File status indicators with semantic colors
[[ ${GIT_STATUS[staged]} -gt 0 ]] && output+="${BOLD}${GREEN}${GIT_SYMBOLS[staged]}${RESET}"
[[ ${GIT_STATUS[untracked]} -gt 0 ]] && output+="${BOLD}${GREY}${GIT_SYMBOLS[untracked]}${RESET}"
[[ ${GIT_STATUS[added]} -gt 0 ]] && output+="${BOLD}${GREEN}${GIT_SYMBOLS[added]}${RESET}"
[[ ${GIT_STATUS[deleted]} -gt 0 ]] && output+="${BOLD}${RED}${GIT_SYMBOLS[deleted]}${RESET}"
[[ ${GIT_STATUS[renamed]} -gt 0 ]] && output+="${BOLD}${CYAN}${GIT_SYMBOLS[renamed]}${RESET}"
echo -n "$output"
}
function _prompt_parse_git_newfile() {
local newfile
local evaltask
newfile="$(git status 2>&1 | tee)"
grep -E 'new file:' <<<"$newfile" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_deleted_file() {
local deleted_file
local evaltask
deleted_file="$(git status 2>&1 | tee)"
grep -E 'deleted:' <<<"$deleted_file" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_renamed() {
local renamed
local evaltask
renamed="$(git status 2>&1 | tee)"
grep -E 'renamed:' <<<"$renamed" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_unstage() {
local unstage
local evaltask
unstage="$(git status 2>&1 | tee)"
grep -E 'not staged' <<<"$unstage" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_parse_git_stage() {
local stage
local evaltask
stage="$(git status -s 2>&1 | tee)"
grep -E 'M' <<<"$stage" &> /dev/null
evaltask=$?
if [ "$evaltask" -eq 0 ]; then echo -n '0'; else echo -n '1'; fi
}
function _prompt_is_on_git() {
git rev-parse 2> /dev/null
}
function _prompt_get_git_status() {
_symbols "$@"
# Grab the git dirty and git behind
count_dirty="$(_git_dirty_count)"
count_behind="$(_git_behind_count)"
count_ahead="$(_git_ahead_count)"
dirty_branch="$(_prompt_parse_git_dirty)"
branch_ahead="$(_prompt_parse_git_ahead)"
branch_behind="$(_prompt_parse_git_behind)"
branch_stage="$(_prompt_parse_git_stage)"
branch_unstage="$(_prompt_parse_git_unstage)"
branch_untracked="$(_prompt_parse_git_untracked)"
branch_newfile="$(_prompt_parse_git_newfile)"
branch_deleted_file="$(_prompt_parse_git_deleted_file)"
branch_renamed="$(_prompt_parse_git_renamed)"
# Iterate through all the cases and if it matches, then printf
case ${dirty_branch}${branch_ahead}${branch_behind}${branch_stage}${branch_unstage}${branch_newfile}${branch_untracked}${branch_deleted_file}${branch_renamed} in
111111111) printf '%s' "${__ss}";;
100111111) printf '%s' "${__ps}${__ahs}$count_ahead${__ps}${__bhs}$count_behind";;
110111111) printf '%s%s' "${__upulls}" "$count_behind";;
101111111) printf '%s%s' "${__ahs}" "$count_ahead";;
111001111) printf '%s%s' "${__ps}${__duus}${__stusts}" "$count_dirty";;
011111111) printf '%s%s' "${__dss}" "$count_dirty";;
010111111) printf '%s%s%s' "${__duplls}" "$count_behind" "$count_dirty";;
001111111) printf '%s%s%s' "${__duphs}" "$count_ahead" "$count_dirty";;
000111111) printf '%s%s%s' "${__duus}" "$count_behind-$count_ahead" "$count_dirty";;
000111011) printf '%s%s' "${__ps}${__ahs}$count_ahead${__ps}${__bhs}$count_behind${__ps}${__uts}${__ps}" "$count_dirty" ;;
010111011) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__uts}" "${__ps}$count_dirty";;
010110111) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}" "${__ps}$count_dirty";;
010110011) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__uts}" "${__ps}$count_dirty";;
010100001) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__usts}${__uts}${__dfs}" "${__ps}$count_dirty";;
010000001) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__stusts}${__uts}${__dfs}" "${__ps}$count_dirty";;
010010100) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__dfs}${__rns}" "${__ps}${__sts}${__ps}$count_dirty";;
010010000) printf '%s%s' "${__ps}${__bhs}$count_behind${__ps}${__dss}${__nfs}${__dfs}${__rns}${__ps}${__uts}" "${__ps}${__sts}${__ps}$count_dirty";;
011001111) printf '%s%s' "${__ps}${__dss}${__stusts}" "$count_dirty";;
011000111) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}" "$count_dirty";;
011001101) printf '%s%s' "${__ps}${__dss}${__stusts}${__dfs}" "$count_dirty";;
011001011) printf '%s%s' "${__ps}${__dss}${__stusts}${__uts}" "$count_dirty" ;;
011001001) printf '%s%s' "${__ps}${__dss}${__stusts}${__uts}${__dfs}" "$count_dirty";;
011000101) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__dfs}" "$count_dirty";;
011000001) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__uts}${__dfs}" "$count_dirty";;
011011111) printf '%s%s' "${__ps}${__dss}${__sts}" "$count_dirty";;
011010111) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}" "$count_dirty";;
011010011) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__uts}" "$count_dirty";;
011010101) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__dfs}" "$count_dirty" ;;
011010001) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__uts}${__dfs}" "$count_dirty";;
011011011) printf '%s%s' "${__ps}${__dss}${__sts}${__uts}" "$count_dirty";;
011011101) printf '%s%s' "${__ps}${__dss}${__sts}${__dfs}" "$count_dirty";;
011110111) printf '%s%s' "${__ps}${__dss}${__nfs}" "$count_dirty";;
011110011) printf '%s%s' "${__ps}${__dss}${__nfs}${__uts}" "$count_dirty";;
011111011) printf '%s%s' "${__ps}${__dss}${__uts}" "$count_dirty";;
011101001) printf '%s%s' "${__ps}${__dss}${__usts}${__uts}${__dfs}" "$count_dirty";;
011111110) printf '%s%s' "${__ps}${__dss}${__rns}" "$count_dirty";;
011110110) printf '%s%s' "${__ps}${__dss}${__nfs}${__rns}" "$count_dirty";;
011110010) printf '%s%s' "${__ps}${__dss}${__nfs}${__uts}${__rns}" "$count_dirty";;
011011110) printf '%s%s' "${__ps}${__dss}${__sts}${__rns}" "$count_dirty";;
011010100) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__dfs}${__rns}" "$count_dirty" ;;
011010000) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__uts}${__dfs}${__rns}" "$count_dirty";;
011001010) printf '%s%s' "${__ps}${__dss}${__stusts}${__uts}${__rns}" "$count_dirty";;
011001000) printf '%s%s' "${__ps}${__dss}${__stusts}${__uts}${__dfs}${__rns}" "$count_dirty";;
011000011) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__uts}" "$count_dirty";;
011000110) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__rns}" "$count_dirty";;
011000010) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__uts}${__rns}" "$count_dirty";;
011000000) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__uts}${__dfs}${__rns}" "$count_dirty";;
011000100) printf '%s%s' "${__ps}${__dss}${__stusts}${__nfs}${__dfs}${__rns}" "$count_dirty";;
011010010) printf '%s%s' "${__ps}${__dss}${__sts}${__nfs}${__uts}${__rns}" "$count_dirty";;
011011010) printf '%s%s' "${__ps}${__dss}${__sts}${__uts}${__rns}" "$count_dirty";;
011111010) printf '%s%s' "${__ps}${__dss}${__uts}${__rns}" "$count_dirty";;
001001111) printf '%s%s' "${__ps}${__duus}${__stusts}" "$count_dirty";;
001000111) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}" "$count_dirty";;
001001101) printf '%s%s' "${__ps}${__duus}${__stusts}${__dfs}" "$count_dirty";;
001001011) printf '%s%s' "${__ps}${__duus}${__stusts}${__uts}" "$count_dirty";;
001001001) printf '%s%s' "${__ps}${__duus}${__stusts}${__uts}${__dfs}" "$count_dirty";;
001000101) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__dfs}" "$count_dirty";;
001000001) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__uts}${__dfs}" "$count_dirty";;
001011111) printf '%s%s' "${__ps}${__duus}${__sts}" "$count_dirty";;
001010111) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}" "$count_dirty" ;;
001010011) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__uts}" "$count_dirty";;
001010101) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__dfs}" "$count_dirty" ;;
001010001) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__uts}${__dfs}" "$count_dirty";;
001011011) printf '%s%s' "${__ps}${__duus}${__sts}${__uts}" "$count_dirty";;
001011101) printf '%s%s' "${__ps}${__duus}${__sts}${__dfs}" "$count_dirty";;
001110111) printf '%s%s' "${__ps}${__duus}${__nfs}" "$count_dirty";;
001110011) printf '%s%s' "${__ps}${__duus}${__nfs}${__uts}" "$count_dirty";;
001111011) printf '%s%s' "${__ps}${__duus}${__uts}" "$count_dirty";;
001101001) printf '%s%s' "${__ps}${__duus}${__usts}${__uts}${__dfs}" "$count_dirty";;
001101101) printf '%s%s' "${__ps}${__duus}${__usts}${__dfs}" "$count_dirty";;
001111110) printf '%s%s' "${__ps}${__duus}${__rns}" "$count_dirty";;
001110110) printf '%s%s' "${__ps}${__duus}${__nfs}${__rns}" "$count_dirty";;
001110010) printf '%s%s' "${__ps}${__duus}${__nfs}${__uts}${__rns}" "$count_dirty";;
001011110) printf '%s%s' "${__ps}${__duus}${__sts}${__rns}" "$count_dirty";;
001010100) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__dfs}${__rns}" "$count_dirty" ;;
001010000) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__uts}${__dfs}${__rns}" "$count_dirty";;
001001010) printf '%s%s' "${__ps}${__duus}${__stusts}${__uts}${__rns}" "$count_dirty";;
001001000) printf '%s%s' "${__ps}${__duus}${__stusts}${__uts}${__dfs}${__rns}" "$count_dirty";;
001000011) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__uts}" "$count_dirty";;
001000110) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__rns}" "$count_dirty";;
001000010) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__uts}${__rns}" "$count_dirty";;
001000000) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__uts}${__dfs}${__rns}" "$count_dirty";;
001000100) printf '%s%s' "${__ps}${__duus}${__stusts}${__nfs}${__dfs}${__rns}" "$count_dirty";;
001010010) printf '%s%s' "${__ps}${__duus}${__sts}${__nfs}${__uts}${__rns}" "$count_dirty";;
001011010) printf '%s%s' "${__ps}${__duus}${__sts}${__uts}${__rns}" "$count_dirty";;
001111010) printf '%s%s' "${__ps}${__duus}${__uts}${__rns}" "$count_dirty";;
*) echo -n "${__uts}" ;;
esac
#
# dirty + unpushed = du stage + unstage = <M>
# ↑ ↓ →M ←M + ? D ⎇
# echo "${dirty_branch}${branch_ahead}${branch_behind}${branch_stage}${branch_unstage}${branch_newfile}${branch_untracked}${branch_deleted_file}${branch_renamed}"
# 0 1 0 1 1 1 0 1 1
}
_prompt_get_git_info() {
# Import colors
_prompt_get_git_info_fast() {
_colors_bash "$@"
# Grab branch
branch=$(_get_git_branch)
local branch
branch="$(_get_git_branch)"
# If there are any branches
if [[ -n $branch ]]; then
# Add on the git status
output=$(_prompt_get_git_status "$@")
# Printf our output
printf '%b%s%b' "${BOLD}${LEMON}" "git:($branch$output" "${BOLD}${LEMON})"
if [[ -n "$branch" ]]; then
local status
status="$(_get_git_status_fast "$@")"
# Use different colors for different parts
printf '%bgit:(%b%s%b%s%b)%b' \
"${GREY}" \
"${BOLD}${LEMON}" "$branch" "${RESET}" \
"$status" \
"${GREY}" "${RESET}"
fi
}
__prompt_git() {
if _prompt_is_on_git &> /dev/null; then
echo -n "${BOLD}${WHITE} on $RESET" && \
echo -n "$(_prompt_get_git_info "$@")" && \
echo -n "${BOLD}${RED}$(_get_git_progress)" && \
echo -n "$RESET"
if git rev-parse --git-dir >/dev/null 2>&1; then
echo -n "${BOLD}${WHITE} on ${RESET}"
_prompt_get_git_info_fast "$@"
echo -n "${BOLD}${RED}$(_get_git_progress)${RESET}"
fi
}

View File

@@ -1,25 +1,14 @@
#!/bin/bash
# System Status
function exitstatus(){
local retval=$?
function exitstatus() {
local retval=$1
unset status
# Import colors
_colors_bash "$@"
case $retval in
0)
status="[${retval}]"
printf '%b%s' "${BOLD}${CYAN}" "${status}"
;;
1)
status="[${retval}]"
printf '%b%s' "${BOLD}${PURPLE}" "${status}"
;;
*)
status="[${retval}]"
printf '%b%s' "${BOLD}${RED}" "${status}"
;;
0) status="[${retval}]"; printf '%b%s' "${BOLD}${CYAN}" "${status}" ;;
1) status="[${retval}]"; printf '%b%s' "${BOLD}${PURPLE}" "${status}" ;;
*) status="[${retval}]"; printf '%b%s' "${BOLD}${RED}" "${status}" ;;
esac
}

View File

@@ -2,18 +2,18 @@ cdfe049ec07f02a1893cda29c13085d06709e09a30b0c2e1111585278315f03139d61080c883cb3f
f363606f41a2c2c8f1cc44110c64fe23b1c8feb4c788ee006222db0f5c7a3adeac2b0948626b313adc985e9b8d303a0b9ce1c5ba42746810accb54efddcd4b84 ./hyperterm.sh
b760a908a3f6222b974abc1f7464bde0f5427f120f1e7ef1c6d97ae61769e552ef3b5cb88e193e955da72a592f07eadb812413dd50a691cd3dbb33e3da581ea6 ./core/update.sh
1cfba599047d84a17ff92b695ebf527a505a30acc9ec21a2b9f410a7ea6dde4b23b5cf62e557d82f2fe9a8980649942424b879ca53baae4d4cb3057681baa7b6 ./core/colors.sh
2036a79215a5434e31f3406bea3f2ffa7e94ffef86c2d1ceb8865db29f19fe7f342f9cab93288f57c75daed36ef146f85d15f8d633931a27d55c3983f55ef15b ./core/git.sh
2083ef4d5abec5e3d647f49ec413071281089445a71fd16b56b317c3510a846d41dcb9b2e6374818925a1e744aae2e61477002d9e236cd264a4faa9896f2362e ./core/git.sh
f3e00b2aa8ab9f3ab44570adaa2520408ed66fd00f551654d60b64a4be3546ec781b7efa39bcd774937e654b6ffb4c7af3f21eeb36caf9c01f82f85cf28e2b4d ./core/languages.sh
fdc570118a65a2b00571fd374be1aa983d41e9722bee6e604e2b00fcd2e1931df4dfd8951f15a2402dfcb3cbc76a5fe8d9d564a83fec73595dcaae2e38ac338a ./core/autodep.sh
b205de01644af11ef1dc96230e4bf12087482e26b7c0472fb6a153bf94662e4dfc01b2da0c3ca0da4af93bce05faf0e33be5422fbee85e6b69ca1cccbe194cff ./core/autodep.sh
7447d3e167ab207d3ef4218e201a06bf5a3fc23281639f16f7f405f1d66b73923845d450fdb0a94672757866a9da0324f728564a1b61b2ed1678fe576eb565cf ./core/autocomplete.sh
065cfa39f1b4312ed275ad1039827a24f703176c653a8d27303d145f9d389a60ec5b3a9eb167e060cc6fd093b9c03cfb1a8b70254d444fbc6e62e2297d88b310 ./core/status.sh
c6c149704883ce5cbbd941019259effb105dd6910c98910782024311b3362df2e68d03c947908d40686c2620c1521aeee2ffb019a906ad367be1cc3d429ecd82 ./themes/minterm.sh
0b6705dae598dff024fc10fd9c4710a298e7d2ab7b7f3895eb8654d1ad7236a0b0f72511f1db7df8155f32aa882ac2bf55a9d6a04c227ed6285b866ec3a29904 ./themes/simple.sh
1d70b22277aa1d37e770f952411687c30d47da8caae278e431208671af239591d259258b4982ca9b61faf57f266958a002180496b0db036a94250604212aa1bb ./themes/pure.sh
074e8549d638dee7470583c04ebbb7408181974806bd5e2cf5fc134ddee83c01040ed9d59a8aa00a87287b25df1c2e23edf3c063426952a8aeb56db8310ef8fd ./themes/joy.sh
403fe028575baa22c39dd11ac56a246369b8e38524c216f6d564b59aa22c60a426941f755ad3adb75f212c9124350ce3aeb114ba365ded1ed33b62ac480a60aa ./themes/light_theme.sh
7efe3770a629d6168b1c9007f420d2d657fa38fc1673dd5dc365dcf3c9d4c34456e346f9ed739c347133f93ad78cf88d0d54fe95523ce5d91a51cd49650d7525 ./themes/special.sh
07bb7b6bd609e855d0a7c9e39a0ff2959851f559106e8f59816312f298b03e87f39e53430869ed61a1271e265e976ea6b56f7ccee46c4ec3c37b40f1fc11cfad ./themes/default.sh
99f9e937e39495f60495bc89f055f29e1bee25911c9bea5c8b2a7c6a5bdc417502f17da8cb9e63ea957eea9337c6fe1c63c208a3ff3ed33ef2ca8c1dbe328599 ./core/status.sh
65f850342f43bdfe68b2b0339a051a795c6640b4bd4f7c6b6b979ca214607f9a87d9cfdc6955785c5ca087d09294781ee8cb3a62dc0160cd8a105ff65cc82465 ./themes/minterm.sh
c6467d21cc7fdf0c3da797be8521db96069361e5064ace5b1c3a509679e2adb6d57c5a865a158fa5dfec3dd94892fa47a3c1b7b985d7808af646118ffeceb771 ./themes/simple.sh
19bf23dd3ca5967125dbd9d7cbb02312a6d230320869d0ebbb2dbd6994921cb02a627180d5ccaafb0e8e16baf25abcb29f5ba94a0b25bd376b6a963dda1a8d7a ./themes/pure.sh
a845a8bbf6bad13bd3c6a40b27c65055a4f55c8f238e30e4bd9bc3ace16d15ae7ccdf51b38d9064f55d60fbd1e1166ae4918ab6ddd3a495b08366f2554dd94e6 ./themes/joy.sh
af819a140b2a66de3bd53ec0911b1253f661aa2c0a84c4fed4608880ec467340c8076805bea622c82b9dfdbc3a70fa6f81559d39d42e7cb053fb8a71a462f3e0 ./themes/light_theme.sh
e0805f47622d0e245333e933fcf767b88e8d2157e57f156f069b24dd13d220866908f7aabfb2592ca9b89dc3c490a4480bd7b19c76328d38f1a72db2f0fc19b6 ./themes/special.sh
7d64675844172bb30235649848147f5b15b7b7575af1e7b33ce24d71e11f1b17c063151f43bc4f858fe7f770c292b11e9a6fb21fdf91b7e180336b1918746841 ./themes/default.sh
f760432c3d76befad30588299eb2d1412d77b22fd850ffbd840c72123885d4e916a7e0b16e7048c5dcd6e58fa3bc0807cda18ae64045a7495684ba37109e4b4a ./tools/compress.sh
1b9c148ab8577fe15b4d503ec480b36eeaea42bf7048e35a0866280ee87a6c8de31c54600a8e455147db987e7aa61c8aa585748a9945c0472992d28fdccb8c0f ./tools/export.sh
8606294d403c5fd9cd5c316401387b5aea79de1d193aa9f23210c94bf32ff83e8d9dc98466d017bc4d9d037cf548335fde1b2f2631e3597a87eec7ccb8e78d6c ./tools/network.sh

View File

@@ -1,11 +1,17 @@
#!/bin/bash
# shellcheck disable=SC1117
# shellcheck disable=SC1117,SC2034,SC2154
unset default
# Import colors
_colors_bash "$@"
PROMPT_COMMAND='
last_status=$?
ps1_status="$(exitstatus "$last_status")"
ps1_git="$(__prompt_git)"
'
default=("\n\
\[$RESET\]\
\[${BOLD}${YELLOW}\][ \u \
@@ -13,11 +19,9 @@ default=("\n\
\[${BOLD}${RED}\] \D{%I:%M%p} ]\n\
\[$RESET\]\
\[${BOLD}${WHITE}\][\$PWD]\[$RESET\] \
\$(exitstatus)\[$RESET\]\
\$(__prompt_git)\
\${ps1_status}\[$RESET\]\
\${ps1_git}\
\n\[${BOLD}${GREEN}\]$SYMBOL \[$RESET\]")
export default
unset _psi
: "${_psi:=\[${BOLD}${CYAN}\]=>\[$RESET\] }"

View File

@@ -1,11 +1,18 @@
#!/bin/bash
# shellcheck disable=SC2034,SC2154
unset joy
# Import colors
_colors_bash "$@"
: "${joy:=\n\
PROMPT_COMMAND='
last_status=$?
ps1_status="$(exitstatus "$last_status")"
ps1_git="$(__prompt_git)"
'
joy="\n\
\[${BOLD}${CYAN}\]\342\224\214\342\224\200[\
\[${BOLD}${YELLOW}\]\u\
\[${BOLD}${CYAN}\]@\
@@ -15,15 +22,15 @@ _colors_bash "$@"
\[${RESET}\]\w\
\[${BOLD}${CYAN}\]]\
\342\224\200\
\$(exitstatus)\
\${ps1_status}\
\[${BOLD}${CYAN}\]\
\342\224\200\
\$(__prompt_git)\
\${ps1_git}\
\[${BOLD}${CYAN}\]\342\224\200[\
\[${RESET}\]\t\
\[${BOLD}${CYAN}\]]\n\
\[${BOLD}${CYAN}\]\342\224\224\342\224\200\342\224\200\342\225\274\
\[${BOLD}${GREEN}\] $SYMBOL \[$RESET\]}"
\[${BOLD}${GREEN}\] $SYMBOL \[$RESET\]"
unset _psi
: "${_psi:=\[${BOLD}${CYAN}\]=>\[$RESET\] }"

View File

@@ -1,20 +1,27 @@
#!/bin/bash
# shellcheck disable=SC2034,SC2154
unset light_theme
# Import colors
_colors_bash "$@"
: "${light_theme:=\n\
PROMPT_COMMAND='
last_status=$?
ps1_status="$(exitstatus "$last_status")"
ps1_git="$(__prompt_git)"
'
light_theme="\n\
\[$RESET\]\
\[${BOLD}${CYAN}\]┌─\[$RESET\]\
\[${BOLD}${YELLOW}\]\u\[$RESET\]\
\[${BOLD}${CYAN}\]@\[$RESET\]\
\[${BOLD}${GREY}\]\h\[$RESET\] \
\$(exitstatus)\[$RESET\] \
\${ps1_status}\[$RESET\] \
\[${BOLD}${WHITE}\][\$PWD]\
\$(__prompt_git)\
\n\[${BOLD}${CYAN}\]╰─➤\[${BOLD}${GREEN}\]$SYMBOL \[$RESET\]}"
\${ps1_git}\
\n\[${BOLD}${CYAN}\]╰─➤\[${BOLD}${GREEN}\]$SYMBOL \[$RESET\]"
unset _psi
: "${_psi:=\[${BOLD}${CYAN}\]=>\[$RESET\] }"

View File

@@ -1,21 +1,29 @@
#!/bin/bash
# shellcheck disable=SC2034,SC2154
unset minterm
# Import colors
_colors_bash "$@"
: "${minterm:=\n\
PROMPT_COMMAND='
last_status=$?
ps1_status="$(exitstatus "$last_status")"
ps1_git="$(__prompt_git)"
ps1_time="$(printf "%b%s" "${BOLD}${GREY}" "$(date +%H:%M)")"
'
minterm="\n\
\[${BOLD}${CYAN}\]┌─\
\[${BOLD}${YELLOW}\]\u\
\[${BOLD}${CYAN}\]@\
\[${BOLD}${GREY}\]\h\[$RESET\] \
\$(exitstatus)\[$RESET\] \
\${ps1_status}\[$RESET\] \
\[${BOLD}${WHITE}\][\$PWD]\
\$(__prompt_git)\n\
\${ps1_git}\n\
\[${BOLD}${CYAN}\]╰─➤\[$RESET\] \
\$( echo -n \"\[${BOLD}${GREY}\]\$(date +%H:%M)\" )\[$RESET\] \
\[${BOLD}${GREEN}\]$SYMBOL \[$RESET\]}"
\${ps1_time}\[$RESET\] \
\[${BOLD}${GREEN}\]$SYMBOL \[$RESET\]"
unset _psi
: "${_psi:=\[${BOLD}${CYAN}\]=>\[$RESET\] }"

View File

@@ -1,19 +1,27 @@
#!/bin/bash
# shellcheck disable=SC2034,SC2154
unset pure
# Import colors
_colors_bash "$@"
: "${pure:=\
PROMPT_COMMAND='
last_status=$?
ps1_status="$(exitstatus "$last_status")"
ps1_git="$(__prompt_git)"
ps1_time="$(printf "%b%s" "${BOLD}${GREY}" "$(date +%H:%M)")"
'
pure="\
\[${BOLD}${GREEN}\]\u\[$RESET\] \
\[${BOLD}${YELLOW}\][\
\[${BOLD}${RED}\]\w\
\[${BOLD}${YELLOW}\]]\[$RESET\] \
\$(exitstatus)\[$RESET\] \
\[${BOLD}${BLUE}\](\$(date +%H:%M:%S))\
\$(__prompt_git)\
\n\[${BOLD}${CYAN}\]$SYMBOL \[$RESET\]}"
\${ps1_status}\[$RESET\] \
\${ps1_time}\
\${ps1_git}\
\n\[${BOLD}${CYAN}\]$SYMBOL \[$RESET\]"
unset _psi
: "${_psi:=\[${BOLD}${CYAN}\]=>\[$RESET\] }"

View File

@@ -1,4 +1,5 @@
#!/bin/bash
# shellcheck disable=SC2034,SC2154
unset simple
@@ -9,15 +10,22 @@ __time_out_command() {
awk '{ print $1 }' /proc/loadavg
}
: "${simple:=\n\
PROMPT_COMMAND='
last_status=$?
ps1_status="$(exitstatus "$last_status")"
ps1_load="$(__time_out_command)"
ps1_git="$(__prompt_git)"
'
simple="\n\
\[${RESET}\]\
\[${BOLD}${GREY}\]\
\$(exitstatus)\[$RESET\] \
\${ps1_status}\[$RESET\] \
\[${BOLD}${GREY}\]\
\$(__time_out_command)\[$RESET\] \
\${ps1_load}\[$RESET\] \
\[${BOLD}${WHITE}\]\W\[$RESET\]\
\$(__prompt_git)\n\
\[${BOLD}${GREEN}\]$SYMBOL \[$RESET\]}"
\${ps1_git}\n\
\[${BOLD}${GREEN}\]$SYMBOL \[$RESET\]"
unset _psi
: "${_psi:=\[${BOLD}${CYAN}\]=>\[$RESET\] }"

View File

@@ -1,5 +1,5 @@
#!/bin/bash
# shellcheck disable=SC1117
# shellcheck disable=SC1117,SC2034,SC2154
unset special
@@ -17,19 +17,24 @@ _prompt_local_name() {
esac
}
special=("\n\
PROMPT_COMMAND='
last_status=$?
ps1_status="$(exitstatus "$last_status")"
ps1_loc="$(_prompt_local_name)"
ps1_git="$(__prompt_git)"
'
special="\n\
\[$RESET\]\
\[${BOLD}${YELLOW}\][$(_prompt_local_name)\
\[${BOLD}${YELLOW}\][\${ps1_loc}\
\[$RESET\] \[${BOLD}${GREY}\]\w\
\[${BOLD}${YELLOW}\]]\[$RESET\] \
\[${BOLD}${CYAN}\]hist:\!\[$RESET\]\n\
\[${BOLD}${GREY}\]\
\D{%Y-%m-%d}@\D{%I:%M%p}\[$RESET\] \
\$(exitstatus)\[$RESET\]\
\$(__prompt_git)\n\
\[${BOLD}${GREEN}\]$SYMBOL \[$RESET\]")
export special
\${ps1_status}\[$RESET\]\
\${ps1_git}\n\
\[${BOLD}${GREEN}\]$SYMBOL \[$RESET\]"
unset _psi
: "${_psi:=\[${BOLD}${CYAN}\]=>\[$RESET\] }"

84
tests/README.md Normal file
View File

@@ -0,0 +1,84 @@
# HyperTerm Tests
Test suite for HyperTerm prompt functionality and performance.
## Test Files
### test_prompt.sh
Comprehensive test suite with full functionality testing.
**Features:**
- Individual function testing
- Performance benchmarking
- Git state testing
- Interactive test mode (skipped in CI)
- Non-interactive mode for CI/automation
**Usage:**
```bash
cd tests
bash test_prompt.sh # Interactive mode
bash test_prompt.sh --non-interactive # Non-interactive mode (for CI)
```
### quick_test.sh
Fast validation test for immediate feedback.
**Features:**
- Quick function validation
- Basic performance check
- Works in current directory or creates temp repo
**Usage:**
```bash
cd tests
bash quick_test.sh
```
## Test Environment
Tests create isolated environments to avoid affecting your working directory:
- Temporary git repositories in `/tmp/`
- Various git states (clean, dirty, staged, untracked)
- Automatic cleanup on exit
## Performance Testing
Both test scripts include performance measurements:
- Multiple iterations for accurate timing
- Average execution time per prompt call
- Performance classification (Excellent < 10ms, Good < 50ms)
## Git States Tested
- Clean repository
- Modified files
- Untracked files
- Staged files
- Mixed states
- Ahead/behind tracking
## Requirements
- Git installed and available in PATH
- Bash 4.0 or later
- HyperTerm core files in `../hyperterm/core/`
## Logging
All tests use structured logging:
- `[INFO]` - General information
- `[SUCCESS]` - Successful operations
- `[WARN]` - Warnings
- `[ERROR]` - Errors
## Interactive Mode
The full test suite includes an interactive mode with commands:
- `status` - Show git status
- `prompt` - Show full prompt
- `perf` - Run performance test
- `states` - Test different git states
- `modify` - Create test modifications
- `clean` - Clean working directory
- `exit` - Exit interactive mode

176
tests/quick_test.sh Normal file
View File

@@ -0,0 +1,176 @@
#!/bin/bash
# Quick Prompt Test - Fast validation
# Simple test for immediate feedback
# shellcheck disable=SC1090,SC2034,SC2155
set -e
# Logging
log_info() { echo "[INFO] $*"; }
log_error() { echo "[ERROR] $*"; }
log_success() { echo "[SUCCESS] $*"; }
# Configuration
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
# Basic colors fallback
setup_colors() {
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
CYAN='\033[36m'
WHITE='\033[37m'
GREY='\033[90m'
}
# Load functions
load_functions() {
log_info "Loading HyperTerm functions"
# Load colors if available
local colors_file="$PROJECT_ROOT/hyperterm/core/colors.sh"
if [[ -f "$colors_file" ]]; then
source "$colors_file"
else
setup_colors
fi
# Load git functions
local git_file="$PROJECT_ROOT/hyperterm/core/git.sh"
if [[ -f "$git_file" ]]; then
source "$git_file"
log_success "Git functions loaded"
return 0
else
log_error "Git functions not found"
return 1
fi
}
# Test in current directory
test_current_directory() {
if git rev-parse --git-dir >/dev/null 2>&1; then
log_success "Current directory is a git repository"
echo "Current git state:"
echo -n " Branch: "
_get_git_branch
echo ""
echo -n " Status: "
if command -v _get_git_status_fast >/dev/null 2>&1; then
_get_git_status_fast
else
_prompt_get_git_status
fi
echo ""
echo -n " Full prompt: "
__prompt_git
echo ""
return 0
else
log_info "Current directory is not a git repository"
return 1
fi
}
# Create temporary test
test_with_temp_repo() {
log_info "Creating temporary git repository for testing"
local temp_dir="/tmp/quick_test_$$"
mkdir -p "$temp_dir"
(
cd "$temp_dir"
git init --quiet
git config user.name "Test User"
git config user.email "test@example.com"
echo "# Quick Test" > README.md
echo "test content" > file.txt
git add README.md
git commit -m "Initial commit" --quiet
# Create changes
echo "modified" >> file.txt
echo "untracked" > new.txt
log_success "Temporary repository created with changes"
echo "Test results:"
echo -n " Branch: "
_get_git_branch
echo ""
echo -n " Status: "
if command -v _get_git_status_fast >/dev/null 2>&1; then
_get_git_status_fast
else
_prompt_get_git_status
fi
echo ""
echo -n " Full prompt: "
__prompt_git
echo ""
)
rm -rf "$temp_dir"
log_info "Temporary repository cleaned up"
}
# Performance check
quick_performance_check() {
log_info "Running quick performance check"
local iterations=10
local start_time end_time duration
start_time=$(date +%s%N)
for ((i=1; i<=iterations; i++)); do
__prompt_git >/dev/null 2>&1
done
end_time=$(date +%s%N)
duration=$(( (end_time - start_time) / 1000000 ))
local avg_duration=$(( duration / iterations ))
echo "Performance: ${avg_duration}ms average (${iterations} iterations)"
if [[ $avg_duration -lt 50 ]]; then
log_success "Performance is good"
elif [[ $avg_duration -lt 100 ]]; then
log_info "Performance is acceptable"
else
log_error "Performance may need optimization"
fi
}
# Main execution
main() {
log_info "HyperTerm Quick Test"
if ! load_functions; then
exit 1
fi
if ! test_current_directory; then
test_with_temp_repo
fi
quick_performance_check
log_success "Quick test completed"
}
# Execute if run directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi

304
tests/test_prompt.sh Normal file
View File

@@ -0,0 +1,304 @@
#!/bin/bash
# HyperTerm Prompt Test Suite
# Organized testing environment for prompt functionality
# shellcheck disable=SC1090,SC2034,SC2155
set -e
# Logging functions
log_info() { echo "[INFO] $*"; }
log_warn() { echo "[WARN] $*"; }
log_error() { echo "[ERROR] $*"; }
log_success() { echo "[SUCCESS] $*"; }
# Configuration
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
readonly TEST_DIR="/tmp/hyperterm_test_$(date +%s)"
# Cleanup function
cleanup() {
if [[ -n "${TEST_DIR:-}" && -d "$TEST_DIR" ]]; then
rm -rf "$TEST_DIR"
log_info "Test directory cleaned: $TEST_DIR"
fi
}
# Setup test environment
setup_test_env() {
log_info "Setting up test environment"
mkdir -p "$TEST_DIR"
cd "$TEST_DIR"
# Create test git repository
git init --quiet
git config user.name "Test User"
git config user.email "test@example.com"
echo "# Test Repository" > README.md
echo "test content" > test.txt
git add README.md
git commit -m "Initial commit" --quiet
# Create various git states for testing
echo "modified content" >> test.txt
echo "untracked file" > untracked.txt
echo "staged content" > staged.txt
git add staged.txt
log_success "Test environment created at: $TEST_DIR"
log_info "Git states created: modified, untracked, staged files"
}
# Load hyperterm functions
load_hyperterm_functions() {
log_info "Loading HyperTerm functions"
# Load colors
local colors_file="$PROJECT_ROOT/hyperterm/core/colors.sh"
if [[ -f "$colors_file" ]]; then
source "$colors_file"
log_success "Colors loaded from: $colors_file"
else
log_warn "Colors file not found, using fallback"
# Fallback colors
RESET='\033[0m'
BOLD='\033[1m'
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
CYAN='\033[36m'
WHITE='\033[37m'
GREY='\033[90m'
fi
# Load git functions
local git_file="$PROJECT_ROOT/hyperterm/core/git.sh"
if [[ -f "$git_file" ]]; then
source "$git_file"
log_success "Git functions loaded"
return 0
else
log_error "Git functions not found"
return 1
fi
}
# Test individual functions
test_individual_functions() {
log_info "Testing individual functions"
echo "Branch detection:"
if command -v _get_git_branch >/dev/null 2>&1; then
local branch
branch="$(_get_git_branch)"
echo " Result: $branch"
log_success "Branch detection working"
else
log_error "Branch detection function not found"
fi
echo "Git progress detection:"
if command -v _get_git_progress >/dev/null 2>&1; then
local progress
progress="$(_get_git_progress)"
echo " Result: ${progress:-"(none)"}"
log_success "Progress detection working"
else
log_error "Progress detection function not found"
fi
echo "Git status:"
if command -v _get_git_status_fast >/dev/null 2>&1; then
local status
status="$(_get_git_status_fast)"
echo " Result: $status"
log_success "Fast git status working"
elif command -v _prompt_get_git_status >/dev/null 2>&1; then
local status
status="$(_prompt_get_git_status)"
echo " Result: $status"
log_success "Original git status working"
else
log_error "No git status function found"
fi
}
# Performance benchmark
run_performance_test() {
log_info "Running performance benchmark"
if ! command -v __prompt_git >/dev/null 2>&1; then
log_error "Prompt function not available"
return 1
fi
local iterations=50
local start_time end_time duration
log_info "Running $iterations iterations"
start_time=$(date +%s%N)
for ((i=1; i<=iterations; i++)); do
__prompt_git >/dev/null 2>&1
done
end_time=$(date +%s%N)
duration=$(( (end_time - start_time) / 1000000 ))
local avg_duration=$(( duration / iterations ))
echo "Performance Results:"
echo " Total time: ${duration}ms"
echo " Average per call: ${avg_duration}ms"
echo " Iterations: $iterations"
if [[ $avg_duration -lt 10 ]]; then
log_success "Performance: Excellent (< 10ms per call)"
elif [[ $avg_duration -lt 50 ]]; then
log_success "Performance: Good (< 50ms per call)"
else
log_warn "Performance: Slow (>= 50ms per call)"
fi
}
# Test different git states
test_git_states() {
log_info "Testing different git states"
# Clean state
git checkout -- . >/dev/null 2>&1
git clean -fd >/dev/null 2>&1
echo "Clean repository:"
__prompt_git
echo ""
# Modified files
echo "modified" >> test.txt
echo "Modified files:"
__prompt_git
echo ""
# Untracked files
echo "untracked" > new_file.txt
echo "With untracked files:"
__prompt_git
echo ""
# Staged files
git add new_file.txt
echo "With staged files:"
__prompt_git
echo ""
log_success "Git states testing completed"
}
# Interactive test mode
interactive_mode() {
log_info "Entering interactive test mode"
echo "Available commands:"
echo " status - Show current git status"
echo " prompt - Show full prompt"
echo " perf - Run performance test"
echo " states - Test different git states"
echo " modify - Modify files for testing"
echo " clean - Clean working directory"
echo " help - Show this help"
echo " exit - Exit interactive mode"
echo ""
while true; do
echo -n "test> "
read -r command
case "$command" in
"status")
if command -v _get_git_status_fast >/dev/null 2>&1; then
_get_git_status_fast
else
_prompt_get_git_status
fi
echo ""
;;
"prompt")
__prompt_git
echo ""
;;
"perf")
run_performance_test
;;
"states")
test_git_states
;;
"modify")
echo "Creating test modifications"
echo "change $(date)" >> test.txt
echo "new file $(date)" > "file_$(date +%s).txt"
log_success "Files modified"
;;
"clean")
git checkout -- . >/dev/null 2>&1
git clean -fd >/dev/null 2>&1
log_success "Working directory cleaned"
;;
"help")
echo "Available commands: status, prompt, perf, states, modify, clean, help, exit"
;;
"exit")
log_info "Exiting interactive mode"
break
;;
"")
# Empty command, continue
;;
*)
log_warn "Unknown command: $command (type 'help' for available commands)"
;;
esac
done
}
# Main execution
main() {
log_info "Starting HyperTerm Prompt Test Suite"
# Setup
setup_test_env
if ! load_hyperterm_functions; then
log_error "Failed to load HyperTerm functions"
exit 1
fi
# Run tests
test_individual_functions
echo ""
run_performance_test
echo ""
test_git_states
echo ""
# Interactive mode (only if not in CI or non-interactive mode)
if [[ "$1" != "--non-interactive" && "$1" != "-n" && -z "${CI:-}" ]]; then
log_info "All automated tests completed"
echo "Enter interactive mode? (y/N)"
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
interactive_mode
fi
else
log_info "Running in non-interactive mode, skipping interactive prompt"
fi
log_success "Test suite completed successfully"
}
# Trap cleanup on exit
trap cleanup EXIT
# Execute main function if script is run directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi