Created
March 4, 2024 12:39
-
-
Save Nate-Wilkins/94543a1482bb072e4c84fb11bb1a468f to your computer and use it in GitHub Desktop.
gcw.zsh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gcw() { | |
# Filter specific workflows. | |
local ADD_STATUS=$(git diff --staged --diff-filter=A --name-only) | |
local DELETE_STATUS=$(git diff --staged --diff-filter=D --name-only) | |
local RENAME_STATUS=$(git diff --staged --diff-filter=R --name-only) | |
# Update status includes everything else. | |
local UPDATE_STATUS=$(git diff --staged --diff-filter=MCTUXB --name-only) | |
# Make sure we're using one workflow by counting up workflow changes. | |
local STATUS_CHANGE_COUNT=0 | |
if [ ! -z "$ADD_STATUS" ]; then | |
STATUS_CHANGE_COUNT=$((STATUS_CHANGE_COUNT+1)) | |
fi | |
if [ ! -z "$DELETE_STATUS" ]; then | |
STATUS_CHANGE_COUNT=$((STATUS_CHANGE_COUNT+1)) | |
fi | |
if [ ! -z "$RENAME_STATUS" ]; then | |
STATUS_CHANGE_COUNT=$((STATUS_CHANGE_COUNT+1)) | |
fi | |
if [ ! -z "$UPDATE_STATUS" ]; then | |
STATUS_CHANGE_COUNT=$((STATUS_CHANGE_COUNT+1)) | |
fi | |
if [ $STATUS_CHANGE_COUNT -gt 1 ]; then | |
echo "Too many changes. Use 'git commit' directly instead." | |
return | |
elif [ $STATUS_CHANGE_COUNT -eq 0 ]; then | |
echo "No changes found." | |
return | |
fi | |
# Find the correct context for these changes. | |
# Select parts of the selected source. | |
# Example: | |
# Selected: src/modules/nvim/nvim.sh | |
# > [src, modules, nvim, nvim.sh] | |
# Select option "modules" | |
# > [nvim, nvim.sh] | |
# Continue until exhausted or "DONE" | |
local SELECTED_UPDATE=$(echo "$ADD_STATUS$DELETE_STATUS$RENAME_STATUS$UPDATE_STATUS" | fzf) | |
local SELECTED_UPDATE_PARTS=($(echo $SELECTED_UPDATE | sed -e 's/\//\n/g')) | |
__gcm_select_source_part() { | |
local SELECTED_UPDATE_PART_OPTIONS=("${SELECTED_UPDATE_PARTS[@]}" "DONE") | |
local SELECTED_UPDATE_PART=$(printf "%s\n" "${SELECTED_UPDATE_PART_OPTIONS[@]}" | fzf | sed 's/^src\///g') | |
# Return "DONE". | |
if [[ "$SELECTED_UPDATE_PART" == "DONE" ]]; then | |
echo -1 | |
return | |
fi | |
# Return selected part index. | |
local PART_INDEX=0; for PART in "${SELECTED_UPDATE_PARTS[@]}"; do | |
[[ $PART == "$SELECTED_UPDATE_PART" ]] && break | |
PART_INDEX=$((PART_INDEX+1)) | |
done | |
echo $((PART_INDEX)) | |
} | |
__gcm_inside_out_select() { | |
local NEXT_INDEX=0; while [ ! $NEXT_INDEX -eq -1 ]; do | |
SELECTED_UPDATE_PARTS=("${SELECTED_UPDATE_PARTS[@]:$NEXT_INDEX}") | |
if [ "${#SELECTED_UPDATE_PARTS[@]}" -le "0" ]; then | |
break | |
fi | |
local SELECTED_INDEX=$(__gcm_select_source_part $NEXT_INDEX) | |
if [ "$SELECTED_INDEX" -le "-1" ]; then | |
# User manually exited. | |
break | |
fi | |
echo "${SELECTED_UPDATE_PARTS[$SELECTED_INDEX+1]}" | |
NEXT_INDEX=$((SELECTED_INDEX+1)) | |
done | |
} | |
# Common message format. | |
local MESSAGE_CONTEXT=$(__gcm_inside_out_select | tr '\n' '/' | sed 's/.$//') | |
# Get additional context if any. | |
git diff --staged | |
echo "\n" | |
local MESSAGE_CONTEXT_ADDITION | |
MESSAGE_CONTEXT_ADDITION=$(bash -c 'read -e -p "Additional Context: " tmp; echo $tmp') | |
if [ ! -z $MESSAGE_CONTEXT_ADDITION ]; then | |
MESSAGE_CONTEXT_ADDITION=" $MESSAGE_CONTEXT_ADDITION" | |
fi | |
# Execute workflow. | |
if [ ! -z "$ADD_STATUS" ]; then | |
# Add. | |
git commit -m "Add '$MESSAGE_CONTEXT'$MESSAGE_CONTEXT_ADDITION" | |
elif [ ! -z "$DELETE_STATUS" ]; then | |
# Delete. | |
git commit -m "Delete '$MESSAGE_CONTEXT'$MESSAGE_CONTEXT_ADDITION" | |
elif [ ! -z "$RENAME_STATUS" ]; then | |
# Rename. | |
git commit -m "Rename '$MESSAGE_CONTEXT'$MESSAGE_CONTEXT_ADDITION" | |
elif [ ! -z "$UPDATE_STATUS" ]; then | |
# Update. | |
git commit -m "Update '$MESSAGE_CONTEXT'$MESSAGE_CONTEXT_ADDITION" | |
fi | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment