A CLI tool that strips comments from source code files across a wide range of languages (C-like languages, Python, Ruby, Rust, Go, shell scripts, SQL, batch files, LaTeX, and more) across an entire directory tree, in parallel.
- Comment removal across many languages, including line comments, block comments, and language-specific quirks like Ruby's
=begin/=endand batch'sREM/::. See Supported languages below. - String-aware lexer: comment markers inside
'...',"...", or`...`are left untouched. - Recursive directory processing with
--include/--excludeglob filters. --dry-runand--diffmodes to preview changes before touching any file.- Optional
.bakbackups before overwriting. - Parallel file processing via
--jobs. - Automatic language detection from file extension or well-known filenames (
Makefile,Dockerfile,Gemfile,Rakefile,Vagrantfile), or force one with--lang.
Requires Python 3.8+.
This installs the package for the current user and automatically adds the launcher's directory to your PATH if it isn't already there.
# Windows (PowerShell)
.\install.ps1# Linux / macOS
./install.shOpen a new terminal window afterwards so the updated PATH takes effect, then run:
comment-stripper --versionTo uninstall:
python scripts/install.py --uninstall # or install.ps1 --uninstall / install.sh --uninstallpip install --user .Pip installs the comment-stripper launcher into your Python user-scripts directory. If that directory isn't already on your PATH, run the install script above (or add it manually) so the command is available globally.
comment-stripper [path] [options]| Option | Description |
|---|---|
path |
File or directory to process (default: current directory). |
--lang |
Force a language, bypassing extension detection. One of the names in Supported languages. |
--include |
Only process files matching one of these glob patterns. |
--exclude |
Skip files matching one of these glob patterns. |
--dry-run |
Report what would change without writing to disk. |
--diff |
Print a unified diff instead of writing changes. |
--backup |
Save the original file as <file>.bak before overwriting. |
--jobs |
Number of worker threads (default: 4). |
--version |
Print the installed version. |
# Preview changes for an entire project
comment-stripper ./src --dry-run
# Strip comments from JS/TS files only, keeping backups
comment-stripper . --include "*.js" "*.ts" --backup
# Force LaTeX rules on a file with a non-standard extension
comment-stripper notes.txt --lang latex
# Show a diff instead of modifying files
comment-stripper ./src --diffLanguage is auto-detected from the file extension (or from well-known filenames like Makefile), and can always be overridden with --lang <name>.
--lang name |
Line comment(s) | Block comment(s) | Recognized extensions / filenames |
|---|---|---|---|
c_like |
// |
/* */ |
.c .h .cpp .cc .cxx .hpp .java .js .jsx .ts .tsx .mjs .cjs .cs .kt .kts .swift .m .mm .scala .dart .groovy |
go |
// |
/* */ |
.go |
rust |
// |
/* */ |
.rs |
python |
# |
— | .py .pyw |
shell |
# |
— | .sh .bash .zsh .ksh, Makefile, Dockerfile |
ruby |
# |
=begin / =end* |
.rb .rake, Gemfile, Rakefile, Vagrantfile |
sql |
-- |
/* */ |
.sql |
batch |
REM* / ::* |
— | .bat .cmd |
css |
— | /* */ |
.css .scss .less |
markup |
— | <!-- --> |
.html .htm .xml .svg |
php |
//, # |
/* */ |
.php .phtml |
lua |
-- |
--[[ ]] |
.lua |
powershell |
# |
<# #> |
.ps1 .psm1 .psd1 |
yaml |
# |
— | .yml .yaml |
ini |
#, ; |
— | .toml .ini .cfg |
perl |
# |
— | .pl .pm |
r |
# |
— | .r |
latex |
% |
— | .tex |
mixed |
//, #, % |
/* */ |
(not auto-detected; use --lang mixed) |
* Recognized only when it's the first non-whitespace text on the line (batch's REM/::), or when the token is the first thing on its own line (Ruby's =begin/=end), matching how those languages actually define comments.
Known limitation: the lexer does not handle nested block comments (e.g. Rust's /* /* */ */) — the first */ always closes the block.
pip install -e .[dev]
pytestCopyright 2026, Seyyed Ali Mohammadiyeh (MAX BASE).
GPL-3.0, see LICENSE.