diff options
| -rw-r--r-- | fedora/.config/bash/autocomplete.bash | 4 | ||||
| -rw-r--r-- | fedora/.config/bash/bashrc | 7 | ||||
| -rw-r--r-- | fedora/.config/bash/keymaps.bash | 2 | ||||
| -rw-r--r-- | fedora/.config/bash/scripts.bash | 18 | ||||
| -rwxr-xr-x | fedora/.local/bin/fzffiles | 99 | ||||
| -rwxr-xr-x | fedora/.local/bin/fzffns | 74 | ||||
| -rwxr-xr-x | fedora/.local/bin/fzfpass | 88 | ||||
| -rw-r--r-- | mac/.config/shell/profile | 29 | ||||
| -rw-r--r-- | mac/.config/zsh/.zshrc | 2 |
9 files changed, 308 insertions, 15 deletions
diff --git a/fedora/.config/bash/autocomplete.bash b/fedora/.config/bash/autocomplete.bash index 0aeeedd..3ee6183 100644 --- a/fedora/.config/bash/autocomplete.bash +++ b/fedora/.config/bash/autocomplete.bash @@ -147,7 +147,7 @@ expand_alias_and_accept_line() { # 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 +# 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: @@ -169,7 +169,7 @@ _bash_accept_line() { # (This is a conservative behavior to avoid interfering unexpectedly.) return 0 } -bind -x '"\C-m":_bash_accept_line' +#bind -x '"\C-m":_bash_accept_line' # ---------- helper: background starter ---------- background() { diff --git a/fedora/.config/bash/bashrc b/fedora/.config/bash/bashrc index 95a1c38..ec1cc46 100644 --- a/fedora/.config/bash/bashrc +++ b/fedora/.config/bash/bashrc @@ -163,6 +163,13 @@ bind '"\C-g":"lfcd\n"' eval "$(dircolors)" +[ -f "$HOME/.config/bash/git.bash" ] && . "$HOME/.config/bash/git.bash" +[ -f "$HOME/.config/bash/p10k.bash" ] && . "$HOME/.config/bash/p10k.bash" +[ -f "$HOME/.config/bash/autocomplete.bash" ] && . "$HOME/.config/bash/autocomplete.bash" +[ -f "$HOME/.config/bash/scripts.bash" ] && . "$HOME/.config/bash/scripts.bash" +[ -f "$HOME/.config/bash/keymaps.bash" ] && . "$HOME/.config/bash/keymaps.bash" +[ -f "$HOME/.config/bash/plugins.bash" ] && . "$HOME/.config/bash/plugins.bash" +[ -f "$HOME/.config/bash/packages.bash" ] && . "$HOME/.config/bash/packages.bash" [ -f "${XDG_CONFIG_HOME:-${HOME}/.config}/shell/aliasrc" ] && . "${XDG_CONFIG_HOME:-${HOME}/.config}/shell/aliasrc" [ -f "${XDG_CONFIG_HOME:-${HOME}/.config}/shell/git-aliasrc" ] && . "${XDG_CONFIG_HOME:-${HOME}/.config}/shell/git-aliasrc" [ -f "${XDG_CONFIG_HOME:-${HOME}/.config}/shell/shortcutrc" ] && . "${XDG_CONFIG_HOME:-${HOME}/.config}/shell/shortcutrc" diff --git a/fedora/.config/bash/keymaps.bash b/fedora/.config/bash/keymaps.bash index 91b3cad..bbe27a0 100644 --- a/fedora/.config/bash/keymaps.bash +++ b/fedora/.config/bash/keymaps.bash @@ -193,7 +193,7 @@ 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 +#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 diff --git a/fedora/.config/bash/scripts.bash b/fedora/.config/bash/scripts.bash index 76644e3..400265d 100644 --- a/fedora/.config/bash/scripts.bash +++ b/fedora/.config/bash/scripts.bash @@ -155,6 +155,24 @@ mkdt() { ########################################################################################### ########################################################################################### +### --- CURSOR --- ### +# vi-mode cursor change +function update_cursor { + if [[ $READLINE_LINE == * ]]; then + if [[ $READLINE_POINT -eq 0 ]]; then + echo -ne '\e[6 q' # insert mode + else + echo -ne '\e[2 q' # command mode + fi + fi +} + +# vi-command, vi-insert 모드 hook 등록 +bind -m vi-insert '":": "\C-o update_cursor"' +bind -m vi-command '":": "\C-o update_cursor"' + +########################################################################################### +########################################################################################### ### --- DISTRIBUTION --- ### # Show the current distribution distribution() { diff --git a/fedora/.local/bin/fzffiles b/fedora/.local/bin/fzffiles new file mode 100755 index 0000000..44634a2 --- /dev/null +++ b/fedora/.local/bin/fzffiles @@ -0,0 +1,99 @@ +#!/bin/sh + +# The set -e option instructs sh to immediately exit if any command has a non-zero exit status +set -e + +# Set new line and tab for word splitting +IFS=' +' + +# Get the list of selected files with key bindings for specific paths +files=$(fzf-tmux \ + --header "^a pwd ^b public ^d .dotfiles ^f configs ^g git ^h home ^k desktop ^r scripts ^s suckless ^u staged files ^v private ^/ help" \ + --preview "selection={}; + clean=\$(printf '%s' \"\$selection\" | sed -e 's/^📄 //' -e 's/^✏️ //' -e 's/^✅ //' -e 's/^❌ //' -e 's/^🔀 //' -e 's/^❓ //'); + [ -z \"\$clean\" ] && { echo 'No selection'; exit 0; } + target=\$(readlink -f \"\$clean\" 2>/dev/null || printf '%s' \"\$clean\"); + if [ -z \"\$target\" ]; then + echo 'Could not resolve path'; + exit 0; + fi + if [ -f \"\$target\" ]; then + dir=\$(dirname \"\$target\"); + if git_root=\$(git -C \"\$dir\" rev-parse --show-toplevel 2>/dev/null); then + rel=\${target#\"\$git_root\"/}; + diff_output=\$(git -C \"\$git_root\" diff --color -- \"\$rel\"); + if [ -n \"\$diff_output\" ]; then + printf '%s\n' \"\$diff_output\" + exit 0 + fi + diff_output=\$(git -C \"\$git_root\" diff --color --cached -- \"\$rel\"); + if [ -n \"\$diff_output\" ]; then + printf '%s\n' \"\$diff_output\" + exit 0 + fi + fi + fi + if [ -d \"\$target\" ]; then + exa --color=always --long --all --header --icons --git \"\$target\" + elif [ -f \"\$target\" ]; then + bat --color=always --style=header,grid --line-range=:500 \"\$target\" + else + file -h \"\$target\" + fi" \ + --reverse \ + --query="$1" \ + --multi \ + --exit-0 \ + --prompt " 💡 " \ + --bind "ctrl-a:change-prompt( ⚡ )+reload(fd -H -L -t f -E .Trash -E .git -E .cache . $PWD)" \ + --bind "ctrl-b:change-prompt( 🌎 )+reload(fd -H -L -t f -E .Trash -E .git -E .cache . ${XDG_PUBLICSHARE_DIR:-${HOME}/Public})" \ + --bind "ctrl-d:change-prompt( ⚙️ )+reload(fd -H -L -t f -E .Trash -E .git -E .cache . ${XDG_DOTFILES_DIR:-${HOME}/.dotfiles})" \ + --bind "ctrl-f:change-prompt( 🗂️ )+reload(fd -H -L -t f -E .Trash -E .git -E .cache . ${XDG_CONFIG_HOME:-${HOME}/.config})" \ + --bind "ctrl-g:change-prompt( )+reload(fd -H -L -t f -E .Trash -E .git -E .cache . $HOME/Private/repos $HOME/Public/repos)" \ + --bind "ctrl-h:change-prompt( 🏠 )+reload(fd -H -L -t f -E .Trash -E .git -E .cache . $HOME)" \ + --bind "ctrl-k:change-prompt( 🖥️ )+reload(fd -H -L -t f -E .Trash -E .git -E .cache . ${XDG_DESKTOP_DIR:-${HOME}/Desktop})" \ + --bind "ctrl-r:change-prompt( 👟 )+reload(fd -H -L -t f -E .Trash -E .git -E .cache -E zsh . ${XDG_BIN_HOME:-${HOME}/.local/bin})" \ + --bind "ctrl-s:change-prompt( 🛠 )+reload(find ${XDG_SOURCES_HOME:-${HOME}/.local/src}/suckless -maxdepth 2 -type f -not -path '*/.git/*')" \ + --bind "ctrl-u:change-prompt( 📝 )+reload(if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then top=\$(git rev-parse --show-toplevel 2>/dev/null); git -C \"\$top\" status --porcelain | awk -v root=\"\$top\" '{ + staged=substr(\$0,1,1); + unstaged=substr(\$0,2,1); + file=substr(\$0,4); + gsub(/^ +/, \"\", file); + if (file == \"\") next; + if (staged == \"?\" && unstaged == \"?\") icon=\"📄\"; + else if (staged == \"!\" && unstaged == \"!\") icon=\"❌\"; + else if (staged != \" \" && staged != \"?\" && unstaged != \" \" && unstaged != \"?\") icon=\"🔀\"; + else if (staged != \" \" && staged != \"?\") icon=\"✅\"; + else if (unstaged != \" \") icon=\"✏️\"; + else icon=\"❓\"; + print icon \" \" root \"/\" file + }'; else echo 'This is not a git repository.'; fi)" \ + --bind "ctrl-v:change-prompt( 🔒 )+reload(fd -H -L -t f -E .Trash -E .git -E .cache . $HOME/Private)" \ + --bind 'ctrl-/:change-prompt( ❓ )+reload(echo "^a all +^b public +^c configs +^d .dotfiles +^g git +^k desktop +^r scripts +^s suckless +^u staged files +^v private +^/ help")') + +# Check if any files were selected, and exit if not +[ -z "$files" ] && exit 0 + +files=$(printf '%s\n' "$files" | sed -e 's/^📄 //' -e 's/^✏️ //' -e 's/^✅ //' -e 's/^❌ //' -e 's/^🔀 //' -e 's/^❓ //') + +if [ -d "$files" ]; then + absolute_files=$(realpath $files) + if echo "$absolute_files" | while read -r file; do file --mime-type "$file" | grep -q 'video/'; done; then + mpv --quiet --loop $absolute_files + else + openfiles "$absolute_files" + fi +else + openfiles "$files" +fi diff --git a/fedora/.local/bin/fzffns b/fedora/.local/bin/fzffns new file mode 100755 index 0000000..c919723 --- /dev/null +++ b/fedora/.local/bin/fzffns @@ -0,0 +1,74 @@ +#!/bin/sh + +# Print all functions and comments in a readable format +# Set the filename of the script containing the functions +file="${ZDOTDIR:-${XDG_CONFIG_HOME:-${HOME}/.config}/zsh}/scripts.zsh" + +# Initialize an empty variable to hold functions, aliases, and comments +functions="" + +# Parse the file for function names, aliases, and comments +while IFS= read -r line || [ -n "$line" ]; do + case "$line" in + \#*) + if [ "$(printf '%s' "$line" | cut -c 2)" != "#" ] && [ "$(printf '%s' "$line" | cut -c 2)" != "!" ]; then + # Remove the '#' from the comment line + comment=$(printf '%s' "$line" | sed 's/^# //') + + # Read the next line to check for alias or function definition + IFS= read -r next_line || break + + # Check if it's an alias definition + if echo "$next_line" | grep -q '^alias '; then + alias_name=$(echo "$next_line" | sed -n 's/^alias \([a-zA-Z0-9_]*\)=.*$/\1/p') + + # Read another line to get the function definition + IFS= read -r func_line || break + f_name=$(printf '%s' "$func_line" | sed -n 's/^function \([^(]*\)().*$/\1/p') + + if [ -n "$f_name" ]; then + functions="$functions$f_name|$alias_name|$comment\n" + fi + + # Check if it's a function definition + elif echo "$next_line" | grep -q '^function '; then + f_name=$(printf '%s' "$next_line" | sed -n 's/^function \([^(]*\)().*$/\1/p') + if [ -n "$f_name" ]; then + functions="$functions$f_name||$comment\n" + fi + fi + fi + ;; + esac +done <"$file" + +# Sort the functions alphabetically by name +sorted=$(printf '%b' "$functions" | sort) + +# Print out the sorted functions with aliases and comments in a readable format +formatted=$(printf '%b' "$sorted" | while IFS='|' read -r f_name alias_name comment; do + if [ -n "$alias_name" ]; then + printf 'fn: %-30s - %s (alias: %s)\n' "$f_name" "$comment" "$alias_name" + else + printf 'fn: %-30s - %s\n' "$f_name" "$comment" + fi +done) + +# Use fzf to select a function +selected=$(printf '%b' "$formatted" | fzf-tmux --header "Select a function:" --reverse) + +# Check if a function was selected +if [ -n "$selected" ]; then + # Extract the function name + f_name=$(echo "$selected" | cut -d ' ' -f 2 | sed 's/[[:space:]]\+//g') + + # Get the line number of the function definition + line_number=$(grep -n "^function $f_name(" "$file" | cut -d ':' -f 1) + + # Open the function in nvim at the specific line number + if [ -n "$line_number" ]; then + nvim "+$line_number" "$file" + else + echo "Function '$f_name' not found in $file." + fi +fi diff --git a/fedora/.local/bin/fzfpass b/fedora/.local/bin/fzfpass new file mode 100755 index 0000000..5190f8e --- /dev/null +++ b/fedora/.local/bin/fzfpass @@ -0,0 +1,88 @@ +#!/bin/sh + +set -e + +usage() { + echo "Find pass gpg files in Password-Store using fzf." + echo "" + echo "Usage: ${0##*/} [-h|--help]" + echo "" + echo "Options:" + echo " -h, --help : Show this message" + echo "" + echo "Shortcuts:" + echo " return - echo password and copy to clipboard (wayland only)" + echo " ctrl+a - new password (named as per the prompt)" + echo " ctrl+e - edit selected password" + echo " ctrl+g - regenerate selected password" + echo " ctrl+r - rename selected password" + echo " ctrl+x - delete selected password" + echo " tab - tab complete" + echo " esc/ctrl+c - exit" + exit 0 +} + +if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + usage +fi + +passdir=${PASSWORD_STORE_DIR:-$HOME/.local/share/.password-store} +cd "$passdir" + +# Unlock the password for this session +pass show "$(tree -Ffi | grep '.gpg' | sed 's/.gpg$//g' | sed 's/^..//' | head -n 1)" >/dev/null + +# Main fzf session +passfile=$( + tree -Ffi | grep '.gpg' | sed 's/.gpg$//g' | sed 's/^..//' | + fzf-tmux \ + --header="🔑 Password Manager" \ + --reverse \ + --no-mouse \ + --preview="pass {}" \ + --header="🔑 ^a: Generate | ^e: Edit | ^g: Generate (no symbol) | ^r: Rename | ^s: Generate (symbol) | ^x: Delete | tab: Replace" \ + --bind="ctrl-a:execute(if [ -z {q} ]; then read -p \"Can't generate empty password. Press enter to continue...\"; else pass generate -n {q} < /dev/tty > /dev/tty 2>&1 && pass edit {q} < /dev/tty > /dev/tty 2>&1; fi)+reload(tree -Ffi | grep '.gpg' | sed 's/.gpg$//g')" \ + --bind="ctrl-e:execute(pass edit {} < /dev/tty > /dev/tty 2>&1)+reload(tree -Ffi | grep '.gpg' | sed 's/.gpg$//g')" \ + --bind="ctrl-r:execute(bash -c ' +echo -n \"Enter new name for {}: \" > /dev/tty; +read new_name < /dev/tty; +if [ -n \"\$new_name\" ]; then + pass mv {} \"\$new_name\" || echo \"Rename failed.\" > /dev/tty; +else + echo \"No name entered. Rename aborted.\" > /dev/tty; +fi' < /dev/tty > /dev/tty 2>&1)+reload(tree -Ffi | grep '.gpg' | sed 's/.gpg$//g')" \ + --bind="ctrl-g:execute(if [ -z {} ]; then read -p \"Can't generate empty password. Press enter to continue...\"; else pass generate -in {} < /dev/tty > /dev/tty 2>&1 && pass edit {} < /dev/tty > /dev/tty 2>&1; fi)+reload(tree -Ffi | grep '.gpg' | sed 's/.gpg$//g')" \ + --bind="ctrl-s:execute(if [ -z {} ]; then read -p \"Can't generate empty password. Press enter to continue...\"; else pass generate -i {} < /dev/tty > /dev/tty 2>&1 && pass edit {} < /dev/tty > /dev/tty 2>&1; fi)+reload(tree -Ffi | grep '.gpg' | sed 's/.gpg$//g')" \ + --bind="ctrl-x:execute(pass rm {} < /dev/tty > /dev/tty 2>&1)+reload(tree -Ffi | grep '.gpg' | sed 's/.gpg$//g')" \ + --bind="tab:replace-query" +) + +show_passdata=false + +if [ "$1" = "-i" ]; then + show_passdata=true + shift +fi + +if [ "$show_passdata" = true ]; then + passdata="$(pass "$passfile")" + echo "$passdata" +else + password="$(pass show "$passfile" | head -n 1)" + echo "$password" + + if [ -n "$password" ]; then + case "$(uname)" in + Darwin*) + printf "%s" "$password" | pbcopy # Use pbcopy on macOS + ;; + Linux*) + printf "%s" "$password" | xclip -selection clipboard # Use xclip on Linux + ;; + *) + echo "Unsupported operating system" + ;; + esac + sleep 0.1 + fi +fi diff --git a/mac/.config/shell/profile b/mac/.config/shell/profile index 0b676be..da5b702 100644 --- a/mac/.config/shell/profile +++ b/mac/.config/shell/profile @@ -1,19 +1,9 @@ ################################################### -### --- ENV PATH --- ### +### --- LANG --- ### ################################################### export LANG=ko_KR.UTF-8 export LC_CTYPE=ko_KR.UTF-8 -# Add all directories in each subdirectory to $PATH -export PATH="$PATH:$(find ~/.local/bin -path '*/.git*' -prune -o \( -type f -o -type l \) -perm -u=x -exec dirname {} \; | sort -u | paste -sd ':' -)" -export PATH="$PATH:$(find ~/.local/share/.password-store -type d -name '.extensions' | paste -sd ':' -)" -export PATH="$PATH:/opt/homebrew/bin" -export PATH="$PATH:$(find -L /opt/homebrew/Caskroom \( -name bin -o -name MacOS \) -type d -print 2>/dev/null | sort -u | paste -s -d ':' -)" -export PATH="$PATH:$(find -L /opt/homebrew/Cellar -name bin -type d -print 2>/dev/null | sort -u | paste -s -d ':' -)" -export PATH="$PATH:$(find -L /opt/homebrew/opt -name bin -type d -print 2>/dev/null | sort -u | paste -s -d ':' -)" - -unsetopt PROMPT_SP 2>/dev/null - ################################################### ### --- DEFAULT PROGRAMS --- ### ################################################### @@ -64,7 +54,6 @@ export ANSIBLE_CONFIG="$XDG_CONFIG_HOME/ansible/ansible.cfg" ### --- ASDF --- ### export ASDF_CONFIG_FILE="$XDG_CONFIG_HOME/asdf/asdfrc" export ASDF_DATA_DIR="$XDG_DATA_HOME/asdf" -export PATH="$ASDF_DATA_DIR/shims:$PATH" ### --- BAT --- ### export BAT_CONFIG_PATH="$XDG_CONFIG_HOME/bat/config" @@ -236,5 +225,21 @@ export STARDICT_DATA_DIR="$XDG_DATA_HOME/dic" export STARDICT_HISTFILE="$XDG_DATA_HOME/history/dic" export SDCV_PAGER='less --quit-if-one-screen -RX' +################################################### +### --- ENV PATH --- ### +################################################### +# Add all directories in each subdirectory to $PATH +export PATH="$(find ~/.local/bin -path '*/.git*' -prune -o \( -type f -o -type l \) -perm -u=x -exec dirname {} \; | sort -u | paste -sd ':' -):$PATH" +export PATH="$(find ~/.local/share/.password-store -type d -name '.extensions' | paste -sd ':' -):$PATH" +export PATH="$ASDF_DATA_DIR/shims:$PATH" +export PATH="/opt/homebrew/bin:$PATH" +export PATH="$(find -L /opt/homebrew/Caskroom \( -name bin -o -name MacOS \) -type d -print 2>/dev/null | sort -u | paste -s -d ':' -):$PATH" +export PATH="$(find -L /opt/homebrew/Cellar -name bin -type d -print 2>/dev/null | sort -u | paste -s -d ':' -):$PATH" +export PATH="$(find -L /opt/homebrew/opt -name bin -type d -print 2>/dev/null | sort -u | paste -s -d ':' -):$PATH" + +unsetopt PROMPT_SP 2>/dev/null + +################################################### ### --- SHORTCUTS --- ### +################################################### [ ! -f "$XDG_CONFIG_HOME/shell/shortcutrc" ] && nohup bmshortcuts >/dev/null 2>&1 & diff --git a/mac/.config/zsh/.zshrc b/mac/.config/zsh/.zshrc index a90fe52..145ee4a 100644 --- a/mac/.config/zsh/.zshrc +++ b/mac/.config/zsh/.zshrc @@ -124,3 +124,5 @@ export AVANTE_OPENAI_API_KEY="$(pass show api/chatGPT/nvim | head -n1)" ### --- OPENAI --- ### export OPENAI_API_KEY="$(pass show api/chatGPT/nvim | head -n1)" + +. "$(brew --prefix asdf)/libexec/asdf.sh" |
