diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-16 07:33:46 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-16 07:33:46 -0500 |
| commit | 3fb4c80eb00d6e89b594eb4e5ce570f20fe2e63b (patch) | |
| tree | d69b199692e5af14fa0459eb94de997eaa3bf56d | |
| parent | 684891d57166953f4314b060afc78403a1d6976d (diff) | |
| download | rulesets-3fb4c80eb00d6e89b594eb4e5ce570f20fe2e63b.tar.gz rulesets-3fb4c80eb00d6e89b594eb4e5ce570f20fe2e63b.zip | |
feat(lint-org): recognize cj-comment blocks and suppress false-positive warnings
org-lint emits three warnings for every `#+begin_src cj: comment ... #+end_src` annotation block: suspicious-language-in-src-block (the language `cj:` isn't a known Babel slug), wrong-header-argument (the trailing `comment` looks like a header arg without a colon), and empty-header-argument (that same `comment` has no value). All three are false positives. The cj-comment block is a Craig-specific annotation marker, not Babel src-block syntax.
I added a helper `lo--cj-comment-block-opener-p` that pattern-matches the opener line, then a short-circuit branch at the top of `lo--handle-item` that silently drops any of the three checkers when they fire on a cj-comment opener. No fix is counted, no judgment is emitted, and the warnings disappear.
Two new tests cover the change. The normal case is a solo cj-comment block, which should produce zero judgments and zero fixes with all three flagged checkers absent from the issue list. The boundary case is a cj-comment block alongside a real `#+begin_src markdown` block. The markdown warning still surfaces, which scopes the suppression to cj openers only — no leak into other src blocks.
Test count goes from 22 to 24, all green. I smoke-tested against rulesets/todo.org: judgment count drops from 7 to 1. Six cj-comment false positives at lines 16 and 1291 are gone, and the unrelated misplaced-heading at 2139 still surfaces correctly.
| -rw-r--r-- | claude-templates/.ai/scripts/lint-org.el | 18 | ||||
| -rw-r--r-- | claude-templates/.ai/scripts/tests/test-lint-org.el | 56 |
2 files changed, 74 insertions, 0 deletions
diff --git a/claude-templates/.ai/scripts/lint-org.el b/claude-templates/.ai/scripts/lint-org.el index 3e643d4..64b78d0 100644 --- a/claude-templates/.ai/scripts/lint-org.el +++ b/claude-templates/.ai/scripts/lint-org.el @@ -221,11 +221,29 @@ org-lint reports the blank line after the heading-like text." ;; Fixer declined — emit as judgment so nothing is silently swallowed. (lo--emit-judgment name line msg)))) +(defun lo--cj-comment-block-opener-p (line) + "Non-nil when LINE in the current buffer is a `#+begin_src cj: ...' opener. +The cj-comment annotation convention puts `cj:' as the src-block language and +`comment' as the apparent header arg. org-lint reads that shape three ways +(unknown language, empty header-arg value, missing colon in header arg) and +flags each — all three are false positives, since cj-comment is a +Craig-specific annotation marker rather than Babel src-block syntax." + (save-excursion + (lo--goto-line line) + (looking-at-p "^[ \t]*#\\+begin_src[ \t]+cj:"))) + (defun lo--handle-item (item) (let ((name (lo--checker-name item)) (line (lo--line item)) (msg (lo--message item))) (cond + ;; Silent suppression of cj-comment false positives — see + ;; `lo--cj-comment-block-opener-p'. No fix counted, no judgment emitted. + ((and (memq name '(suspicious-language-in-src-block + empty-header-argument + wrong-header-argument)) + (lo--cj-comment-block-opener-p line)) + nil) ((eq name 'item-number) (lo--apply-or-preview name line msg #'lo-fix-item-number)) ((eq name 'missing-language-in-src-block) diff --git a/claude-templates/.ai/scripts/tests/test-lint-org.el b/claude-templates/.ai/scripts/tests/test-lint-org.el index 8e1ebc4..9328064 100644 --- a/claude-templates/.ai/scripts/tests/test-lint-org.el +++ b/claude-templates/.ai/scripts/tests/test-lint-org.el @@ -168,6 +168,31 @@ content #+end_src ") +;; cj-comment annotation block — Craig's convention #+begin_src cj: comment. +;; org-lint flags the language (cj:) as unknown and the comment header arg as +;; both missing-colon and empty-value. All three are false positives. +(defconst lo-test--cj-comment-block "\ +* Heading + +#+begin_src cj: comment +my annotation text +#+end_src +") + +;; cj-comment block alongside a real suspicious-language warning — verifies +;; the cj suppression doesn't leak into other src blocks in the same file. +(defconst lo-test--cj-comment-with-real-warning "\ +* Heading + +#+begin_src cj: comment +my annotation +#+end_src + +#+begin_src markdown +real suspicious-language warning here +#+end_src +") + ;; Mixed fixture — each category once. (defconst lo-test--mixed "\ * Mixed @@ -317,6 +342,37 @@ content (lo-test--checkers judgments))))) ;;; --------------------------------------------------------------------------- +;;; cj-comment block — Craig's annotation convention is silently suppressed + +(ert-deftest lo-cj-comment-block-emits-no-judgments () + "Normal: a `#+begin_src cj: comment ...' block must not trigger the three +false-positive warnings org-lint emits for it (unknown language, empty +header-arg value, missing colon in header arg)." + (let* ((out (lo-test--run lo-test--cj-comment-block)) + (res (plist-get out :result)) + (judgments (lo-test--judgments (plist-get out :issues))) + (checkers (lo-test--checkers judgments))) + ;; File untouched, no fixes applied. + (should (equal lo-test--cj-comment-block res)) + (should (= 0 (plist-get out :fixes))) + ;; None of the three false-positive checkers fired. + (should-not (member 'suspicious-language-in-src-block checkers)) + (should-not (member 'empty-header-argument checkers)) + (should-not (member 'wrong-header-argument checkers)))) + +(ert-deftest lo-cj-comment-suppression-does-not-mask-real-warnings () + "Boundary: the cj-comment suppression is scoped to cj-comment block openers +only — a regular `#+begin_src markdown' in the same file still emits its +suspicious-language judgment." + (let* ((out (lo-test--run lo-test--cj-comment-with-real-warning)) + (judgments (lo-test--judgments (plist-get out :issues))) + (suspicious (cl-count 'suspicious-language-in-src-block + (lo-test--checkers judgments)))) + ;; Exactly one suspicious-language judgment — from the markdown block, + ;; not the cj-comment block. + (should (= 1 suspicious)))) + +;;; --------------------------------------------------------------------------- ;;; --check mode (ert-deftest lo-check-mode-does-not-modify-file () |
