From 6d936bb05c5218226b6d1dfa266a2e5865c0de2a Mon Sep 17 00:00:00 2001 From: Will Owens Date: Sat, 17 Feb 2024 15:56:41 -0500 Subject: [PATCH 1/3] fix: get rid of global $shell that can be unset by direnv --- lib/git/aliases.sh | 7 ++- lib/git/branch_shortcuts.sh | 2 +- lib/git/fallback/status_shortcuts_shell.sh | 10 ++-- lib/git/keybindings.sh | 14 +++--- lib/git/repo_index.sh | 6 +-- lib/git/shell_shortcuts.sh | 4 +- lib/git/status_shortcuts.sh | 21 +++++---- lib/git/tools.sh | 9 +--- lib/scm_breeze.sh | 55 ++++++++++++++++++---- test/lib/git/status_shortcuts_test.sh | 4 +- 10 files changed, 82 insertions(+), 50 deletions(-) diff --git a/lib/git/aliases.sh b/lib/git/aliases.sh index 2d6a6b87..09485402 100644 --- a/lib/git/aliases.sh +++ b/lib/git/aliases.sh @@ -75,7 +75,7 @@ __git_alias () { fi alias $alias_str="$cmd_prefix $cmd${cmd_args:+ }${cmd_args[*]}" - if [ "$shell" = "bash" ]; then + if breeze_shell_is "bash"; then __define_git_completion "$alias_str" "$cmd" complete -o default -o nospace -F _git_"$alias_str"_shortcut "$alias_str" fi @@ -177,10 +177,9 @@ if [ "$git_setup_aliases" = "yes" ]; then _alias "$git_pull_request_alias" 'gh pr' fi - - +# TODO(ghthor): apply these same fixes for NixOS # Tab completion -if [ $shell = "bash" ]; then +if breeze_shell_is "bash"; then # Fix to preload Arch bash completion for git [[ -s "/usr/share/git/completion/git-completion.bash" ]] && source "/usr/share/git/completion/git-completion.bash" # new path in Ubuntu 13.04 diff --git a/lib/git/branch_shortcuts.sh b/lib/git/branch_shortcuts.sh index 0a195f2a..467b2038 100644 --- a/lib/git/branch_shortcuts.sh +++ b/lib/git/branch_shortcuts.sh @@ -47,7 +47,7 @@ __git_alias "$git_branch_delete_alias" "_scmb_git_branch_shortcuts" "-d" __git_alias "$git_branch_delete_force_alias" "_scmb_git_branch_shortcuts" "-D" # Define completions for git branch shortcuts -if [ "$shell" = "bash" ]; then +if breeze_shell_is "bash"; then for alias_str in $git_branch_alias $git_branch_all_alias $git_branch_move_alias $git_branch_delete_alias; do __define_git_completion $alias_str branch complete -o default -o nospace -F _git_"$alias_str"_shortcut $alias_str diff --git a/lib/git/fallback/status_shortcuts_shell.sh b/lib/git/fallback/status_shortcuts_shell.sh index 0a103870..22cdda66 100755 --- a/lib/git/fallback/status_shortcuts_shell.sh +++ b/lib/git/fallback/status_shortcuts_shell.sh @@ -53,10 +53,14 @@ git_status_shortcuts() { echo -e "$c_dark#$c_rst On branch: $c_branch$branch$c_rst $c_dark| [$c_rst*$c_dark]$c_rst => \$$git_env_char*\n$c_dark#$c_rst" for line in $git_status; do - if [[ $shell == *bash ]]; then - x=${line:0:1}; y=${line:1:1}; file=${line:3} + if breeze_shell_is "bash"; then + x=${line:0:1} + y=${line:1:1} + file=${line:3} else - x=$line[1]; y=$line[2]; file=$line[4,-1] + x=$line[1] + y=$line[2] + file=$line[4,-1] fi # Index modification states diff --git a/lib/git/keybindings.sh b/lib/git/keybindings.sh index 4bbca42b..28865915 100644 --- a/lib/git/keybindings.sh +++ b/lib/git/keybindings.sh @@ -10,9 +10,9 @@ # See [here](http://qntm.org/bash#sec1) for info about why I wanted a prompt. # Cross-shell key bindings -_bind(){ +_bind() { if [ -n "$1" ]; then - if [[ $shell == "zsh" ]]; then + if breeze_shell_is "zsh"; then bindkey -s "$1" "$2" else # bash bind "\"$1\": $2" @@ -24,11 +24,11 @@ _bind(){ if [[ "$git_keyboard_shortcuts_enabled" = "true" ]]; then case "$-" in *i*) - if [ -n "$ZSH_VERSION" ]; then - RETURN_CHAR="^M" - else - RETURN_CHAR="\n" - fi + if [ -n "$ZSH_VERSION" ]; then + RETURN_CHAR="^M" + else + RETURN_CHAR="\n" + fi # Uses emacs style keybindings, so vi mode is not supported for now if ! set -o | grep -q '^vi .*on$'; then diff --git a/lib/git/repo_index.sh b/lib/git/repo_index.sh index fa60797a..51622cfb 100644 --- a/lib/git/repo_index.sh +++ b/lib/git/repo_index.sh @@ -79,8 +79,8 @@ function git_index() { echo # If $1 starts with '/', change to top-level directory within $GIT_REPO_DIR - elif ([ $shell = "bash" ] && [ "${1:0:1}" = "/" ]) || \ - ([ $shell = "zsh" ] && [ "${1[1]}" = "/" ]); then + elif (breeze_shell_is "bash" && [ "${1:0:1}" = "/" ]) || \ + (breeze_shell_is "zsh" && [ "${1[1]}" = "/" ]); then if [ -d "$GIT_REPO_DIR$1" ]; then builtin cd "$GIT_REPO_DIR$1" fi @@ -278,7 +278,7 @@ function _git_index_batch_cmd() { } -if [ $shell = 'bash' ]; then +if breeze_shell_is "bash"; then # Bash tab completion function for git_index() function _git_index_tab_completion() { _check_git_index diff --git a/lib/git/shell_shortcuts.sh b/lib/git/shell_shortcuts.sh index de1693dc..3b8f2289 100644 --- a/lib/git/shell_shortcuts.sh +++ b/lib/git/shell_shortcuts.sh @@ -127,7 +127,7 @@ if [ "$shell_ls_aliases_enabled" = "true" ] && builtin command -v ruby >/dev/nul ll_output="$(CLICOLOR_FORCE=1 "${ll_command[@]}" -lG "$@")" fi - if [[ $shell == "zsh" ]]; then + if breeze_shell_is "zsh"; then # Ensure sh_word_split is on [[ -o shwordsplit ]] && SHWORDSPLIT_ON=true setopt shwordsplit @@ -227,7 +227,7 @@ EOF done # Turn off shwordsplit unless it was on previously - if [[ $shell == "zsh" && -z $SHWORDSPLIT_ON ]]; then unsetopt shwordsplit; fi + if breeze_shell_is "zsh" && [[ -z $SHWORDSPLIT_ON ]]; then unsetopt shwordsplit; fi } # Setup aliases diff --git a/lib/git/status_shortcuts.sh b/lib/git/status_shortcuts.sh index a8616ce6..9f40e53a 100644 --- a/lib/git/status_shortcuts.sh +++ b/lib/git/status_shortcuts.sh @@ -8,7 +8,6 @@ # Numbered file shortcuts for git commands # ------------------------------------------------------------------------------ - # Processes 'git status --porcelain', and exports numbered # env variables that contain the path of each affected file. # Output is also more concise than standard 'git status'. @@ -17,6 +16,11 @@ # 1 || staged, 2 || unmerged, 3 || unstaged, 4 || untracked # -------------------------------------------------------------------- git_status_shortcuts() { + if [ "${scmbDebug:-}" = "true" ]; then + set -x + trap "set +x;" RETURN + fi + fail_if_not_git_repo || return 1 zsh_compat # Ensure shwordsplit is on for zsh git_clear_vars @@ -50,8 +54,6 @@ git_status_shortcuts() { zsh_reset # Reset zsh environment to default } - - # 'git add' & 'git rm' wrapper # This shortcut means 'stage the change to the file' # i.e. It will add new and changed files, and remove deleted files. @@ -155,8 +157,8 @@ scmb_expand_args() { _print_path() { local pathname pathname=$(eval printf '%s' "\"\${$2}\"") - if [ "$1" = 1 ]; then # print relative - pathname=${pathname#$PWD/} # Remove $PWD from beginning of the path + if [ "$1" = 1 ]; then # print relative + pathname=${pathname#$PWD/} # Remove $PWD from beginning of the path fi printf '%s' "$pathname" } @@ -183,7 +185,6 @@ git_clear_vars() { done } - # Shortcuts for resolving merge conflicts. _git_resolve_merge_conflict() { if [ -n "$2" ]; then @@ -216,7 +217,7 @@ git_commit_prompt() ( saved_commit_msg="$(cat /tmp/.git_commit_message~)" echo -e "\033[0;36mLeave blank to use saved commit message: \033[0m$saved_commit_msg" fi - if [[ $shell == "zsh" ]]; then + if breeze_shell_is "zsh"; then vared -h -p "Commit Message: " commit_msg else read -r -e -p "Commit Message: " commit_msg @@ -242,7 +243,7 @@ git_commit_prompt() ( escaped_msg=$(echo "$commit_msg" | sed -e 's/"/\\"/g' -e "s/!/\"'!'\"/g") # Add command to bash history, so that if a git pre-commit hook fails, # you can just press "up" and "return" to retry the commit. - if [[ $shell == "zsh" ]]; then + if breeze_shell_is "zsh"; then # zsh's print needs double escaping print -s "git commit -m \"${escaped_msg//\\/\\\\}\"" else @@ -252,14 +253,14 @@ git_commit_prompt() ( fi # Also save the commit message to a temp file in case git commit fails - echo "$commit_msg" > "/tmp/.git_commit_message~" + echo "$commit_msg" >"/tmp/.git_commit_message~" eval $@ # run any prequisite commands echo "$commit_msg" | git commit -F - | tail -n +2 # Fetch the pipe status (for both bash and zsh): GIT_PIPE_STATUS=("${PIPESTATUS[@]}${pipestatus[@]}") - if [[ $shell == "zsh" ]]; then + if breeze_shell_is "zsh"; then git_exit_status="${GIT_PIPE_STATUS[2]}" # zsh array indexes start at 1 else git_exit_status="${GIT_PIPE_STATUS[1]}" diff --git a/lib/git/tools.sh b/lib/git/tools.sh index c158a772..313c6276 100644 --- a/lib/git/tools.sh +++ b/lib/git/tools.sh @@ -10,7 +10,6 @@ # at https://github.com/ndbroadbent/scm_breeze # ----------------------------------------------------------------- - # Remove files/folders from git history # ------------------------------------------------------------------- # To use it, cd to your repository's root and then run the function @@ -30,7 +29,6 @@ git_remove_history() { rm -rf .git/refs/original/ && $_git_cmd reflog expire --all && $_git_cmd gc --aggressive --prune } - # Set default remote and merge for a git branch (pull and push) # Usage: git_set_default_remote(branch = master, remote = origin) git_set_default_remote() { @@ -68,8 +66,6 @@ git_exclude_basename() { exec_scmb_expand_args __git_exclude_basename "$@" } - - # Use git bisect to find where text was removed from a file. # # Example: @@ -91,7 +87,6 @@ git_bisect_grep() { $_git_cmd bisect run grep -qRE "$2" $search_path } - # Removes a git submodule # (from http://stackoverflow.com/a/7646931/304706) # Deletes the sections from .gitmodules, .git/config, @@ -108,7 +103,6 @@ git_submodule_rm() { $_git_cmd rm --cached "$1" } - # Swaps git remotes # i.e. swap origin <-> username git_swap_remotes() { @@ -122,11 +116,10 @@ git_swap_remotes() { echo "Swapped $1 <-> $2" } # (use git fetch tab completion) -if [ "$shell" = "bash" ]; then +if breeze_shell_is "bash"; then complete -o default -o nospace -F _git_fetch git_swap_remotes fi - # Delete a git branch from local, cached remote and remote server git_branch_delete_all() { if [ -z "$1" ]; then diff --git a/lib/scm_breeze.sh b/lib/scm_breeze.sh index 2744b007..f5a06ed0 100644 --- a/lib/scm_breeze.sh +++ b/lib/scm_breeze.sh @@ -1,13 +1,48 @@ # Detect shell -if [ -n "${ZSH_VERSION:-}" ]; then shell="zsh"; else shell="bash"; fi +breeze_detect_shell() { + if [ -n "${ZSH_VERSION:-}" ]; then + echo "zsh" + else + echo "bash" + fi +} + +breeze_shell_is() { + [ "$(breeze_detect_shell)" = "$1" ] && return 0 + return 1 +} # Detect whether zsh 'shwordsplit' option is on by default. -if [ $shell = "zsh" ]; then zsh_shwordsplit=$( (setopt | grep -q shwordsplit) && echo "true" ); fi +if breeze_shell_is "zsh"; then + zsh_shwordsplit=$( (setopt | grep -q shwordsplit) && echo "true") +fi + # Switch on/off shwordsplit for functions that require it. -zsh_compat(){ if [ $shell = "zsh" ] && [ -z $zsh_shwordsplit ]; then setopt shwordsplit; fi; } -zsh_reset(){ if [ $shell = "zsh" ] && [ -z $zsh_shwordsplit ]; then unsetopt shwordsplit; fi; } +zsh_compat() { + if breeze_shell_is "zsh" && [ -z $zsh_shwordsplit ]; then + setopt shwordsplit + fi +} +zsh_reset() { + if breeze_shell_is "zsh" && [ -z $zsh_shwordsplit ]; then + unsetopt shwordsplit + fi +} + # Enable/disable nullglob for zsh or bash -enable_nullglob() { if [ $shell = "zsh" ]; then setopt NULL_GLOB; else shopt -s nullglob; fi; } -disable_nullglob() { if [ $shell = "zsh" ]; then unsetopt NULL_GLOB; else shopt -u nullglob; fi; } +enable_nullglob() { + if breeze_shell_is "zsh"; then + setopt NULL_GLOB + else + shopt -s nullglob + fi +} +disable_nullglob() { + if breeze_shell_is "zsh"; then + unsetopt NULL_GLOB + else + shopt -u nullglob + fi +} # Alias wrapper that ignores errors if alias is not defined. _safe_alias(){ alias "$@" 2> /dev/null; } @@ -31,7 +66,7 @@ function token_quote { # Keep this code for use when minimum versions of {ba,z}sh can be increased. # See https://github.com/scmbreeze/scm_breeze/issues/260 # - # if [[ $shell = bash ]]; then + # if breeze_detect_shell "bash"; then # # ${parameter@operator} where parameter is ${@} and operator is 'Q' # # https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html # eval "${@@Q}" @@ -50,7 +85,7 @@ function _safe_eval() { # Keep this code for use when minimum versions of {ba,z}sh can be increased. # See https://github.com/scmbreeze/scm_breeze/issues/260 # - # if [[ $shell = bash ]]; then + # if breeze_detect_shell "bash"; then # # ${parameter@operator} where parameter is ${@} and operator is 'Q' # # https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html # eval "${@@Q}" @@ -60,8 +95,8 @@ function _safe_eval() { # fi } -find_binary(){ - if [ $shell = "zsh" ]; then +find_binary() { + if breeze_shell_is "bash"; then builtin type -p "$1" | sed "s/$1 is //" | head -1 else builtin type -P "$1" diff --git a/test/lib/git/status_shortcuts_test.sh b/test/lib/git/status_shortcuts_test.sh index d24ed231..5ba6a7b5 100755 --- a/test/lib/git/status_shortcuts_test.sh +++ b/test/lib/git/status_shortcuts_test.sh @@ -335,7 +335,7 @@ test_git_commit_prompt() { assertIncludes "$git_show_output" "$commit_msg" # Test that history was appended correctly. - if [[ $shell == "zsh" ]]; then + if breeze_shell_is "zsh"; then test_history="$(history)" # TODO(ghthor): zsh isn't working here # assertIncludes "$test_history" "git commit -m \"$dbl_escaped_msg\"" @@ -371,7 +371,7 @@ test_git_commit_prompt_with_append() { assertIncludes "$git_show_output" "$commit_msg \[ci skip\]" # Test that history was appended correctly. - if [[ $shell == "zsh" ]]; then + if breeze_shell_is "zsh"; then test_history="$(history)" # TODO(ghthor): zsh isn't working here # assertIncludes "$test_history" "$commit_msg \[ci skip\]" From 881300079b2ee445432ae74a74add5719509d859 Mon Sep 17 00:00:00 2001 From: Will Owens Date: Sat, 2 Mar 2024 17:10:34 -0500 Subject: [PATCH 2/3] apply some changes from shfmt -i 2 --- lib/git/aliases.sh | 41 ++++++++-------- lib/git/branch_shortcuts.sh | 8 ++-- lib/git/fallback/status_shortcuts_shell.sh | 54 +++++++++++++++------- lib/git/keybindings.sh | 9 ++-- lib/git/status_shortcuts.sh | 38 +++++++-------- lib/git/tools.sh | 12 ++--- lib/scm_breeze.sh | 17 +++---- test/lib/git/status_shortcuts_test.sh | 2 +- 8 files changed, 107 insertions(+), 74 deletions(-) diff --git a/lib/git/aliases.sh b/lib/git/aliases.sh index 09485402..0aefbb99 100644 --- a/lib/git/aliases.sh +++ b/lib/git/aliases.sh @@ -13,45 +13,48 @@ list_aliases() { alias | grep "$*" --color=never | sed -e 's/alias //' -e "s/=/: alias git_aliases="list_aliases git" # Remove any existing git alias or function -unalias git > /dev/null 2>&1 -unset -f git > /dev/null 2>&1 +unalias git >/dev/null 2>&1 +unset -f git >/dev/null 2>&1 # Use the full path to git to avoid infinite loop with git function export _git_cmd="$(bin_path git)" # Wrap git with the 'hub' github wrapper, if installed (https://github.com/defunkt/hub) -if type hub > /dev/null 2>&1; then export _git_cmd="hub"; fi +if type hub >/dev/null 2>&1; then export _git_cmd="hub"; fi # gh is now deprecated, and merged into the `hub` command line tool. #if type gh > /dev/null 2>&1; then export _git_cmd="gh"; fi # Create 'git' function that calls hub if defined, and expands all numeric arguments -function git(){ +function git() { # Only expand args for git commands that deal with paths or branches case $1 in - commit|blame|add|log|rebase|merge|difftool|switch) - exec_scmb_expand_args "$_git_cmd" "$@";; - checkout|diff|rm|reset|restore) - exec_scmb_expand_args --relative "$_git_cmd" "$@";; - branch) - _scmb_git_branch_shortcuts "${@:2}";; - *) - "$_git_cmd" "$@";; + commit | blame | add | log | rebase | merge | difftool | switch) + exec_scmb_expand_args "$_git_cmd" "$@" + ;; + checkout | diff | rm | reset | restore) + exec_scmb_expand_args --relative "$_git_cmd" "$@" + ;; + branch) + _scmb_git_branch_shortcuts "${@:2}" + ;; + *) + "$_git_cmd" "$@" + ;; esac } _alias "$git_alias" "git" - # -------------------------------------------------------------------- # Thanks to Scott Bronson for coming up the following git tab completion workaround, # which I've altered slightly to be more flexible. # https://github.com/bronson/dotfiles/blob/731bfd951be68f395247982ba1fb745fbed2455c/.bashrc#L81 # (only works for bash) -__define_git_completion () { -eval " +__define_git_completion() { + eval " _git_$1_shortcut () { COMP_LINE=\"git $2 \${COMP_LINE/$1 }\" -let COMP_POINT+=$((4+${#2}-${#1})) +let COMP_POINT+=$((4 + ${#2} - ${#1})) COMP_WORDS=(git $2 \"\${COMP_WORDS[@]:1}\") let COMP_CWORD+=1 @@ -64,11 +67,13 @@ __git_wrap__git_main # Define git alias with tab completion # Usage: __git_alias -__git_alias () { +__git_alias() { if [ -n "$1" ]; then local alias_str cmd_prefix cmd cmd_args - alias_str="$1"; cmd_prefix="$2"; cmd="$3"; + alias_str="$1" + cmd_prefix="$2" + cmd="$3" if [ $# -gt 2 ]; then shift 3 2>/dev/null cmd_args=("$@") diff --git a/lib/git/branch_shortcuts.sh b/lib/git/branch_shortcuts.sh index 467b2038..6d5f5ede 100644 --- a/lib/git/branch_shortcuts.sh +++ b/lib/git/branch_shortcuts.sh @@ -10,7 +10,8 @@ # Function wrapper around 'll' # Adds numbered shortcuts to output of ls -l, just like 'git status' -unalias $git_branch_alias > /dev/null 2>&1; unset -f $git_branch_alias > /dev/null 2>&1 +unalias $git_branch_alias >/dev/null 2>&1 +unset -f $git_branch_alias >/dev/null 2>&1 function _scmb_git_branch_shortcuts { fail_if_not_git_repo || return 1 @@ -21,7 +22,8 @@ function _scmb_git_branch_shortcuts { fi # Use ruby to inject numbers into git branch output - ruby -e "$( cat < /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'` + local branch=$(git branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/') # Get project root if [ -d .git ]; then local project_root="$PWD" else - local project_root=$(git rev-parse --git-dir 2> /dev/null | sed "s%/\.git$%%g") + local project_root=$(git rev-parse --git-dir 2>/dev/null | sed "s%/\.git$%%g") fi # Colors @@ -46,9 +51,13 @@ git_status_shortcuts() { local c_cpy="\033[0;33m" local c_ign="\033[0;36m" # Following colors must be prepended with modifiers e.g. '\033[1;', '\033[0;' - local c_grp_1="33m"; local c_grp_2="31m"; local c_grp_3="32m"; local c_grp_4="36m" + local c_grp_1="33m" + local c_grp_2="31m" + local c_grp_3="32m" + local c_grp_4="36m" - local f=1; local e=1 # Counters for number of files, and ENV variables + local f=1 + local e=1 # Counters for number of files, and ENV variables echo -e "$c_dark#$c_rst On branch: $c_branch$branch$c_rst $c_dark| [$c_rst*$c_dark]$c_rst => \$$git_env_char*\n$c_dark#$c_rst" @@ -82,18 +91,30 @@ git_status_shortcuts() { esac if [ -n "$msg" ]; then # Store data at array index and add to group - stat_file[$f]=$file; stat_msg[$f]=$msg; stat_col[$f]=$col + stat_file[$f]=$file + stat_msg[$f]=$msg + stat_col[$f]=$col stat_grp[$grp]="${stat_grp[$grp]} $f" let f++ fi # Work tree modification states msg="" - if [[ "$y" == "M" ]]; then msg=" modified"; col="$c_mod"; grp="3"; fi + if [[ "$y" == "M" ]]; then + msg=" modified" + col="$c_mod" + grp="3" + fi # Don't show {Y} as deleted during a merge conflict. - if [[ "$y" == "D" && "$x" != "D" && "$x" != "U" ]]; then msg=" deleted"; col="$c_del"; grp="3"; fi + if [[ "$y" == "D" && "$x" != "D" && "$x" != "U" ]]; then + msg=" deleted" + col="$c_del" + grp="3" + fi if [ -n "$msg" ]; then - stat_file[$f]=$file; stat_msg[$f]=$msg; stat_col[$f]=$col + stat_file[$f]=$file + stat_msg[$f]=$msg + stat_col[$f]=$col stat_grp[$grp]="${stat_grp[$grp]} $f" let f++ fi @@ -135,10 +156,10 @@ _gs_output_file_group() { local absolute="$project_root/${stat_file[$i]}" local dest=$(readlink -f "$absolute") local pwd=$(readlink -f "$PWD") - relative="$(_gs_relative_path "$pwd" "${dest:-$absolute}" )" + relative="$(_gs_relative_path "$pwd" "${dest:-$absolute}")" fi - if [[ $f -gt 10 && $e -lt 10 ]]; then local pad=" "; else local pad=""; fi # (padding) + if [[ $f -gt 10 && $e -lt 10 ]]; then local pad=" "; else local pad=""; fi # (padding) echo -e "$c_hash#$c_rst ${stat_col[$i]}${stat_msg[$i]}:\ $pad$c_dark [$c_rst$e$c_dark] $c_group$relative$c_rst" # Export numbered variables in the order they are displayed. @@ -152,14 +173,15 @@ $pad$c_dark [$c_rst$e$c_dark] $c_group$relative$c_rst" } # Show relative path if current directory is not project root -_gs_relative_path(){ +_gs_relative_path() { # Credit to 'pini' for the following script. # (http://stackoverflow.com/questions/2564634/bash-convert-absolute-path-into-relative-path-given-a-current-directory) - target=$2; common_part=$1; back="" + target=$2 + common_part=$1 + back="" while [[ -n "${common_part}" && "${target#$common_part}" == "${target}" ]]; do common_part="${common_part%/*}" back="../${back}" done echo "${back}${target#$common_part/}" } - diff --git a/lib/git/keybindings.sh b/lib/git/keybindings.sh index 28865915..4265e79e 100644 --- a/lib/git/keybindings.sh +++ b/lib/git/keybindings.sh @@ -45,9 +45,10 @@ if [[ "$git_keyboard_shortcuts_enabled" = "true" ]]; then fi fi - # Commands are prepended with a space so that they won't be added to history. - # Make sure this is turned on with: - # zsh: setopt histignorespace histignoredups - # bash: HISTCONTROL=ignorespace:ignoredups + # Commands are prepended with a space so that they won't be added to history. + # Make sure this is turned on with: + # zsh: setopt histignorespace histignoredups + # bash: HISTCONTROL=ignorespace:ignoredups + ;; esac fi diff --git a/lib/git/status_shortcuts.sh b/lib/git/status_shortcuts.sh index 9f40e53a..dde9f3fb 100644 --- a/lib/git/status_shortcuts.sh +++ b/lib/git/status_shortcuts.sh @@ -82,7 +82,7 @@ git_silent_add_shortcuts() { if [ -n "$1" ]; then # Expand args and process resulting set of files. local args - eval args="$(scmb_expand_args "$@")" # populate $args array + eval args="$(scmb_expand_args "$@")" # populate $args array for file in "${args[@]}"; do # Use 'git rm' if file doesn't exist and 'ga_auto_remove' is enabled. if [[ $ga_auto_remove = yes && ! -e $file ]]; then @@ -99,16 +99,19 @@ git_silent_add_shortcuts() { # Prints a list of all files affected by a given SHA1, # and exports numbered environment variables for each file. -git_show_affected_files(){ +git_show_affected_files() { fail_if_not_git_repo || return 1 - local f=0 # File count + local f=0 # File count # Show colored revision and commit message - echo -n "# "; git show --oneline --name-only "$@" | head -n1; echo "# " + echo -n "# " + git show --oneline --name-only "$@" | head -n1 + echo "# " for file in $(git show --pretty="format:" --name-only "$@" | \grep -v '^$'); do let f++ - export $git_env_char$f=$file # Export numbered variable. + export $git_env_char$f=$file # Export numbered variable. echo -e "# \033[2;37m[\033[0m$f\033[2;37m]\033[0m $file" - done; echo "# " + done + echo "# " } # Allows expansion of numbered shortcuts, ranges of shortcuts, or standard paths. @@ -124,20 +127,20 @@ scmb_expand_args() { fi local args - args=() # initially empty array. zsh 5.0.2 from Ubuntu 14.04 requires this to be separated + args=() # initially empty array. zsh 5.0.2 from Ubuntu 14.04 requires this to be separated for arg in "$@"; do - if [[ "$arg" =~ ^[0-9]{0,4}$ ]] ; then # Substitute $e{*} variables for any integers + if [[ "$arg" =~ ^[0-9]{0,4}$ ]]; then # Substitute $e{*} variables for any integers if [ -e "$arg" ]; then # Don't expand files or directories with numeric names args+=("$arg") else args+=("$(_print_path "$relative" "$git_env_char$arg")") fi - elif [[ "$arg" =~ ^[0-9]+-[0-9]+$ ]]; then # Expand ranges into $e{*} variables + elif [[ "$arg" =~ ^[0-9]+-[0-9]+$ ]]; then # Expand ranges into $e{*} variables for i in $(eval echo {${arg/-/..}}); do args+=("$(_print_path "$relative" "$git_env_char$i")") done - else # Otherwise, treat $arg as a normal string. + else # Otherwise, treat $arg as a normal string. args+=("$arg") fi done @@ -167,14 +170,14 @@ _print_path() { # Fails if command is a number or range (probably not worth fixing) exec_scmb_expand_args() { local args - eval "args=$(scmb_expand_args "$@")" # populate $args array + eval "args=$(scmb_expand_args "$@")" # populate $args array _safe_eval "${args[@]}" } # Clear numbered env variables git_clear_vars() { local i - for (( i=1; i<=$gs_max_changes; i++ )); do + for ((i = 1; i <= $gs_max_changes; i++)); do # Stop clearing after first empty var local env_var_i=${git_env_char}${i} if [[ -z "$(eval echo "\${$env_var_i:-}")" ]]; then @@ -190,18 +193,17 @@ _git_resolve_merge_conflict() { if [ -n "$2" ]; then # Expand args and process resulting set of files. local args - eval "args=$(scmb_expand_args "$@")" # populate $args array + eval "args=$(scmb_expand_args "$@")" # populate $args array for file in "${args[@]:2}"; do - git checkout "--$1""s" "$file" # "--$1""s" is expanded to --ours or --theirs + git checkout "--$1""s" "$file" # "--$1""s" is expanded to --ours or --theirs git add "$file" echo -e "# Added $1 version of '$file'" done echo -e "# -- If you have finished resolving conflicts, commit the resolutions with 'git commit'" fi } -ours(){ _git_resolve_merge_conflict "our" "$@"; } -theirs(){ _git_resolve_merge_conflict "their" "$@"; } - +ours() { _git_resolve_merge_conflict "our" "$@"; } +theirs() { _git_resolve_merge_conflict "their" "$@"; } # Git commit prompts # ------------------------------------------------------------------------------ @@ -292,7 +294,7 @@ git_add_and_commit() ( git_silent_add_shortcuts "$@" changes=$(git diff --cached --numstat | wc -l) if [ "$changes" -gt 0 ]; then - git_status_shortcuts 1 # only show staged changes + git_status_shortcuts 1 # only show staged changes git_commit_prompt else echo "# No staged changes to commit." diff --git a/lib/git/tools.sh b/lib/git/tools.sh index 313c6276..2076088e 100644 --- a/lib/git/tools.sh +++ b/lib/git/tools.sh @@ -18,21 +18,21 @@ git_remove_history() { # Make sure we're at the root of a git repo if [ ! -d .git ]; then - echo "Error: must run this script from the root of a git repository" - return + echo "Error: must run this script from the root of a git repository" + return fi # Remove all paths passed as arguments from the history of the repo local files files=("$@") $_git_cmd filter-branch --index-filter "$_git_cmd rm -rf --cached --ignore-unmatch ${files[*]}" HEAD # Remove the temporary history git-filter-branch otherwise leaves behind for a long time - rm -rf .git/refs/original/ && $_git_cmd reflog expire --all && $_git_cmd gc --aggressive --prune + rm -rf .git/refs/original/ && $_git_cmd reflog expire --all && $_git_cmd gc --aggressive --prune } # Set default remote and merge for a git branch (pull and push) # Usage: git_set_default_remote(branch = master, remote = origin) git_set_default_remote() { - curr_branch=$($_git_cmd branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/') + curr_branch=$($_git_cmd branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/') if [ -n "$1" ]; then branch="$1"; else branch="$curr_branch"; fi if [ -n "$2" ]; then remote="$2"; else remote="origin"; fi echo "branch.$branch.remote: $remote" @@ -45,7 +45,7 @@ git_set_default_remote() { # Usage: git_ignore [rule] [ignore_file=.gitignore] __git_ignore() { if [ -n "$2" ]; then local f="$2"; else local f=".gitignore"; fi - if [ -n "$1" ] && ! ([ -e $f ] && grep -q "$1" $f); then echo "$1" >> $f; fi + if [ -n "$1" ] && ! ([ -e $f ] && grep -q "$1" $f); then echo "$1" >>$f; fi } # Always expand args git_ignore() { @@ -77,7 +77,7 @@ git_exclude_basename() { # git_bisect_grep() { if [ -z "$2" ]; then - echo "Usage: $0 "; + echo "Usage: $0 " return fi if [ -n "$3" ]; then search_path="$3"; else search_path="."; fi diff --git a/lib/scm_breeze.sh b/lib/scm_breeze.sh index f5a06ed0..23521801 100644 --- a/lib/scm_breeze.sh +++ b/lib/scm_breeze.sh @@ -45,21 +45,22 @@ disable_nullglob() { } # Alias wrapper that ignores errors if alias is not defined. -_safe_alias(){ alias "$@" 2> /dev/null; } +_safe_alias() { alias "$@" 2>/dev/null; } _alias() { if [ -n "$1" ]; then - local alias_str="$1"; local cmd="$2" + local alias_str="$1" + local cmd="$2" _safe_alias $alias_str="$cmd" fi } # Quote the contents of "$@" function token_quote { - # Older versions of {ba,z}sh don't support the built-in quoting, so fall back to printf %q + # Older versions of {ba,z}sh don't support the built-in quoting, so fall back to printf %q local quoted - quoted=() # Assign separately for zsh 5.0.2 of Ubuntu 14.04 + quoted=() # Assign separately for zsh 5.0.2 of Ubuntu 14.04 for token; do - quoted+=( "$(printf '%q' "$token")" ) + quoted+=("$(printf '%q' "$token")") done printf '%s\n' "${quoted[*]}" @@ -109,7 +110,7 @@ export GIT_BINARY=$(find_binary git) update_scm_breeze() { currDir=$PWD cd "$scmbDir" - oldHEAD=$(git rev-parse HEAD 2> /dev/null) + oldHEAD=$(git rev-parse HEAD 2>/dev/null) git pull origin master # Reload latest version of '_create_or_patch_scmbrc' function source "$scmbDir/lib/scm_breeze.sh" @@ -131,8 +132,8 @@ _create_or_patch_scmbrc() { # If file exists, attempt to update it with any new settings elif [ -n "$1" ]; then # Create diff of example file, substituting example file for user's config. - git diff $1 "$prefix""scmbrc.example" | sed "s/$prefix""scmbrc.example/.$prefix""scmbrc/g" >| $patchfile - if [ -s $patchfile ]; then # If patchfile is not empty + git diff $1 "$prefix""scmbrc.example" | sed "s/$prefix""scmbrc.example/.$prefix""scmbrc/g" >|$patchfile + if [ -s $patchfile ]; then # If patchfile is not empty cd "$HOME" # If the patch cannot be applied cleanly, show the updates and tell user to update file manually. if ! patch -f "$HOME/.$prefix""scmbrc" $patchfile; then diff --git a/test/lib/git/status_shortcuts_test.sh b/test/lib/git/status_shortcuts_test.sh index 5ba6a7b5..40a08548 100755 --- a/test/lib/git/status_shortcuts_test.sh +++ b/test/lib/git/status_shortcuts_test.sh @@ -184,7 +184,7 @@ test_git_status_shortcuts() { # (This is needed so that env variables are exported in the current shell) temp_file=$(mktemp -t scm_breeze.XXXXXXXXXX) git_status_shortcuts >$temp_file - git_status=$(<$temp_file strip_colors) + git_status=$(strip_colors <$temp_file) assertIncludes "$git_status" "new file: *\[1\] *new_file" || return assertIncludes "$git_status" "deleted: *\[2\] *deleted_file" || return From 6425b126412b0ba0f7c7838f6f52d2bf63d7407e Mon Sep 17 00:00:00 2001 From: Will Owens Date: Sat, 2 Mar 2024 18:09:59 -0500 Subject: [PATCH 3/3] flake init: WIP --- .gitignore | 1 + flake.lock | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ flake.nix | 19 +++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 .gitignore create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..41fbeb02 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +**/result diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..e20ad069 --- /dev/null +++ b/flake.lock @@ -0,0 +1,60 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1707347730, + "narHash": "sha256-0etC/exQIaqC9vliKhc3eZE2Mm2wgLa0tj93ZF/egvM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6832d0d99649db3d65a0e15fa51471537b2c56a6", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-23.11", + "type": "indirect" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..61d069d7 --- /dev/null +++ b/flake.nix @@ -0,0 +1,19 @@ +{ + description = "scm_breeze shell plugin for git and interactive shell"; + + inputs = { + flake-utils.url = "github:numtide/flake-utils"; + nixpkgs.url = "nixpkgs/nixos-23.11"; + }; + + outputs = { self, flake-utils, nixpkgs, ... }: + flake-utils.lib.eachDefaultSystem (system: + let pkgs = import nixpkgs { inherit system; }; + in rec { + formatter = pkgs.nixfmt; + packages = rec { + hello = pkgs.hello; + default = hello; + }; + }); +}