Skip to content

Custom Scripts

Kevin Zhuang edited this page Jul 10, 2020 · 5 revisions

dotbare may not contains all the functionalities of everyone's need as they were initially created based on my personal needs. Feel free to open feature request in issues or alternatively you could create your own custom scripts.

dotbare essentially is just a collection of scripts that query the information from git and perform corresponding actions, the role for the main dotbare executable is like "router" which routes commands to either a script under the "scripts" folder or to git and perform git actions. With this architecture, you could easily define your custom scripts under the scripts folder in dotbare. The .gitignore are configured to ignore everything except the scripts used by dotbare default, hence you can name your scripts any name you want. You can then track these scripts using dotbare to ensure the scripts are available in all of your machines. Feel free to open pull request for your script, I'm happy to review and discuss for merging.

Setup

Note: Your script will probably need to be written in bash because all helper functions are designed to use with bash.

You should always include the lines below at the top of your script. mydir is the PATH of the script directory, and the source function is used to set all the relevant env variables like DOTBARE_DIR, DOTBARE_TREE.

#!/usr/bin/env bash

mydir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "${mydir}"/../helper/set_variable.sh

API

git_query.sh

All of the git information displayed by dotbare in fzf are from helper functions in the git_query.sh file. To use them, simply source the file.

source "${mydir}"/../helper/git_query.sh

get_commit

List all commits through fzf while providing commit information in the fzf preview window. The selected commit hash will be returned.

Arguments:

  • $1: the helper message to display in the fzf header, optional

Outputs: The selected commit 7 char hash (e.g. b60b330)

selected_commit=$(get_commit "select a commit to foo boo")

get_branch

List all branch through fzf while providing git log information on the branch in the fzf preview window. The selected branch name will be returned.

Arguments:

  • $1: the helper message to display in the fzf header, optional

Outputs: the name of the selected branch (e.g. master)

selected_branch=$(get_branch 'select a branch to checkout')

get_git_file

List all tracked dotfiles through fzf and providing a preview of the file. The selected file path will be returned.

Arguments:

  • $1: the helper message to display in the fzf header, optional
  • $2: print option. Controls how to print the return value. Possible values: full|raw, optional
    • full will print the full path of the selected file, raw will just print the file displayed in fzf
    • default to full path being printed
  • $3: determine if fzf should support multi select, if not present, perform multi select, optional

Outputs: the selected file path, depending of $2, print full path or raw path displayed on fzf

selected_files=$(get_git_file "select files to backup" "raw")

get_modified_file

List all modified files through fzf and providing a preview of the changes made to the file in the fzf preview window. The selected file path will be returned.

Arguments:

  • $1: the helper message to display in the fzf header, optional
  • $2: display mode of modified file. Default: all
    • all: display all modified files, including stagged and unstaged files
    • staged: only display staged files
    • unstaged: only display unstaged files
  • $3: output format, Default: name
    • name: formatted name of the file
    • raw: raw file name with status e.g. M file1.txt
  • $4: determine if fzf should support multi select. If not present, perform multi select

Outputs: selected file path, depending on $3, either with status or not.

selected_files=()
while IFS= read -r line: do
  selected_files+=("${line}")
done < <(get_modified_file "select files to stage" "unstaged" "name")

get_stash

List all stash and display the stash diff against HEAD in the fzf preview window. The selected stash identifier will be returned.

Arguments:

  • $1: the helper message to display in the fzf header, optional
  • $2: determine if fzf should support multi select. If not present, perform multi select

Outputs: selected stash identifier. e.g. stash@{0}

selected_stash=$(get_stash "select stash to delete")

search_file.sh

dotbare by default comes with a very simple search function which will search under current directory by 1 level of depth. I didn't want to add extra dependencies (fd, rg or ag) to dotbare so the search_file function is quite limited, you'll need to define your own custom search if you wish to have a extended functionality in your custom scripts.

source "${mydir}"/../helper/search_file.sh

Arguments:

  • $1: indicate searching file or directory.
    • f: search file
    • d: search directory

Outputs: the selected file path

selected_files=()
while IFS= read -r line; do
  selected_files+=("${line}")
done < <(search_file 'f')

preview.sh

In v1.2.1, dotbare introduced a flexible preview script (modified version of fzf.vim preview script) to display files with syntax highlighting when appropriate package is installed (bat, highlight etc). This is a executable script, hence it shouldn't be sourced, rather it should be invoked in the preview argument of fzf.

Arguments:

  • $1: The filename and line info to be previed
    • Format: filepath[:lineno][:ignored] (e.g. .bashrc or .bashrc:10 to highlight the 10th line)
mydir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
find . -maxdepth 1 -type f | sed "s|\./||g" | fzf --multi --preview "${mydir}/preview.sh {}"

Full example

This example is very arbitrary..as really all my needs are covered when I'm developing dotbare. Maybe a good feature request sometime in the future would be worth to put as an example here.

Let's say for example you want to delete a dotbare branch through fzf, but dotbare doesn't provide that functionality with "f" scripts. Of course, you could just do dotbare branch -D [branch name], but let's just say you want to do it through fzf to select the branch.

#!/usr/bin/env bash

mydir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
source "${mydir}"/../helper/set_variable.sh
source "${mydir}"/../helper/git_query.sh

selected_branch=$(get_branch 'select a branch to delete')

[[ -z "${selected_branch}" ]] && exit 1

remote_branch_regex="^remotes\/.*$"

if [[ "${selected_branch}" =~ $remote_branch_regex ]]; then
  read -r remote_name origin_name branch_name <<< $(
    echo "${selected_branch}" \
      | awk -F "/" '{
          remote=$1
          origin=$2
          sub($1 FS $2 FS, "")
          print remote " " origin " " $0
        }'
  )
  git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" push -d "${origin_name}" "${branch_name}"
else
  git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" branch -D "${selected_branch}"
fi
Clone this wiki locally