TODO Comment Search
Use ripgrep (rg) to find TODO-style comments quickly across projects. This
is useful for local cleanup, release checks, and CI gates.
Quick search
rg --no-messages --vimgrep -H --column --line-number --color never \
-e '(TODO|FIXME|BUG|HACK|XXX)' .
--vimgrep, -H, --column, and --line-number produce rows in this form:
path/to/file:line:column:matched text
Comment-aware search
This pattern looks for common comment prefixes, markdown task/list items, or a tag at the start of a line:
TAGS='BUG|HACK|FIXME|TODO|XXX|\[ \]|\[x\]'
PREFIX='//|#|<!--|;|/\*|^|^[[:blank:]]*(-|[0-9]+\.)'
rg --no-messages --vimgrep -H --column --line-number --color never \
--max-columns=1000 --no-config \
-e "(${PREFIX})[[:space:]]*(${TAGS})" \
-g '!**/.git/**' \
-g '!**/node_modules/**' \
-g '!**/target/**' \
-g '!**/.build/**' \
.
Notes:
--no-configkeeps personal rg config from changing project results.--max-columns=1000avoids dropping long lines too early.- Add
-ifor case-insensitive tags. - Add
--hiddenwhen dotfiles should be scanned too.
Project script
Add this as scripts/todos:
#!/usr/bin/env bash
set -euo pipefail
TAGS='BUG|HACK|FIXME|TODO|XXX|\[ \]|\[x\]'
PREFIX='//|#|<!--|;|/\*|^|^[[:blank:]]*(-|[0-9]+\.)'
rg --no-messages --vimgrep -H --column --line-number --color never \
--max-columns=1000 --no-config \
-e "(${PREFIX})[[:space:]]*(${TAGS})" \
-g '!**/.git/**' \
-g '!**/node_modules/**' \
-g '!**/target/**' \
-g '!**/.build/**' \
"$@" \
.
Then:
chmod +x scripts/todos
scripts/todos
Filters
Use -g for include and exclude globs. A glob beginning with ! excludes
matches.
# Only source and markdown paths
scripts/todos -g 'src/**' -g 'docs/**' -g '*.md'
# Exclude generated/vendor paths
scripts/todos -g '!**/vendor/**' -g '!**/dist/**' -g '!**/*.lock'
# Include hidden files
scripts/todos --hidden
CI check
Fail when TODO-style comments are present:
if scripts/todos >/tmp/todos.txt; then
cat /tmp/todos.txt
echo "TODO comments found"
exit 1
fi
rg exits with 0 when it finds a match and 1 when it finds none.