Skip to content
bkerin edited this page Feb 14, 2024 · 19 revisions

[ 日本語 | English ]

R1. Insert date through sabbrev \date

# blerc

function blerc/define-sabbrev-date {
  ble-sabbrev -m '\date'='ble/util/assign COMPREPLY "date +%F"'
}
blehook/eval-after-load complete blerc/define-sabbrev-date

sabbrev \date

R2. Insert git branch name from menu through sabbrev \branch

# blerc

function blerc/define-sabbrev-branch {
  function blerc/sabbrev-git-branch {
    ble/util/assign-array COMPREPLY "git branch | sed 's/^\*\{0,1\}[[:space:]]*//'" 2>/dev/null
  }
  ble-sabbrev -m '\branch'=blerc/sabbrev-git-branch
}
blehook/eval-after-load complete blerc/define-sabbrev-branch

sabbrev \date

R3. Insert git commit ID from menu through sabbrev \commit

# blerc

function blerc/define-sabbrev-commit {
  ble/color/defface blerc_git_commit_id fg=navy
  ble/complete/action#inherit-from blerc_git_commit_id word
  function ble/complete/action:blerc_git_commit_id/init-menu-item {
    local ret
    ble/color/face2g blerc_git_commit_id; g=$ret
  }
  function blerc/sabbrev-git-commit {
    bleopt sabbrev_menu_style=desc-raw
    bleopt sabbrev_menu_opts=enter_menu

    local format=$'%h \e[1;32m(%ar)\e[m %s - \e[4m%an\e[m\e[1;33m%d\e[m'
    local arr; ble/util/assign-array arr 'git log --pretty=format:"$format"' &>/dev/null
    local line hash subject
    for line in "${arr[@]}"; do
      builtin read hash subject <<< "$line"
      ble/complete/cand/yield blerc_git_commit_id "$hash" "$subject"
    done
  }
  ble-sabbrev -m '\commit'='blerc/sabbrev-git-commit'
}
blehook/eval-after-load complete blerc/define-sabbrev-commit

sabbrev \date

R4. Show current working directory and git branch in right prompt

# blerc

_blerc_prompt_git_vars=(git_base)

function blerc/prompt/git/initialize {
  type git &>/dev/null || return 1
  local path=$PWD
  while
    if [[ -f $path/.git/HEAD ]]; then
      git_base=$path
      return 0
    fi
    [[ $path == */* ]]
  do path=${path%/*}; done
  return 1
}
function blerc/prompt/git/get-head-information {
  branch= hash=

  local head_file=$git_base/.git/HEAD
  [[ -s $head_file ]] || return 1
  local content; ble/util/mapfile content < "$head_file"

  if [[ $content == *'ref: refs/heads/'* ]]; then
    branch=${content#*refs/heads/}

    local branch_file=$git_base/.git/refs/heads/$branch
    [[ -s $branch_file ]] || return 1
    local content; ble/util/mapfile content < "$branch_file"
  fi

  [[ ! ${content//[0-9a-fA-F]} ]] && hash=$content
  return 0
}
function blerc/prompt/git/get-tag-name {
  tag=
  local hash=$1; [[ $hash ]] || return 1

  local file tagsdir=$git_base/.git/refs/tags hash1
  local files ret; ble/util/eval-pathname-expansion '"$tagsdir"/*'; files=("${ret[@]}")
  for file in "${files[@]}"; do
    local tag1=${file#$tagsdir/}
    [[ -s $file ]] || continue
    ble/util/mapfile hash1 < "$file"
    if [[ $hash1 == "$hash" ]]; then
      tag=$tag1
      return 0
    fi
  done
}
function blerc/prompt/git/describe-head {
  ret=

  local hash branch
  blerc/prompt/git/get-head-information
  if [[ $branch ]]; then
    local sgr=$'\e[1;34m' sgr0=$'\e[m'
    ret=$sgr$branch$sgr0
    [[ $hash ]] && ret="$ret (${hash::7})"
    return 0
  fi

  local DETACHED=$'\e[91mDETACHED\e[m'

  local tag
  blerc/prompt/git/get-tag-name "$hash"
  if [[ $tag ]]; then
    local sgr=$'\e[1;32m' sgr0=$'\e[m'
    ret=$sgr$tag$sgr0
    [[ $hash ]] && ret="$ret ${hash::7}"
    ret="$DETACHED ($ret)"
    return 0
  fi

  if [[ $hash ]]; then
    ret="$DETACHED (${hash::7})"
    return 0
  fi

  ret=$'\e[91mUNKNOWN\e[m'
}

function ble/prompt/backslash:X {
  local "${_blerc_prompt_git_vars[@]/%/=}"
  if blerc/prompt/git/initialize; then
    local sgr=$'\e[1m' sgr0=$'\e[m'
    local name=$sgr${git_base##*?/}$sgr0
    local ret; blerc/prompt/git/describe-head; local branch=$ret
    ble/prompt/print "$name $branch"
    [[ $PWD == "$git_base"/?* ]] &&
      ble/prompt/print " /${PWD#$git_base/}"
  else
    ble/prompt/process-prompt-string '\w'
  fi

  return 0
}
bleopt prompt_rps1='\X'
#bleopt prompt_rps1_transient=1

rps1

R5. Expand sabbev via automatic magic-space on Enter

The sabbrev feature is nice compared to aliases or functions for setting up default command line options for programs, because it prevents the aggravation of forgetting what you've done and allows completion that's sensitive to context earlier in the command to work without additional effort. Unfortunately in the case where the abbreviation comes at the end of the line it doesn't get expanded. Assuming you have the default bleopt edit_magic_expand=history:sabbrev setting this can be fixed by making Enter do an implicit magic-space:

FIXME: this leaves the space on the line and probably ignores some option about where the cursor is supposed to end up in the history, it could certainly be done better by looking into what magic-space does rather than wrapping it.

# blerc

function ble/widget/my/magic-space-auto-appender {
  local my_oei=${_ble_edit_ind}   # Old Edit Index
  _ble_edit_ind=${#_ble_edit_str}
  ble/widget/magic-space
  _ble_edit_ind=$my_oei
  "${@/#/ble/widget/}"
}

# Assuming you were using the default bindings for C-m at the start:
ble-bind -m 'vi_imap' -f 'C-m' 'my/magic-space-auto-appender accept-single-line-or-newline'
ble-bind -m 'vi_nmap' -f 'C-m' 'my/magic-space-auto-appender accept-single-line-or vi-command/forward-first-non-space'

[ 日本語 | English ]