From 9ce32f5670a89e05f3fe3001143479e4123a4766 Mon Sep 17 00:00:00 2001 From: Zedhugh Chen Date: Mon, 16 Mar 2026 18:23:38 +0800 Subject: [PATCH] dot: change bash configuration --- dot/.bashrc | 40 +++------ dot/.bashrc.d/android-studio.bash | 11 +++ dot/.bashrc.d/fnm.bash | 44 ++++++++++ dot/.bashrc.d/function.bash | 136 ++++++++++++++++++++++++++++++ dot/.bashrc.d/mise.bash | 28 ++++++ dot/.bashrc.d/pip-search.bash | 10 +++ dot/.bashrc.d/pnpm.bash | 24 ++++++ dot/.bashrc.d/proxy.bash | 50 +++++++++++ dot/.bashrc.d/rust.bash | 17 ++++ dot/.bashrc.d/volta.bash | 25 ++++++ 10 files changed, 358 insertions(+), 27 deletions(-) create mode 100644 dot/.bashrc.d/android-studio.bash create mode 100644 dot/.bashrc.d/fnm.bash create mode 100644 dot/.bashrc.d/function.bash create mode 100644 dot/.bashrc.d/mise.bash create mode 100644 dot/.bashrc.d/pip-search.bash create mode 100755 dot/.bashrc.d/pnpm.bash create mode 100644 dot/.bashrc.d/proxy.bash create mode 100644 dot/.bashrc.d/rust.bash create mode 100644 dot/.bashrc.d/volta.bash diff --git a/dot/.bashrc b/dot/.bashrc index 6771d8e..54cebf1 100644 --- a/dot/.bashrc +++ b/dot/.bashrc @@ -23,18 +23,13 @@ HISTCONTROL=ignoreboth # export CCACHE_DIR="/var/cache/ccache" export GPG_TTY=$(tty) -export PATH="~/.local/bin${PATH:+:}$PATH" +export PATH="${HOME}/.local/bin${PATH:+:}$PATH" alias ll="ls -l" alias la="ls -a" alias lh="ls -lh" alias lha="ls -lha" -PROXY_SHELL_FILE="$(realpath ~/.bash_proxy.sh)" -if [[ -e $PROXY_SHELL_FILE ]] ; then - . $PROXY_SHELL_FILE -fi - if [[ "$TERM" == "linux" ]]; then PS1="(tty) $PS1" elif [[ "$TERM" == "fbterm" ]]; then @@ -48,26 +43,17 @@ elif [[ "${TERM}" != "tmux-256color" ]] && [[ -z "${TERM_PROGRAM}" ]] && [[ -x $ tmux fi -alias pip='function _pip() { - if [ $1 == "search" ]; then - pip_search "$2"; - else pip "$@"; - fi; -};_pip' +# bash completion error +if [[ -n $(type -t _comp__split_longopt) ]] && [[ -z $(type -t _split_longopt) ]]; then + alias _split_longopt="_comp__split_longopt" +fi -# pnpm -export PNPM_HOME="$(realpath ~/.local/share/pnpm)" -export PATH="$PNPM_HOME:$PATH" -# pnpm end -# tabtab source for packages -# uninstall by removing these lines -[ -f ~/.config/tabtab/bash/__tabtab.bash ] && . ~/.config/tabtab/bash/__tabtab.bash || true - -clean-pnpm-node() { - if [[ -d "$PNPM_HOME" ]]; then - rm -f "$PNPM_HOME/nodejs_current" - rm -f "$PNPM_HOME/node" - rm -f "$PNPM_HOME/npm" - rm -f "$PNPM_HOME/npx" +for _ in ${HOME}/.bashrc.d/*; do + if [[ $_ == *.@(bash|sh) && -r $_ ]]; then + source "$_" fi -} +done + +if [[ -n "$(type -t mise-activate)" ]]; then + mise-activate +fi diff --git a/dot/.bashrc.d/android-studio.bash b/dot/.bashrc.d/android-studio.bash new file mode 100644 index 0000000..a1fbd7f --- /dev/null +++ b/dot/.bashrc.d/android-studio.bash @@ -0,0 +1,11 @@ +basedir=$(realpath -m $(dirname "${BASH_SOURCE[0]:-$0}")) +source "${basedir}/function.bash" + +unset basedir + +export JAVA_HOME="/opt/android-studio/jbr" +export ANDROID_HOME="${HOME}/Android/Sdk" +export NDK_HOME="$ANDROID_HOME/ndk/$(ls -1 $ANDROID_HOME/ndk)" + +add-to-path "${ANDROID_HOME}/emulator" "${ANDROID_HOME}/platform-tools" + diff --git a/dot/.bashrc.d/fnm.bash b/dot/.bashrc.d/fnm.bash new file mode 100644 index 0000000..35fa523 --- /dev/null +++ b/dot/.bashrc.d/fnm.bash @@ -0,0 +1,44 @@ +basedir=$(realpath -m $(dirname "${BASH_SOURCE[0]:-$0}")) +source "${basedir}/function.bash" + +unset basedir + +if [[ -e "$(type -p fnm)" ]]; then + generate-bash-completion fnm "fnm completions --shell bash" + + fnm-activate() { + hash -r + eval "$(fnm env --use-on-cd --version-file-strategy=recursive)" + export FNM_NODE_DIST_MIRROR="https://npmmirror.com/mirrors/node" + + __fnmcd() { + \cd "$@" || return $? + unhash-command-in-dirs "$FNM_MULTISHELL_PATH"/bin + __fnm_use_if_file_found + } + } + + fnm-deactivate() { + if [[ "$(type -t cd)" == "alias" ]]; then + unalias cd + fi + + if [[ -z "$FNM_MULTISHELL_PATH" ]]; then + return 0 + fi + + local fnm_multishell="$(dirname "$FNM_MULTISHELL_PATH")" + local -a envs=$(compgen -v | grep '^FNM_') + local -a all_tmp_dir=("$fnm_multishell"/*) + local -a bin_paths=("$fnm_multishell"/*/bin) + + remove-from-path "${bin_paths[@]}" + unhash-command-in-dirs "${bin_paths[@]}" + rm -rf "${all_tmp_dir[@]}" + + local var + for var in $envs; do + unset "$var" + done + } +fi diff --git a/dot/.bashrc.d/function.bash b/dot/.bashrc.d/function.bash new file mode 100644 index 0000000..3fef356 --- /dev/null +++ b/dot/.bashrc.d/function.bash @@ -0,0 +1,136 @@ +generate-bash-completion() { + local file="$1" + local command="$2" + + if [[ -z "$file" || -z "$command" ]]; then + echo "usage: generate-bash-completion " >&2 + echo "example: generate-bash-completion mycmd '_mycmd_completion'" >&2 + return 1 + fi + + local completion_dir="${HOME}/.local/share/bash-completion/completions" + local completion_file="$(realpath -m "${completion_dir}/${file}")" + + if [[ -d "$completion_dir" && ! -w "$completion_dir" ]]; then + echo "ERROR: has no permission to write to directory '${completion_dir}'" >&2 + return 1 + fi + + if [[ ! -f "$completion_file" ]]; then + if ! mkdir -p "$completion_dir"; then + echo "ERROR: cannot create directory '$completion_dir'" >&2 + return 1 + fi + + if ! bash -c "$command" > "$completion_file"; then + echo "ERROR: failed to execute command '$command'" >&2 + rm -f "$completion_file" + return 1 + fi + fi +} + +add-to-path() { + if [[ $# -eq 0 ]]; then + echo "usage: add-to-path [path2 ...]" >&2 + echo "example: add-to-path /usr/local/bin /tmp/my-dir" >&2 + return 1 + fi + + local -a dirs=("$@") + local dir + local dir_normalized + local new_path="$PATH" + + for dir in "${dirs[@]}"; do + [[ -z "$dir" ]] && continue + + dir_normalized="${dir%/}" + if [[ ! -d "$dir_normalized" ]]; then + echo "WARNING: '${dir}' is not a valid directory, skipped." >&2 + continue + fi + + case ":${new_path}:" in + *":${dir_normalized}:"*) ;; + *) + new_path="${dir_normalized}${new_path:+:}${new_path}" + ;; + esac + done + + if [[ "$new_path" != "$PATH" ]]; then + export PATH="$new_path" + fi +} + +remove-from-path() { + if [[ $# -eq 0 ]]; then + echo "usage: remove-from-path [path2 ...]" >&2 + echo "example: remove-from-path /usr/local/bin /tmp/my-dir" >&2 + return 1 + fi + + local original_ifs="$IFS" + + local -a remove_paths=("$@") + local new_path="" + local path + local remove_path + local path_normalized + local remove_path_normalized + local -i keep_path=1 # 1=keep, 0=remove + + IFS=':' + for path in $PATH; do + [[ -z "$path" ]] && continue + + path_normalized="${path%/}" # remove / at tail + keep_path=1 + + for remove_path in "${remove_paths[@]}"; do + remove_path_normalized="${remove_path%/}" + if [[ "$path_normalized" == "$remove_path_normalized" ]]; then + keep_path=0 + break + fi + done + + if [[ $keep_path -eq 1 ]]; then + new_path="${new_path}${new_path:+:}${path}" + fi + done + IFS="$original_ifs" + + export PATH="${new_path}" +} + +show-path() { + echo "$PATH" | tr ':' '\n' | nl -w2 -s'. ' +} + +unhash-command-in-dirs() { + if [[ $# -eq 0 ]]; then + echo "usage: unhash-command-in-dir [dir2 ...]" >&2 + echo "example: unhash-command-in-dir ~/.local/bin/ ~/.volta/bin/" >&2 + return 1 + fi + + local -a dirs=("$1") + local dir + local dir_normalized + local file_path + local filename + for dir in "${dirs[@]}"; do + [[ -z "$dir" || ! -d "$dir" ]] && continue + + dir_normalized="${dir%/}" + + for file_path in "$dir_normalized"/*; do + [[ ! -f "$file_path" || ! -x "$file_path" ]] && continue + + filename="$(basename "$file_path")" + hash -d "$filename" 2>/dev/null + done + done +} diff --git a/dot/.bashrc.d/mise.bash b/dot/.bashrc.d/mise.bash new file mode 100644 index 0000000..1bceb9d --- /dev/null +++ b/dot/.bashrc.d/mise.bash @@ -0,0 +1,28 @@ +basedir=$(realpath -m $(dirname "${BASH_SOURCE[0]:-$0}")) +source "${basedir}/function.bash" + +unset basedir + +if [[ -x $(type -p mise) ]]; then + completion_cmd="mise completion --include-bash-completion-lib bash" + generate-bash-completion mise "$completion_cmd" + unset completion_cmd + + mise-activate() { + eval "$(mise activate bash)" + } + + mise-deactivate() { + mise deactivate + + if [[ "$(type -p cd)" == "function" ]]; then + unset cd + fi + + local all_mise=$(compgen -v | grep -i '_mise') + local mise + for mise in $all_mise; do + unset "$mise" + done + } +fi diff --git a/dot/.bashrc.d/pip-search.bash b/dot/.bashrc.d/pip-search.bash new file mode 100644 index 0000000..1a5d8f5 --- /dev/null +++ b/dot/.bashrc.d/pip-search.bash @@ -0,0 +1,10 @@ +if [[ -x $(type -p pip_search) ]]; then + function _pip() { + if [[ "$1" == "search" ]]; then + pip_search "$2" + else + pip "$@" + fi + } + alias pip=_pip +fi diff --git a/dot/.bashrc.d/pnpm.bash b/dot/.bashrc.d/pnpm.bash new file mode 100755 index 0000000..57633fd --- /dev/null +++ b/dot/.bashrc.d/pnpm.bash @@ -0,0 +1,24 @@ +basedir=$(realpath -m $(dirname "${BASH_SOURCE[0]:-$0}")) +source "${basedir}/function.bash" + +unset basedir + +export PNPM_HOME="${HOME}/.local/share/pnpm" +add-to-path $PNPM_HOME + +if [[ -x "$(type -p pnpm)" ]]; then + generate-bash-completion pnpm "pnpm completion bash" +fi + +if [[ -x "$(type -p npm)" ]]; then + generate-bash-completion npm "npm completion" +fi + +clean-pnpm-node() { + if [[ -d "$PNPM_HOME" ]]; then + rm -f "$[PNPM_HOME]/nodejs_current" + rm -f "${PNPM_HOME}/node" + rm -f "${PNPM_HOME}/npm" + rm -f "${PNPM_HOME}/npx" + fi +} diff --git a/dot/.bashrc.d/proxy.bash b/dot/.bashrc.d/proxy.bash new file mode 100644 index 0000000..a632e09 --- /dev/null +++ b/dot/.bashrc.d/proxy.bash @@ -0,0 +1,50 @@ +HTTP_PROXY="http://192.168.1.13:20172" +SOCKS_PROXY="socks5://192.168.1.13:20170" + +set-shell-proxy() { + export http_proxy="$HTTP_PROXY" + export https_proxy="$HTTP_PROXY" +} + +unset-shell-proxy() { + unset http_proxy + unset https_proxy +} + +set-git-proxy() { + prefix_cmd="" + flag="--global" + if [[ "$1" == "-s" ]]; then + prefix_cmd="sudo" + flag="--system" + elif [[ "$1" == "-l" ]]; then + flag="--local" + fi + + $prefix_cmd git config $flag http.proxy $HTTP_PROXY + $prefix_cmd git config $flag http.sslVerify false +} + +unset-git-proxy() { + prefix_cmd="" + flag="--global" + if [[ "$1" == "-s" ]]; then + prefix_cmd="sudo" + flag="--system" + elif [[ "$1" == "-l" ]]; then + flag="--local" + fi + + $prefix_cmd git config $flag --unset http.proxy + $prefix_cmd git config $flag --unset http.sslVerify +} + +set-npm-proxy() { + npm config set proxy $HTTP_PROXY + npm config set https-proxy $HTTP_PROXY +} + +unset-npm-proxy() { + npm config delete proxy + npm config delete https-proxy +} diff --git a/dot/.bashrc.d/rust.bash b/dot/.bashrc.d/rust.bash new file mode 100644 index 0000000..bda869e --- /dev/null +++ b/dot/.bashrc.d/rust.bash @@ -0,0 +1,17 @@ +basedir=$(realpath -m $(dirname "${BASH_SOURCE[0]:-$0}")) +source "${basedir}/function.bash" + +unset basedir + +if [[ -d "${HOME}/.cargo/bin" ]]; then + add-to-path "${HOME}/.cargo/bin" +fi + +if [[ -e "${HOME}/.cargo/env" ]]; then + . "${HOME}/.cargo/env" +fi + +if [[ -x "$(type -p rustup)" ]]; then + generate-bash-completion rustup "rustup completions bash cargo" + generate-bash-completion cargo "rustup completions bash cargo" +fi diff --git a/dot/.bashrc.d/volta.bash b/dot/.bashrc.d/volta.bash new file mode 100644 index 0000000..8d3d572 --- /dev/null +++ b/dot/.bashrc.d/volta.bash @@ -0,0 +1,25 @@ +basedir=$(realpath -m $(dirname "${BASH_SOURCE[0]:-$0}")) +source "${basedir}/function.bash" + +unset basedir + +export VOLTA_HOME="${HOME}/.volta" + +if [[ -x $(type -p volta) || -x "${VOLTA_HOME}/bin/volta" ]]; then + generate-bash-completion volta "volta completions bash" + + volta-activate() { + add-to-path "${VOLTA_HOME}/bin" + + # enable pnpm support + # export VOLTA_FEATURE_PNPM=1 + } + + volta-deactivate() { + local bin_dir="${VOLTA_HOME}/bin" + remove-from-path "$bin_dir" + unhash-command-in-dirs "$bin_dir" + } +fi + +