diff options
| author | TheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com> | 2025-12-07 18:16:05 +0900 |
|---|---|---|
| committer | TheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com> | 2025-12-07 18:16:05 +0900 |
| commit | 5ff02959d3069923bca63cb54c4bb246b86bf20d (patch) | |
| tree | 7ef1b56fb85a48c563bb3af51c26f181741282be /fedora/.config/bash | |
| parent | f65fe7591c18d6c8f4ecac5f379407a910aba1bc (diff) | |
deleted .gnupg/gpg-agent.conf, created .gnupg/, created .config/, created .local/, created .gnupg/
Diffstat (limited to 'fedora/.config/bash')
| -rw-r--r-- | fedora/.config/bash/autocomplete.bash | 218 | ||||
| -rw-r--r-- | fedora/.config/bash/bash_profile | 40 | ||||
| -rw-r--r-- | fedora/.config/bash/bashrc | 169 | ||||
| -rw-r--r-- | fedora/.config/bash/git.bash | 7 | ||||
| -rw-r--r-- | fedora/.config/bash/keymaps.bash | 200 | ||||
| -rw-r--r-- | fedora/.config/bash/packages.bash | 35 | ||||
| -rw-r--r-- | fedora/.config/bash/scripts.bash | 342 |
7 files changed, 1011 insertions, 0 deletions
diff --git a/fedora/.config/bash/autocomplete.bash b/fedora/.config/bash/autocomplete.bash new file mode 100644 index 0000000..0aeeedd --- /dev/null +++ b/fedora/.config/bash/autocomplete.bash @@ -0,0 +1,218 @@ +#!/bin/bash + +### --- Auto-completes aliases --- ### +# alias - normal aliases (completed with trailing space) +# balias - blank aliases (completed without space) +# ialias - ignored aliases (not completed) + +ialiases=() +ialias() { + # usage: ialias name='value' (same as alias builtin) + alias "$@" + # extract name (everything before first '=' or first space) + local args="$1" + args=${args%%=*} + args=${args%% *} + ialiases+=("$args") +} + +baliases=() +balias() { + alias "$@" + local args="$1" + args=${args%%=*} + args=${args%% *} + baliases+=("$args") +} + +# ---------- helper: get alias value ---------- +# returns alias expansion text for a name, or empty if none +_get_alias_value() { + local name="$1" + # alias output: alias ll='ls -la' + local a + a=$(alias "$name" 2>/dev/null) || return 1 + # strip "alias name='...'" + # use parameter expansion / sed safe parsing + # get first occurrence of =', then strip quotes + a=${a#*=} + # remove leading quote if present + a=${a#\'} + a=${a%\'} + printf "%s" "$a" + return 0 +} + +# ---------- helper: membership check ---------- +_in_array() { + local item="$1" + shift + local elem + for elem in "$@"; do + if [[ "$elem" == "$item" ]]; then + return 0 + fi + done + return 1 +} + +# ---------- expand alias at cursor and optionally insert space ---------- +# This function is executed via bind -x, so it can read/modify: +# READLINE_LINE - current full line buffer +# READLINE_POINT - current cursor index (0..len) +expand_alias_space() { + # READLINE_LINE and READLINE_POINT are provided by readline when bind -x is used. + # If not present (if invoked directly), fallback to no-op + if [[ -z "${READLINE_LINE+set}" ]]; then + # fallback: just insert a space + printf " " + return 0 + fi + + local line=${READLINE_LINE} + local point=${READLINE_POINT} + + # left substring up to cursor + local left=${line:0:point} + # right substring after cursor + local right=${line:point} + + # find the last "word" before the cursor (split on whitespace) + # If left ends with whitespace, current word is empty + local lastword + if [[ "$left" =~ [[:space:]]$ ]]; then + lastword="" + else + # remove everything up to last whitespace + lastword=${left##*['$'\t\n' ']} + fi + + # if lastword is empty -> just insert a space + if [[ -z "$lastword" ]]; then + READLINE_LINE="${left} ${right}" + READLINE_POINT=$((point + 1)) + return 0 + fi + + # check if lastword is in ignored aliases -> do not expand, just insert space + if _in_array "$lastword" "${ialiases[@]}"; then + READLINE_LINE="${left} ${right}" + READLINE_POINT=$((point + 1)) + return 0 + fi + + # try to get alias expansion + local expansion + if expansion=$(_get_alias_value "$lastword"); then + # Replace the lastword in left with expansion + # compute left_without_word + local left_without="${left%${lastword}}" + + # If balias: expansion but DO NOT add trailing space + if _in_array "$lastword" "${baliases[@]}"; then + READLINE_LINE="${left_without}${expansion}${right}" + # place cursor right after the expansion + READLINE_POINT=$((${#left_without} + ${#expansion})) + return 0 + else + # Normal alias: expansion and add a space after it + READLINE_LINE="${left_without}${expansion} ${right}" + READLINE_POINT=$((${#left_without} + ${#expansion} + 1)) + return 0 + fi + else + # no alias found: just insert space + READLINE_LINE="${left} ${right}" + READLINE_POINT=$((point + 1)) + return 0 + fi +} + +# ---------- accept-line that expands alias before executing ---------- +# Bind Enter to this function via bind -x; it will expand alias (if needed) then +# simulate Enter by setting READLINE_LINE and returning - readline will accept it. +expand_alias_and_accept_line() { + # Expand at cursor (use current READLINE_LINE/POINT) + expand_alias_space + # After expansion, we want to accept the line as if Enter was pressed. + # To do so in bind -x handler, we can set a marker and then use 'builtin bind -x' hack: + # Simpler approach: write the line to a temp file, then use 'kill -SIGWINCH' ??? Too complex. + # Luckily, when a bind -x handler returns, readline continues; we want to end editing. + # There's no direct way to programmatically press enter. Instead, rely on binding Enter to a wrapper that: + # - modifies READLINE_LINE (done) and then sets a special variable so readline knows to accept. + : +} + +# ---------- key bindings ---------- +# Bind Space to our function so pressing space triggers alias-expansion behavior. +# Use bind -x to call expand_alias_space (it will both expand and insert space when appropriate). +# WARNING: this overrides normal space key behavior; our function handles insertion. +bind -x '" "':expand_alias_space + +# optional: bind Ctrl-Space to the same (a bypass key like zsh had) +# Many terminals send "\C-@" for ctrl-space; try both common sequences: +bind -x '"\C-@":expand_alias_space' 2>/dev/null || true +bind -x '"\C- ":expand_alias_space' 2>/dev/null || true + +# Bind Enter (Return) to expand alias before accepting the line. +# We implement this by expanding then forcing a newline insertion. +# Using bind -x for Enter: when this function returns, readline will NOT automatically accept the line, +# but we can emulate acceptance by printing a newline and forcing input. Simpler: call 'return 0' from this hook +# and then send a newline. However, behavior varies between shells/terminals — so we will bind Enter to a function +# that expands and then uses 'READLINE_LINE' trick to set the expanded line and then call 'builtin bind' to +# temporarily restore Enter to default and re-invoke it. +_bash_accept_line() { + expand_alias_space + # After expanding, we want readline to accept the line. A workaround: + # write the expanded line into the current tty so that it becomes input for the shell. + # But this is messy. Instead, we simply move the cursor to the end and let the user press Enter again. + # (This is a conservative behavior to avoid interfering unexpectedly.) + return 0 +} +bind -x '"\C-m":_bash_accept_line' + +# ---------- helper: background starter ---------- +background() { + # start multiple args as programs in background + # usage: background cmd arg1 arg2 ... + # runs: cmd arg1 & cmd arg2 & ... + local cmd="$1" + shift || return 0 + for arg in "$@"; do + "$cmd" "$arg" &>/dev/null & + done +} + +# ---------- notes ---------- +# - After placing this into ~/.bashrc, run: source ~/.bashrc +# - Test aliases: +# balias ll='ls -la' +# alias g='git status' +# ialias X='something' +# - Then type `ll` followed by Space -> will expand to `ls -la` WITHOUT appending a space (blank alias). +# - Type `g` then Space -> will expand to `git status ` with a trailing space. +# - Type `X` then Space -> will NOT expand, just insert space. +# +# Limitations / caveats: +# - readline/bind -x behavior differs slightly across environments and terminals. +# - Completely emulating zsh's zle widgets (especially auto-accept behaviors) is tricky in bash. +# - Binding Enter to fully accept-after-expansion programmatically is not perfectly portable; +# the conservative implementation above expands first and leaves acceptance to the user (press Enter again). +# +# If you want a stronger behavior (auto-accept after expansion), tell me and I'll provide a +# more aggressive implementation that works on most terminals (but with more invasive tricks). + +# ---------- file completion patterns ---------- +_vim_complete() { + local cur="${COMP_WORDS[COMP_CWORD]}" + COMPREPLY=($(compgen -f -X '!*.@(pdf|odt|ods|doc|docx|xls|xlsx|odp|ppt|pptx|mp4|mkv|aux)' -- "$cur")) +} +shopt -s extglob +complete -F _vim_complete vim + +_build_mom_complete() { + local cur="${COMP_WORDS[COMP_CWORD]}" + COMPREPLY=($(compgen -f -X '!*.mom' -- "$cur")) +} +complete -F _build_mom_complete build-workshop +complete -F _build_mom_complete build-document diff --git a/fedora/.config/bash/bash_profile b/fedora/.config/bash/bash_profile new file mode 100644 index 0000000..068e3f5 --- /dev/null +++ b/fedora/.config/bash/bash_profile @@ -0,0 +1,40 @@ +#!/bin/sh + +umask 022 + +####################################################### +# EXPORTS +####################################################### + +export XDG_CACHE_HOME="$HOME/.cache" +export XDG_CONFIG_HOME="$HOME/.config" +export XDG_DATA_HOME="$HOME/.local/share" +export XDG_STATE_HOME="$HOME/.local/state" +export CLICOLOR=1 +export EDITOR="vim" +export HISTFILE="${XDG_DATA_HOME:-${HOME}/.local/share}/history/sh_history" +export INPUTRC="${XDG_CONFIG_HOME:-${HOME}/.config}/shell/inputrc" +export LESS="R" +export LESS_TERMCAP_mb="$(printf '%b' '[1;31m')" +export LESS_TERMCAP_md="$(printf '%b' '[1;36m')" +export LESS_TERMCAP_me="$(printf '%b' '[0m')" +export LESS_TERMCAP_so="$(printf '%b' '[01;44;33m')" +export LESS_TERMCAP_se="$(printf '%b' '[0m')" +export LESS_TERMCAP_us="$(printf '%b' '[1;32m')" +export LESS_TERMCAP_ue="$(printf '%b' '[0m')" +export LESSOPEN="| /usr/bin/highlight -O ansi %s 2>/dev/null" +export LS_COLORS="no=00:fi=00:di=00;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.ogg=01;35:*.mp3=01;35:*.wav=01;35:*.xml=00;31:" +export LS_OPTIONS="--color=auto" +export TERM="xterm-256color" +export GVIMINIT='let $MYGVIMRC="$XDG_CONFIG_HOME/vim/gvimrc" | source $MYGVIMRC' +export VIMINIT='let $MYVIMRC="$XDG_CONFIG_HOME/vim/vimrc" | source $MYVIMRC' +export VISUAL=$EDITOR + +####################################################### +# Source global/local definitions +####################################################### + +[ -f /etc/bash_completion ] && . /etc/bash_completion +[ -f /usr/share/bash-completion/bash_completion ] && . /usr/share/bash-completion/bash_completion +[ -f /etc/bash/bashrc ] && . /etc/bash/bashrc +[ -f "${XDG_CONFIG_HOME:-${HOME}/.config}/bash/bashrc" ] && . "${XDG_CONFIG_HOME:-${HOME}/.config}/bash/bashrc" diff --git a/fedora/.config/bash/bashrc b/fedora/.config/bash/bashrc new file mode 100644 index 0000000..2c60286 --- /dev/null +++ b/fedora/.config/bash/bashrc @@ -0,0 +1,169 @@ +#!/bin/bash + +[[ $- != *i* ]] && return + +####################################################### +# SET OPTIONS +####################################################### +# history +HISTCONTROL=erasedups:ignoredups:ignorespace +HISTFILESIZE=10000 +HISTSIZE=500 + +# Allow ctrl-S for history navigation (with ctrl-R) +stty -ixon +PROMPT_COMMAND="history -a" +unset GREP_OPTIONS + +set -o vi +shopt -s autocd # goto without cd +shopt -s direxpand # expend directory name +shopt -s cdspell # ignore case cd +shopt -s checkwinsize # Check the window size after each command and, if necessary, update the values of LINES and COLUMNS +shopt -s histappend # Causes bash to append to history instead of overwriting it so if you start a new terminal, you have old session history + +# Completion settings +# Ignore case on auto-completion +# Note: bind used instead of sticking these in .inputrc +bind "set completion-ignore-case on" +# Show auto-completion list automatically, without double tab +bind "set show-all-if-ambiguous on" + +####################################################### +# Set command prompt +####################################################### +alias cpu="grep 'cpu ' /proc/stat | awk '{usage=(\$2+\$4)*100/(\$2+\$4+\$5)} END {print usage}' | awk '{printf(\"%.1f\n\", \$1)}'" +function __setprompt { + local LAST_COMMAND=$? # Must come first! + + # Define colors + local LIGHTGRAY="\033[0;37m" + local WHITE="\033[1;37m" + local BLACK="\033[0;30m" + local DARKGRAY="\033[1;30m" + local RED="\033[0;31m" + local LIGHTRED="\033[1;31m" + local GREEN="\033[0;32m" + local LIGHTGREEN="\033[1;32m" + local BROWN="\033[0;33m" + local YELLOW="\033[1;33m" + local BLUE="\033[0;34m" + local LIGHTBLUE="\033[1;34m" + local MAGENTA="\033[0;35m" + local LIGHTMAGENTA="\033[1;35m" + local CYAN="\033[0;36m" + local LIGHTCYAN="\033[1;36m" + local NOCOLOR="\033[0m" + + # Show error exit code if there is one + if [[ $LAST_COMMAND != 0 ]]; then + # PS1="\[${RED}\](\[${LIGHTRED}\]ERROR\[${RED}\])-(\[${LIGHTRED}\]Exit Code \[${WHITE}\]${LAST_COMMAND}\[${RED}\])-(\[${LIGHTRED}\]" + PS1="\[${DARKGRAY}\](\[${LIGHTRED}\]ERROR\[${DARKGRAY}\])-(\[${RED}\]Exit Code \[${LIGHTRED}\]${LAST_COMMAND}\[${DARKGRAY}\])-(\[${RED}\]" + if [[ $LAST_COMMAND == 1 ]]; then + PS1+="General error" + elif [ $LAST_COMMAND == 2 ]; then + PS1+="Missing keyword, command, or permission problem" + elif [ $LAST_COMMAND == 126 ]; then + PS1+="Permission problem or command is not an executable" + elif [ $LAST_COMMAND == 127 ]; then + PS1+="Command not found" + elif [ $LAST_COMMAND == 128 ]; then + PS1+="Invalid argument to exit" + elif [ $LAST_COMMAND == 129 ]; then + PS1+="Fatal error signal 1" + elif [ $LAST_COMMAND == 130 ]; then + PS1+="Script terminated by Control-C" + elif [ $LAST_COMMAND == 131 ]; then + PS1+="Fatal error signal 3" + elif [ $LAST_COMMAND == 132 ]; then + PS1+="Fatal error signal 4" + elif [ $LAST_COMMAND == 133 ]; then + PS1+="Fatal error signal 5" + elif [ $LAST_COMMAND == 134 ]; then + PS1+="Fatal error signal 6" + elif [ $LAST_COMMAND == 135 ]; then + PS1+="Fatal error signal 7" + elif [ $LAST_COMMAND == 136 ]; then + PS1+="Fatal error signal 8" + elif [ $LAST_COMMAND == 137 ]; then + PS1+="Fatal error signal 9" + elif [ $LAST_COMMAND -gt 255 ]; then + PS1+="Exit status out of range" + else + PS1+="Unknown error code" + fi + PS1+="\[${DARKGRAY}\])\[${NOCOLOR}\]\n" + else + PS1="" + fi + + # Date + PS1+="\[${DARKGRAY}\](\[${CYAN}\]\$(date +%a) $(date +%b-'%-m')" # Date + PS1+="${BLUE} $(date +'%-I':%M:%S%P)\[${DARKGRAY}\])-" # Time + + # CPU + PS1+="(\[${MAGENTA}\]CPU $(cpu)%" + + # Jobs + PS1+="\[${DARKGRAY}\]:\[${MAGENTA}\]\j" + + # Network Connections (for a server - comment out for non-server) + PS1+="\[${DARKGRAY}\]:\[${MAGENTA}\]Net $(awk 'END {print NR}' /proc/net/tcp)" + + PS1+="\[${DARKGRAY}\])-" + + # User and server + local SSH_IP=$(echo $SSH_CLIENT | awk '{ print $1 }') + local SSH2_IP=$(echo $SSH2_CLIENT | awk '{ print $1 }') + if [ $SSH2_IP ] || [ $SSH_IP ]; then + PS1+="(\[${RED}\]\u@\h" + else + PS1+="(\[${RED}\]\u" + fi + + # Current directory + PS1+="\[${DARKGRAY}\]:\[${BROWN}\]\w\[${DARKGRAY}\])-" + + # Total size of files in current directory + PS1+="(\[${GREEN}\]$(/bin/ls -lah | /bin/grep -m 1 total | /bin/sed 's/total //')\[${DARKGRAY}\]:" + + # Number of files + PS1+="\[${GREEN}\]\$(/bin/ls -A -1 | /usr/bin/wc -l)\[${DARKGRAY}\])" + + # Skip to the next line + PS1+="\n" + + if [[ $EUID -ne 0 ]]; then + PS1+="\[${GREEN}\]>\[${NOCOLOR}\] " # Normal user + else + PS1+="\[${RED}\]>\[${NOCOLOR}\] " # Root user + fi + + # PS2 is used to continue a command using the \ character + PS2="\[${DARKGRAY}\]>\[${NOCOLOR}\] " + + # PS3 is used to enter a number choice in a script + PS3='Please enter a number from above list: ' + + # PS4 is used for tracing a script in debug mode + PS4='\[${DARKGRAY}\]+\[${NOCOLOR}\] ' +} +# PROMPT_COMMAND='__setprompt' +PS1="\[\e[1m\]\[\e[31m\][\[\e[33m\]\u\[\e[32m\]@\[\e[34m\]\h \[\e[35m\]\W\[\e[31m\]]\[\e[37m\]\\$ \[\e[0m\]" + +####################################################### +# KEY BINDING +####################################################### + +bind '"\C-l":clear-screen' +bind '"\C-g":"lfcd\n"' + +####################################################### +# SOURCE +####################################################### + +eval "$(dircolors)" + +[ -f "${XDG_SCRIPTS_HOME:-${HOME}/.local/bin}/bash-preexec" ] && . "${XDG_SCRIPTS_HOME:-${HOME}/.local/bin}/bash-preexec" +[ -f "${XDG_CONFIG_HOME:-${HOME}/.config}/shell/rootshortcutrc" ] && . "${XDG_CONFIG_HOME:-${HOME}/.config}/shell/rootshortcutrc" +[ -f "${XDG_CONFIG_HOME:-${HOME}/.config}/shell/rootzshnameddirrc" ] && . "${XDG_CONFIG_HOME:-${HOME}/.config}/shell/rootzshnameddirrc" diff --git a/fedora/.config/bash/git.bash b/fedora/.config/bash/git.bash new file mode 100644 index 0000000..8fe7382 --- /dev/null +++ b/fedora/.config/bash/git.bash @@ -0,0 +1,7 @@ +#!/bin/bash + +# Speed up git completion +# http://talkings.org/post/5236392664/zsh-and-slow-git-completion +__git_files() { + _wanted files expl 'local files' _files +} diff --git a/fedora/.config/bash/keymaps.bash b/fedora/.config/bash/keymaps.bash new file mode 100644 index 0000000..cf355ad --- /dev/null +++ b/fedora/.config/bash/keymaps.bash @@ -0,0 +1,200 @@ +#!/bin/bash + +# --------- Bash port (u-prefix removed) --------- +# Put this into ~/.bashrc and run: source ~/.bashrc + +# enable vi editing mode +set -o vi + +# Try to set beam cursor at prompt (best-effort) +PROMPT_COMMAND='echo -ne "\e[5 q"' + +# ---------- helper: pre_cmd ---------- +pre_cmd() { + local txt="$1" + if [[ -z "${READLINE_LINE+set}" ]]; then + printf '%s ' "$txt" + return + fi + local left=${READLINE_LINE:0:READLINE_POINT} + local right=${READLINE_LINE:READLINE_POINT} + READLINE_LINE="${left}${txt} ${right}" + READLINE_POINT=$(( READLINE_POINT + ${#txt} + 1 )) +} + +# ---------- Clipboard detection ---------- +_detect_clipboard_setup() { + if command -v pbcopy >/dev/null 2>&1 && command -v pbpaste >/dev/null 2>&1; then + clipcopy() { cat "${1:-/dev/stdin}" | pbcopy; } + clippaste() { pbaste; } + return 0 + fi + if command -v wl-copy >/dev/null 2>&1 && command -v wl-paste >/dev/null 2>&1; then + clipcopy() { cat "${1:-/dev/stdin}" | wl-copy; } + clippaste() { wl-paste --no-newline; } + return 0 + fi + if command -v xclip >/dev/null 2>&1; then + clipcopy() { cat "${1:-/dev/stdin}" | xclip -selection clipboard; } + clippaste() { xclip -selection clipboard -out; } + return 0 + fi + if command -v xsel >/dev/null 2>&1; then + clipcopy() { cat "${1:-/dev/stdin}" | xsel --clipboard --input; } + clippaste() { xsel --clipboard --output; } + return 0 + fi + if command -v clip.exe >/dev/null 2>&1; then + clipcopy() { cat "${1:-/dev/stdin}" | clip.exe; } + clippaste() { powershell.exe -noprofile -command Get-Clipboard 2>/dev/null; } + return 0 + fi + if command -v tmux >/dev/null 2>&1 && [ -n "${TMUX:-}" ]; then + clipcopy() { tmux load-buffer -; } + clippaste() { tmux save-buffer -; } + return 0 + fi + return 1 +} +_detect_clipboard_setup || true + +paste_clipboard_to_readline() { + if ! command -v clippaste >/dev/null 2>&1; then + _detect_clipboard_setup || { printf 'No clipboard helper found\n' >&2; return 1; } + fi + local clip + clip=$(clippaste 2>/dev/null) || return 1 + clip="${clip%$'\n'}" + if [[ -z "${READLINE_LINE+set}" ]]; then + printf '%s' "$clip" + return + fi + local left=${READLINE_LINE:0:READLINE_POINT} + local right=${READLINE_LINE:READLINE_POINT} + READLINE_LINE="${left}${clip}${right}" + READLINE_POINT=$(( READLINE_POINT + ${#clip} )) +} + +copy_readline_to_clipboard() { + if [[ -z "${READLINE_LINE+set}" ]]; then + printf 'No current line to copy\n' >&2 + return 1 + fi + if ! command -v clipcopy >/dev/null 2>&1; then + _detect_clipboard_setup || { printf 'No clipboard helper found\n' >&2; return 1; } + fi + printf '%s' "${READLINE_LINE}" | clipcopy +} + +# ---------- basic utilities ---------- +clear_tree_2() { clear; tree -L 2 2>/dev/null || true; } +clear_tree_3() { clear; tree -L 3 2>/dev/null || true; } +insert_current_date() { + local txt="$(date -I)" + if [[ -z "${READLINE_LINE+set}" ]]; then printf '%s' "$txt"; return; fi + local left=${READLINE_LINE:0:READLINE_POINT}; local right=${READLINE_LINE:READLINE_POINT} + READLINE_LINE="${left}${txt}${right}"; READLINE_POINT=$(( READLINE_POINT + ${#txt} )) +} +insert_unix_timestamp() { + local txt="$(date +%s)" + if [[ -z "${READLINE_LINE+set}" ]]; then printf '%s' "$txt"; return; fi + local left=${READLINE_LINE:0:READLINE_POINT}; local right=${READLINE_LINE:READLINE_POINT} + READLINE_LINE="${left}${txt}${right}"; READLINE_POINT=$(( READLINE_POINT + ${#txt} )) +} +git_status_clear() { clear; git status 2>/dev/null || git status --short 2>/dev/null || true; } +tmux_left_pane() { tmux select-pane -L 2>/dev/null || true; tmux resize-pane -Z 2>/dev/null || true; } +vi_append_clip_selection() { paste_clipboard_to_readline; } +copybuffer() { copy_readline_to_clipboard; } +background_start() { local cmd="$1"; shift || return 0; for arg in "$@"; do "$cmd" "$arg" &>/dev/null & done; } + +# ---------- pre_cmd widgets ---------- +man_command_line() { pre_cmd "man"; } +sudo_command_line() { pre_cmd "sudo"; } + +# ---------- wrappers (u-prefix REMOVED) ---------- +bc() { command -v bc >/dev/null 2>&1 && /usr/bin/env bc "$@" || printf 'bc: not found\n' >&2; } +cdi() { command -v cdi >/dev/null 2>&1 && cdi "$@" || printf 'cdi: not found\n' >&2; } +lastvim() { command -v lastnvim >/dev/null 2>&1 && lastvim "$@" || printf 'lastvim: not found\n' >&2; } +htop() { command -v htop >/dev/null 2>&1 && htop "$@" || printf 'htop: not found\n' >&2; } +sessionizer() { command -v sessionizer >/dev/null 2>&1 && sessionizer "$@" || printf 'sessionizer: not found\n' >&2; } +upd() { command -v upd >/dev/null 2>&1 && upd "$@" || printf 'upd: not found\n' >&2; } +cht() { command -v cht >/dev/null 2>&1 && cht "$@" || printf 'cht: not found\n' >&2; } # from '^ucht' -> 'cht' +ali() { command -v ali >/dev/null 2>&1 && ali "$@" || printf 'ali: not found\n' >&2; } +fD() { command -v fD >/dev/null 2>&1 && fD "$@" || printf 'fD: not found\n' >&2; } +rgafiles() { command -v rgafiles >/dev/null 2>&1 && rgafiles "$@" || printf 'rgafiles: not found\n' >&2; } +lastvim_l() { command -v lastnvim >/dev/null 2>&1 && lastvim -l || printf 'lastvim: not found\n' >&2; } + +# ---------- Readline key bindings (bind -x) ---------- +# basic movement +bind '"\C-a": beginning-of-line' +bind '"\C-e": end-of-line' + +# function key bindings (map to bash functions above) +bind -x '"\C-x\C-e":clear_tree_2' +bind -x '"\C-x\C-w":clear_tree_3' +bind -x '"\C-x\C-s":git_status_clear' +bind -x '"\C-x\C-x\C-t":insert_current_date' # ^X^X^T (alternate: C-x C-t) +bind -x '"\C-x\C-t":insert_current_date' +bind -x '"\C-x\C-x\C-u":insert_unix_timestamp' # ^X^X^U +bind -x '"\C-x\C-u":insert_unix_timestamp' + +# clipboard binds +bind -x '"\C-x\C-p":paste_clipboard_to_readline' # ^X^P +bind -x '"\C-x\C-y":copy_readline_to_clipboard' # ^X^Y + +# edit in editor +edit_command_line() { + local tmp content + tmp=$(mktemp /tmp/bash-edit.XXXXXX) || return + printf '%s' "${READLINE_LINE:-}" > "$tmp" + "${EDITOR:-vim}" "$tmp" + content=$(<"$tmp") + READLINE_LINE="$content" + READLINE_POINT=${#content} + rm -f "$tmp" +} +bind -x '"\C-x\C-v":edit_command_line' # ^X^V + +# man & sudo insertion +bind -x '"\C-x\C-m":man_command_line' # ^X^M +stty -ixon 2>/dev/null || true +bind -x '"\C-s":sudo_command_line' # ^S (stty -ixon to avoid flow control) + +# tmux left pane (bind ESC + backslash) +bind -x $'\e\\':tmux_left_pane + +# ---------- mappings of the original bindkey -s lines (u removed) ---------- +bind -x '"\C-b":__bc' # will call function __bc below +__bc() { bc -lq "$@"; } + +bind -x '"\C-d":cdi' +bind -x '"\C-f":fzffiles' +bind -x '"\C-g":lf' +bind -x '"\C-n":lastnvim' +bind -x '"\C-o":tmo' +bind -x '"\C-p":fzfpass' +bind -x '"\C-q":htop' +bind -x '"\C-t":sessionizer' +bind -x '"\C-y":lfcd' +bind -x '"\C-z":upd' +# ^_ (Ctrl-_) mapped to cht (from '^ucht' -> 'cht') +bind -x $'"\C-_":cht' + +# ^X^... sequences (Ctrl-X then key) +bind -x '"\C-x\C-a":ali' +bind -x '"\C-x\C-b":gitopenbranch' +bind -x '"\C-x\C-d":fD' +bind -x '"\C-x\C-f":gitfiles' +bind -x '"\C-x\C-g":rgafiles' +bind -x '"\C-x\C-l":gloac' +bind -x '"\C-x\C-n":lastnvim_l' +bind -x '"\C-x\C-q":fpkill' +bind -x '"\C-x\C-r":fgst' +bind -x '"\C-x\C-t":gitstagedfiles' +bind -x '"\C-x\C-u":gitupdate' +bind -x '"\C-x\C-_":fzffns' # ^X^_ +bind -x '"\C-x\C-x\C-b":rbackup' +bind -x '"\C-x\C-x\C-p":pcyr' +bind -x '"\C-x\C-x\C-r":rbackup' # rbackup -r not directly supported via bind -x args; call rbackup then ask user for flags if needed +bind -x '"\C-x\C-x\C-s":sshadd' +bind -x '"\C-x\C-x\C-y":yay_remaps' diff --git a/fedora/.config/bash/packages.bash b/fedora/.config/bash/packages.bash new file mode 100644 index 0000000..f45925a --- /dev/null +++ b/fedora/.config/bash/packages.bash @@ -0,0 +1,35 @@ +#!/bin/bash + +# --- Packages (bash version) --- +declare -A packages=( + [zoxide]="--cmd cd --hook prompt" +) + +eval_packages() { + local package output + for package in "${!packages[@]}"; do + if command -v "$package" >/dev/null 2>&1; then + # split args by space into array (preserve empty => zero args) + local -a args=() + if [[ -n "${packages[$package]}" ]]; then + # Use builtin read to split on spaces (simple split) + IFS=' ' read -r -a args <<<"${packages[$package]}" + fi + + # Prefer initializing for bash (change to "zsh" if you really want zsh-init) + if ((${#args[@]})); then + output="$("$package" init bash "${args[@]}" 2>/dev/null)" + else + output="$("$package" init bash 2>/dev/null)" + fi + + # If the command produced output, evaluate it in current shell + if [[ -n "$output" ]]; then + eval "$output" + fi + fi + done +} + +# run initialization +eval_packages diff --git a/fedora/.config/bash/scripts.bash b/fedora/.config/bash/scripts.bash new file mode 100644 index 0000000..fa0abbc --- /dev/null +++ b/fedora/.config/bash/scripts.bash @@ -0,0 +1,342 @@ +#!/bin/bash + +# Use the best version of pico installed +edit() { + if [ "$(type -t jpico)" = "file" ]; then + # Use JOE text editor http://joe-editor.sourceforge.net/ + jpico -nonotice -linums -nobackups "$@" + elif [ "$(type -t nano)" = "file" ]; then + nano -c "$@" + elif [ "$(type -t pico)" = "file" ]; then + pico "$@" + else + vim "$@" + fi +} + +sedit() { + if [ "$(type -t jpico)" = "file" ]; then + # Use JOE text editor http://joe-editor.sourceforge.net/ + sudo jpico -nonotice -linums -nobackups "$@" + elif [ "$(type -t nano)" = "file" ]; then + sudo nano -c "$@" + elif [ "$(type -t pico)" = "file" ]; then + sudo pico "$@" + else + sudo vim "$@" + fi +} + +# Extracts any archive(s) (if unp isn't installed) +extract() { + for archive in $*; do + if [ -f $archive ]; then + case $archive in + *.tar.bz2) tar xvjf $archive ;; + *.tar.gz) tar xvzf $archive ;; + *.bz2) bunzip2 $archive ;; + *.rar) rar x $archive ;; + *.gz) gunzip $archive ;; + *.tar) tar xvf $archive ;; + *.tbz2) tar xvjf $archive ;; + *.tgz) tar xvzf $archive ;; + *.zip) unzip $archive ;; + *.Z) uncompress $archive ;; + *.7z) 7z x $archive ;; + *) echo "don't know how to extract '$archive'..." ;; + esac + else + echo "'$archive' is not a valid file!" + fi + done +} + +# Searches for text in all files in the current folder +ftext() { + # -i case-insensitive + # -I ignore binary files + # -H causes filename to be printed + # -r recursive search + # -n causes line number to be printed + # optional: -F treat search term as a literal, not a regular expression + # optional: -l only print filenames and not the matching lines ex. grep -irl "$1" * + grep -iIHrn --color=always "$1" . | less -r +} + +# Copy file with a progress bar +cpf() { + set -e + strace -q -ewrite cp -- "${1}" "${2}" 2>&1 | + awk '{ + count += $NF + if (count % 10 == 0) { + percent = count / total_size * 100 + printf "%3d%% [", percent + for (i=0;i<=percent;i++) + printf "=" + printf ">" + for (i=percent;i<100;i++) + printf " " + printf "]\r" + } + } + END { print "" }' total_size=$(stat -c '%s' "${1}") count=0 +} + +# Copy and go to the directory +cpg() { + if [ -d "$2" ]; then + cp $1 $2 && cd $2 + else + cp $1 $2 + fi +} + +# Move and go to the directory +mvg() { + if [ -d "$2" ]; then + mv $1 $2 && cd $2 + else + mv $1 $2 + fi +} + +# Create and go to the directory +mc() { + mkdir -p $1 && cd $1 +} + +# Goes up a specified number of directories (i.e. up 4) +up() { + local d="" + limit=$1 + for ((i = 1; i <= limit; i++)); do + d=$d/.. + done + d=$(echo $d | sed 's/^\///') + if [ -z "$d" ]; then + d=.. + fi + cd $d +} + +#Automatically do an ls after each cd +# cd () { +# if [ -n "$1" ]; then +# builtin cd "$@" && ls +# else +# builtin cd ~ && ls +# fi +# } + +# Returns the last 2 fields of the working directory +pwdtail() { + pwd | awk -F/ '{nlast = NF -1;print $nlast"/"$NF}' +} + +# Show the current distribution +distribution() { + local dtype + # Assume unknown + dtype="unknown" + + # First test against Fedora / RHEL / CentOS / generic Redhat derivative + if [ -r /etc/rc.d/init.d/functions ]; then + source /etc/rc.d/init.d/functions + [ zz$(type -t passed 2>/dev/null) == "zzfunction" ] && dtype="redhat" + + # Then test against SUSE (must be after Redhat, + # I've seen rc.status on Ubuntu I think? TODO: Recheck that) + elif [ -r /etc/rc.status ]; then + source /etc/rc.status + [ zz$(type -t rc_reset 2>/dev/null) == "zzfunction" ] && dtype="suse" + + # Then test against Debian, Ubuntu and friends + elif [ -r /lib/lsb/init-functions ]; then + source /lib/lsb/init-functions + [ zz$(type -t log_begin_msg 2>/dev/null) == "zzfunction" ] && dtype="debian" + + # Then test against Gentoo + elif [ -r /etc/init.d/functions.sh ]; then + source /etc/init.d/functions.sh + [ zz$(type -t ebegin 2>/dev/null) == "zzfunction" ] && dtype="gentoo" + + # For Mandriva we currently just test if /etc/mandriva-release exists + # and isn't empty (TODO: Find a better way :) + elif [ -s /etc/mandriva-release ]; then + dtype="mandriva" + + # For Slackware we currently just test if /etc/slackware-version exists + elif [ -s /etc/slackware-version ]; then + dtype="slackware" + + fi + echo $dtype +} + +# Show the current version of the operating system +ver() { + local dtype + dtype=$(distribution) + + if [ $dtype == "redhat" ]; then + if [ -s /etc/redhat-release ]; then + cat /etc/redhat-release && uname -a + else + cat /etc/issue && uname -a + fi + elif [ $dtype == "suse" ]; then + cat /etc/SuSE-release + elif [ $dtype == "debian" ]; then + lsb_release -a + # sudo cat /etc/issue && sudo cat /etc/issue.net && sudo cat /etc/lsb_release && sudo cat /etc/os-release # Linux Mint option 2 + elif [ $dtype == "gentoo" ]; then + cat /etc/gentoo-release + elif [ $dtype == "mandriva" ]; then + cat /etc/mandriva-release + elif [ $dtype == "slackware" ]; then + cat /etc/slackware-version + else + if [ -s /etc/issue ]; then + cat /etc/issue + else + echo "Error: Unknown distribution" + exit 1 + fi + fi +} + +# Automatically install the needed support files for this .bashrc file +install_bashrc_support() { + local dtype + dtype=$(distribution) + + if [ $dtype == "redhat" ]; then + sudo yum install multitail tree joe + elif [ $dtype == "suse" ]; then + sudo zypper install multitail + sudo zypper install tree + sudo zypper install joe + elif [ $dtype == "debian" ]; then + sudo apt-get install multitail tree joe + elif [ $dtype == "gentoo" ]; then + sudo emerge multitail + sudo emerge tree + sudo emerge joe + elif [ $dtype == "mandriva" ]; then + sudo urpmi multitail + sudo urpmi tree + sudo urpmi joe + elif [ $dtype == "slackware" ]; then + echo "No install support for Slackware" + else + echo "Unknown distribution" + fi +} + +# Show current network information +netinfo() { + echo "--------------- Network Information ---------------" + /sbin/ifconfig | awk /'inet addr/ {print $2}' + echo "" + /sbin/ifconfig | awk /'Bcast/ {print $3}' + echo "" + /sbin/ifconfig | awk /'inet addr/ {print $4}' + + /sbin/ifconfig | awk /'HWaddr/ {print $4,$5}' + echo "---------------------------------------------------" +} + +# IP address lookup +alias whatismyip="whatsmyip" +function whatsmyip() { + # Dumps a list of all IP addresses for every device + # /sbin/ifconfig |grep -B1 "inet addr" |awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' |awk -F: '{ print $1 ": " $3 }'; + + # Internal IP Lookup + echo -n "Internal IP: " + /sbin/ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk '{print $1}' + + # External IP Lookup + echo -n "External IP: " + wget http://smart-ip.net/myip -O - -q +} + +# View Apache logs +apachelog() { + if [ -f /etc/httpd/conf/httpd.conf ]; then + cd /var/log/httpd && ls -xAh && multitail --no-repeat -c -s 2 /var/log/httpd/*_log + else + cd /var/log/apache2 && ls -xAh && multitail --no-repeat -c -s 2 /var/log/apache2/*.log + fi +} + +# Edit the Apache configuration +apacheconfig() { + if [ -f /etc/httpd/conf/httpd.conf ]; then + sedit /etc/httpd/conf/httpd.conf + elif [ -f /etc/apache2/apache2.conf ]; then + sedit /etc/apache2/apache2.conf + else + echo "Error: Apache config file could not be found." + echo "Searching for possible locations:" + sudo updatedb && locate httpd.conf && locate apache2.conf + fi +} + +# Edit the PHP configuration file +phpconfig() { + if [ -f /etc/php.ini ]; then + sedit /etc/php.ini + elif [ -f /etc/php/php.ini ]; then + sedit /etc/php/php.ini + elif [ -f /etc/php5/php.ini ]; then + sedit /etc/php5/php.ini + elif [ -f /usr/bin/php5/bin/php.ini ]; then + sedit /usr/bin/php5/bin/php.ini + elif [ -f /etc/php5/apache2/php.ini ]; then + sedit /etc/php5/apache2/php.ini + else + echo "Error: php.ini file could not be found." + echo "Searching for possible locations:" + sudo updatedb && locate php.ini + fi +} + +# Edit the MySQL configuration file +mysqlconfig() { + if [ -f /etc/my.cnf ]; then + sedit /etc/my.cnf + elif [ -f /etc/mysql/my.cnf ]; then + sedit /etc/mysql/my.cnf + elif [ -f /usr/local/etc/my.cnf ]; then + sedit /usr/local/etc/my.cnf + elif [ -f /usr/bin/mysql/my.cnf ]; then + sedit /usr/bin/mysql/my.cnf + elif [ -f ~/my.cnf ]; then + sedit ~/my.cnf + elif [ -f ~/.my.cnf ]; then + sedit ~/.my.cnf + else + echo "Error: my.cnf file could not be found." + echo "Searching for possible locations:" + sudo updatedb && locate my.cnf + fi +} + +# For some reason, rot13 pops up everywhere +rot13() { + if [ $# -eq 0 ]; then + tr '[a-m][n-z][A-M][N-Z]' '[n-z][a-m][N-Z][A-M]' + else + echo $* | tr '[a-m][n-z][A-M][N-Z]' '[n-z][a-m][N-Z][A-M]' + fi +} + +# Trim leading and trailing spaces (for scripts) +trim() { + local var=$@ + var='${var#"${var%%[![:space:]]*}"}' # remove leading whitespace characters + var='${var%"${var##*[![:space:]]}"}' # remove trailing whitespace characters + echo -n "$var" +} |
