From b4b9266564d91a6d5b8bcbda0e3e3df5e60c108c Mon Sep 17 00:00:00 2001 From: TheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com> Date: Tue, 19 May 2026 11:15:10 +0900 Subject: updates --- linux/.local/bin/rgafiles | 206 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100755 linux/.local/bin/rgafiles (limited to 'linux/.local/bin/rgafiles') diff --git a/linux/.local/bin/rgafiles b/linux/.local/bin/rgafiles new file mode 100755 index 0000000..2fc8488 --- /dev/null +++ b/linux/.local/bin/rgafiles @@ -0,0 +1,206 @@ +#!/bin/sh + +# Usage function to display script options +usage() { + echo "Find files using ripgrep and open them in Vim." + echo "" + echo "Usage: ${0##*/} [-s] [-i] [-l] [-p] [] " + echo "" + echo "Options:" + echo " -h : Show this message" + echo " -i : Perform a case-insensitive search (default)" + echo " -l : List files associated with the given tag" + echo " -p : Search for files in the specified project directories using the specified tag (default: PROJECT)" + echo " -s : Perform a case-sensitive search" + echo " [] : Optional tag for project mode, followed by the search query" + echo "" + echo "Examples:" + echo " ${0##*/} -p TODO 'KEYWORD' # Search for 'KEYWORD' in files tagged with 'TODO' in the project directories" + echo " ${0##*/} -l -p 'KEYWORD' # List files associated with the default 'PROJECT' tag and 'KEYWORD'" + echo " ${0##*/} 'KEYWORD' # Open files containing 'KEYWORD' in vim" + exit 0 +} + +search_term() { + case_flag="$1" + shift + + if ! command -v rga >/dev/null 2>&1; then + echo "Error: 'rga' is not installed." >&2 + exit 1 + fi + if ! command -v xclip >/dev/null 2>&1; then + echo "Error: 'xclip' is not installed." >&2 + exit 1 + fi + + # Construct the preview command + preview_cmd=$(printf "rga %s --pretty --context 10 '%s' {}" "$case_flag" "$*") + query="$*" + rga_output=$(rga --follow --no-ignore --hidden --text --max-count=1 ${case_flag:+$case_flag} --files-with-matches --no-messages \ + --glob '!**/.cache/*' \ + --glob '!**/.git/*' \ + --glob '!**/.github/*' \ + --glob '!**/.next/*' \ + --glob '!**/.venv/*' \ + --glob '!**/build/*' \ + --glob '!**/coverage/*' \ + --glob '!**/dist/*' \ + --glob '!**/node_modules/*' \ + --glob '!**/target/*' \ + --glob '!**/vendor/*' \ + --glob '!**/venv/*' \ + "$query") + + # Use fzf to select files + files=$(echo "$rga_output" | fzf +m --preview="$preview_cmd" --reverse --multi --select-1 --exit-0) || return 1 + + # Check if files are selected + if [ -z "$files" ]; then + echo "No files selected." + return 0 + fi + + # copy target to the clipboard + echo "$query" | xclip -selection clipboard 2>/dev/null + + # Open files at matching lines + count=$(echo "$files" | wc -l) + if [ "$count" -eq 1 ]; then + # Find the first matching line number in the selected file + line=$(rga --max-count=1 --line-number --no-filename ${case_flag:+$case_flag} --no-messages "$query" "$files" 2>/dev/null | head -1 | cut -d: -f1) + if [ -n "$line" ]; then + ${EDITOR:-vim} "+${line}" "$(realpath "$files")" + else + openfiles "$files" + fi + else + # Multiple files: open at matching lines via quickfix + tmpfile=$(mktemp) + echo "$files" | while IFS= read -r file; do + match=$(rga --max-count=1 --line-number --no-filename ${case_flag:+$case_flag} --no-messages "$query" "$file" 2>/dev/null | head -1) + if [ -n "$match" ]; then + printf '%s:%s\n' "$(realpath "$file")" "$match" >> "$tmpfile" + else + printf '%s:1:\n' "$(realpath "$file")" >> "$tmpfile" + fi + done + if [ "$count" -lt 5 ]; then + ${EDITOR:-vim} -q "$tmpfile" \ + -c 'for i in range(2,len(getqflist())) | vsplit | execute "cc ".i | endfor | wincmd t' + else + first_line=$(head -1 "$tmpfile" | cut -d: -f2) + file_args="" + while IFS=: read -r fpath _; do + file_args="$file_args \"$fpath\"" + done < "$tmpfile" + eval "${EDITOR:-vim}" "+${first_line}" "$file_args" + fi + rm -f "$tmpfile" + fi + + # print the file names + echo "$rga_output" +} + +# Function to list and/or open all files associated with a given project tag +list_or_open_project_files() { + # Use the provided tag or default to "PROJECT" + project_tag="${1:-PROJECT}: $2" + + # Define the project paths as a space-separated string + project_paths="$HOME/.dotfiles $HOME/.local/src/suckless $HOME/Public/repos" + + # Use rga to find files containing the project tag across all project paths + rga_output="" + for path in $project_paths; do + if [ -d "$path" ]; then + rga_result=$(rga --follow --no-ignore --hidden --text --max-count=1 --files-with-matches --no-messages \ + --glob '!**/.cache/*' \ + --glob '!**/.git/*' \ + --glob '!**/.github/*' \ + --glob '!**/.next/*' \ + --glob '!**/.venv/*' \ + --glob '!**/build/*' \ + --glob '!**/coverage/*' \ + --glob '!**/dist/*' \ + --glob '!**/node_modules/*' \ + --glob '!**/target/*' \ + --glob '!**/vendor/*' \ + --glob '!**/venv/*' \ + "$project_tag" "$path") + rga_output="$rga_output $rga_result" + fi + done + + # Remove leading/trailing whitespace + rga_output=$(echo "$rga_output" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + + # Check if any files were found + if [ -z "$rga_output" ]; then + echo "No files found for tag $project_tag." + return 0 + fi + + # If the script was called in list mode, simply print the files + if [ "$list_mode" -eq 1 ]; then + echo "$rga_output" + else + # Open files at matching lines + file_count=$(echo "$rga_output" | wc -w) + if [ "$file_count" -eq 1 ]; then + line=$(rga --max-count=1 --line-number --no-filename --no-messages "$project_tag" "$rga_output" 2>/dev/null | head -1 | cut -d: -f1) + if [ -n "$line" ]; then + ${EDITOR:-vim} "+${line}" "$(realpath "$rga_output")" + else + openfiles "$rga_output" + fi + else + # Multiple files: open at matching lines via quickfix + tmpfile=$(mktemp) + for file in $rga_output; do + match=$(rga --max-count=1 --line-number --no-filename --no-messages "$project_tag" "$file" 2>/dev/null | head -1) + if [ -n "$match" ]; then + printf '%s:%s\n' "$(realpath "$file")" "$match" >> "$tmpfile" + else + printf '%s:1:\n' "$(realpath "$file")" >> "$tmpfile" + fi + done + if [ "$file_count" -lt 5 ]; then + ${EDITOR:-vim} -q "$tmpfile" \ + -c 'for i in range(2,len(getqflist())) | vsplit | execute "cc ".i | endfor | wincmd t' + else + ${EDITOR:-vim} -q "$tmpfile" \ + -c 'silent! for i in range(2,len(getqflist())+1) | execute "silent! cc ".i | endfor | silent! cfirst' + fi + rm -f "$tmpfile" + fi + fi +} + +# Main function to handle options +case_flag="--ignore-case" # Default to case-insensitive +list_mode=0 +project_mode=0 + +# Parse the options +while getopts "silph" opt; do + case $opt in + s) case_flag="--case-sensitive" ;; # Case-sensitive + i) case_flag="--ignore-case" ;; # Case-insensitive + l) list_mode=1 ;; # List mode + p) project_mode=1 ;; # Project mode + h) usage ;; + *) ;; + esac +done + +shift $((OPTIND - 1)) + +# Handle project mode search +if [ "$project_mode" -eq 1 ]; then + list_or_open_project_files "$1" "$2" +else + # Otherwise, call the common search function + search_term "$case_flag" "$@" +fi -- cgit v1.2.3