mostly improvements
authorIan Kelling <ian@iankelling.org>
Thu, 20 Nov 2025 08:02:00 +0000 (03:02 -0500)
committerIan Kelling <ian@iankelling.org>
Thu, 20 Nov 2025 08:02:00 +0000 (03:02 -0500)
.dataprinter
.gitconfig
brc
brc2
filesystem/usr/local/bin/bk-backup
filesystem/usr/local/bin/btrbk-run
filesystem/usr/local/bin/i3-mouse-warp
filesystem/usr/local/bin/mailbindwatchdog
machine_specific/vps/filesystem/etc/bind/named.conf.local
mailtest-check
subdir_files/.config/dunst/dunstrc

index bec4a8b94132c48ab355b31f5f79b900edd36772..dbcdd1442904e721a9b19bc033d7d2560722cc7b 100644 (file)
@@ -17,13 +17,6 @@ show_reftype = 1
 # recommended by the manual.
 filters = DateTime
 
-# copied docs of use_prototypes:
-# p { foo => 1 };   # works, but now p(@foo) will fail, you must always pass a ref,
-# e.g. p(\@foo)
-# end docs. Looking in the source code,
-# we don't need reference for single arguments. But
-# beware that lists automatically become multiple arguments.
-use_prototypes = 0
 
 caller_info = 1
 
@@ -33,7 +26,19 @@ caller_message = __FILENAME__:__LINE__
 
 scalar_quotes = '
 
-string_max = 400000
+string_max = 250
 array_max = 400
 hash_max = 400
-string_overflow = (.IANK-DDP.. __SKIPPED__ chars...)
+string_overflow = (.DDP.. __SKIPPED__ chars...)
+
+### settings I thought better of.
+# allows a few less characters for anonymous references & avoids some
+#possibility of autovivification. However, it makes everything passed to
+#p needing to be a reference, which is a huge pain when debugging.
+#use_prototypes = 0
+
+## copied examples of how to print anonymous references:
+# p %{{ foo => 1 }};    # right
+# p { foo => 1 }->%*;   # right on perl 5.24+
+# &p( { foo => 1 } );   # right, but requires the parenthesis
+# sub pp { p @_ };      # wrapping it also lets you use anonymous data. iank: but it prints extra ugly symbols.
index 8cfe86b1869c47a7d0b89b8d3dc37b7382ca7148..9d45ab5b2de8070039758fc09388f6b00ae8ed5a 100644 (file)
@@ -3,12 +3,12 @@ name = Ian Kelling
 email = iank@fsf.org
 #email = ian@iankelling.org
 [alias]
-lg = log --graph
-lgstat = log --stat --graph --pretty=format:'%h %ad- %s [%an]'
+lg = log --graph --follow
+lgstat = log --stat --graph --follow --pretty=format:'%h %ad- %s [%an]'
 co = checkout
 s = status
 ci = commit
-lol = log --graph --pretty=oneline --abbrev-commit --all
+lol = log --graph --follow --pretty=oneline --abbrev-commit --all
 dt = difftool
 # https://stackoverflow.com/questions/17369254/is-there-a-way-to-cause-git-reflog-to-show-a-date-alongside-each-entry
 rl = reflog --format='%C(auto)%h %<|(17)%gd %C(blue)%ci%C(reset) %s'
@@ -33,8 +33,8 @@ tool = meld
 # on git pull of coreboot:
 # warning: inexact rename detection was skipped due to too many files.
 # warning: you may want to set your diff.renameLimit variable to at least 3694 and retry the command.
-renameLimit = 50000
-renames = copy
+renameLimit = 999999
+       renames = true
 
 [gitreview]
 username = iank
@@ -88,3 +88,6 @@ default = simple
 # https://stackoverflow.com/questions/70663523/the-unauthenticated-git-protocol-on-port-9418-is-no-longer-supported
 [url "https://github.com/"]
        insteadOf = git://github.com/
+[merge]
+       renames = true
+       renameLimit = 999999
diff --git a/brc b/brc
index 2fe28800b71bee297ff329e7fced3a7ac3a34ec1..7ef25cb8801490e08c10cf3081af09d229c04689 100644 (file)
--- a/brc
+++ b/brc
@@ -84,13 +84,6 @@ export GLOBIGNORE="*/.:*/.."
 
 
 
-PATH="/home/iank/perl5/bin${PATH:+:${PATH}}"; export PATH;
-PERL5LIB="/home/iank/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB;
-PERL_LOCAL_LIB_ROOT="/home/iank/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT;
-PERL_MB_OPT="--install_base \"/home/iank/perl5\""; export PERL_MB_OPT;
-PERL_MM_OPT="INSTALL_BASE=/home/iank/perl5"; export PERL_MM_OPT;
-
-
 # Useful info. see man bash.
 PS4='$LINENO+ '
 
@@ -356,21 +349,7 @@ mysrc /a/bin/small-misc-bash/ll-function
 mysrc /a/bin/distro-functions/src/package-manager-abstractions
 mysrc /a/bin/fai/fai/config/distro-install-common/bash-misc-funcs
 
-# things to remember:
-# ALT-C - cd into the selected directory
-# CTRL-T - Paste the selected file path into the command line
-#
-# good guide to some of its basic features is the readme file
-# https://github.com/junegunn/fzf
-
-# if [[ -s /usr/share/doc/fzf/examples/key-bindings.bash ]]; then
-#   source /usr/share/doc/fzf/examples/key-bindings.bash
-# fi
 
-# this looks more interesting for more easily selecting multiple files:
-# https://github.com/peco/peco?tab=readme-ov-file#keymaps
-# This also looks like it could be customized more than fzf:
-# https://github.com/lotabout/skim
 
 # * aliases
 
@@ -1312,8 +1291,23 @@ ccomp bg d
 z() { builtin fg "$@"; }
 ccomp fg z
 
