Skip to content

Instantly share code, notes, and snippets.

@dcai
Last active May 6, 2025 07:57
Show Gist options
  • Save dcai/1168657 to your computer and use it in GitHub Desktop.
Save dcai/1168657 to your computer and use it in GitHub Desktop.
cgvg: code grep, vim grepped
#!/bin/bash
#
# Inspired by uzix's cgvg https://uzix.org/cgvg.html
#
# cg: code grep
# vg: vim grepped
#
INDEX_FILE="$XDG_STATE_HOME/cgvg.index"
export GRAY="\033[37m"
export CLROFF="\033[0;0m"
out() {
echo -e "$GRAY$1$CLROFF"
}
RG_BIN='rg --follow --color never --hidden --no-config'
AWK_BIN='gawk'
CMD_NAME=$(basename "$0")
USE_PAGER=false
VERBOSE=false
ARGS=''
POSITIONAL=()
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
-t | --type)
ARGS+=" -t $2 "
shift
shift
;;
--no-ignore)
ARGS+=' --no-ignore '
shift # past argument
;;
--debug)
ARGS+=' --debug '
shift
;;
-p | --pager)
USE_PAGER=true
shift
;;
-v | --verbose)
VERBOSE='true'
shift
;;
*) # unknown option
POSITIONAL+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters
SCRIPTPATH="$(
cd "$(dirname "$0")" || exit 1
pwd -P
)"
if [ $# -lt 1 ]; then
echo "Usage: ${CMD_NAME} [search_term] --no-ignore"
exit 1
fi
# the `sort` command makes sure the lines are sorted and unique by filename and line number (don't are column number)
CMD="${RG_BIN} --smart-case --fixed-strings '$*' --vimgrep ${ARGS} | sort --unique --field-separator=: --key=1,2 >$INDEX_FILE"
if [ $VERBOSE == 'true' ]; then
out "> $CMD"
fi
eval "$CMD"
# formatting the awk file, use command:
# gawk -o- ./cgvg_parser.awk | pbcopy
CMD="cat $INDEX_FILE | $AWK_BIN -f '${SCRIPTPATH}/cgvg_parser.awk' | grep '$1' -i --color"
if [ $USE_PAGER == 'true' ]; then
CMD="$CMD | less --RAW-CONTROL-CHARS --chop-long-lines --quit-if-one-screen"
fi
if [ $VERBOSE == 'true' ]; then
out "> $CMD"
fi
eval "$CMD"
LC=$(wc -l "$INDEX_FILE" | $AWK_BIN '{print $1}')
if [ $VERBOSE == 'true' ]; then
if [ "$LC" -gt 0 ]; then
out "# found $LC matches"
else
out "# nothing found"
fi
fi
BEGIN {
FS = ":"
OFS = ":"
m[0] = "a"
m[1] = "b"
m[2] = "c"
m[3] = "d"
m[4] = "e"
m[5] = "f"
m[6] = "g"
m[7] = "h"
m[8] = "i"
m[9] = "j"
}
{
text = $0
nr = encode(NR)
redbg(sprintf("%3s", nr)) # index number
gray($1) # file name field
space()
green($2) # line number
space()
$1 = ""
$2 = ""
$3 = ""
gsub(/:::/, "", $0)
print trim($text) # matched line text
}
function br()
{
printf "\n"
}
function encode(str)
{
code = ""
for (i = 1; i <= length(str); i++) {
char = substr(str, i, 1)
code = code m[char]
}
return code
}
function gray(str)
{
printf "%s", "\033[1;30m" str "\033[0m"
}
function green(str)
{
printf "%s", "\033[1;32m" str "\033[0m "
}
function redbg(str)
{
printf "%s", "\033[1;41m" str "\033[0m "
}
function space()
{
printf "%s", " "
}
function trim(s)
{
gsub(/^[ \t\r\n-]+|[ \t\r\n-]+$/, "", s)
return s
}
function yellow(str)
{
printf "%s", "\033[1;33m" str "\033[0m"
}
#!/bin/sh
INDEX_FILE="$XDG_STATE_HOME/cgvg.index"
BASENAME=$(basename "$0")
if [ $# -ne 1 ]; then
echo "Usage: ${BASENAME} [index]"
exit 1
fi
LNUM=$(echo "$1" | tr 'a-j' '0-9')
CMD="sed -n '$LNUM'p ${INDEX_FILE}"
ARGS=$(eval "$CMD" | awk -F: '{print " +"$2 " \"" $1 "\""}')
CMD="$EDITOR $ARGS"
echo "> $CMD"
eval "$CMD"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment