Skip to content

Instantly share code, notes, and snippets.

@Nate-Wilkins
Created March 4, 2024 12:39
Show Gist options
  • Save Nate-Wilkins/94543a1482bb072e4c84fb11bb1a468f to your computer and use it in GitHub Desktop.
Save Nate-Wilkins/94543a1482bb072e4c84fb11bb1a468f to your computer and use it in GitHub Desktop.
gcw.zsh
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