From e64ef321121727e02aa8c3c142e609abe365f03f Mon Sep 17 00:00:00 2001 From: cubernetes Date: Fri, 16 Oct 2026 15:55:34 +0200 Subject: [PATCH 1/2] Implement custom bash_completion loading so it doesn't conflict with bashrc_forward plugin --- modules/home-manager/bash.nix | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/home-manager/bash.nix b/modules/home-manager/bash.nix index 0000c74..5943aa3 100644 --- a/modules/home-manager/bash.nix +++ b/modules/home-manager/bash.nix @@ -1,10 +1,14 @@ -{ ... }: +{ pkgs, ... }: { programs.bash = { enable = true; + enableCompletion = false; initExtra = '' - [ "''${BASH_COMPLETION_VERSINFO-}" ] || unset -v BASH_COMPLETION_VERSINFO +if [[ ! -v BASH_COMPLETION_VERSINFO ]] && + [[ -f "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh" ]]; then + source "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh" +fi [ "$DISPLAY" ] && xset r rate 300 60 From 10c415c3e5d90f462d31a669ce719b0a091001b9 Mon Sep 17 00:00:00 2001 From: cubernetes Date: Fri, 16 Oct 2026 15:55:48 +0200 Subject: [PATCH 2/2] Fix cd function and dedent everything so it's nice and clean --- modules/home-manager/bash.nix | 470 +++++++++++++++++----------------- 1 file changed, 235 insertions(+), 235 deletions(-) diff --git a/modules/home-manager/bash.nix b/modules/home-manager/bash.nix index 5943aa3..8a1f2a9 100644 --- a/modules/home-manager/bash.nix +++ b/modules/home-manager/bash.nix @@ -10,259 +10,259 @@ if [[ ! -v BASH_COMPLETION_VERSINFO ]] && source "${pkgs.bash-completion}/etc/profile.d/bash_completion.sh" fi - [ "$DISPLAY" ] && xset r rate 300 60 +[ "$DISPLAY" ] && xset r rate 300 60 - #-##################### user specific aliases and functions ###################### - if [ -d ~/.bashrc.d ]; then - for rc in ~/.bashrc.d/*; do - bn=''${rc##*/} - if [ -f "''$rc" ] && [ -r "''$rc" ] && [ ! "''${bn::1}" = '.' ]; then - \. "''$rc" - fi - done - fi - unset rc bn +#-##################### user specific aliases and functions ###################### +if [ -d ~/.bashrc.d ]; then + for rc in ~/.bashrc.d/*; do + bn=''${rc##*/} + if [ -f "''$rc" ] && [ -r "''$rc" ] && [ ! "''${bn::1}" = '.' ]; then + \. "''$rc" + fi + done +fi +unset rc bn - #-########################### shell settings & options ########################### - set -E - set -o pipefail +#-########################### shell settings & options ########################### +set -E +set -o pipefail - shopt -s nullglob dotglob globstar extglob - shopt -s autocd cdable_vars cdspell - shopt -s checkwinsize - shopt -s lastpipe - shopt -s inherit_errexit - shopt -s no_empty_cmd_completion - shopt -s histreedit - shopt -s lithist - shopt -u histverify - _have bash_abbr && shopt -u expand_aliases +shopt -s nullglob dotglob globstar extglob +shopt -s autocd cdable_vars cdspell +shopt -s checkwinsize +shopt -s lastpipe +shopt -s inherit_errexit +shopt -s no_empty_cmd_completion +shopt -s histreedit +shopt -s lithist +shopt -u histverify +_have bash_abbr && shopt -u expand_aliases - #-############################### shell variables ################################ - FIGNORE='.o' - HISTCONTROL=ignoreboth:erasedups - HISTTIMEFORMAT='%y-%m-%d %H:%M:%S ' - HISTSIZE=-1 - HISTFILESIZE=-1 - HISTFILE=''$HOME/.''${USER:-default}_bash_history +#-############################### shell variables ################################ +FIGNORE='.o' +HISTCONTROL=ignoreboth:erasedups +HISTTIMEFORMAT='%y-%m-%d %H:%M:%S ' +HISTSIZE=-1 +HISTFILESIZE=-1 +HISTFILE=''$HOME/.''${USER:-default}_bash_history - #-############################ environment variables ############################# - export PYTHON_BASIC_REPL=1 # I'm good at readline so I'm gonna use readline whereever possible! - export LESS='-SRFX' - export PAGER='less' GIT_PAGER='less' MANPAGER='less' SYSTEMD_PAGER='less' - export BAT_PAGER=''' - export EDITOR='vim' VISUAL='vim' FCEDIT='vim' SYSTEMD_EDITOR='vim' - export PATH +#-############################ environment variables ############################# +export PYTHON_BASIC_REPL=1 # I'm good at readline so I'm gonna use readline whereever possible! +export LESS='-SRFX' +export PAGER='less' GIT_PAGER='less' MANPAGER='less' SYSTEMD_PAGER='less' +export BAT_PAGER=''' +export EDITOR='vim' VISUAL='vim' FCEDIT='vim' SYSTEMD_EDITOR='vim' +export PATH - #-########################## generally useful functions ########################## - take () { - : 'Idempotently create directory recursively and cd into it' - local out - out=''$(set -o pipefail && mkdir -vp "''$@" | tail -1) || return - printf '%s\n' "''$out" - eval "out=''${out#"mkdir: created directory "}" - CDPATH= cd "''${out:-''${@: -1}}" - } +#-########################## generally useful functions ########################## +take () { + : 'Idempotently create directory recursively and cd into it' + local out + out=''$(set -o pipefail && mkdir -vp "''$@" | tail -1) || return + printf '%s\n' "''$out" + eval "out=''${out#"mkdir: created directory "}" + CDPATH= cd "''${out:-''${@: -1}}" +} - cd () { - : 'Run cd; on success in a terminal, show the 4 newest entries (with a count of hidden ones)' +cd () { + : 'Run cd; on success in a terminal, show the 4 newest entries (with a count of hidden ones)' - builtin cd "''$@" || return - [[ -t 1 ]] || return 0 - command -v ls &>/dev/null || return 0 + builtin cd "''$@" || return + [[ -t 1 ]] || return 0 + command -v ls &>/dev/null || return 0 - local -a lines - mapfile -t lines < <(command ls --color=always --quoting-style=shell-escape -lArth) - if (( ''${#lines[@]} > 10 )); then - printf '\033[7m... %d more entries ...\033[27m\n' "$(( ''${#lines[@]} - 10 ))"; - printf '%s\n' "''${lines[@]: -4}" - else - printf '%s\n' "''${lines[@]}" - fi - } + local -a lines + mapfile -t lines < <(command ls --color=always --quoting-style=shell-escape -lArth) + if (( ''${#lines[@]} > 10 )); then + printf '\033[7m... %d more entries ...\033[27m\n' "$(( ''${#lines[@]} - 10 ))"; + printf '%s\n' "''${lines[@]: -9}" + else + printf '%s\n' "''${lines[@]}" + fi +} - drop_caches () { - : 'Drop pagecache, dentries and inodes' - : 'https://unix.stackexchange.com/a/87909' - echo 3 | sudo tee /proc/sys/vm/drop_caches >/dev/null - } +drop_caches () { + : 'Drop pagecache, dentries and inodes' + : 'https://unix.stackexchange.com/a/87909' + echo 3 | sudo tee /proc/sys/vm/drop_caches >/dev/null +} - respawn_shell () { - : 'Intelligently respawn shell' - : 'pure posix sh without forking' - if [ "''${BASH_VERSINFO-}" ] && command -v bash 1>/dev/null 2>&1; then - if _is_login_shell; then - exec bash -l - else - exec bash - fi - : 'TODO: Implement more detection mechanisms for various shells (zsh, etc.)' - elif [ -x /proc/self/exe ]; then - if _is_login_shell; then - exec -l /proc/self/exe - else - exec /proc/self/exe - fi - elif command -v "''${0#-}" 1>/dev/null 2>&1; then - : 'TODO: Make it work with shells that actually start with a dash (unlikely, but possible)' - printf 'Warning: replacing current shell with unreliable ''$0, which is: %s\n' "''$0" - if _is_login_shell; then - exec -l "''${0#-}" - else - exec "''${0#-}" - fi - else - printf 'Error: Don'\'''t know how to reliably replace this shell, not exec'\'''ing and not exiting\n' - printf 'You might want to manually run `exec [-l] "''$SHELL"`, however, `''$SHELL` might not be the shell you are currently running' - return 1 - fi - } +respawn_shell () { + : 'Intelligently respawn shell' + : 'pure posix sh without forking' + if [ "''${BASH_VERSINFO-}" ] && command -v bash 1>/dev/null 2>&1; then + if _is_login_shell; then + exec bash -l + else + exec bash + fi + : 'TODO: Implement more detection mechanisms for various shells (zsh, etc.)' + elif [ -x /proc/self/exe ]; then + if _is_login_shell; then + exec -l /proc/self/exe + else + exec /proc/self/exe + fi + elif command -v "''${0#-}" 1>/dev/null 2>&1; then + : 'TODO: Make it work with shells that actually start with a dash (unlikely, but possible)' + printf 'Warning: replacing current shell with unreliable ''$0, which is: %s\n' "''$0" + if _is_login_shell; then + exec -l "''${0#-}" + else + exec "''${0#-}" + fi + else + printf 'Error: Don'\'''t know how to reliably replace this shell, not exec'\'''ing and not exiting\n' + printf 'You might want to manually run `exec [-l] "''$SHELL"`, however, `''$SHELL` might not be the shell you are currently running' + return 1 + fi +} - export_bashrc () { - CDPATH= command cd ~/.bashrc.d/ || return - : 'Not using an associative array because those are not sorted!' - declare -ar plugins=(*) - [[ ''${#plugins[@]} -eq 0 ]] || [[ ''${#plugins} -eq 1 && ''${plugins[0]} = '*' ]] && return - local IFS=' ' - declare -Ai selected - declare plugin - for plugin in "''${plugins[@]}"; do - case "''$plugin" in - #-# Comment below case match if you don'\'''t want to have a pre-selection of plugins to export - #-# Requires `shopt -s extglob` - (+([0-9])-@(util|redact|prompt|docker-tools|funcs|init-and-complete|general-aliases|bash-abbr)) selected[''$plugin]=1 ;; - (*) selected[''$plugin]= - esac - done - declare -a plugins_with_selection - while :; do - local PS3='Which plugins do you want to export/not export (enter a single number)? ' - plugins_with_selection=() - for plugin in "''${plugins[@]}"; do - if [[ ''${selected[''$plugin]} -eq 0 ]]; then - plugins_with_selection+=(''$'\033[31m'''$plugin''$'\033[m') - else - plugins_with_selection+=(''$'\033[32m'''$plugin''$'\033[m') - fi - done - select plugin in ''$'\033[31mQUIT\033[m' ''$'\033[34mDONE\033[m' "''${plugins_with_selection[@]}"; do - plugin=''${plugin#''$'\033[3'[0-7]m} - plugin=''${plugin%''$'\033[m'} - [[ -z ''$REPLY || ''$plugin = QUIT || ''$plugin = DONE ]] && break 2 - [[ -z ''$plugin ]] && { echo "Please enter a number (1-''$((''${#plugins[@]}+2)))."; continue; } - selected[''$plugin]=1-''${selected[''$plugin]} - break - done - [[ -z ''$REPLY || ''$plugin = QUIT || ''$plugin = DONE ]] && break - done - [[ -z ''$REPLY || ''$plugin = QUIT ]] && { echo "Aborting"; return; } - declare -a exported_plugins=() - for plugin in "''${!selected[@]}"; do - if [[ ''${selected[''$plugin]} -eq 1 ]]; then - exported_plugins+=(".bashrc.d/''$plugin") - fi - done - command rm -vf "exported_bashrc.tar.gz" - CDPATH= command cd - >/dev/null - CDPATH= command cd ~ - as_base64=''$(command tar -cvhzf - ".bashrc" "''${exported_plugins[@]}" | base64 -w0) - CDPATH= command cd - >/dev/null - as_base64_wrapped=''$(printf %s "''$as_base64" | sed 's#.\{,70\}#'\'''&'\'''\\\n#g' | sed ''\'''$s#\\$##') - command install -m775 /dev/stdin ~/bashrc_installer.sh <<-EOF - #! /usr/bin/env bash +export_bashrc () { + CDPATH= command cd ~/.bashrc.d/ || return + : 'Not using an associative array because those are not sorted!' + declare -ar plugins=(*) + [[ ''${#plugins[@]} -eq 0 ]] || [[ ''${#plugins} -eq 1 && ''${plugins[0]} = '*' ]] && return + local IFS=' ' + declare -Ai selected + declare plugin + for plugin in "''${plugins[@]}"; do + case "''$plugin" in + #-# Comment below case match if you don'\'''t want to have a pre-selection of plugins to export + #-# Requires `shopt -s extglob` + (+([0-9])-@(util|redact|prompt|docker-tools|funcs|init-and-complete|general-aliases|bash-abbr)) selected[''$plugin]=1 ;; + (*) selected[''$plugin]= + esac + done + declare -a plugins_with_selection + while :; do + local PS3='Which plugins do you want to export/not export (enter a single number)? ' + plugins_with_selection=() + for plugin in "''${plugins[@]}"; do + if [[ ''${selected[''$plugin]} -eq 0 ]]; then + plugins_with_selection+=(''$'\033[31m'''$plugin''$'\033[m') + else + plugins_with_selection+=(''$'\033[32m'''$plugin''$'\033[m') + fi + done + select plugin in ''$'\033[31mQUIT\033[m' ''$'\033[34mDONE\033[m' "''${plugins_with_selection[@]}"; do + plugin=''${plugin#''$'\033[3'[0-7]m} + plugin=''${plugin%''$'\033[m'} + [[ -z ''$REPLY || ''$plugin = QUIT || ''$plugin = DONE ]] && break 2 + [[ -z ''$plugin ]] && { echo "Please enter a number (1-''$((''${#plugins[@]}+2)))."; continue; } + selected[''$plugin]=1-''${selected[''$plugin]} + break + done + [[ -z ''$REPLY || ''$plugin = QUIT || ''$plugin = DONE ]] && break + done + [[ -z ''$REPLY || ''$plugin = QUIT ]] && { echo "Aborting"; return; } + declare -a exported_plugins=() + for plugin in "''${!selected[@]}"; do + if [[ ''${selected[''$plugin]} -eq 1 ]]; then + exported_plugins+=(".bashrc.d/''$plugin") + fi + done + command rm -vf "exported_bashrc.tar.gz" + CDPATH= command cd - >/dev/null + CDPATH= command cd ~ + as_base64=''$(command tar -cvhzf - ".bashrc" "''${exported_plugins[@]}" | base64 -w0) + CDPATH= command cd - >/dev/null + as_base64_wrapped=''$(printf %s "''$as_base64" | sed 's#.\{,70\}#'\'''&'\'''\\\n#g' | sed ''\'''$s#\\$##') + command install -m775 /dev/stdin ~/bashrc_installer.sh <<-EOF + #! /usr/bin/env bash - set -e + set -e - [ "\''$BASH_VERSINFO" ] && command -v declare >/dev/null 2>&1 && command declare -p BASH_VERSINFO | { IFS=' ' read -r _ flags _; case "\''$flags" in (*r*) ;; (*) false; esac; } || { printf 'This installer must be run with bash!\\n'; exit 1; } - command -v bash >/dev/null 2>&1 || { printf 'bash must be installed!\\n'; exit 2; } + [ "\''$BASH_VERSINFO" ] && command -v declare >/dev/null 2>&1 && command declare -p BASH_VERSINFO | { IFS=' ' read -r _ flags _; case "\''$flags" in (*r*) ;; (*) false; esac; } || { printf 'This installer must be run with bash!\\n'; exit 1; } + command -v bash >/dev/null 2>&1 || { printf 'bash must be installed!\\n'; exit 2; } - as_base64=''$as_base64_wrapped - tempdir=\''$(mktemp -d) - trap 'rm -rf -- "\''$tempdir"' EXIT - cd -- "\''$tempdir" - base64 -d <<< "\''$as_base64" | tar xzf - - create_dir_and_move () { - src=\''$1 - dst=\''$2 - [ ! -f "\''$src" ] && { printf '%s\\n' "Source argument '\''$src' is not a regular file"; return 1; } - dst_dir=\''$(dirname -- "\''${dst//[^!-~]/-}") - [ ! -d "\''$dst_dir" ] && { printf '%s\\n' "Trying to create destination directory '\''$dst_dir'"; mkdir -p -- "\''$dst_dir"; } || : - [ -d "\''$dst_dir" ] && mv -v -t "\''$dst_dir" -- "\''$src" || : - } - ask_overwrite () { - file1=\''$1 - file2=\''$2 - if [[ ! -e \''$file2 ]]; then - create_dir_and_move "\''$file1" "\''$file2" - elif [[ -d \''$file2 ]]; then - printf 'WARNING: Destination file %s is a directory! Skipping this file\\n' "\''${file2@Q}" - return - elif [[ ! -f \''$file2 ]]; then - printf 'WARNING: Destination file %s is not a regular file! Skipping this file\\n' "\''${file2@Q}" - return - elif ! diff -q "\''$file1" "\''$file2"; then - printf 'File to be installed (%s) differs from already installed file (%s)\\n' "\''${file1@Q}" "\''${file2@Q}" - read -p 'Press enter to show diff. ' || : - diff --color -u "\''$file1" "\''$file2" || : - printf 'Giving you a plain bash shell to resolve the situation. Once done, just exit.\\n' - printf 'After you exit, the destination file WILL BE FORCEFULLY OVERWRITTEN!!!\n' - read -p 'Press enter to continue in the shell. ' || : - bash --rcfile <(printf 'cd; printf "You are running bash version \''$BASH_VERSION. Your CWD is \''$PWD. Your HOME is \''$HOME. You are \''$USER and HOSTNAME is \''$HOSTNAME.\\nUse this bash shell to make changes, backups, etc.\\nThen just exit.\\n"') --noprofile || : - printf 'Destination file %s will be overwritten. Continue? ' "\''${file2@Q}" - read || : - create_dir_and_move "\''$file1" "\''$file2" - else - printf 'File %s was not changed\\n' "\''${file2@Q}" - fi - } - ask_overwrite .bashrc ~/.bashrc - set +f - shopt -s nullglob dotglob - for file in .bashrc.d/*; do - ask_overwrite "\''$file" ~/"\''$file" - done - cd - >/dev/null - read -p 'Self destruct (y/N)? ' choice || : - [[ \''$choice = y ]] && { printf 'Trying to rm myself (%s)\\n' "\''${0@Q}"; rm -- "\''$0" && printf 'Success\\n' || printf 'Failed. Not trying further\\n'; } - EOF - } + as_base64=''$as_base64_wrapped + tempdir=\''$(mktemp -d) + trap 'rm -rf -- "\''$tempdir"' EXIT + cd -- "\''$tempdir" + base64 -d <<< "\''$as_base64" | tar xzf - + create_dir_and_move () { + src=\''$1 + dst=\''$2 + [ ! -f "\''$src" ] && { printf '%s\\n' "Source argument '\''$src' is not a regular file"; return 1; } + dst_dir=\''$(dirname -- "\''${dst//[^!-~]/-}") + [ ! -d "\''$dst_dir" ] && { printf '%s\\n' "Trying to create destination directory '\''$dst_dir'"; mkdir -p -- "\''$dst_dir"; } || : + [ -d "\''$dst_dir" ] && mv -v -t "\''$dst_dir" -- "\''$src" || : + } + ask_overwrite () { + file1=\''$1 + file2=\''$2 + if [[ ! -e \''$file2 ]]; then + create_dir_and_move "\''$file1" "\''$file2" + elif [[ -d \''$file2 ]]; then + printf 'WARNING: Destination file %s is a directory! Skipping this file\\n' "\''${file2@Q}" + return + elif [[ ! -f \''$file2 ]]; then + printf 'WARNING: Destination file %s is not a regular file! Skipping this file\\n' "\''${file2@Q}" + return + elif ! diff -q "\''$file1" "\''$file2"; then + printf 'File to be installed (%s) differs from already installed file (%s)\\n' "\''${file1@Q}" "\''${file2@Q}" + read -p 'Press enter to show diff. ' || : + diff --color -u "\''$file1" "\''$file2" || : + printf 'Giving you a plain bash shell to resolve the situation. Once done, just exit.\\n' + printf 'After you exit, the destination file WILL BE FORCEFULLY OVERWRITTEN!!!\n' + read -p 'Press enter to continue in the shell. ' || : + bash --rcfile <(printf 'cd; printf "You are running bash version \''$BASH_VERSION. Your CWD is \''$PWD. Your HOME is \''$HOME. You are \''$USER and HOSTNAME is \''$HOSTNAME.\\nUse this bash shell to make changes, backups, etc.\\nThen just exit.\\n"') --noprofile || : + printf 'Destination file %s will be overwritten. Continue? ' "\''${file2@Q}" + read || : + create_dir_and_move "\''$file1" "\''$file2" + else + printf 'File %s was not changed\\n' "\''${file2@Q}" + fi + } + ask_overwrite .bashrc ~/.bashrc + set +f + shopt -s nullglob dotglob + for file in .bashrc.d/*; do + ask_overwrite "\''$file" ~/"\''$file" + done + cd - >/dev/null + read -p 'Self destruct (y/N)? ' choice || : + [[ \''$choice = y ]] && { printf 'Trying to rm myself (%s)\\n' "\''${0@Q}"; rm -- "\''$0" && printf 'Success\\n' || printf 'Failed. Not trying further\\n'; } + EOF +} - #-#################################### binds ##################################### - bind '"\e\C-r": kill-region' \ - '"\C-x\C-k": kill-whole-line' \ - '"\e\C-p": history-search-backward' \ - '"\e\C-n": history-search-forward' \ - '"\eP": history-substring-search-backward' \ - '"\eN": history-substring-search-forward' \ - '"\C-x\C-d": "\e#\C-m exit\C-m"' \ - '"\ej": "\C-e |& tac | \\cat -n | tac | \\cat -n | less -SFXR\C-m"' \ - '"\eX": ">/dev/null "' \ - '"\t": menu-complete' \ - '"\e[Z": menu-complete-backward' \ - '"\C-x\C-r": forward-search-history' \ - 'set show-all-if-ambiguous on' \ - 'set completion-query-items 0' \ - 'set menu-complete-display-prefix on' \ - 'set colored-completion-prefix on' \ - 'set colored-stats on' +#-#################################### binds ##################################### +bind '"\e\C-r": kill-region' \ + '"\C-x\C-k": kill-whole-line' \ + '"\e\C-p": history-search-backward' \ + '"\e\C-n": history-search-forward' \ + '"\eP": history-substring-search-backward' \ + '"\eN": history-substring-search-forward' \ + '"\C-x\C-d": "\e#\C-m exit\C-m"' \ + '"\ej": "\C-e |& tac | \\cat -n | tac | \\cat -n | less -SFXR\C-m"' \ + '"\eX": ">/dev/null "' \ + '"\t": menu-complete' \ + '"\e[Z": menu-complete-backward' \ + '"\C-x\C-r": forward-search-history' \ + 'set show-all-if-ambiguous on' \ + 'set completion-query-items 0' \ + 'set menu-complete-display-prefix on' \ + 'set colored-completion-prefix on' \ + 'set colored-stats on' - #-################################## autoclear ################################### - #-# TODO +#-################################## autoclear ################################### +#-# TODO - #-# prank () { - #-# line_up_until_cursor=''${READLINE_LINE::READLINE_POINT} - #-# line_after_cursor=''${READLINE_LINE:READLINE_POINT} - #-# if [[ ''$((RANDOM % 5)) -eq 0 ]]; then - #-# READLINE_LINE="''$line_up_until_cursor''$line_after_cursor" - #-# #READLINE_LINE="''$line_up_until_cursor''${1^}''$line_after_cursor" - #-# READLINE_POINT=''$((READLINE_POINT+1)) - #-# else - #-# READLINE_LINE="''$line_up_until_cursor''$1''$line_after_cursor" - #-# READLINE_POINT=''$((READLINE_POINT+1)) - #-# fi - #-# } - #-# bind -x '" ": prank " "' - #-# bind -x '"a": prank "a"' +#-# prank () { +#-# line_up_until_cursor=''${READLINE_LINE::READLINE_POINT} +#-# line_after_cursor=''${READLINE_LINE:READLINE_POINT} +#-# if [[ ''$((RANDOM % 5)) -eq 0 ]]; then +#-# READLINE_LINE="''$line_up_until_cursor''$line_after_cursor" +#-# #READLINE_LINE="''$line_up_until_cursor''${1^}''$line_after_cursor" +#-# READLINE_POINT=''$((READLINE_POINT+1)) +#-# else +#-# READLINE_LINE="''$line_up_until_cursor''$1''$line_after_cursor" +#-# READLINE_POINT=''$((READLINE_POINT+1)) +#-# fi +#-# } +#-# bind -x '" ": prank " "' +#-# bind -x '"a": prank "a"' ''; }; }