Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Getting started

Install it

cargo install ocomment --locked

That is one of several channels — a prebuilt archive, Homebrew, Scoop, WinGet, a container image, a GitHub Action, and a pre-commit hook are all documented under Installation. Everything below works the same way whichever one you used.

Look before you leap

ocomment with no command is ocomment check, and check with no path is the current directory, so the shortest useful run is the tool’s own name:

$ ocomment check src
src/main.rs:2:5: removable line comment: // TODO: drop this
Found 1 removable comment in 1 file (1 file scanned). Run `ocomment fix` to remove it.

Nothing has changed on disk. check only reports, and it reports the same set of comments that fix would remove.

See the change as a patch

$ ocomment diff src
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,4 @@
 fn main() {
-    // TODO: drop this
+    
     println!("hello");
 }
Found 1 removable comment in 1 file (1 file scanned). Run `ocomment fix` to apply the patch.

The patch goes to standard output and the summary line goes to standard error, so ocomment diff src > fix.patch writes a file git apply will take. The blank line the removal leaves behind is the lines layout at work; compact and columns leave something else, and Policies and layouts shows all three side by side.

ocomment fix --dry-run src prints the same patch and applies nothing, which is the form to reach for inside a script.

Make the change

$ ocomment fix src
fixed src/main.rs: removed 1 comment
Removed 1 comment in 1 file (1 file scanned).

Every edit of a run is prepared first and committed as one transaction, so an interrupted fix leaves the tree as it found it rather than half-rewritten.

ocomment fix -i asks about each comment instead, with three lines of context either side: y removes it, n keeps it, a and d answer for the rest of the file, q stops asking and applies what was accepted, and x abandons the run without writing anything.

Exit codes

CodeMeaning
0Nothing removable was found, and every requested change was applied.
1Removable comments were reported, a diff was printed, --tidy left a removal for you, or a staged fix rewrote the index.
2An invalid source, configuration, plugin, or I/O failure.

That is why ocomment check works as a CI gate on its own, and why 1 from diff is not an error: it means the patch is not empty.

Decide what your project keeps

The default conservative policy removes ordinary comments and keeps the ones something else depends on: documentation, licence notices, tool and language directives, shebangs and encoding lines. Write the decision down instead of passing flags every time:

ocomment init config

init config writes a .ocomment.toml holding every default spelled out, so the file starts as a complete description of what the tool already does and you change the lines you disagree with. A project that has made a few decisions ends up looking like this:

version = 1

[policy]
mode = "conservative"
layout = "lines"
keep_kind = ["doc-line", "doc-block"]
keep_regex = ['^//\s*NOTE\b']

[[overrides]]
paths = ["generated/**"]
policy = "all"

That file keeps licence headers, keeps documentation comments, keeps any comment opening with NOTE, and takes everything out of generated/. Configuration documents every key, and ocomment config explain prints the resolved result with the source of each value.

Ask why a comment survived

ocomment check --explain

--explain puts the rule that decided each comment, and the setting behind that rule, on the line underneath it — for the comments it kept as much as the ones it would remove. Why was this comment kept? walks through a real answer.

Put it in the loop

ocomment init lefthook --tidy
lefthook install

The generated hook runs ocomment fix --tidy --staged, which judges the bytes the commit will actually carry rather than the working tree — the distinction that matters for a partially staged file. --tidy writes the half a machine can settle and leaves every removal reported and unapplied, so nothing is deleted on your behalf; the run exits 1 when it rewrote the index, which stops the commit long enough for you to look at what changed. Write ocomment init lefthook for a hook that only reports, or --fix for one that applies the removals too. CI and hooks covers the pre-commit manifest, the composite GitHub Action, and SARIF upload to code scanning; Editors and LSP covers seeing the same diagnostics as you type.