Skip to content
Koichi Murase edited this page Feb 25, 2024 · 17 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. This can be fixed by setting the option bleopt edit_magic_accept:

# blerc

bleopt edit_magic_accept=sabbrev:verify-syntax

Or one can instead design a widget to make Enter do an implicit sabbrev expansion:

# blerc

function ble/widget/my/magic-space-auto-appender {
  _ble_edit_ind=${#_ble_edit_str} ble/widget/sabbrev-expand; local ext=$?
  ((_ble_edit_ind>${#_ble_edit_str})) && _ble_edit_ind=${#_ble_edit_str}
  ((ext==0)) && ble/widget/"$@"
}

# Assuming you were using the default bindings for C-m or RET 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_imap' -f 'RET' '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'
ble-bind -m 'vi_nmap' -f 'RET' 'my/magic-space-auto-appender accept-single-line-or vi-command/forward-first-non-space'

[ 日本語 | English ]