Skip to content

Instantly share code, notes, and snippets.

@sunyi00
Forked from drmingdrmer/p8ln
Created December 20, 2021 09:03
Show Gist options
  • Save sunyi00/1bd3dff94a9167f44f75d44e0c774d1f to your computer and use it in GitHub Desktop.
Save sunyi00/1bd3dff94a9167f44f75d44e0c774d1f to your computer and use it in GitHub Desktop.

Revisions

  1. @drmingdrmer drmingdrmer revised this gist Mar 25, 2019. 1 changed file with 31 additions and 0 deletions.
    31 changes: 31 additions & 0 deletions p8ln
    Original file line number Diff line number Diff line change
    @@ -21,6 +21,36 @@



    clr()
    {
    # clr light read blabla

    local black=0
    local white=7
    local red=1
    local green=2
    local brown=3
    local blue=4
    local purple=5
    local cyan=6

    local light=""
    local color=$1
    shift

    if [ "$color" == "light" ]; then
    light="tput bold; "
    color=$1
    shift
    fi

    local code=$(eval 'echo $'$color)
    local cmd="${light}tput setaf $code"
    local color_str="$(eval "$cmd")"

    echo $color_str"$@""$(tput sgr0)"
    }

    shlib_init_colors()
    {
    Black="$( tput setaf 0)"
    @@ -50,6 +80,7 @@ shlib_init_colors()
    NC="$( tput sgr0)" # No Color
    }


    screen_width()
    {
    local chr="${1--}"
  2. @drmingdrmer drmingdrmer revised this gist Feb 12, 2019. 1 changed file with 10 additions and 21 deletions.
    31 changes: 10 additions & 21 deletions p8ln
    Original file line number Diff line number Diff line change
    @@ -19,8 +19,6 @@
    # by diff work-tree(unstaged) with HEAD,
    # or by diff index(staged or cached) with HEAD.

    #include 'shlib.sh' begin
    #!/bin/sh


    shlib_init_colors()
    @@ -172,7 +170,7 @@ debug()
    {
    if [ ".$SHLIB_LOG_VERBOSE" = ".1" ]; then
    local LightCyan="$(tput bold ; tput setaf 6)"
    _LOG_LEVEL=DEBUG log "$LightCyan" "$@"
    _LOG_LEVEL=DEBUG log "$LightCyan" "$@" >&2
    fi
    }
    info()
    @@ -484,6 +482,15 @@ git_workdir_load()
    git reset --soft ORIG_HEAD || die reset to ORIG_HEAD
    git read-tree $index_hash || die "load saved index tree from $index_hash"
    }
    git_workdir_is_clean()
    {
    local untracked="$1"
    if [ "$untracked" == "untracked" ]; then
    [ -z "$(git status --porcelain)" ]
    else
    [ -z "$(git status --porcelain --untracked-files=no)" ]
    fi
    }

    git_copy_commit()
    {
    @@ -540,24 +547,7 @@ git_diff_ln_new()
    }'
    }

    # test:

    # # file to root
    # git reset --hard HEAD
    # git_object_add_by_commit_path a HEAD dist/shlib.sh
    # git status
    # # dir to root
    # git reset --hard HEAD
    # git_object_add_by_commit_path a HEAD dist
    # git status
    # # file to folder
    # git reset --hard HEAD
    # git_object_add_by_commit_path a/b/c HEAD dist/shlib.sh
    # git status
    # # dir to folder
    # git reset --hard HEAD
    # git_object_add_by_commit_path a/b/c HEAD dist
    # git status


    os_detect()
    @@ -626,7 +616,6 @@ fn_match()
    esac
    return 1
    }
    #include 'shlib.sh' end

    autopep8_options='--max-line-length 120'

  3. @drmingdrmer drmingdrmer revised this gist Oct 29, 2018. 1 changed file with 9 additions and 0 deletions.
    9 changes: 9 additions & 0 deletions p8ln
    Original file line number Diff line number Diff line change
    @@ -354,6 +354,10 @@ git_object_add_by_tree_name()
    treeish="$src_treeish"
    else
    treeish=$(git ls-tree "$src_treeish" "$src_name" | awk '{print $3}')

    if [ -z "$treeish" ]; then
    die "source treeish not found: in tree: ($src_treeish) name: ($src_name)"
    fi
    fi

    dd "hash of object to add is: $treeish"
    @@ -469,6 +473,11 @@ git_workdir_load()
    #
    # git-read-index to index and git-reset does not work because deleted file in
    # index does not apply to working tree.
    #
    # But there is an issue with this:
    # git checkout --orphan br
    # git_workdir_load
    # would fails, because ORIG_HEAD is not a commit.

    local working_commit=$(echo "x" | git commit-tree $working_hash) || die get working commit
    git reset --hard $working_commit || die reset to tmp commit
  4. @drmingdrmer drmingdrmer revised this gist Sep 4, 2018. 1 changed file with 36 additions and 1 deletion.
    37 changes: 36 additions & 1 deletion p8ln
    Original file line number Diff line number Diff line change
    @@ -251,7 +251,10 @@ git_branch_default_upstream_ref()
    }
    git_branch_default_upstream()
    {
    git_branch_default_upstream_ref "$@" | sed 's/^refs\/heads\///'
    git rev-parse --abbrev-ref --symbolic-full-name "$1"@{upstream}

    # OR
    # git_branch_default_upstream_ref "$@" | sed 's/^refs\/heads\///'
    }
    git_branch_exist()
    {
    @@ -441,6 +444,38 @@ git_tree_add_blob()
    } | git mktree
    }

    git_workdir_save()
    {
    local index_hash=$(git write-tree)

    # add modified file to index and read index tree
    git add -u
    local working_hash=$(git write-tree)

    # restore index tree
    git read-tree $index_hash

    echo $index_hash $working_hash
    }
    git_workdir_load()
    {
    local index_hash=$1
    local working_hash=$2

    git_object_type $index_hash || die "invalid index hash: $index_hash"
    git_object_type $working_hash || die "invalid workdir hash: $working_hash"

    # First create a temp commit to restore working tree.
    #
    # git-read-index to index and git-reset does not work because deleted file in
    # index does not apply to working tree.

    local working_commit=$(echo "x" | git commit-tree $working_hash) || die get working commit
    git reset --hard $working_commit || die reset to tmp commit
    git reset --soft ORIG_HEAD || die reset to ORIG_HEAD
    git read-tree $index_hash || die "load saved index tree from $index_hash"
    }

    git_copy_commit()
    {
    git_commit_copy "$@"
  5. @drmingdrmer drmingdrmer revised this gist Apr 30, 2018. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions p8ln
    Original file line number Diff line number Diff line change
    @@ -587,7 +587,7 @@ fn_match()
    autopep8_options='--max-line-length 120'

    cmd_reverse=tac
    which -s $cmd_reverse || cmd_reverse="tail -r"
    which $cmd_reverse >/dev/null 2>/dev/null || cmd_reverse="tail -r"

    {
    if [ "$#" -gt 0 ]; then
    @@ -601,7 +601,7 @@ which -s $cmd_reverse || cmd_reverse="tail -r"
    # get changed fn
    git diff --name-only --relative HEAD
    fi
    } | while read fn; do
    } | grep "\.py$" | while read fn; do

    # reverse order, autopep8 may add or remove lines

  6. @drmingdrmer drmingdrmer revised this gist Apr 30, 2018. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions p8ln
    Original file line number Diff line number Diff line change
    @@ -253,6 +253,10 @@ git_branch_default_upstream()
    {
    git_branch_default_upstream_ref "$@" | sed 's/^refs\/heads\///'
    }
    git_branch_exist()
    {
    git_rev_exist "refs/heads/$1"
    }

    git_head_branch()
    {
  7. @drmingdrmer drmingdrmer revised this gist Apr 20, 2018. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions p8ln
    Original file line number Diff line number Diff line change
    @@ -234,6 +234,11 @@ git_working_root()
    git rev-parse --show-toplevel
    }

    git_rev_exist()
    {
    git rev-parse --verify --quiet "$1" >/dev/null
    }

    git_branch_default_remote()
    {
    local branchname=$1
  8. @drmingdrmer drmingdrmer revised this gist Mar 31, 2018. 1 changed file with 16 additions and 5 deletions.
    21 changes: 16 additions & 5 deletions p8ln
    Original file line number Diff line number Diff line change
    @@ -336,7 +336,13 @@ git_object_add_by_tree_name()

    local target_dir="$(dirname $target_path)/"
    local target_fn="$(basename $target_path)"
    local treeish=$(git ls-tree "$src_treeish" "$src_name" | awk '{print $3}')
    local treeish

    if [ -z "$src_name" ] || [ "$src_name" = "." ] || [ "$src_name" = "./" ]; then
    treeish="$src_treeish"
    else
    treeish=$(git ls-tree "$src_treeish" "$src_name" | awk '{print $3}')
    fi

    dd "hash of object to add is: $treeish"

    @@ -364,15 +370,20 @@ git_object_add_by_tree_name()
    dd "target_path set to: $target_path"
    else
    dd "object to add is tree"

    treeish=$(git ls-tree "$src_treeish" "$src_name" | awk '{print $3}')
    dd "updated treeish: $treeish"
    fi

    git_treeish_add_to_prefix "$target_path" "$treeish"
    }

    git_treeish_add_to_prefix()
    {
    local target_path="$1"
    local treeish="$2"

    dd treeish content:
    git ls-tree $treeish

    git rm "$target_path" -r --cached || die removing target "$target_path"
    git rm "$target_path" -r --cached || dd removing target "$target_path"

    if [ "$target_path" = "./" ]; then
    git read-tree "$treeish" \
  9. @drmingdrmer drmingdrmer revised this gist Mar 26, 2018. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions p8ln
    Original file line number Diff line number Diff line change
    @@ -372,6 +372,8 @@ git_object_add_by_tree_name()
    dd treeish content:
    git ls-tree $treeish

    git rm "$target_path" -r --cached || die removing target "$target_path"

    if [ "$target_path" = "./" ]; then
    git read-tree "$treeish" \
    || die "read-tree $target_path $treeish"
  10. @drmingdrmer drmingdrmer revised this gist Feb 14, 2018. 1 changed file with 128 additions and 1 deletion.
    129 changes: 128 additions & 1 deletion p8ln
    Original file line number Diff line number Diff line change
    @@ -304,12 +304,120 @@ git_commit_copy()
    ) || die "Can't copy commit $1"
    }

    git_objetct_type()
    git_object_type()
    {
    # $0 ref|hash
    # output "commit", "tree" etc
    git cat-file -t "$@" 2>/dev/null
    }
    git_object_add_by_commit_path()
    {
    # add an blob or tree object to target_path in index
    # the object to add is specified by commit and path
    local target_path="$1"
    local src_commit="$2"
    local src_path="$3"

    local src_dir="$(dirname "$src_path")/"
    local src_name="$(basename "$src_path")"
    local src_treeish="$(git rev-parse "$src_commit:$src_dir")"

    git_object_add_by_tree_name "$target_path" "$src_treeish" "$src_name"

    }
    git_object_add_by_tree_name()
    {
    # add an blob or tree object to target_path in index
    local target_path="$1"
    local src_treeish="$2"
    local src_name="$3"

    dd "arg: target_path: ($target_path) src_treeish: ($src_treeish) src_name: ($src_name)"

    local target_dir="$(dirname $target_path)/"
    local target_fn="$(basename $target_path)"
    local treeish=$(git ls-tree "$src_treeish" "$src_name" | awk '{print $3}')

    dd "hash of object to add is: $treeish"

    if [ "$(git_object_type $treeish)" = "blob" ]; then
    # the treeish imported is a file, not a dir
    # first create a wrapper tree or replace its containing tree

    dd "object to add is blob"

    local dir_treeish
    local target_dir_treeish="$(git rev-parse "HEAD:$target_dir")"
    if [ -n "target_dir_treeish" ]; then
    dir_treeish="$(git rev-parse "HEAD:$target_dir")"
    dd "target dir presents: $target_dir"

    else
    dd "target dir absent"
    dir_treeish=""
    fi

    treeish=$(git_tree_add_blob "$dir_treeish" "$target_fn" $src_treeish $src_name) || die create wrapper treeish
    target_path="$target_dir"

    dd "wrapper treeish: $treeish"
    dd "target_path set to: $target_path"
    else
    dd "object to add is tree"

    treeish=$(git ls-tree "$src_treeish" "$src_name" | awk '{print $3}')
    dd "updated treeish: $treeish"
    fi

    dd treeish content:
    git ls-tree $treeish

    if [ "$target_path" = "./" ]; then
    git read-tree "$treeish" \
    || die "read-tree $target_path $treeish"
    else
    git read-tree --prefix="$target_path" "$treeish" \
    || die "read-tree $target_path $treeish"
    fi
    }

    git_tree_add_tree()
    {
    # output new tree hash in stdout
    # treeish can be empty
    local treeish="$1"
    local target_fn="$2"
    local item_hash="$3"
    local item_name="$4"

    {
    if [ -n "$treeish" ]; then
    git ls-tree "$treeish" \
    | fgrep -v " $item_name"
    fi

    cat "040000 tree $item_hash $target_fn"
    } | git mktree
    }
    git_tree_add_blob()
    {
    # output new tree hash in stdout
    # treeish can be empty
    local treeish="$1"
    local target_fn="$2"
    local blob_treeish="$3"
    local blob_name="$4"

    {
    if [ -n "$treeish" ]; then
    git ls-tree "$treeish" \
    | fgrep -v " $target_fn"
    fi

    git ls-tree "$blob_treeish" "$blob_name" \
    | awk -v target_fn="$target_fn" -F" " '{print $1" "target_fn}'
    } | git mktree
    }

    git_copy_commit()
    {
    @@ -366,6 +474,25 @@ git_diff_ln_new()
    }'
    }

    # test:

    # # file to root
    # git reset --hard HEAD
    # git_object_add_by_commit_path a HEAD dist/shlib.sh
    # git status
    # # dir to root
    # git reset --hard HEAD
    # git_object_add_by_commit_path a HEAD dist
    # git status
    # # file to folder
    # git reset --hard HEAD
    # git_object_add_by_commit_path a/b/c HEAD dist/shlib.sh
    # git status
    # # dir to folder
    # git reset --hard HEAD
    # git_object_add_by_commit_path a/b/c HEAD dist
    # git status


    os_detect()
    {
  11. @drmingdrmer drmingdrmer revised this gist Sep 27, 2017. 1 changed file with 24 additions and 0 deletions.
    24 changes: 24 additions & 0 deletions p8ln
    Original file line number Diff line number Diff line change
    @@ -254,6 +254,30 @@ git_head_branch()
    git symbolic-ref --short HEAD
    }

    git_commit_date()
    {

    # git_commit_date author|commit <ref> [date-format]

    # by default output author-date
    local what_date="%ad"
    if [ "$1" = "commit" ]; then
    # commit date instead of author date
    what_date="%cd"
    fi
    shift

    local ref=$1
    shift

    local fmt="%Y-%m-%d %H:%M:%S"
    if [ "$#" -gt 0 ]; then
    fmt="$1"
    fi
    shift

    git log -n1 --format="$what_date" --date=format:"$fmt" "$ref"
    }
    git_commit_copy()
    {
    # We're going to set some environment vars here, so
  12. @drmingdrmer drmingdrmer revised this gist Aug 23, 2017. 1 changed file with 0 additions and 0 deletions.
    Empty file modified p8ln
    100644 → 100755
    Empty file.
  13. @drmingdrmer drmingdrmer created this gist Aug 23, 2017.
    444 changes: 444 additions & 0 deletions p8ln
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,444 @@
    #!/bin/sh

    # Format python source codes with autopep8 on changed lines.
    #
    # Usage:
    # format all uncommitted lines:
    # > p8ln
    #
    # format file:
    # > p8ln a.py b.py
    #
    # ---
    # # Explaination:
    #
    # # show all changed file names:
    # git diff --name-only --relative HEAD
    #
    # And a helper script `git-changed-ln` outputs changed line numbers,
    # by diff work-tree(unstaged) with HEAD,
    # or by diff index(staged or cached) with HEAD.

    #include 'shlib.sh' begin
    #!/bin/sh


    shlib_init_colors()
    {
    Black="$( tput setaf 0)"
    BlackBG="$( tput setab 0)"
    DarkGrey="$( tput bold; tput setaf 0)"
    LightGrey="$( tput setaf 7)"
    LightGreyBG="$( tput setab 7)"
    White="$( tput bold; tput setaf 7)"
    Red="$( tput setaf 1)"
    RedBG="$( tput setab 1)"
    LightRed="$( tput bold; tput setaf 1)"
    Green="$( tput setaf 2)"
    GreenBG="$( tput setab 2)"
    LightGreen="$( tput bold; tput setaf 2)"
    Brown="$( tput setaf 3)"
    BrownBG="$( tput setab 3)"
    Yellow="$( tput bold; tput setaf 3)"
    Blue="$( tput setaf 4)"
    BlueBG="$( tput setab 4)"
    LightBlue="$( tput bold; tput setaf 4)"
    Purple="$( tput setaf 5)"
    PurpleBG="$( tput setab 5)"
    Pink="$( tput bold; tput setaf 5)"
    Cyan="$( tput setaf 6)"
    CyanBG="$( tput setab 6)"
    LightCyan="$( tput bold; tput setaf 6)"
    NC="$( tput sgr0)" # No Color
    }

    screen_width()
    {
    local chr="${1--}"
    chr="${chr:0:1}"

    local width=$(tput cols 2||echo 80)
    width="${COLUMNS:-$width}"

    echo $width
    }

    hr()
    {
    # generate a full screen width horizontal ruler
    local width=$(screen_width)

    printf -vl "%${width}s\n" && echo ${l// /$chr};
    }

    remove_color()
    {
    # remove color control chars from stdin or first argument

    local sed=gsed
    which -s $sed || sed=sed

    local s="$1"
    if [ -z "$s" ]; then
    $sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g"
    else
    echo "$s" | remove_color
    fi

    }

    text_hr()
    {
    # generate a full screen width sperator line with text.
    # text_hr "-" "a title"
    # > a title -----------------------------------------
    #
    # variable LR=l|m|r controls alignment

    local chr="$1"
    shift

    local bb="$(echo "$@" | remove_color)"
    local text_len=${#bb}

    local width=$(screen_width)
    let width=width-text_len

    local lr=${LR-m}
    case $lr in
    m)
    let left=width/2
    let right=width-left
    echo "$(printf -vl "%${left}s\n" && echo ${l// /$chr})$@$(printf -vl "%${right}s\n" && echo ${l// /$chr})"
    ;;
    r)

    echo "$(printf -vl "%${width}s\n" && echo ${l// /$chr})$@"
    ;;
    *)
    # l by default
    echo "$@$(printf -vl "%${width}s\n" && echo ${l// /$chr})"
    ;;
    esac

    }



    SHLIB_LOG_VERBOSE=1
    SHLIB_LOG_FORMAT='[$(date +"%Y-%m-%d %H:%M:%S")] $level $title $mes'

    die()
    {
    err "$@" >&2
    exit 1
    }
    die_empty()
    {
    if test -z "$1"
    then
    shift
    die empty: "$@"
    fi
    }

    set_verbose()
    {
    SHLIB_LOG_VERBOSE=${1-1}
    }

    log()
    {
    local color="$1"
    local title="$2"
    local level="$_LOG_LEVEL"
    shift
    shift

    local mes="$@"
    local NC="$(tput sgr0)"

    if [ -t 1 ]; then
    title="${color}${title}${NC}"
    level="${color}${level}${NC}"
    fi
    eval "echo \"$SHLIB_LOG_FORMAT\""
    }
    dd()
    {
    debug "$@"
    }
    debug()
    {
    if [ ".$SHLIB_LOG_VERBOSE" = ".1" ]; then
    local LightCyan="$(tput bold ; tput setaf 6)"
    _LOG_LEVEL=DEBUG log "$LightCyan" "$@"
    fi
    }
    info()
    {
    local Brown="$(tput setaf 3)"
    _LOG_LEVEL=" INFO" log "$Brown" "$@"
    }
    ok() {
    local Green="$(tput setaf 2)"
    _LOG_LEVEL=" OK" log "${Green}" "$@"
    }
    err() {
    local Red="$(tput setaf 1)"
    _LOG_LEVEL="ERROR" log "${Red}" "$@"
    }

    git_hash()
    {
    git rev-parse $1 \
    || die "'git_hash $@'"
    }
    git_is_merge()
    {
    test $(git cat-file -p "$1" | grep "^parent " | wc -l) -gt 1
    }
    git_parents()
    {
    git rev-list --parents -n 1 ${1-HEAD} | { read self parents; echo $parents; }
    }
    git_rev_list()
    {
    # --parents
    # print parent in this form:
    # <commit> <parent-1> <parent-2> ..

    git rev-list \
    --reverse \
    --topo-order \
    --default HEAD \
    --simplify-merges \
    "$@" \
    || die "'git rev-list $@'"
    }
    git_tree_hash()
    {
    git rev-parse "$1^{tree}"
    }
    git_ver()
    {
    local git_version=$(git --version | awk '{print $NF}')
    local git_version_1=${git_version%%.*}
    local git_version_2=${git_version#*.}
    git_version_2=${git_version_2%%.*}

    printf "%03d%03d" $git_version_1 $git_version_2
    }
    git_working_root()
    {
    git rev-parse --show-toplevel
    }

    git_branch_default_remote()
    {
    local branchname=$1
    git config --get branch.${branchname}.remote
    }
    git_branch_default_upstream_ref()
    {
    local branchname=$1
    git config --get branch.${branchname}.merge
    }
    git_branch_default_upstream()
    {
    git_branch_default_upstream_ref "$@" | sed 's/^refs\/heads\///'
    }

    git_head_branch()
    {
    git symbolic-ref --short HEAD
    }

    git_commit_copy()
    {
    # We're going to set some environment vars here, so
    # do it in a subshell to get rid of them safely later
    dd copy_commit "{$1}" "{$2}" "{$3}"
    git log -1 --pretty=format:'%an%n%ae%n%ad%n%cn%n%ce%n%cd%n%s%n%n%b' "$1" |
    (
    read GIT_AUTHOR_NAME
    read GIT_AUTHOR_EMAIL
    read GIT_AUTHOR_DATE
    read GIT_COMMITTER_NAME
    read GIT_COMMITTER_EMAIL
    read GIT_COMMITTER_DATE
    export GIT_AUTHOR_NAME \
    GIT_AUTHOR_EMAIL \
    GIT_AUTHOR_DATE \
    GIT_COMMITTER_NAME \
    GIT_COMMITTER_EMAIL \
    GIT_COMMITTER_DATE

    # (echo -n "$annotate"; cat ) |

    git commit-tree "$2" $3 # reads the rest of stdin
    ) || die "Can't copy commit $1"
    }

    git_objetct_type()
    {
    # $0 ref|hash
    # output "commit", "tree" etc
    git cat-file -t "$@" 2>/dev/null
    }

    git_copy_commit()
    {
    git_commit_copy "$@"
    }

    git_diff_ln_new()
    {
    # output changed line number of a file: <from> <end>; inclusive:
    # 27 28
    # 307 309
    # 350 350
    #
    # Usage:
    #
    # diff working tree with HEAD:
    # git_diff_ln_new HEAD -- <fn>
    #
    # diff working tree with staged:
    # git_diff_ln_new -- <fn>
    #
    # diff staged(cached) with HEAD:
    # git_diff_ln_new --cached -- <fn>
    #
    # in git-diff output:
    # for add lines:
    # @@ -53 +72,8
    #
    # for remove lines:
    # @@ -155 +179,0

    git diff -U0 "$@" \
    | grep '^@@' \
    | awk '{
    # @@ -155 +179,0
    # $1 $2 $3
    l = $3
    gsub("^+", "", l)
    # add default offset: ",1"
    split(l",1", x, ",")
    # inclusive line range:
    x[2] = x[1] + x[2] - 1
    # line remove format: @@ -155, +179,0
    # do need to output line range for removed.
    if (x[2] >= x[1]) {
    print x[1] " " x[2]
    }
    }'
    }


    os_detect()
    {
    local os
    case $(uname -s) in
    Linux)
    os=linux ;;
    *[bB][sS][dD])
    os=bsd ;;
    Darwin)
    os=mac ;;
    *)
    os=unix ;;
    esac
    echo $os
    }

    mac_ac_power_connection()
    {
    # Connected: (Yes|No)
    system_profiler SPPowerDataType \
    | sed '1,/^ *AC Charger Information:/d' \
    | grep Connected:
    }


    mac_power()
    {

    # $0 is-battery exit code 0 if using battery.
    # $0 is-ac-power exit code 0 if using ac power.

    local cmd="$1"
    local os=$(os_detect)

    if [ "$os" != "mac" ]; then
    err "not mac but: $os"
    return 1
    fi

    case $cmd in

    is-battery)
    mac_ac_power_connection | grep -q No
    ;;

    is-ac-power)
    mac_ac_power_connection | grep -q Yes
    ;;

    *)
    err "invalid cmd: $cmd"
    return 1
    ;;
    esac
    }

    fn_match()
    {
    # $0 a.txt *.txt
    case "$1" in
    $2)
    return 0
    ;;
    esac
    return 1
    }
    #include 'shlib.sh' end

    autopep8_options='--max-line-length 120'

    cmd_reverse=tac
    which -s $cmd_reverse || cmd_reverse="tail -r"

    {
    if [ "$#" -gt 0 ]; then
    # fns specified by command line args
    while [ "$#" -gt 0 ]; do
    echo "$1"
    shift
    done
    else
    # find fns by diff
    # get changed fn
    git diff --name-only --relative HEAD
    fi
    } | while read fn; do

    # reverse order, autopep8 may add or remove lines

    echo formating "$fn" ...
    git_diff_ln_new HEAD -- "$fn"

    git_diff_ln_new HEAD -- "$fn" \
    | $cmd_reverse \
    | while read f t; do
    autopep8 $autopep8_options -i --line-range $f $t "$fn"
    done
    done