-# quick kill.
-x() { builtin kill %%; }
+# kill just the "current" job.
+k1() { builtin kill %%; }
+
+# gracefully kill all jobs
+x() {
+  local -a arr jspecs
+  local l
+  mapfile -t arr <<<$(jobs)
+  for l in "${arr[@]}"; do
+    [[ ${l:1:1} == [0-9] ]] || continue
+    l="${l:1}"
+    jspecs+=(%${l%%[^0-9]*})
+  done
+  (( ${#jspecs[@]} )) || return 1
+  m kill -INT ${jspecs[@]}
+}
+
 
 # diff content, aka word diff.
 dc() {
@@ -1427,17 +1421,36 @@ ea() {
 
 # echo args verbosely
 eav() {
+  local arg
+  local -i i=0
+  if (( ! $# )); then
+    echo no args
+  fi
+  for arg; do
+    printf "%d '%q'\n" "$i" "${arg}"
+    i+=1
+  done
+}
+
+# echo args double verbose: adds hexdump.
+eavv() {
+  local arg
+  local -i i=0
   if (( ! $# )); then
     echo no args
   fi
   for arg; do
-    printf "%qEOL\n" "${arg}"
+    printf "%d '%q'\n" "$i" "${arg}"
     printf "%s" "${arg}" |& hexdump -C
+    i+=1
   done
 }
 
+
 # echo variables. print var including escapes, etc, like xxd for variable
 ev() {
+  local arg
+  local -i i=0
   if (( ! $# )); then
     echo no args
   fi
@@ -2985,7 +2998,7 @@ shellcheck-except() {
   shellcheck -e $quotes,$others "$@" || return $?
 }
 # wrapper for shellcheck with better defaults.
-sk() {
+shk() {
   # see https://savannah.gnu.org/maintenance/fsf/bash-style-guide/ for justifications
   local quotes others
   local -i ret=0
@@ -3691,9 +3704,22 @@ lswc() {
   # shellcheck disable=SC2790 disable=SC2012 # intentional
   ls -Uq "$@"|wc -l
 }
+### rename, remove earlier name after migration.
+lc() {
+  # shellcheck disable=SC2790 disable=SC2012 # intentional
+  ls -Uq "$@"|wc -l
+}
 # count files recursively
 fndwc() {
-  find -L "$@" -type f -printf a | wc -c
+  local -i total count
+  for d; do
+    count=$(find -L "$d" -type f -printf a | wc -c)
+    total+=$count
+    e "$count $d "
+  done
+  if (( total > count )); then
+    e "total $total"
+  fi
 }
 
 # run then notify. close notification after the next prompt.
@@ -4573,6 +4599,38 @@ join-arr() {
 # all the lines will be joined and stored in $x.
 jl() {
   x=$(cat)
+}
+
+jrm() {
+  local x
+  x=$(cat)
+  rm -I $x
+}
+
+# Usage LIST_OF_PERL_VARS
+perlpgen() {
+  local var out space_regex=' ' info_text
+  if [[ $1 == -i ]]; then
+    info_text="$2"
+    shift 2
+  elif [[ $1 =~ $space_regex ]]; then
+    info_text="$1"
+    shift
+  fi
+  if [[ $info_text ]]; then
+    info_text=", as => '$info_text'"
+  fi
+  for var; do
+    out+="$var => \$$var, "
+  done
+  jc echo "p { $out}->%*$info_text;"
+}
+
+dtsort() {
+  local daystart
+  daystart=$(date -d 00:00 +%s)
+  day_mins=$(( ( EPOCHSECONDS - daystart ) / 60 ))
+  echo $(date +%j)---$day_mins
   }
 
 # * stuff that makes sense to be at the end
@@ -4597,3 +4655,9 @@ fi
 
 # ensure no bad programs appending to this file will have an affect
 return 0
+
+
+## just dumping this useful code
+# sleep 100 &
+# pid=$!
+# job_num=$(jobs -l | awk -v pid="$pid" '$2 == pid {gsub(/[\[\]+-]/, "", $1); print $1}')
diff --git a/brc2 b/brc2
index 6d28b901fcfb0aca3db396b7b3d43245a9d5177b..4be5d67a1c4f76b5ae10cf2eac22ca0c345c4ec1 100644 (file)
--- a/brc2
+++ b/brc2
@@ -65,6 +65,18 @@ path_add --end ~/.local/bin
 #path_add --ifexists --end /a/opt/scancode-toolkit-3.10.
 path_add --ifexists --end /p/bin
 
+### stuff recommended by CPAN. However it is quite annoying that these things blindly
+# add on to existing vars, so if you source this file multiple times, you get crazy long vars.
+# So, I fix.
+path_add --end /home/iank/perl5/bin
+if [[ ! $PERL5LIB ]]; then
+  PERL5LIB=/home/iank/perl5/lib/perl5
+  PERL_LOCAL_LIB_ROOT=/home/iank/perl5
+  PERL_MB_OPT="--install_base \"/home/iank/perl5\""
+  PERL_MM_OPT=INSTALL_BASE=/home/iank/perl5
+  export PERL5LIB PERL_LOCAL_LIB_ROOT PERL_MB_OPT PERL_MM_OPT
+fi
+
 case $HOSTNAME in
   sy|bo)
     # https://askubuntu.com/questions/1254544/vlc-crashes-when-opening-any-file-ubuntu-20-04
@@ -96,6 +108,8 @@ if [[ $EUID == 1000 ]]; then
   }
 fi
 
+export I2X_SORT_ORDER=path_desc
+
 
 # * include files
 
@@ -794,11 +808,9 @@ beetrating-stdin() {
   userid=23cc2eb9-e35e-4811-a0f0-d5f0dd6eb634
   while read -r rating path; do
     cpath="/i/converted${path#/i/m}" # converted path
-    case $cpath in
-      *.flac)
-        cpath="${cpath%.*}.mp3"
-        ;;
-    esac
+    if [[ $cpath == *.flac ]]; then
+      cpath="${cpath%.*}.mp3"
+    fi
     if [[ ! -e $cpath ]]; then
       echo "beetraing: error: this should not happen, path does not exist: $cpath"
       return 1
@@ -1214,7 +1226,7 @@ jepush() { # no emacs. for running faster.
 }
 
 bindpush() {
-  dsign iankelling.org expertpathologyreview.com zroe.org amnimal.ninja
+  dsign iankelling.org zroe.org amnimal.ninja
   lipush
   for h in li bk; do
     m ssh iank@$h.b8.nz dnsup
@@ -2854,7 +2866,7 @@ mpvd() {
 # mpv profile e. good for videos
 mpe () {
   mpv --profile=e "$@";
-  }
+}
 mpva() {
   mpv --profile=a "$@";
 }
@@ -4955,9 +4967,6 @@ if [[ ! $DISPLAY && $XDG_VTNR == 1 ]] && shopt -q login_shell && isarch; then
 fi
 
 
-# ensure no bad programs appending to this file will have an affect
-return 0
-
 
 # finding the letter pages that have hardly any text due to overflow:
 letter-hac-fsf() {
@@ -4967,3 +4976,892 @@ letter-hac-fsf() {
 {words += NF}
 END {print  words, page}' ISAL.txt | sort -n
 }
+
+
+# things to remember:
+# ALT-C - cd into the selected directory
+# CTRL-T - Paste the selected file path into the command line
+#
+# good guide to some of its basic features is the readme file
+# https://github.com/junegunn/fzf
+
+path_add --end --ifexists /a/opt/fzf/bin
+
+if ! type -p fzf &>/dev/null; then
+  return 0
+fi
+
+#####  this is from output of fzf --bash plus a small modification to
+# prevent a command from reporting a superflous nonzero exit, search for
+# iank below.
+
+### key-bindings.bash ###
+#     ____      ____
+#    / __/___  / __/
+#   / /_/_  / / /_
+#  / __/ / /_/ __/
+# /_/   /___/_/ key-bindings.bash
+#
+# - $FZF_TMUX_OPTS
+# - $FZF_CTRL_T_COMMAND
+# - $FZF_CTRL_T_OPTS
+# - $FZF_CTRL_R_COMMAND
+# - $FZF_CTRL_R_OPTS
+# - $FZF_ALT_C_COMMAND
+# - $FZF_ALT_C_OPTS
+
+if [[ $- =~ i ]]; then
+
+
+  # Key bindings
+  # ------------
+
+  #----BEGIN shfmt
+  #----BEGIN INCLUDE common.sh
+  # NOTE: Do not directly edit this section, which is copied from "common.sh".
+  # To modify it, one can edit "common.sh" and run "./update.sh" to apply
+  # the changes. See code comments in "common.sh" for the implementation details.
+
+  __fzf_defaults() {
+    printf '%s\n' "--height ${FZF_TMUX_HEIGHT:-40%} --min-height 20+ --bind=ctrl-z:ignore $1"
+    command cat "${FZF_DEFAULT_OPTS_FILE-}" 2> /dev/null
+    printf '%s\n' "${FZF_DEFAULT_OPTS-} $2"
+  }
+
+  __fzf_exec_awk() {
+    if [[ -z ${__fzf_awk-} ]]; then
+      __fzf_awk=awk
+      if [[ $OSTYPE == solaris* && -x /usr/xpg4/bin/awk ]]; then
+        __fzf_awk=/usr/xpg4/bin/awk
+      elif command -v mawk > /dev/null 2>&1; then
+        local n x y z d
+        IFS=' .' read -r n x y z d <<< $(command mawk -W version 2> /dev/null)
+        [[ $n == mawk ]] && ((d >= 20230302 && (x * 1000 + y) * 1000 + z >= 1003004)) && __fzf_awk=mawk
+      fi
+    fi
+    LC_ALL=C exec "$__fzf_awk" "$@"
+  }
+  #----END INCLUDE
+
+  __fzf_select__() {
+    FZF_DEFAULT_COMMAND=${FZF_CTRL_T_COMMAND:-} \
+                       FZF_DEFAULT_OPTS=$(__fzf_defaults "--reverse --walker=file,dir,follow,hidden --scheme=path" "${FZF_CTRL_T_OPTS-} -m") \
+                       FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd) "$@" |
+      while read -r item; do
+        printf '%q ' "$item" # escape special chars
+      done
+  }
+
+  __fzfcmd() {
+    [[ -n ${TMUX_PANE-} ]] && { [[ ${FZF_TMUX:-0} != 0 ]] || [[ -n ${FZF_TMUX_OPTS-} ]]; } &&
+      echo "fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- " || echo "fzf"
+  }
+
+  fzf-file-widget() {
+    local selected="$(__fzf_select__ "$@")"
+    READLINE_LINE="${READLINE_LINE:0:READLINE_POINT}$selected${READLINE_LINE:READLINE_POINT}"
+    READLINE_POINT=$((READLINE_POINT + ${#selected}))
+  }
+
+  __fzf_cd__() {
+    local dir
+    dir=$(
+      FZF_DEFAULT_COMMAND=${FZF_ALT_C_COMMAND:-} \
+                         FZF_DEFAULT_OPTS=$(__fzf_defaults "--reverse --walker=dir,follow,hidden --scheme=path" "${FZF_ALT_C_OPTS-} +m") \
+                         FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd)
+       ) && printf 'builtin cd -- %q' "$(builtin unset CDPATH && builtin cd -- "$dir" && builtin pwd)"
+  }
+
+  if command -v perl > /dev/null; then
+    __fzf_history__() {
+      local output script
+      script='BEGIN { getc; $/ = "\n\t"; $HISTCOUNT = $ENV{last_hist} + 1 } s/^[ *]//; s/\n/\n\t/gm; print $HISTCOUNT - $. . "\t$_" if !$seen{$_}++'
+      output=$(
+        set +o pipefail
+        builtin fc -lnr -2147483648 |
+          last_hist=$(HISTTIMEFORMAT='' builtin history 1) command perl -n -l0 -e "$script" |
+          FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,alt-r:toggle-raw --wrap-sign '"$'\t'"↳ ' --highlight-line ${FZF_CTRL_R_OPTS-} +m --read0") \
+                          FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd) --query "$READLINE_LINE"
+            ) || return
+      READLINE_LINE=$(command perl -pe 's/^\d*\t//' <<< "$output")
+      if [[ -z $READLINE_POINT ]]; then
+        echo "$READLINE_LINE"
+      else
+        READLINE_POINT=0x7fffffff
+      fi
+    }
+  else # awk - fallback for POSIX systems
+    __fzf_history__() {
+      local output script
+      [[ $(HISTTIMEFORMAT='' builtin history 1) =~ [[:digit:]]+ ]] # how many history entries
+      script='function P(b) { ++n; sub(/^[ *]/, "", b); if (!seen[b]++) { printf "%d\t%s%c", '$((BASH_REMATCH + 1))' - n, b, 0 } }
+    NR==1 { b = substr($0, 2); next }
+    /^\t/ { P(b); b = substr($0, 2); next }
+    { b = b RS $0 }
+    END { if (NR) P(b) }'
+      output=$(
+        set +o pipefail
+        builtin fc -lnr -2147483648 2> /dev/null | # ( $'\t '<lines>$'\n' )* ; <lines> ::= [^\n]* ( $'\n'<lines> )*
+          __fzf_exec_awk "$script" |               # ( <counter>$'\t'<lines>$'\000' )*
+          FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,alt-r:toggle-raw --wrap-sign '"$'\t'"↳ ' --highlight-line ${FZF_CTRL_R_OPTS-} +m --read0") \
+                          FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd) --query "$READLINE_LINE"
+            ) || return
+      READLINE_LINE=${output#*$'\t'}
+      if [[ -z $READLINE_POINT ]]; then
+        echo "$READLINE_LINE"
+      else
+        READLINE_POINT=0x7fffffff
+      fi
+    }
+  fi
+
+  # Required to refresh the prompt after fzf
+  bind -m emacs-standard '"\er": redraw-current-line'
+
+  bind -m vi-command '"\C-z": emacs-editing-mode'
+  bind -m vi-insert '"\C-z": emacs-editing-mode'
+  bind -m emacs-standard '"\C-z": vi-editing-mode'
+
+  if ((BASH_VERSINFO[0] < 4)); then
+    # CTRL-T - Paste the selected file path into the command line
+    if [[ ${FZF_CTRL_T_COMMAND-x} != "" ]]; then
+      bind -m emacs-standard '"\C-t": " \C-b\C-k \C-u`__fzf_select__`\e\C-e\er\C-a\C-y\C-h\C-e\e \C-y\ey\C-x\C-x\C-f\C-y\ey\C-_"'
+      bind -m vi-command '"\C-t": "\C-z\C-t\C-z"'
+      bind -m vi-insert '"\C-t": "\C-z\C-t\C-z"'
+    fi
+
+    # CTRL-R - Paste the selected command from history into the command line
+    if [[ ${FZF_CTRL_R_COMMAND-x} != "" ]]; then
+      if [[ -n ${FZF_CTRL_R_COMMAND-} ]]; then
+        echo "warning: FZF_CTRL_R_COMMAND is set to a custom command, but custom commands are not yet supported for CTRL-R" >&2
+      fi
+      bind -m emacs-standard '"\C-r": "\C-e \C-u\C-y\ey\C-u`__fzf_history__`\e\C-e\er"'
+      bind -m vi-command '"\C-r": "\C-z\C-r\C-z"'
+      bind -m vi-insert '"\C-r": "\C-z\C-r\C-z"'
+    fi
+  else
+    # CTRL-T - Paste the selected file path into the command line
+    if [[ ${FZF_CTRL_T_COMMAND-x} != "" ]]; then
+      bind -m emacs-standard -x '"\C-t": fzf-file-widget'
+      bind -m vi-command -x '"\C-t": fzf-file-widget'
+      bind -m vi-insert -x '"\C-t": fzf-file-widget'
+    fi
+
+    # CTRL-R - Paste the selected command from history into the command line
+    if [[ ${FZF_CTRL_R_COMMAND-x} != "" ]]; then
+      if [[ -n ${FZF_CTRL_R_COMMAND-} ]]; then
+        echo "warning: FZF_CTRL_R_COMMAND is set to a custom command, but custom commands are not yet supported for CTRL-R" >&2
+      fi
+      bind -m emacs-standard -x '"\C-r": __fzf_history__'
+      bind -m vi-command -x '"\C-r": __fzf_history__'
+      bind -m vi-insert -x '"\C-r": __fzf_history__'
+    fi
+  fi
+
+  # ALT-C - cd into the selected directory
+  if [[ ${FZF_ALT_C_COMMAND-x} != "" ]]; then
+    bind -m emacs-standard '"\ec": " \C-b\C-k \C-u`__fzf_cd__`\e\C-e\er\C-m\C-y\C-h\e \C-y\ey\C-x\C-x\C-d\C-y\ey\C-_"'
+    bind -m vi-command '"\ec": "\C-z\ec\C-z"'
+    bind -m vi-insert '"\ec": "\C-z\ec\C-z"'
+  fi
+  #----END shfmt
+
+fi
+### end: key-bindings.bash ###
+### completion.bash ###
+#     ____      ____
+#    / __/___  / __/
+#   / /_/_  / / /_
+#  / __/ / /_/ __/
+# /_/   /___/_/ completion.bash
+#
+# - $FZF_TMUX                 (default: 0)
+# - $FZF_TMUX_OPTS            (default: empty)
+# - $FZF_COMPLETION_TRIGGER   (default: '**')
+# - $FZF_COMPLETION_OPTS      (default: empty)
+# - $FZF_COMPLETION_PATH_OPTS (default: empty)
+# - $FZF_COMPLETION_DIR_OPTS  (default: empty)
+
+if [[ $- =~ i ]]; then
+
+
+  # To use custom commands instead of find, override _fzf_compgen_{path,dir}
+  #
+  #   _fzf_compgen_path() {
+  #     echo "$1"
+  #     command find -L "$1" \
+    #       -name .git -prune -o -name .hg -prune -o -name .svn -prune -o \( -type d -o -type f -o -type l \) \
+    #       -a -not -path "$1" -print 2> /dev/null | command sed 's@^\./@@'
+  #   }
+  #
+  #   _fzf_compgen_dir() {
+  #     command find -L "$1" \
+    #       -name .git -prune -o -name .hg -prune -o -name .svn -prune -o -type d \
+    #       -a -not -path "$1" -print 2> /dev/null | command sed 's@^\./@@'
+  #   }
+
+  ###########################################################
+
+  #----BEGIN shfmt
+  #----BEGIN INCLUDE common.sh
+  # NOTE: Do not directly edit this section, which is copied from "common.sh".
+  # To modify it, one can edit "common.sh" and run "./update.sh" to apply
+  # the changes. See code comments in "common.sh" for the implementation details.
+
+  __fzf_defaults() {
+    printf '%s\n' "--height ${FZF_TMUX_HEIGHT:-40%} --min-height 20+ --bind=ctrl-z:ignore $1"
+    command cat "${FZF_DEFAULT_OPTS_FILE-}" 2> /dev/null
+    printf '%s\n' "${FZF_DEFAULT_OPTS-} $2"
+  }
+
+  __fzf_exec_awk() {
+    if [[ -z ${__fzf_awk-} ]]; then
+      __fzf_awk=awk
+      if [[ $OSTYPE == solaris* && -x /usr/xpg4/bin/awk ]]; then
+        __fzf_awk=/usr/xpg4/bin/awk
+      elif command -v mawk > /dev/null 2>&1; then
+        local n x y z d
+        IFS=' .' read -r n x y z d <<< $(command mawk -W version 2> /dev/null)
+        [[ $n == mawk ]] && ((d >= 20230302 && (x * 1000 + y) * 1000 + z >= 1003004)) && __fzf_awk=mawk
+      fi
+    fi
+    LC_ALL=C exec "$__fzf_awk" "$@"
+  }
+  #----END INCLUDE
+
+  __fzf_comprun() {
+    if [[ "$(type -t _fzf_comprun 2>&1)" == function ]]; then
+      _fzf_comprun "$@"
+    elif [[ -n ${TMUX_PANE-} ]] && { [[ ${FZF_TMUX:-0} != 0 ]] || [[ -n ${FZF_TMUX_OPTS-} ]]; }; then
+      shift
+      fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- "$@"
+    else
+      shift
+      fzf "$@"
+    fi
+  }
+
+  __fzf_orig_completion() {
+    local l comp f cmd
+    while read -r l; do
+      if [[ $l =~ ^(.*\ -F)\ *([^ ]*).*\ ([^ ]*)$ ]]; then
+        comp="${BASH_REMATCH[1]}"
+        f="${BASH_REMATCH[2]}"
+        cmd="${BASH_REMATCH[3]}"
+        [[ $f == _fzf_* ]] && continue
+        printf -v "_fzf_orig_completion_${cmd//[^A-Za-z0-9_]/_}" "%s" "${comp} %s ${cmd} #${f}"
+        if [[ $l == *" -o nospace "* ]] && [[ ${__fzf_nospace_commands-} != *" $cmd "* ]]; then
+          __fzf_nospace_commands="${__fzf_nospace_commands-} $cmd "
+        fi
+      fi
+    done
+  }
+
+  # @param $1 cmd - Command name for which the original completion is searched
+  # @var[out] REPLY - Original function name is returned
+  __fzf_orig_completion_get_orig_func() {
+    local cmd orig_var orig
+    cmd=$1
+    orig_var="_fzf_orig_completion_${cmd//[^A-Za-z0-9_]/_}"
+    orig="${!orig_var-}"
+    REPLY="${orig##*#}"
+    [[ $REPLY ]] && type "$REPLY" &> /dev/null
+  }
+
+  # @param $1 cmd - Command name for which the original completion is searched
+  # @param $2 func - Fzf's completion function to replace the original function
+  # @var[out] REPLY - Completion setting is returned as a string to "eval"
+  __fzf_orig_completion_instantiate() {
+    local cmd func orig_var orig
+    cmd=$1
+    func=$2
+    orig_var="_fzf_orig_completion_${cmd//[^A-Za-z0-9_]/_}"
+    orig="${!orig_var-}"
+    orig="${orig%#*}"
+    [[ $orig == *' %s '* ]] || return 1
+    printf -v REPLY "$orig" "$func"
+  }
+
+  _fzf_opts_completion() {
+    local cur prev opts
+    COMPREPLY=()
+    cur="${COMP_WORDS[COMP_CWORD]}"
+    prev="${COMP_WORDS[COMP_CWORD - 1]}"
+    opts="
+    +c --no-color
+    +i --no-ignore-case
+    +s --no-sort
+    +x --no-extended
+    --ansi
+    --bash
+    --bind
+    --border
+    --border-label
+    --border-label-pos
+    --color
+    --cycle
+    --disabled
+    --ellipsis
+    --expect
+    --filepath-word
+    --fish
+    --header
+    --header-first
+    --header-lines
+    --height
+    --highlight-line
+    --history
+    --history-size
+    --hscroll-off
+    --info
+    --jump-labels
+    --keep-right
+    --layout
+    --listen
+    --listen-unsafe
+    --literal
+    --man
+    --margin
+    --marker
+    --min-height
+    --no-bold
+    --no-clear
+    --no-hscroll
+    --no-mouse
+    --no-scrollbar
+    --no-separator
+    --no-unicode
+    --padding
+    --pointer
+    --preview
+    --preview-label
+    --preview-label-pos
+    --preview-window
+    --print-query
+    --print0
+    --prompt
+    --read0
+    --reverse
+    --scheme
+    --scroll-off
+    --separator
+    --sync
+    --tabstop
+    --tac
+    --tiebreak
+    --tmux
+    --track
+    --version
+    --with-nth
+    --with-shell
+    --wrap
+    --zsh
+    -0 --exit-0
+    -1 --select-1
+    -d --delimiter
+    -e --exact
+    -f --filter
+    -h --help
+    -i --ignore-case
+    -m --multi
+    -n --nth
+    -q --query
+    --"
+
+    case "${prev}" in
+      --scheme)
+        COMPREPLY=($(compgen -W "default path history" -- "$cur"))
+        return 0
+        ;;
+      --tiebreak)
+        COMPREPLY=($(compgen -W "length chunk begin end index" -- "$cur"))
+        return 0
+        ;;
+      --color)
+        COMPREPLY=($(compgen -W "dark light 16 bw no" -- "$cur"))
+        return 0
+        ;;
+      --layout)
+        COMPREPLY=($(compgen -W "default reverse reverse-list" -- "$cur"))
+        return 0
+        ;;
+      --info)
+        COMPREPLY=($(compgen -W "default right hidden inline inline-right" -- "$cur"))
+        return 0
+        ;;
+      --preview-window)
+        COMPREPLY=($(compgen -W "
+      default
+      hidden
+      nohidden
+      wrap
+      nowrap
+      cycle
+      nocycle
+      up top
+      down bottom
+      left
+      right
+      rounded border border-rounded
+      sharp border-sharp
+      border-bold
+      border-block
+      border-thinblock
+      border-double
+      noborder border-none
+      border-horizontal
+      border-vertical
+      border-up border-top
+      border-down border-bottom
+      border-left
+      border-right
+      follow
+      nofollow" -- "$cur"))
+        return 0
+        ;;
+      --border)
+        COMPREPLY=($(compgen -W "rounded sharp bold block thinblock double horizontal vertical top bottom left right none" -- "$cur"))
+        return 0
+        ;;
+      --border-label-pos | --preview-label-pos)
+        COMPREPLY=($(compgen -W "center bottom top" -- "$cur"))
+        return 0
+        ;;
+    esac
+
+    if [[ $cur =~ ^-|\+ ]]; then
+      COMPREPLY=($(compgen -W "${opts}" -- "$cur"))
+      return 0
+    fi
+
+    return 0
+  }
+
+  _fzf_handle_dynamic_completion() {
+    local cmd ret REPLY orig_cmd orig_complete
+    cmd="$1"
+    shift
+    orig_cmd="$1"
+    if __fzf_orig_completion_get_orig_func "$cmd"; then
+      "$REPLY" "$@"
+    elif [[ -n ${_fzf_completion_loader-} ]]; then
+      orig_complete=$(complete -p "$orig_cmd" 2> /dev/null)
+      $_fzf_completion_loader "$@"
+      ret=$?
+      # _completion_loader may not have updated completion for the command
+      if [[ "$(complete -p "$orig_cmd" 2> /dev/null)" != "$orig_complete" ]]; then
+        __fzf_orig_completion < <(complete -p "$orig_cmd" 2> /dev/null)
+        __fzf_orig_completion_get_orig_func "$cmd" || ret=1
+
+        # Update orig_complete by _fzf_orig_completion entry
+        [[ $orig_complete =~ ' -F '(_fzf_[^ ]+)' ' ]] &&
+          __fzf_orig_completion_instantiate "$cmd" "${BASH_REMATCH[1]}" &&
+          orig_complete=$REPLY
+
+        if [[ ${__fzf_nospace_commands-} == *" $orig_cmd "* ]]; then
+          eval "${orig_complete/ -F / -o nospace -F }"
+        else
+          eval "$orig_complete"
+        fi
+      fi
+      [[ $ret -eq 0 ]] && return 124
+      return $ret
+    fi
+  }
+
+  __fzf_generic_path_completion() {
+    local cur base dir leftover matches trigger cmd
+    cmd="${COMP_WORDS[0]}"
+    if [[ $cmd == \\* ]]; then
+      cmd="${cmd:1}"
+    fi
+    COMPREPLY=()
+    trigger=${FZF_COMPLETION_TRIGGER-'**'}
+    [[ $COMP_CWORD -ge 0 ]] && cur="${COMP_WORDS[COMP_CWORD]}"
+    if [[ $cur == *"$trigger" ]] && [[ $cur != *'$('* ]] && [[ $cur != *':='* ]] && [[ $cur != *'`'* ]]; then
+      base=${cur:0:${#cur}-${#trigger}}
+      eval "base=$base" 2> /dev/null || return
+
+      dir=
+      [[ $base == *"/"* ]] && dir="$base"
+      while true; do
+        if [[ -z $dir ]] || [[ -d $dir ]]; then
+          leftover=${base/#"$dir"/}
+          leftover=${leftover/#\//}
+          [[ -z $dir ]] && dir='.'
+          [[ $dir != "/" ]] && dir="${dir/%\//}"
+          matches=$(
+            export FZF_DEFAULT_OPTS=$(__fzf_defaults "--reverse --scheme=path" "${FZF_COMPLETION_OPTS-} $2")
+            unset FZF_DEFAULT_COMMAND FZF_DEFAULT_OPTS_FILE
+            if declare -F "$1" > /dev/null; then
+              eval "$1 $(printf %q "$dir")" | __fzf_comprun "$4" -q "$leftover"
+            else
+              if [[ $1 =~ dir ]]; then
+                walker=dir,follow
+                eval "rest=(${FZF_COMPLETION_DIR_OPTS-})"
+              else
+                walker=file,dir,follow,hidden
+                eval "rest=(${FZF_COMPLETION_PATH_OPTS-})"
+              fi
+              __fzf_comprun "$4" -q "$leftover" --walker "$walker" --walker-root="$dir" "${rest[@]}"
+            fi | while read -r item; do
+              printf "%q " "${item%$3}$3"
+            done
+                 )
+          matches=${matches% }
+          [[ -z $3 ]] && [[ ${__fzf_nospace_commands-} == *" ${COMP_WORDS[0]} "* ]] && matches="$matches "
+          if [[ -n $matches ]]; then
+            COMPREPLY=("$matches")
+          else
+            COMPREPLY=("$cur")
+          fi
+          # To redraw line after fzf closes (printf '\e[5n')
+          bind '"\e[0n": redraw-current-line' 2> /dev/null
+          printf '\e[5n'
+          return 0
+        fi
+        dir=$(command dirname "$dir")
+        [[ $dir =~ /$ ]] || dir="$dir"/
+      done
+    else
+      shift
+      shift
+      shift
+      _fzf_handle_dynamic_completion "$cmd" "$@"
+    fi
+  }
+
+  _fzf_complete() {
+    # Split arguments around --
+    local args rest str_arg i sep
+    args=("$@")
+    sep=
+    for i in "${!args[@]}"; do
+      if [[ ${args[$i]} == -- ]]; then
+        sep=$i
+        break
+      fi
+    done
+    if [[ -n $sep ]]; then
+      str_arg=
+      rest=("${args[@]:$((sep + 1)):${#args[@]}}")
+      args=("${args[@]:0:sep}")
+    else
+      str_arg=$1
+      args=()
+      shift
+      rest=("$@")
+    fi
+
+    local cur selected trigger cmd post
+    post="$(caller 0 | __fzf_exec_awk '{print $2}')_post"
+    type -t "$post" > /dev/null 2>&1 || post='command cat'
+
+    trigger=${FZF_COMPLETION_TRIGGER-'**'}
+    cmd="${COMP_WORDS[0]}"
+    cur="${COMP_WORDS[COMP_CWORD]}"
+    if [[ $cur == *"$trigger" ]] && [[ $cur != *'$('* ]] && [[ $cur != *':='* ]] && [[ $cur != *'`'* ]]; then
+      cur=${cur:0:${#cur}-${#trigger}}
+
+      selected=$(
+        FZF_DEFAULT_OPTS=$(__fzf_defaults "--reverse" "${FZF_COMPLETION_OPTS-} $str_arg") \
+                        FZF_DEFAULT_OPTS_FILE='' \
+                        __fzf_comprun "${rest[0]}" "${args[@]}" -q "$cur" | eval "$post" | command tr '\n' ' '
+              )
+      selected=${selected% } # Strip trailing space not to repeat "-o nospace"
+      if [[ -n $selected ]]; then
+        COMPREPLY=("$selected")
+      else
+        COMPREPLY=("$cur")
+      fi
+      bind '"\e[0n": redraw-current-line' 2> /dev/null
+      printf '\e[5n'
+      return 0
+    else
+      _fzf_handle_dynamic_completion "$cmd" "${rest[@]}"
+    fi
+  }
+
+  _fzf_path_completion() {
+    __fzf_generic_path_completion _fzf_compgen_path "-m" "" "$@"
+  }
+
+  # Deprecated. No file only completion.
+  _fzf_file_completion() {
+    _fzf_path_completion "$@"
+  }
+
+  _fzf_dir_completion() {
+    __fzf_generic_path_completion _fzf_compgen_dir "" "/" "$@"
+  }
+
+  _fzf_complete_kill() {
+    _fzf_proc_completion "$@"
+  }
+
+  _fzf_proc_completion() {
+    local transformer
+    transformer='
+    if [[ $FZF_KEY =~ ctrl|alt|shift ]] && [[ -n $FZF_NTH ]]; then
+      nths=( ${FZF_NTH//,/ } )
+      new_nths=()
+      found=0
+      for nth in ${nths[@]}; do
+        if [[ $nth = $FZF_CLICK_HEADER_NTH ]]; then
+          found=1
+        else
+          new_nths+=($nth)
+        fi
+      done
+      [[ $found = 0 ]] && new_nths+=($FZF_CLICK_HEADER_NTH)
+      new_nths=${new_nths[*]}
+      new_nths=${new_nths// /,}
+      echo "change-nth($new_nths)+change-prompt($new_nths> )"
+    else
+      if [[ $FZF_NTH = $FZF_CLICK_HEADER_NTH ]]; then
+        echo "change-nth()+change-prompt(> )"
+      else
+        echo "change-nth($FZF_CLICK_HEADER_NTH)+change-prompt($FZF_CLICK_HEADER_WORD> )"
+      fi
+    fi
+  '
+    _fzf_complete -m --header-lines=1 --no-preview --wrap --color fg:dim,nth:regular \
+                  --bind "click-header:transform:$transformer" -- "$@" < <(
+      command ps -eo user,pid,ppid,start,time,command 2> /dev/null ||
+        command ps -eo user,pid,ppid,time,args 2> /dev/null || # For BusyBox
+        command ps --everyone --full --windows                 # For cygwin
+    )
+  }
+
+  _fzf_proc_completion_post() {
+    __fzf_exec_awk '{print $2}'
+  }
+
+  # To use custom hostname lists, override __fzf_list_hosts.
+  # The function is expected to print hostnames, one per line as well as in the
+  # desired sorting and with any duplicates removed, to standard output.
+  #
+  # e.g.
+  #   # Use bash-completions’s _known_hosts_real() for getting the list of hosts
+  #   __fzf_list_hosts() {
+  #     # Set the local attribute for any non-local variable that is set by _known_hosts_real()
+  #     local COMPREPLY=()
+  #     _known_hosts_real ''
+  #     printf '%s\n' "${COMPREPLY[@]}" | command sort -u --version-sort
+  #   }
+  if ! declare -F __fzf_list_hosts > /dev/null; then
+    __fzf_list_hosts() {
+      command sort -u \
+              <(
+        # Note: To make the pathname expansion of "~/.ssh/config.d/*" work
+        # properly, we need to adjust the related shell options.  We need to
+        # unset "set -f" and "GLOBIGNORE", which disable the pathname expansion
+        # totally or partially.  We need to unset "dotglob" and "nocaseglob" to
+        # avoid matching unwanted files.  We need to unset "failglob" to avoid
+        # outputting the error messages to the terminal when no matching is
+        # found.  We need to set "nullglob" to avoid attempting to read the
+        # literal filename '~/.ssh/config.d/*' when no matching is found.
+        set +f
+        GLOBIGNORE=
+        shopt -u dotglob nocaseglob failglob
+        shopt -s nullglob
+
+        __fzf_exec_awk '
+          # Note: mawk <= 1.3.3-20090705 does not support the POSIX brackets of
+          # the form [[:blank:]], and Ubuntu 18.04 LTS still uses this
+          # 16-year-old mawk unfortunately.  We need to use [ \t] instead.
+          match(tolower($0), /^[ \t]*host(name)?[ \t]*[ \t=]/) {
+            $0 = substr($0, RLENGTH + 1) # Remove "Host(name)?=?"
+            sub(/#.*/, "")
+            for (i = 1; i <= NF; i++)
+              if ($i !~ /[*?%]/)
+                print $i
+          }
+        ' ~/.ssh/config ~/.ssh/config.d/* /etc/ssh/ssh_config 2> /dev/null
+      ) \
+              <(
+        __fzf_exec_awk -F ',' '
+          match($0, /^[][a-zA-Z0-9.,:-]+/) {
+            $0 = substr($0, 1, RLENGTH)
+            gsub(/[][]|:[^,]*/, "")
+            for (i = 1; i <= NF; i++)
+              print $i
+          }
+        ' ~/.ssh/known_hosts 2> /dev/null
+      ) \
+              <(
+        __fzf_exec_awk '
+          {
+            sub(/#.*/, "")
+            for (i = 2; i <= NF; i++)
+              if ($i != "0.0.0.0")
+                print $i
+          }
+        ' /etc/hosts 2> /dev/null
+      )
+    }
+  fi
+
+  _fzf_host_completion() {
+    _fzf_complete +m -- "$@" < <(__fzf_list_hosts)
+  }
+
+  # Values for $1 $2 $3 are described here
+  # https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html
+  # > the first argument ($1) is the name of the command whose arguments are being completed,
+  # > the second argument ($2) is the word being completed,
+  # > and the third argument ($3) is the word preceding the word being completed on the current command line.
+  _fzf_complete_ssh() {
+    case $3 in
+      -i | -F | -E)
+        _fzf_path_completion "$@"
+        ;;
+      *)
+        local user=
+        [[ $2 =~ '@' ]] && user="${2%%@*}@"
+        _fzf_complete +m -- "$@" < <(__fzf_list_hosts | __fzf_exec_awk -v user="$user" '{print user $0}')
+        ;;
+    esac
+  }
+
+  _fzf_var_completion() {
+    _fzf_complete -m -- "$@" < <(
+      declare -xp | command sed -En 's|^declare [^ ]+ ([^=]+).*|\1|p'
+    )
+  }
+
+  _fzf_alias_completion() {
+    _fzf_complete -m -- "$@" < <(
+      alias | command sed -En 's|^alias ([^=]+).*|\1|p'
+    )
+  }
+
+  # fzf options
+  complete -o default -F _fzf_opts_completion fzf
+  # fzf-tmux is a thin fzf wrapper that has only a few more options than fzf
+  # itself. As a quick improvement we take fzf's completion. Adding the few extra
+  # fzf-tmux specific options (like `-w WIDTH`) are left as a future patch.
+  complete -o default -F _fzf_opts_completion fzf-tmux
+
+  # Default path completion
+  __fzf_default_completion() {
+    __fzf_generic_path_completion _fzf_compgen_path "-m" "" "$@"
+
+    # Dynamic completion loader has updated the completion for the command
+    if [[ $? -eq 124 ]]; then
+      # We trigger _fzf_setup_completion so that fuzzy completion for the command
+      # still works. However, loader can update the completion for multiple
+      # commands at once, and fuzzy completion will no longer work for those
+      # other commands. e.g. pytest -> py.test, pytest-2, pytest-3, etc
+      _fzf_setup_completion path "$1"
+      return 124
+    fi
+  }
+
+  # Set fuzzy path completion as the default completion for all commands.
+  # We can't set up default completion,
+  # 1. if it's already set up by another script
+  # 2. or if the current version of bash doesn't support -D option
+  complete | command grep -q __fzf_default_completion ||
+    complete | command grep -- '-D$' | command grep -qv _comp_complete_load ||
+    complete -D -F __fzf_default_completion -o default -o bashdefault 2> /dev/null
+
+  d_cmds="${FZF_COMPLETION_DIR_COMMANDS-cd pushd rmdir}"
+
+  # NOTE: $FZF_COMPLETION_PATH_COMMANDS and $FZF_COMPLETION_VAR_COMMANDS are
+  # undocumented and subject to change in the future.
+  #
+  # NOTE: Although we have default completion, we still need to set up completion
+  # for each command in case they already have completion set up by another script.
+  a_cmds="${FZF_COMPLETION_PATH_COMMANDS-"
+  awk bat cat code diff diff3
+  emacs emacsclient ex file ftp g++ gcc gvim head hg hx java
+  javac ld less more mvim nvim patch perl python ruby
+  sed sftp sort source tail tee uniq vi view vim wc xdg-open
+  basename bunzip2 bzip2 chmod chown curl cp dirname du
+  find git grep gunzip gzip hg jar
+  ln ls mv open rm rsync scp
+  svn tar unzip zip"}"
+  v_cmds="${FZF_COMPLETION_VAR_COMMANDS-export unset printenv}"
+
+  # Preserve existing completion
+  # iank: added ||: at the end, exit is nonzero due to some commands not having a completion spec.
+  __fzf_orig_completion < <(complete -p $d_cmds $a_cmds $v_cmds unalias kill ssh 2> /dev/null ||:)
+
+  if type _comp_load > /dev/null 2>&1; then
+    # _comp_load was added in bash-completion 2.12 to replace _completion_loader.
+    # We use it without -D option so that it does not use _comp_complete_minimal as the fallback.
+    _fzf_completion_loader=_comp_load
+  elif type __load_completion > /dev/null 2>&1; then
+    # In bash-completion 2.11, _completion_loader internally calls __load_completion
+    # and if it returns a non-zero status, it sets the default 'minimal' completion.
+    _fzf_completion_loader=__load_completion
+  elif type _completion_loader > /dev/null 2>&1; then
+    _fzf_completion_loader=_completion_loader
+  fi
+
+  __fzf_defc() {
+    local cmd func opts REPLY
+    cmd="$1"
+    func="$2"
+    opts="$3"
+    if __fzf_orig_completion_instantiate "$cmd" "$func"; then
+      eval "$REPLY"
+    else
+      eval "complete -F \"$func\" $opts \"$cmd\""
+    fi
+  }
+
+  # Anything
+  for cmd in $a_cmds; do
+    __fzf_defc "$cmd" _fzf_path_completion "-o default -o bashdefault"
+  done
+
+  # Directory
+  for cmd in $d_cmds; do
+    __fzf_defc "$cmd" _fzf_dir_completion "-o bashdefault -o nospace -o dirnames"
+  done
+
+  # Variables
+  for cmd in $v_cmds; do
+    __fzf_defc "$cmd" _fzf_var_completion "-o default -o nospace -v"
+  done
+
+  # Aliases
+  __fzf_defc unalias _fzf_alias_completion "-a"
+
+  # Processes
+  __fzf_defc kill _fzf_proc_completion "-o default -o bashdefault"
+
+  # ssh
+  __fzf_defc ssh _fzf_complete_ssh "-o default -o bashdefault"
+
+  unset cmd d_cmds a_cmds v_cmds
+
+  _fzf_setup_completion() {
+    local kind fn cmd
+    kind=$1
+    fn=_fzf_${1}_completion
+    if [[ $# -lt 2 ]] || ! type -t "$fn" > /dev/null; then
+      echo "usage: ${FUNCNAME[0]} path|dir|var|alias|host|proc COMMANDS..."
+      return 1
+    fi
+    shift
+    __fzf_orig_completion < <(complete -p "$@" 2> /dev/null)
+    for cmd in "$@"; do
+      case "$kind" in
+        dir) __fzf_defc "$cmd" "$fn" "-o nospace -o dirnames" ;;
+        var) __fzf_defc "$cmd" "$fn" "-o default -o nospace -v" ;;
+        alias) __fzf_defc "$cmd" "$fn" "-a" ;;
+        *) __fzf_defc "$cmd" "$fn" "-o default -o bashdefault" ;;
+      esac
+    done
+  }
+  #----END shfmt
+
+fi
+### end: completion.bash ###
+
+
+# ensure no bad programs appending to this file will have an affect
+return 0
index e47576669945141456d3600853ffd5410c2f7a78..1c32607396c4cf6e96b3df722c35d10a7970ee6c 100755 (executable)
@@ -46,7 +46,7 @@ esac
 # https://docs.nextcloud.com/server/latest/admin_manual/maintenance/restore.html
 if $restore; then
   set -x
-  for ncdir in /var/www/ncexpertpath /var/www/ncninja; do
+  for ncdir in /var/www/ncninja; do
     ncbase=${ncdir##*/}
     ssh root@$host sudo -u www-data php $ncdir/occ -q maintenance:mode --on ||: # might not be running
     rsync -ravhi --numeric-ids /p/bkbackup/$ncbase/ root@$host:$ncdir  || ret=$?
@@ -64,7 +64,7 @@ fi
 ret=0
 if [[ $HOSTNAME == "$MAIL_HOST" ]]; then
   mkdir -p /p/bkbackup
-  for ncdir in /var/www/ncexpertpath /var/www/ncninja; do
+  for ncdir in /var/www/ncninja; do
     ncbase=${ncdir##*/}
     mkdir -p /p/bkbackup/$ncbase
     ssh root@$host sudo -u www-data php $ncdir/occ -q maintenance:mode --on
index f7486e3c4424191e7c2274695590d430d43a7d86..132711c2033316b2232722819695b21de7ef68d3 100755 (executable)
@@ -45,6 +45,52 @@ usage() {
 btrbk-run [OPTIONS] [run|resume|archive]
 usually -t TARGET_HOST or -s SOURCE_HOST
 
+Options:
+
+-2|-3   Config suffix, for the rare case we want to run multiple instances at the same time.
+
+-a    Use all known mountpoints.
+
+-c    Config creation only.
+
+-e    Quit early, just btrbk, no extra remounting etc.
+
+-f  Avoids some default behaviors:
+     - exit if we can't ssh to 1 or more hosts
+     - still set default hosts despite MAIL_HOST status
+     - negates -x.
+
+--fast   Skip various checks. when we run twice in a row for
+         switch mail-host, no need to repeat the same checks again.
+
+-k   Aka kd_spread. Run in resume mode to spread recent backup to other home lan hosts.
+     This implies resume and -p because it is just meant to make
+     other hosts have the same snapshots, not do any expiry or new
+     backups.
+
+-l RATE_LIMIT   Bytes per second unless it has a suffix of k/m/g.
+
+-m MOUNTPOINTS    Comma separated mountpoints to backup. This has defaults, see code logic.
+
+-p      Preserve existing snapshots and backups
+
+--pull-reexec   Internal option for rerunning under newer SOURCE_HOST version.
+
+
+-q      Quiet.
+
+-s SOURCE_HOST    Source host to receive a backup from
+
+-t TARGET_HOSTS   Target hosts to send to. empty is valid for just doing local
+                  snapshot. we have default hosts we will populate.
+
+-v        Verbose
+
+-x     Exit if we have unlocked xscreensaver, to avoid interrupting machine in active use.
+       -f turns this off.
+
+-h|--help   Print usage.
+
 EOF
   echo "top of script file:"
   sed -n '/^[# ]*begin command line/,/^[# ]*end command line/{p;b};q' "$0"
@@ -177,6 +223,8 @@ EOF
 write-config() {
   local q_mp=false
   local -a tmp_mps
+  local mp
+  snap_list_glob=
 
   cat >/etc/btrbk$conf_suf.conf <<EOF
 ssh_identity /q/root/h
@@ -226,12 +274,11 @@ EOF
   fi
 
   # make /q be last.
-  mp_count=${#mountpoints[@]}
-  for (( i=0; i < mp_count - 1 ; i++ )); do
-    if [[ ${mountpoints[i]} == /q ]]; then
+  for mp in "${mountpoints[@]}"; do
+    if [[ $mp == /q ]]; then
       q_mp=true
     else
-      tmp_mps+=(${mountpoints[i]})
+      tmp_mps+=($mp)
     fi
   done
   if $q_mp; then
@@ -306,9 +353,12 @@ EOF
 
 
 get-orphan-tg-snaps() {
-  local mp_to_snap_regex snap
+  local mp_to_snap_regex snap mp mp_tg_snap
+  local -i i
   local -a mp_orphan_tg_snaps mp_tg_snaps
 
+  orphan_tg_snaps=()
+
   ## sanity checking
   for (( i=0; i < ${#tg_snaps[@]}; i++ )); do
     if [[ ! ${tg_snaps[$i]} =~ $good_path_regex ]]; then
@@ -321,6 +371,14 @@ get-orphan-tg-snaps() {
     fi
   done
 
+  # debug
+  if $verbose; then
+    echo "source_snaps: ${!source_snaps[@]}"
+    echo "tg_snaps: ${tg_snaps[@]}"
+    echo "mountpoints: ${mountpoints[@]}"
+    echo "snap_list_glob: $snap_list_glob"
+  fi
+
 
   # note: we do each mountpoint separately just so we can better sanity
   # check that we aren't incorrectly classifying all target snaps as
@@ -336,8 +394,8 @@ get-orphan-tg-snaps() {
     done
     for mp_tg_snap in "${mp_tg_snaps[@]}"; do
       if [[ ! ${source_snaps[$mp_tg_snap]} ]]; then
-        orphan_tg_snaps+=("$tg_snap")
-        mp_orphan_tg_snaps+=("$tg_snap")
+        orphan_tg_snaps+=("$mp_tg_snap")
+        mp_orphan_tg_snaps+=("$mp_tg_snap")
       fi
 
       ## sanity checking
@@ -477,42 +535,25 @@ while true; do
     # for the rare case we want to run multiple instances at the same time
     -2) conf_suf=2 ;;
     -3) conf_suf=3 ;;
-    -a)
-      # all moiuntpoints
+    -a) # all
       mountpoints=(/a /o /q)
       ;;
-    # only creates the config file, does not run btrbk
     -c) conf_only=true ;;
     --check-installed)
       check_installed=true
       ;;
-    # quit early, just btrbk, no extra remounting etc.
-    -e) early=true ;;
-    # avoids some default behaviors:
-    # - exit if we can't ssh to 1 or more hosts
-    # - still set default hosts despite MAIL_HOST status
-    # - negates -x.
+    -e) early=true ;; # quit early
     -f) force=true ;;
-    # skip various checks. when we run twice in a row for
-    # switch mail-host, no need to repeat the same checks again.
     --fast) fast=true ;;
     -i) incremental_strict=true ;;
-    # note this implies resume and -p because it is just meant to make
-    # other hosts have the same snapshots, not do any expiry or new
-    # backups.
     -k) kd_spread=true ;;
-    # bytes per second, suffix k m g
     -l) rate_limit=$2; shift ;;
-    # Comma separated mountpoints to backup. This has defaults set below.
     -m) IFS=, mountpoints=($2); unset IFS; shift ;;
     -n) dry_run=true ;;
-    # preserve existing snapshots and backups
     -p) preserve_arg=-p ;;
-    # internal option for rerunning under newer SOURCE_HOST version.
     --pull-reexec) pull_reexec=true;;
     # quiet
     -q) verbose=false; verbose_arg=; progress_arg= ;;
-    # source host to receive a backup from
     -s)
       source=$2
       bbksource=$source
@@ -521,15 +562,11 @@ while true; do
       fi
       shift
       ;;
-    # target hosts to send to. empty is valid for just doing local
-    # snapshot. we have default hosts we will populate.
     -t) IFS=, targets=($2); unset IFS; shift ;;
     # verbose.
     -v)
       verbose=true; verbose_arg="-l trace"
       ;;
-    # exit if we have unlocked xscreensaver, to avoid interrupting machine in active use.
-    # -f turns this off.
     -x) xlock=true ;;
     -h|--help) usage ;;
     --) shift; break ;;
index 733db2bfdf08d3ed5863620b8319dee5fe68087e..b020dca3c62c6969c852d36346f19d25bdb0df53 100755 (executable)
@@ -26,14 +26,22 @@ set -e; . /usr/local/lib/bash-bear; set +e
 ## https://github.com/i3/i3/issues/2971
 
 window=$(xdotool getwindowfocus)
+name=$(xdotool getwindowname $window)
+
 
 # this brings in variables WIDTH and HEIGHT
 eval "$(xdotool getwindowgeometry --shell $window)"
 
 
 if (( HEIGHT > 100 )); then
-  TX=$(( WIDTH / 2))
-  TY=$(( HEIGHT / 2))
+
+  if [[ $name == i2x\ * ]]; then
+    TX=80
+    TY=0
+    else
+    TX=$(( WIDTH / 2))
+    TY=$(( HEIGHT / 2))
+  fi
 
   xdotool mousemove -window $window $TX $TY
   # iank, original says "Check for height of 100 assumes that anything
index e6c3d6d3db205bac09d999d9d4d563508f057b37..c88a3042d5b85d35c226e9b74fadfa07ccaf73b7 100755 (executable)
@@ -57,16 +57,15 @@ while true; do
   run_as_nonroot=true
 
   if $run_as_nonroot; then
-  # settings that go away when exim gets upgraded. obviously the best
-  # way to do this would be to modify the exim package itself, but this
-  # is easier.
-  caps=$(getcap /usr/sbin/exim4)
-  if [[ ! $caps ]]; then
-    echo "$0: setting capabilities, user and setuid/gid on /usr/sbin/exim4"
-    chown Debian-exim:Debian-exim /usr/sbin/exim4
-    chmod g+s,u+s /usr/sbin/exim4
-    setcap CAP_NET_BIND_SERVICE+ei /usr/sbin/exim4
+    # settings that go away when exim gets upgraded. obviously the best
+    # way to do this would be to modify the exim package itself, but this
+    # is easier.
+    caps=$(getcap /usr/sbin/exim4)
+    if [[ ! $caps ]]; then
+      echo "$0: setting capabilities, user and setuid/gid on /usr/sbin/exim4"
+      chown Debian-exim:Debian-exim /usr/sbin/exim4
+      chmod g+s,u+s /usr/sbin/exim4
+      setcap CAP_NET_BIND_SERVICE+ei /usr/sbin/exim4
+    fi
   fi
-
-
 done
index 596c9b31af69b860de41874958605fb8071ab074..f2d1c50b323fde42194d108709c224cc9939ef4e 100644 (file)
@@ -33,11 +33,6 @@ type master;
 file "/var/lib/bind/db.zroe.org.signed";
 };
 
-zone "expertpathologyreview.com" {
-type master;
-file "/var/lib/bind/db.expertpathologyreview.com.signed";
-};
-
 zone "amnimal.ninja" {
 type master;
 file "/var/lib/bind/db.amnimal.ninja.signed";
index 23d1e23476e6a77dfc368b713d831568b0e414c4..8e7050607a72a8e88d55c6d984ae59eb6fbd742a 100755 (executable)
@@ -289,7 +289,7 @@ main() {
   local -a p_unexpected_spamd_results p_missing_dnswl p_last_usec
   case $HOSTNAME in
     bk)
-      folders=(/m/md/{expertpathologyreview.com,amnimal.ninja}/testignore)
+      folders=(/m/md/{amnimal.ninja}/testignore)
       froms=(ian@iankelling.org z@zroe.org testignore@je.b8.nz iank@gnu.org)
       ;;
     je)
@@ -299,7 +299,7 @@ main() {
     *)
       folders=(/m/md/l/testignore)
       # save some cpu cycles
-      froms=(testignore@je.b8.nz testignore@expertpathologyreview.com testignore@amnimal.ninja ian@iankelling.org z@zroe.org)
+      froms=(testignore@je.b8.nz testignore@amnimal.ninja ian@iankelling.org z@zroe.org)
       if ! $int; then
         ### begin rsyncing fencepost email ###
         # We dont want to exit if rsync fails, that will get caught by
index 9e72d5747da55d3a5e48b23340a798a1d59a5876..2555a2152a8bcff677214f4f399c0ef633badc26 100644 (file)
+
 [global]
+    ### Display ###
+
+    # Which monitor should the notifications be displayed on.
     monitor = 0
-    follow = mouse
-    geometry = "300x5-30+20"
+
+    # Display notification on focused monitor.  Possible modes are:
+    #   mouse: follow mouse pointer
+    #   keyboard: follow window with keyboard focus
+    #   none: don't follow anything
+    #
+    # "keyboard" needs a window manager that exports the
+    # _NET_ACTIVE_WINDOW property.
+    # This should be the case for almost all modern window managers.
+    #
+    # If this option is set to mouse or keyboard, the monitor option
+    # will be ignored.
+    follow = none
+
+    ### Geometry ###
+
+    # dynamic width from 0 to 300
+    # width = (0, 300)
+    # constant width of 300
+    width = 300
+
+    # The maximum height of a single notification, excluding the frame.
+    height = 300
+
+    # Position the notification in the top right corner
+    origin = top-right
+
+    # Offset from the origin
+    offset = 700x50
+
+    # Scale factor. It is auto-detected if value is 0.
+    scale = 0
+
+    # Maximum number of notification (0 means no limit)
+    notification_limit = 20
+
+    ### Progress bar ###
+
+    # Turn on the progess bar. It appears when a progress hint is passed with
+    # for example dunstify -h int:value:12
+    progress_bar = true
+
+    # Set the progress bar height. This includes the frame, so make sure
+    # it's at least twice as big as the frame width.
+    progress_bar_height = 10
+
+    # Set the frame width of the progress bar
+    progress_bar_frame_width = 1
+
+    # Set the minimum width for the progress bar
+    progress_bar_min_width = 150
+
+    # Set the maximum width for the progress bar
+    progress_bar_max_width = 300
+
+    # Corner radius for the progress bar. 0 disables rounded corners.
+    progress_bar_corner_radius = 0
+
+    # Corner radius for the icon image.
+    icon_corner_radius = 0
+
+    # Show how many messages are currently hidden (because of
+    # notification_limit).
     indicate_hidden = yes
-    shrink = no
+
+    # The transparency of the window.  Range: [0; 100].
+    # This option will only work if a compositing window manager is
+    # present (e.g. xcompmgr, compiz, etc.). (X11 only)
     transparency = 0
-    notification_height = 0
+
+    # Draw a line of "separator_height" pixel height between two
+    # notifications.
+    # Set to 0 to disable.
+    # If gap_size is greater than 0, this setting will be ignored.
     separator_height = 2
+
+    # Padding between text and separator.
     padding = 8
+
+    # Horizontal padding.
     horizontal_padding = 8
+
+    # Padding between text and icon.
+    text_icon_padding = 0
+
+    # Defines width in pixels of frame around the notification window.
+    # Set to 0 to disable.
     frame_width = 3
+
+    # Defines color of the frame around the notification window.
     frame_color = "#aaaaaa"
+
+    # Size of gap to display between notifications - requires a compositor.
+    # If value is greater than 0, separator_height will be ignored and a border
+    # of size frame_width will be drawn around each notification instead.
+    # Click events on gaps do not currently propagate to applications below.
+    gap_size = 0
+
+    # Define a color for the separator.
+    # possible values are:
+    #  * auto: dunst tries to find a color fitting to the background;
+    #  * foreground: use the same color as the foreground;
+    #  * frame: use the same color as the frame;
+    #  * anything else will be interpreted as a X color.
     separator_color = frame
+
+    # Sort messages by urgency.
     sort = yes
-    idle_threshold = 120
+
+    # Don't remove messages, if the user is idle (no mouse or keyboard input)
+    # for longer than idle_threshold seconds.
+    # Set to 0 to disable.
+    # A client can set the 'transient' hint to bypass this. See the rules
+    # section for how to disable this if necessary
+    # idle_threshold = 120
+
+    ### Text ###
+
     font = Monospace 8
+
+    # The spacing between lines.  If the height is smaller than the
+    # font height, it will get raised to the font height.
     line_height = 0
+
+    # Possible values are:
+    # full: Allow a small subset of html markup in notifications:
+    #        <b>bold</b>
+    #        <i>italic</i>
+    #        <s>strikethrough</s>
+    #        <u>underline</u>
+    #
+    #        For a complete reference see
+    #        <https://docs.gtk.org/Pango/pango_markup.html>.
+    #
+    # strip: This setting is provided for compatibility with some broken
+    #        clients that send markup even though it's not enabled on the
+    #        server. Dunst will try to strip the markup but the parsing is
+    #        simplistic so using this option outside of matching rules for
+    #        specific applications *IS GREATLY DISCOURAGED*.
+    #
+    # no:    Disable markup parsing, incoming notifications will be treated as
+    #        plain text. Dunst will not advertise that it has the body-markup
+    #        capability if this is set as a global setting.
+    #
+    # It's important to note that markup inside the format option will be parsed
+    # regardless of what this is set to.
     markup = full
+
+    # The format of the message.  Possible variables are:
+    #   %a  appname
+    #   %s  summary
+    #   %b  body
+    #   %i  iconname (including its path)
+    #   %I  iconname (without its path)
+    #   %p  progress value if set ([  0%] to [100%]) or nothing
+    #   %n  progress value if set without any extra characters
+    #   %%  Literal %
+    # Markup is allowed
     format = "<b>%s</b>\n%b"
+
+    # Alignment of message text.
+    # Possible values are "left", "center" and "right".
     alignment = left
+
+    # Vertical alignment of message text and icon.
+    # Possible values are "top", "center" and "bottom".
     vertical_alignment = center
+
+    # Show age of message if message is older than show_age_threshold
+    # seconds.
+    # Set to -1 to disable.
     show_age_threshold = 60
-    word_wrap = yes
+
+    # Specify where to make an ellipsis in long lines.
+    # Possible values are "start", "middle" and "end".
     ellipsize = middle
+
+    # Ignore newlines '\n' in notifications.
     ignore_newline = no
+
+    # Stack together notifications with the same content
     stack_duplicates = true
+
+    # Hide the count of stacked notifications with the same content
     hide_duplicate_count = false
+
+    # Display indicators for URLs (U) and actions (A).
     show_indicators = yes
+
+    ### Icons ###
+
+    # Recursive icon lookup. You can set a single theme, instead of having to
+    # define all lookup paths.
+    enable_recursive_icon_lookup = true
+
+    # Set icon theme (only used for recursive icon lookup)
+    icon_theme = Adwaita
+    # You can also set multiple icon themes, with the leftmost one being used first.
+    # icon_theme = "Adwaita, breeze"
+
+    # Align icons left/right/top/off
     icon_position = left
-    min_icon_size = 0
-    max_icon_size = 32
+
+    # Scale small icons up to this size, set to 0 to disable. Helpful
+    # for e.g. small files or high-dpi screens. In case of conflict,
+    # max_icon_size takes precedence over this.
+    min_icon_size = 32
+
+    # Scale larger icons down to this size, set to 0 to disable
+    max_icon_size = 128
+
+    # Paths to default icons (only neccesary when not using recursive icon lookup)
     icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/
+
+    ### History ###
+
+    # Should a notification popped up from history be sticky or timeout
+    # as if it would normally do.
     sticky_history = yes
+
+    # Maximum amount of notifications kept in history
     history_length = 20
+
+    ### Misc/Advanced ###
+
+    # dmenu path.
     dmenu = /usr/bin/dmenu -p dunst:
-    browser = /usr/bin/sensible-browser
+
+    # Browser for opening urls in context menu.
+    browser = /usr/bin/xdg-open
+
+    # Always run rule-defined scripts, even if the notification is suppressed
     always_run_script = true
+
+    # Define the title of the windows spawned by dunst
     title = Dunst
+
+    # Define the class of the windows spawned by dunst
     class = Dunst
-    startup_notification = false
-    verbosity = mesg
+
+    # Define the corner radius of the notification window
+    # in pixel size. If the radius is 0, you have no rounded
+    # corners.
+    # The radius will be automatically lowered if it exceeds half of the
+    # notification height to avoid clipping text and/or icons.
     corner_radius = 0
+
+    # Ignore the dbus closeNotification message.
+    # Useful to enforce the timeout set by dunst configuration. Without this
+    # parameter, an application may close the notification sent before the
+    # user defined timeout.
     ignore_dbusclose = false
+
+    ### Wayland ###
+    # These settings are Wayland-specific. They have no effect when using X11
+
+    # Uncomment this if you want to let notications appear under fullscreen
+    # applications (default: overlay)
+    # layer = top
+
+    # Set this to true to use X11 output on Wayland.
+    force_xwayland = false
+
+    ### Legacy
+
+    # Use the Xinerama extension instead of RandR for multi-monitor support.
+    # This setting is provided for compatibility with older nVidia drivers that
+    # do not support RandR and using it on systems that support RandR is highly
+    # discouraged.
+    #
+    # By enabling this setting dunst will not be able to detect when a monitor
+    # is connected or disconnected which might break follow mode if the screen
+    # layout changes.
     force_xinerama = false
+
+    ### mouse
+
+    # Defines list of actions for each mouse event
+    # Possible values are:
+    # * none: Don't do anything.
+    # * do_action: Invoke the action determined by the action_name rule. If there is no
+    #              such action, open the context menu.
+    # * open_url: If the notification has exactly one url, open it. If there are multiple
+    #             ones, open the context menu.
+    # * close_current: Close current notification.
+    # * close_all: Close all notifications.
+    # * context: Open context menu for the notification.
+    # * context_all: Open context menu for all notifications.
+    # These values can be strung together for each mouse event, and
+    # will be executed in sequence.
     mouse_left_click = close_current
     mouse_middle_click = do_action, close_current
     mouse_right_click = close_all
+
+# Experimental features that may or may not work correctly. Do not expect them
+# to have a consistent behaviour across releases.
 [experimental]
+    # Calculate the dpi to use on a per-monitor basis.
+    # If this setting is enabled the Xft.dpi value will be ignored and instead
+    # dunst will attempt to calculate an appropriate dpi value for each monitor
+    # using the resolution and physical size. This might be useful in setups
+    # where there are multiple screens with very different dpi values.
     per_monitor_dpi = false
-[shortcuts]
-    close = ctrl+space
-    close_all = ctrl+shift+space
-    history = ctrl+grave
-    context = ctrl+shift+period
+
+
 [urgency_low]
+    # IMPORTANT: colors have to be defined in quotation marks.
+    # Otherwise the "#" and following would be interpreted as a comment.
     background = "#222222"
     foreground = "#888888"
     timeout = 10
+    # Icon for notifications with low urgency, uncomment to enable
+    #default_icon = /path/to/icon
+
 [urgency_normal]
     background = "#285577"
     foreground = "#ffffff"
     timeout = 10
+    # Icon for notifications with normal urgency, uncomment to enable
+    #default_icon = /path/to/icon
+
 [urgency_critical]
     background = "#900000"
     foreground = "#ffffff"
     frame_color = "#ff0000"
     timeout = 0
+    # Icon for notifications with critical urgency, uncomment to enable
+    #default_icon = /path/to/icon
+
+# Every section that isn't one of the above is interpreted as a rules to
+# override settings for certain messages.
+#
+# Messages can be matched by
+#    appname (discouraged, see desktop_entry)
+#    body
+#    category
+#    desktop_entry
+#    icon
+#    match_transient
+#    msg_urgency
+#    stack_tag
+#    summary
+#
+# and you can override the
+#    background
+#    foreground
+#    format
+#    frame_color
+#    fullscreen
+#    new_icon
+#    set_stack_tag
+#    set_transient
+#    set_category
+#    timeout
+#    urgency
+#    icon_position
+#    skip_display
+#    history_ignore
+#    action_name
+#    word_wrap
+#    ellipsize
+#    alignment
+#    hide_text
+#
+# Shell-like globbing will get expanded.
+#
+# Instead of the appname filter, it's recommended to use the desktop_entry filter.
+# GLib based applications export their desktop-entry name. In comparison to the appname,
+# the desktop-entry won't get localized.
+#
+# SCRIPTING
+# You can specify a script that gets run when the rule matches by
+# setting the "script" option.
+# The script will be called as follows:
+#   script appname summary body icon urgency
+# where urgency can be "LOW", "NORMAL" or "CRITICAL".
+#
+# NOTE: It might be helpful to run dunst -print in a terminal in order
+# to find fitting options for rules.
+
+# Disable the transient hint so that idle_threshold cannot be bypassed from the
+# client
+#[transient_disable]
+#    match_transient = yes
+#    set_transient = no
+#
+# Make the handling of transient notifications more strict by making them not
+# be placed in history.
+#[transient_history_ignore]
+#    match_transient = yes
+#    history_ignore = yes
+
+# fullscreen values
+# show: show the notifications, regardless if there is a fullscreen window opened
+# delay: displays the new notification, if there is no fullscreen window active
+#        If the notification is already drawn, it won't get undrawn.
+# pushback: same as delay, but when switching into fullscreen, the notification will get
+#           withdrawn from screen again and will get delayed like a new notification
+#[fullscreen_delay_everything]
+#    fullscreen = delay
+#[fullscreen_show_critical]
+#    msg_urgency = critical
+#    fullscreen = show
+
+#[espeak]
+#    summary = "*"
+#    script = dunst_espeak.sh
+
+#[script-test]
+#    summary = "*script*"
+#    script = dunst_test.sh
+
+#[ignore]
+#    # This notification will not be displayed
+#    summary = "foobar"
+#    skip_display = true
+
+#[history-ignore]
+#    # This notification will not be saved in history
+#    summary = "foobar"
+#    history_ignore = yes
+
+#[skip-display]
+#    # This notification will not be displayed, but will be included in the history
+#    summary = "foobar"
+#    skip_display = yes
+
+#[signed_on]
+#    appname = Pidgin
+#    summary = "*signed on*"
+#    urgency = low
+#
+#[signed_off]
+#    appname = Pidgin
+#    summary = *signed off*
+#    urgency = low
+#
+#[says]
+#    appname = Pidgin
+#    summary = *says*
+#    urgency = critical
+#
+#[twitter]
+#    appname = Pidgin
+#    summary = *twitter.com*
+#    urgency = normal
+#
+#[stack-volumes]
+#    appname = "some_volume_notifiers"
+#    set_stack_tag = "volume"
+#
+# vim: ft=cfg
+
+
+# above are the defaults from t12 in /etc/xdg/dunst/dunstrc,
+# except i changed offset from the default of
+#    offset = 10x50
 
-# above are the defaults from t11 in /etc/xdg/dunst/dunstrc
 
 [play_sound]
     stack_tag = "profanity"
     script = /b/ds/sound-alert
 
-
 # default light blue is too light
 #[urgency_normal]
 #    background = "#335EA8"