"body": "{\"fileCount\":12,\"files\":[{\"chunks\":[{\"content\":\"//! Counting, kept apart from reading so it can be tested.\\n\",\"highlights\":\"comment:0,59\",\"ranges\":[{\"byteEnd\":9,\"byteStart\":4,\"line\":1}],\"startLine\":1},{\"content\":\"#[derive(Debug, Default, PartialEq)]\\npub struct Counts {\\n pub lines: usize,\",\"highlights\":\"keyword:37,3,1,6,14,3;type:9,5,2,7,2,9,14,6,18,5;attr:0,9,5,2,7,2,9,2\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":7}],\"startLine\":6},{\"content\":\"\\n/// Counts `text` in one pass.\\npub fn count(text: &str) -> Counts {\\n let mut counts = Counts { bytes: text.len(), ..Counts::default() };\\n for line in parse::lines(text) {\\n counts.lines += 1;\\n counts.words += parse::words(line);\\n }\\n counts\\n}\",\"highlights\":\"comment:1,31;keyword:32,3,1,2,35,3,1,3,65,3,6,2;number:202,1;function:39,5,67,3,14,7,29,5,67,5;type:52,3,5,6,24,6,24,6\",\"ranges\":[{\"byteEnd\":9,\"byteStart\":4,\"line\":13},{\"byteEnd\":12,\"byteStart\":7,\"line\":14},{\"byteEnd\":33,\"byteStart\":28,\"line\":14},{\"byteEnd\":17,\"byteStart\":12,\"line\":15},{\"byteEnd\":26,\"byteStart\":21,\"line\":15},{\"byteEnd\":56,\"byteStart\":51,\"line\":15},{\"byteEnd\":13,\"byteStart\":8,\"line\":17},{\"byteEnd\":13,\"byteStart\":8,\"line\":18},{\"byteEnd\":9,\"byteStart\":4,\"line\":20}],\"startLine\":12},{\"content\":\" #[test]\\n fn counts() {\\n let c = count(\\\"one two\\\\nthree\\\\n\\\");\\n assert_eq!(c, Counts { lines: 2, words: 3, bytes: 14 });\\n }\",\"highlights\":\"string:52,18;keyword:16,2,20,3;number:111,1,9,1,9,2;function:19,6,21,5,30,10;type:95,6;attr:4,7\",\"ranges\":[{\"byteEnd\":12,\"byteStart\":7,\"line\":28},{\"byteEnd\":21,\"byteStart\":16,\"line\":29},{\"byteEnd\":27,\"byteStart\":22,\"line\":30}],\"startLine\":27},{\"content\":\" fn a_last_line_without_a_newline() {\\n assert_eq!(count(\\\"a\\\\nb\\\").lines, 2);\\n }\",\"highlights\":\"string:66,6;keyword:4,2;number:81,1;function:7,29,13,10\",\"ranges\":[{\"byteEnd\":24,\"byteStart\":19,\"line\":35}],\"startLine\":34}],\"commit\":\"4c4f3483836ee19f1f64f7976d1bc44ebc9db642\",\"language\":\"Rust\",\"path\":\"src/lib.rs\",\"repo\":{\"createdAt\":\"2026-10-09T16:47:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"forkOf\":\"at://did:plc:abe24xewga4qdbzjcxmuzdt3/dev.knotless.repo/tally\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"handle\":\"bob.test\"}}},{\"chunks\":[{\"content\":\"//! Counting, kept apart from reading so it can be tested.\\n\",\"highlights\":\"comment:0,59\",\"ranges\":[{\"byteEnd\":9,\"byteStart\":4,\"line\":1}],\"startLine\":1},{\"content\":\"#[derive(Debug, Default, PartialEq)]\\npub struct Counts {\\n pub lines: usize,\",\"highlights\":\"keyword:37,3,1,6,14,3;type:9,5,2,7,2,9,14,6,18,5;attr:0,9,5,2,7,2,9,2\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":7}],\"startLine\":6},{\"content\":\"\\n/// Counts `text` in one pass.\\npub fn count(text: &str) -> Counts {\\n let mut counts = Counts { bytes: text.len(), ..Counts::default() };\\n for line in parse::lines(text) {\\n counts.lines += 1;\\n counts.words += parse::words(line);\\n }\\n counts\\n}\",\"highlights\":\"comment:1,31;keyword:32,3,1,2,35,3,1,3,65,3,6,2;number:202,1;function:39,5,67,3,14,7,29,5,67,5;type:52,3,5,6,24,6,24,6\",\"ranges\":[{\"byteEnd\":9,\"byteStart\":4,\"line\":13},{\"byteEnd\":12,\"byteStart\":7,\"line\":14},{\"byteEnd\":33,\"byteStart\":28,\"line\":14},{\"byteEnd\":17,\"byteStart\":12,\"line\":15},{\"byteEnd\":26,\"byteStart\":21,\"line\":15},{\"byteEnd\":56,\"byteStart\":51,\"line\":15},{\"byteEnd\":13,\"byteStart\":8,\"line\":17},{\"byteEnd\":13,\"byteStart\":8,\"line\":18},{\"byteEnd\":9,\"byteStart\":4,\"line\":20}],\"startLine\":12},{\"content\":\" #[test]\\n fn counts() {\\n let c = count(\\\"one two\\\\nthree\\\\n\\\");\\n assert_eq!(c, Counts { lines: 2, words: 3, bytes: 14 });\\n }\",\"highlights\":\"string:52,18;keyword:16,2,20,3;number:111,1,9,1,9,2;function:19,6,21,5,30,10;type:95,6;attr:4,7\",\"ranges\":[{\"byteEnd\":12,\"byteStart\":7,\"line\":28},{\"byteEnd\":21,\"byteStart\":16,\"line\":29},{\"byteEnd\":27,\"byteStart\":22,\"line\":30}],\"startLine\":27},{\"content\":\" fn a_last_line_without_a_newline() {\\n assert_eq!(count(\\\"a\\\\nb\\\").lines, 2);\\n }\",\"highlights\":\"string:66,6;keyword:4,2;number:81,1;function:7,29,13,10\",\"ranges\":[{\"byteEnd\":24,\"byteStart\":19,\"line\":35}],\"startLine\":34}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Rust\",\"path\":\"src/lib.rs\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"\\ntally reads the whole input before counting. Inputs are small, and one\\npass over a string is simpler than a streaming reader.\",\"highlights\":\"\",\"ranges\":[{\"byteEnd\":40,\"byteStart\":35,\"line\":3}],\"startLine\":2},{\"content\":\" input[File or stdin] --> read[Read it whole]\\n read --> count{Count}\\n count --> lines\\n count --> words\\n count --> bytes\\n lines & words & bytes --> row[One row, lined up]\",\"highlights\":\"attr:8,13,11,13,112,17\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":9},{\"byteEnd\":22,\"byteStart\":17,\"line\":9},{\"byteEnd\":7,\"byteStart\":2,\"line\":10},{\"byteEnd\":7,\"byteStart\":2,\"line\":11},{\"byteEnd\":7,\"byteStart\":2,\"line\":12}],\"startLine\":8}],\"commit\":\"4c4f3483836ee19f1f64f7976d1bc44ebc9db642\",\"language\":\"Markdown\",\"path\":\"docs/DESIGN.md\",\"repo\":{\"createdAt\":\"2026-10-09T16:47:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"forkOf\":\"at://did:plc:abe24xewga4qdbzjcxmuzdt3/dev.knotless.repo/tally\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"handle\":\"bob.test\"}}},{\"chunks\":[{\"content\":\"use std::io::Read;\\nuse tally::count;\\n\",\"highlights\":\"keyword:0,3,16,3;type:13,4\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":2}],\"startLine\":1},{\"content\":\" };\\n let c = count(&text);\\n let name = path.as_deref().unwrap_or(\\\"-\\\");\",\"highlights\":\"string:74,3;keyword:11,3,23,3;function:19,5,29,8,3,9\",\"ranges\":[{\"byteEnd\":17,\"byteStart\":12,\"line\":14}],\"startLine\":13}],\"commit\":\"4c4f3483836ee19f1f64f7976d1bc44ebc9db642\",\"language\":\"Rust\",\"path\":\"src/main.rs\",\"repo\":{\"createdAt\":\"2026-10-09T16:47:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"forkOf\":\"at://did:plc:abe24xewga4qdbzjcxmuzdt3/dev.knotless.repo/tally\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"handle\":\"bob.test\"}}},{\"chunks\":[{\"content\":\"use std::io::Read;\\nuse tally::count;\\n\",\"highlights\":\"keyword:0,3,16,3;type:13,4\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":2}],\"startLine\":1},{\"content\":\" };\\n let c = count(&text);\\n let name = path.as_deref().unwrap_or(\\\"-\\\");\",\"highlights\":\"string:74,3;keyword:11,3,23,3;function:19,5,29,8,3,9\",\"ranges\":[{\"byteEnd\":17,\"byteStart\":12,\"line\":14}],\"startLine\":13}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Rust\",\"path\":\"src/main.rs\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"//! Splitting text into the things tally counts.\\n\",\"highlights\":\"comment:0,49\",\"ranges\":[{\"byteEnd\":46,\"byteStart\":41,\"line\":1}],\"startLine\":1},{\"content\":\"pub fn words(line: &str) -> usize {\\n line.split_whitespace().count()\\n}\",\"highlights\":\"keyword:0,3,1,2;function:7,5,33,16,3,5;type:20,3,5,5\",\"ranges\":[{\"byteEnd\":33,\"byteStart\":28,\"line\":5}],\"startLine\":4},{\"content\":\"\\n/// The lines of `text`. A last line without a newline still counts.\\npub fn lines(text: &str) -> impl Iterator<Item = &str> {\",\"highlights\":\"comment:1,69;keyword:70,3,1,2,22,4;type:90,3,10,8,1,4,4,3\",\"ranges\":[{\"byteEnd\":66,\"byteStart\":61,\"line\":8}],\"startLine\":7}],\"commit\":\"4c4f3483836ee19f1f64f7976d1bc44ebc9db642\",\"language\":\"Rust\",\"path\":\"src/parse.rs\",\"repo\":{\"createdAt\":\"2026-10-09T16:47:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"forkOf\":\"at://did:plc:abe24xewga4qdbzjcxmuzdt3/dev.knotless.repo/tally\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"handle\":\"bob.test\"}}},{\"chunks\":[{\"content\":\"//! Splitting text into the things tally counts.\\n\",\"highlights\":\"comment:0,49\",\"ranges\":[{\"byteEnd\":46,\"byteStart\":41,\"line\":1}],\"startLine\":1},{\"content\":\"pub fn words(line: &str) -> usize {\\n line.split_whitespace().count()\\n}\",\"highlights\":\"keyword:0,3,1,2;function:7,5,33,16,3,5;type:20,3,5,5\",\"ranges\":[{\"byteEnd\":33,\"byteStart\":28,\"line\":5}],\"startLine\":4},{\"content\":\"\\n/// The lines of `text`. A last line without a newline still counts, and\\n/// empty input has none.\",\"highlights\":\"comment:1,98\",\"ranges\":[{\"byteEnd\":66,\"byteStart\":61,\"line\":8}],\"startLine\":7},{\"content\":\" fn empty_input_has_no_lines() {\\n assert_eq!(super::lines(\\\"\\\").count(), 0);\\n }\",\"highlights\":\"string:68,2;keyword:4,2,49,5;number:81,1;function:7,24,13,10\",\"ranges\":[{\"byteEnd\":41,\"byteStart\":36,\"line\":18}],\"startLine\":17}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Rust\",\"path\":\"src/parse.rs\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"\\ntally reads the whole input before counting. Inputs are small, and one\\npass over a string is simpler than a streaming reader.\",\"highlights\":\"\",\"ranges\":[{\"byteEnd\":40,\"byteStart\":35,\"line\":3}],\"startLine\":2},{\"content\":\" input[File or stdin] --> read[Read it whole]\\n read --> count{Count}\\n count --> lines\\n count --> words\\n count --> bytes\\n lines & words & bytes --> row[One row, lined up]\",\"highlights\":\"attr:8,13,11,13,112,17\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":9},{\"byteEnd\":22,\"byteStart\":17,\"line\":9},{\"byteEnd\":7,\"byteStart\":2,\"line\":10},{\"byteEnd\":7,\"byteStart\":2,\"line\":11},{\"byteEnd\":7,\"byteStart\":2,\"line\":12}],\"startLine\":8}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Markdown\",\"path\":\"docs/DESIGN.md\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"\\nCounts lines, words and bytes, like `wc`, with output that lines up.\\n\",\"highlights\":\"string:37,4\",\"ranges\":[{\"byteEnd\":5,\"byteStart\":0,\"line\":3}],\"startLine\":2}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Markdown\",\"path\":\"README.md\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"\\nCounts lines, words and bytes, like `wc`, with output that lines up.\\n\",\"highlights\":\"string:37,4\",\"ranges\":[{\"byteEnd\":5,\"byteStart\":0,\"line\":3}],\"startLine\":2}],\"commit\":\"4c4f3483836ee19f1f64f7976d1bc44ebc9db642\",\"language\":\"Markdown\",\"path\":\"README.md\",\"repo\":{\"createdAt\":\"2026-10-09T16:47:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"forkOf\":\"at://did:plc:abe24xewga4qdbzjcxmuzdt3/dev.knotless.repo/tally\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"handle\":\"bob.test\"}}},{\"chunks\":[{\"content\":\"edition = \\\"2024\\\"\\ndescription = \\\"Counts lines, words and bytes\\\"\\nlicense = \\\"MIT\\\"\",\"highlights\":\"string:10,6,15,31,11,5;type:0,7,10,11,35,7\",\"ranges\":[{\"byteEnd\":20,\"byteStart\":15,\"line\":5}],\"startLine\":4}],\"commit\":\"4c4f3483836ee19f1f64f7976d1bc44ebc9db642\",\"language\":\"TOML\",\"path\":\"Cargo.toml\",\"repo\":{\"createdAt\":\"2026-10-09T16:47:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"forkOf\":\"at://did:plc:abe24xewga4qdbzjcxmuzdt3/dev.knotless.repo/tally\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"handle\":\"bob.test\"}}},{\"chunks\":[{\"content\":\"edition = \\\"2024\\\"\\ndescription = \\\"Counts lines, words and bytes\\\"\\nlicense = \\\"MIT\\\"\",\"highlights\":\"string:10,6,15,31,11,5;type:0,7,10,11,35,7\",\"ranges\":[{\"byteEnd\":20,\"byteStart\":15,\"line\":5}],\"startLine\":4}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"TOML\",\"path\":\"Cargo.toml\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}}],\"matchCount\":57}"
"body": "{\"fileCount\":12,\"files\":[{\"chunks\":[{\"content\":\"//! Counting, kept apart from reading so it can be tested.\\n\",\"highlights\":\"comment:0,59\",\"ranges\":[{\"byteEnd\":9,\"byteStart\":4,\"line\":1}],\"startLine\":1},{\"content\":\"#[derive(Debug, Default, PartialEq)]\\npub struct Counts {\\n pub lines: usize,\",\"highlights\":\"keyword:37,3,1,6,14,3;type:9,5,2,7,2,9,14,6,18,5;attr:0,9,5,2,7,2,9,2\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":7}],\"startLine\":6},{\"content\":\"\\n/// Counts `text` in one pass.\\npub fn count(text: &str) -> Counts {\\n let mut counts = Counts { bytes: text.len(), ..Counts::default() };\\n for line in parse::lines(text) {\\n counts.lines += 1;\\n counts.words += parse::words(line);\\n }\\n counts\\n}\",\"highlights\":\"comment:1,31;keyword:32,3,1,2,35,3,1,3,65,3,6,2;number:202,1;function:39,5,67,3,14,7,29,5,67,5;type:52,3,5,6,24,6,24,6\",\"ranges\":[{\"byteEnd\":9,\"byteStart\":4,\"line\":13},{\"byteEnd\":12,\"byteStart\":7,\"line\":14},{\"byteEnd\":33,\"byteStart\":28,\"line\":14},{\"byteEnd\":17,\"byteStart\":12,\"line\":15},{\"byteEnd\":26,\"byteStart\":21,\"line\":15},{\"byteEnd\":56,\"byteStart\":51,\"line\":15},{\"byteEnd\":13,\"byteStart\":8,\"line\":17},{\"byteEnd\":13,\"byteStart\":8,\"line\":18},{\"byteEnd\":9,\"byteStart\":4,\"line\":20}],\"startLine\":12},{\"content\":\" #[test]\\n fn counts() {\\n let c = count(\\\"one two\\\\nthree\\\\n\\\");\\n assert_eq!(c, Counts { lines: 2, words: 3, bytes: 14 });\\n }\",\"highlights\":\"string:52,18;keyword:16,2,20,3;number:111,1,9,1,9,2;function:19,6,21,5,30,10;type:95,6;attr:4,7\",\"ranges\":[{\"byteEnd\":12,\"byteStart\":7,\"line\":28},{\"byteEnd\":21,\"byteStart\":16,\"line\":29},{\"byteEnd\":27,\"byteStart\":22,\"line\":30}],\"startLine\":27},{\"content\":\" fn a_last_line_without_a_newline() {\\n assert_eq!(count(\\\"a\\\\nb\\\").lines, 2);\\n }\",\"highlights\":\"string:66,6;keyword:4,2;number:81,1;function:7,29,13,10\",\"ranges\":[{\"byteEnd\":24,\"byteStart\":19,\"line\":35}],\"startLine\":34}],\"commit\":\"4c4f3483836ee19f1f64f7976d1bc44ebc9db642\",\"language\":\"Rust\",\"path\":\"src/lib.rs\",\"repo\":{\"createdAt\":\"2026-10-09T16:47:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"forkOf\":\"at://did:plc:abe24xewga4qdbzjcxmuzdt3/dev.knotless.repo/tally\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"handle\":\"bob.test\"}}},{\"chunks\":[{\"content\":\"//! Counting, kept apart from reading so it can be tested.\\n\",\"highlights\":\"comment:0,59\",\"ranges\":[{\"byteEnd\":9,\"byteStart\":4,\"line\":1}],\"startLine\":1},{\"content\":\"#[derive(Debug, Default, PartialEq)]\\npub struct Counts {\\n pub lines: usize,\",\"highlights\":\"keyword:37,3,1,6,14,3;type:9,5,2,7,2,9,14,6,18,5;attr:0,9,5,2,7,2,9,2\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":7}],\"startLine\":6},{\"content\":\"\\n/// Counts `text` in one pass.\\npub fn count(text: &str) -> Counts {\\n let mut counts = Counts { bytes: text.len(), ..Counts::default() };\\n for line in parse::lines(text) {\\n counts.lines += 1;\\n counts.words += parse::words(line);\\n }\\n counts\\n}\",\"highlights\":\"comment:1,31;keyword:32,3,1,2,35,3,1,3,65,3,6,2;number:202,1;function:39,5,67,3,14,7,29,5,67,5;type:52,3,5,6,24,6,24,6\",\"ranges\":[{\"byteEnd\":9,\"byteStart\":4,\"line\":13},{\"byteEnd\":12,\"byteStart\":7,\"line\":14},{\"byteEnd\":33,\"byteStart\":28,\"line\":14},{\"byteEnd\":17,\"byteStart\":12,\"line\":15},{\"byteEnd\":26,\"byteStart\":21,\"line\":15},{\"byteEnd\":56,\"byteStart\":51,\"line\":15},{\"byteEnd\":13,\"byteStart\":8,\"line\":17},{\"byteEnd\":13,\"byteStart\":8,\"line\":18},{\"byteEnd\":9,\"byteStart\":4,\"line\":20}],\"startLine\":12},{\"content\":\" #[test]\\n fn counts() {\\n let c = count(\\\"one two\\\\nthree\\\\n\\\");\\n assert_eq!(c, Counts { lines: 2, words: 3, bytes: 14 });\\n }\",\"highlights\":\"string:52,18;keyword:16,2,20,3;number:111,1,9,1,9,2;function:19,6,21,5,30,10;type:95,6;attr:4,7\",\"ranges\":[{\"byteEnd\":12,\"byteStart\":7,\"line\":28},{\"byteEnd\":21,\"byteStart\":16,\"line\":29},{\"byteEnd\":27,\"byteStart\":22,\"line\":30}],\"startLine\":27},{\"content\":\" fn a_last_line_without_a_newline() {\\n assert_eq!(count(\\\"a\\\\nb\\\").lines, 2);\\n }\",\"highlights\":\"string:66,6;keyword:4,2;number:81,1;function:7,29,13,10\",\"ranges\":[{\"byteEnd\":24,\"byteStart\":19,\"line\":35}],\"startLine\":34}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Rust\",\"path\":\"src/lib.rs\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"\\ntally reads the whole input before counting. Inputs are small, and one\\npass over a string is simpler than a streaming reader.\",\"highlights\":\"\",\"ranges\":[{\"byteEnd\":40,\"byteStart\":35,\"line\":3}],\"startLine\":2},{\"content\":\" input[File or stdin] --> read[Read it whole]\\n read --> count{Count}\\n count --> lines\\n count --> words\\n count --> bytes\\n lines & words & bytes --> row[One row, lined up]\",\"highlights\":\"attr:8,13,11,13,112,17\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":9},{\"byteEnd\":22,\"byteStart\":17,\"line\":9},{\"byteEnd\":7,\"byteStart\":2,\"line\":10},{\"byteEnd\":7,\"byteStart\":2,\"line\":11},{\"byteEnd\":7,\"byteStart\":2,\"line\":12}],\"startLine\":8}],\"commit\":\"4c4f3483836ee19f1f64f7976d1bc44ebc9db642\",\"language\":\"Markdown\",\"path\":\"docs/DESIGN.md\",\"repo\":{\"createdAt\":\"2026-10-09T16:47:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"forkOf\":\"at://did:plc:abe24xewga4qdbzjcxmuzdt3/dev.knotless.repo/tally\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"handle\":\"bob.test\"}}},{\"chunks\":[{\"content\":\"use std::io::Read;\\nuse tally::count;\\n\",\"highlights\":\"keyword:0,3,16,3;type:13,4\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":2}],\"startLine\":1},{\"content\":\" };\\n let c = count(&text);\\n let name = path.as_deref().unwrap_or(\\\"-\\\");\",\"highlights\":\"string:74,3;keyword:11,3,23,3;function:19,5,29,8,3,9\",\"ranges\":[{\"byteEnd\":17,\"byteStart\":12,\"line\":14}],\"startLine\":13}],\"commit\":\"4c4f3483836ee19f1f64f7976d1bc44ebc9db642\",\"language\":\"Rust\",\"path\":\"src/main.rs\",\"repo\":{\"createdAt\":\"2026-10-09T16:47:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"forkOf\":\"at://did:plc:abe24xewga4qdbzjcxmuzdt3/dev.knotless.repo/tally\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"handle\":\"bob.test\"}}},{\"chunks\":[{\"content\":\"use std::io::Read;\\nuse tally::count;\\n\",\"highlights\":\"keyword:0,3,16,3;type:13,4\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":2}],\"startLine\":1},{\"content\":\" };\\n let c = count(&text);\\n let name = path.as_deref().unwrap_or(\\\"-\\\");\",\"highlights\":\"string:74,3;keyword:11,3,23,3;function:19,5,29,8,3,9\",\"ranges\":[{\"byteEnd\":17,\"byteStart\":12,\"line\":14}],\"startLine\":13}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Rust\",\"path\":\"src/main.rs\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"//! Splitting text into the things tally counts.\\n\",\"highlights\":\"comment:0,49\",\"ranges\":[{\"byteEnd\":46,\"byteStart\":41,\"line\":1}],\"startLine\":1},{\"content\":\"pub fn words(line: &str) -> usize {\\n line.split_whitespace().count()\\n}\",\"highlights\":\"keyword:0,3,1,2;function:7,5,33,16,3,5;type:20,3,5,5\",\"ranges\":[{\"byteEnd\":33,\"byteStart\":28,\"line\":5}],\"startLine\":4},{\"content\":\"\\n/// The lines of `text`. A last line without a newline still counts.\\npub fn lines(text: &str) -> impl Iterator<Item = &str> {\",\"highlights\":\"comment:1,69;keyword:70,3,1,2,22,4;type:90,3,10,8,1,4,4,3\",\"ranges\":[{\"byteEnd\":66,\"byteStart\":61,\"line\":8}],\"startLine\":7}],\"commit\":\"4c4f3483836ee19f1f64f7976d1bc44ebc9db642\",\"language\":\"Rust\",\"path\":\"src/parse.rs\",\"repo\":{\"createdAt\":\"2026-10-09T16:47:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"forkOf\":\"at://did:plc:abe24xewga4qdbzjcxmuzdt3/dev.knotless.repo/tally\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"handle\":\"bob.test\"}}},{\"chunks\":[{\"content\":\"//! Splitting text into the things tally counts.\\n\",\"highlights\":\"comment:0,49\",\"ranges\":[{\"byteEnd\":46,\"byteStart\":41,\"line\":1}],\"startLine\":1},{\"content\":\"pub fn words(line: &str) -> usize {\\n line.split_whitespace().count()\\n}\",\"highlights\":\"keyword:0,3,1,2;function:7,5,33,16,3,5;type:20,3,5,5\",\"ranges\":[{\"byteEnd\":33,\"byteStart\":28,\"line\":5}],\"startLine\":4},{\"content\":\"\\n/// The lines of `text`. A last line without a newline still counts, and\\n/// empty input has none.\",\"highlights\":\"comment:1,98\",\"ranges\":[{\"byteEnd\":66,\"byteStart\":61,\"line\":8}],\"startLine\":7},{\"content\":\" fn empty_input_has_no_lines() {\\n assert_eq!(super::lines(\\\"\\\").count(), 0);\\n }\",\"highlights\":\"string:68,2;keyword:4,2,49,5;number:81,1;function:7,24,13,10\",\"ranges\":[{\"byteEnd\":41,\"byteStart\":36,\"line\":18}],\"startLine\":17}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Rust\",\"path\":\"src/parse.rs\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"\\ntally reads the whole input before counting. Inputs are small, and one\\npass over a string is simpler than a streaming reader.\",\"highlights\":\"\",\"ranges\":[{\"byteEnd\":40,\"byteStart\":35,\"line\":3}],\"startLine\":2},{\"content\":\" input[File or stdin] --> read[Read it whole]\\n read --> count{Count}\\n count --> lines\\n count --> words\\n count --> bytes\\n lines & words & bytes --> row[One row, lined up]\",\"highlights\":\"attr:8,13,11,13,112,17\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":9},{\"byteEnd\":22,\"byteStart\":17,\"line\":9},{\"byteEnd\":7,\"byteStart\":2,\"line\":10},{\"byteEnd\":7,\"byteStart\":2,\"line\":11},{\"byteEnd\":7,\"byteStart\":2,\"line\":12}],\"startLine\":8}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Markdown\",\"path\":\"docs/DESIGN.md\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"\\nCounts lines, words and bytes, like `wc`, with output that lines up.\\n\",\"highlights\":\"string:37,4\",\"ranges\":[{\"byteEnd\":5,\"byteStart\":0,\"line\":3}],\"startLine\":2}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Markdown\",\"path\":\"README.md\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"\\nCounts lines, words and bytes, like `wc`, with output that lines up.\\n\",\"highlights\":\"string:37,4\",\"ranges\":[{\"byteEnd\":5,\"byteStart\":0,\"line\":3}],\"startLine\":2}],\"commit\":\"4c4f3483836ee19f1f64f7976d1bc44ebc9db642\",\"language\":\"Markdown\",\"path\":\"README.md\",\"repo\":{\"createdAt\":\"2026-10-09T16:47:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"forkOf\":\"at://did:plc:abe24xewga4qdbzjcxmuzdt3/dev.knotless.repo/tally\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"handle\":\"bob.test\"}}},{\"chunks\":[{\"content\":\"edition = \\\"2024\\\"\\ndescription = \\\"Counts lines, words and bytes\\\"\\nlicense = \\\"MIT\\\"\",\"highlights\":\"string:10,6,15,31,11,5;type:0,7,10,11,35,7\",\"ranges\":[{\"byteEnd\":20,\"byteStart\":15,\"line\":5}],\"startLine\":4}],\"commit\":\"4c4f3483836ee19f1f64f7976d1bc44ebc9db642\",\"language\":\"TOML\",\"path\":\"Cargo.toml\",\"repo\":{\"createdAt\":\"2026-10-09T16:47:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"forkOf\":\"at://did:plc:abe24xewga4qdbzjcxmuzdt3/dev.knotless.repo/tally\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:55j6e4wxzlzndxm4nov2lz7x\",\"handle\":\"bob.test\"}}},{\"chunks\":[{\"content\":\"edition = \\\"2024\\\"\\ndescription = \\\"Counts lines, words and bytes\\\"\\nlicense = \\\"MIT\\\"\",\"highlights\":\"string:10,6,15,31,11,5;type:0,7,10,11,35,7\",\"ranges\":[{\"byteEnd\":20,\"byteStart\":15,\"line\":5}],\"startLine\":4}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"TOML\",\"path\":\"Cargo.toml\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}}],\"languages\":[{\"name\":\"Rust\",\"color\":\"#dea584\",\"files\":6},{\"name\":\"Markdown\",\"color\":\"#083fa1\",\"files\":4},{\"name\":\"TOML\",\"color\":\"#9c4221\",\"files\":2}],\"matchCount\":57}"
"body": "{\"fileCount\":6,\"files\":[{\"chunks\":[{\"content\":\"//! Counting, kept apart from reading so it can be tested.\\n\",\"highlights\":\"comment:0,59\",\"ranges\":[{\"byteEnd\":9,\"byteStart\":4,\"line\":1}],\"startLine\":1},{\"content\":\"#[derive(Debug, Default, PartialEq)]\\npub struct Counts {\\n pub lines: usize,\",\"highlights\":\"keyword:37,3,1,6,14,3;type:9,5,2,7,2,9,14,6,18,5;attr:0,9,5,2,7,2,9,2\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":7}],\"startLine\":6},{\"content\":\"\\n/// Counts `text` in one pass.\\npub fn count(text: &str) -> Counts {\\n let mut counts = Counts { bytes: text.len(), ..Counts::default() };\\n for line in parse::lines(text) {\\n counts.lines += 1;\\n counts.words += parse::words(line);\\n }\\n counts\\n}\",\"highlights\":\"comment:1,31;keyword:32,3,1,2,35,3,1,3,65,3,6,2;number:202,1;function:39,5,67,3,14,7,29,5,67,5;type:52,3,5,6,24,6,24,6\",\"ranges\":[{\"byteEnd\":9,\"byteStart\":4,\"line\":13},{\"byteEnd\":12,\"byteStart\":7,\"line\":14},{\"byteEnd\":33,\"byteStart\":28,\"line\":14},{\"byteEnd\":17,\"byteStart\":12,\"line\":15},{\"byteEnd\":26,\"byteStart\":21,\"line\":15},{\"byteEnd\":56,\"byteStart\":51,\"line\":15},{\"byteEnd\":13,\"byteStart\":8,\"line\":17},{\"byteEnd\":13,\"byteStart\":8,\"line\":18},{\"byteEnd\":9,\"byteStart\":4,\"line\":20}],\"startLine\":12},{\"content\":\" #[test]\\n fn counts() {\\n let c = count(\\\"one two\\\\nthree\\\\n\\\");\\n assert_eq!(c, Counts { lines: 2, words: 3, bytes: 14 });\\n }\",\"highlights\":\"string:52,18;keyword:16,2,20,3;number:111,1,9,1,9,2;function:19,6,21,5,30,10;type:95,6;attr:4,7\",\"ranges\":[{\"byteEnd\":12,\"byteStart\":7,\"line\":28},{\"byteEnd\":21,\"byteStart\":16,\"line\":29},{\"byteEnd\":27,\"byteStart\":22,\"line\":30}],\"startLine\":27},{\"content\":\" fn a_last_line_without_a_newline() {\\n assert_eq!(count(\\\"a\\\\nb\\\").lines, 2);\\n }\",\"highlights\":\"string:66,6;keyword:4,2;number:81,1;function:7,29,13,10\",\"ranges\":[{\"byteEnd\":24,\"byteStart\":19,\"line\":35}],\"startLine\":34}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Rust\",\"path\":\"src/lib.rs\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"use std::io::Read;\\nuse tally::count;\\n\",\"highlights\":\"keyword:0,3,16,3;type:13,4\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":2}],\"startLine\":1},{\"content\":\" };\\n let c = count(&text);\\n let name = path.as_deref().unwrap_or(\\\"-\\\");\",\"highlights\":\"string:74,3;keyword:11,3,23,3;function:19,5,29,8,3,9\",\"ranges\":[{\"byteEnd\":17,\"byteStart\":12,\"line\":14}],\"startLine\":13}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Rust\",\"path\":\"src/main.rs\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"\\ntally reads the whole input before counting. Inputs are small, and one\\npass over a string is simpler than a streaming reader.\",\"highlights\":\"\",\"ranges\":[{\"byteEnd\":40,\"byteStart\":35,\"line\":3}],\"startLine\":2},{\"content\":\" input[File or stdin] --> read[Read it whole]\\n read --> count{Count}\\n count --> lines\\n count --> words\\n count --> bytes\\n lines & words & bytes --> row[One row, lined up]\",\"highlights\":\"attr:8,13,11,13,112,17\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":9},{\"byteEnd\":22,\"byteStart\":17,\"line\":9},{\"byteEnd\":7,\"byteStart\":2,\"line\":10},{\"byteEnd\":7,\"byteStart\":2,\"line\":11},{\"byteEnd\":7,\"byteStart\":2,\"line\":12}],\"startLine\":8}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Markdown\",\"path\":\"docs/DESIGN.md\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"//! Splitting text into the things tally counts.\\n\",\"highlights\":\"comment:0,49\",\"ranges\":[{\"byteEnd\":46,\"byteStart\":41,\"line\":1}],\"startLine\":1},{\"content\":\"pub fn words(line: &str) -> usize {\\n line.split_whitespace().count()\\n}\",\"highlights\":\"keyword:0,3,1,2;function:7,5,33,16,3,5;type:20,3,5,5\",\"ranges\":[{\"byteEnd\":33,\"byteStart\":28,\"line\":5}],\"startLine\":4},{\"content\":\"\\n/// The lines of `text`. A last line without a newline still counts, and\\n/// empty input has none.\",\"highlights\":\"comment:1,98\",\"ranges\":[{\"byteEnd\":66,\"byteStart\":61,\"line\":8}],\"startLine\":7},{\"content\":\" fn empty_input_has_no_lines() {\\n assert_eq!(super::lines(\\\"\\\").count(), 0);\\n }\",\"highlights\":\"string:68,2;keyword:4,2,49,5;number:81,1;function:7,24,13,10\",\"ranges\":[{\"byteEnd\":41,\"byteStart\":36,\"line\":18}],\"startLine\":17}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Rust\",\"path\":\"src/parse.rs\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"\\nCounts lines, words and bytes, like `wc`, with output that lines up.\\n\",\"highlights\":\"string:37,4\",\"ranges\":[{\"byteEnd\":5,\"byteStart\":0,\"line\":3}],\"startLine\":2}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Markdown\",\"path\":\"README.md\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"edition = \\\"2024\\\"\\ndescription = \\\"Counts lines, words and bytes\\\"\\nlicense = \\\"MIT\\\"\",\"highlights\":\"string:10,6,15,31,11,5;type:0,7,10,11,35,7\",\"ranges\":[{\"byteEnd\":20,\"byteStart\":15,\"line\":5}],\"startLine\":4}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"TOML\",\"path\":\"Cargo.toml\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}}],\"matchCount\":29}"
"body": "{\"fileCount\":6,\"files\":[{\"chunks\":[{\"content\":\"//! Counting, kept apart from reading so it can be tested.\\n\",\"highlights\":\"comment:0,59\",\"ranges\":[{\"byteEnd\":9,\"byteStart\":4,\"line\":1}],\"startLine\":1},{\"content\":\"#[derive(Debug, Default, PartialEq)]\\npub struct Counts {\\n pub lines: usize,\",\"highlights\":\"keyword:37,3,1,6,14,3;type:9,5,2,7,2,9,14,6,18,5;attr:0,9,5,2,7,2,9,2\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":7}],\"startLine\":6},{\"content\":\"\\n/// Counts `text` in one pass.\\npub fn count(text: &str) -> Counts {\\n let mut counts = Counts { bytes: text.len(), ..Counts::default() };\\n for line in parse::lines(text) {\\n counts.lines += 1;\\n counts.words += parse::words(line);\\n }\\n counts\\n}\",\"highlights\":\"comment:1,31;keyword:32,3,1,2,35,3,1,3,65,3,6,2;number:202,1;function:39,5,67,3,14,7,29,5,67,5;type:52,3,5,6,24,6,24,6\",\"ranges\":[{\"byteEnd\":9,\"byteStart\":4,\"line\":13},{\"byteEnd\":12,\"byteStart\":7,\"line\":14},{\"byteEnd\":33,\"byteStart\":28,\"line\":14},{\"byteEnd\":17,\"byteStart\":12,\"line\":15},{\"byteEnd\":26,\"byteStart\":21,\"line\":15},{\"byteEnd\":56,\"byteStart\":51,\"line\":15},{\"byteEnd\":13,\"byteStart\":8,\"line\":17},{\"byteEnd\":13,\"byteStart\":8,\"line\":18},{\"byteEnd\":9,\"byteStart\":4,\"line\":20}],\"startLine\":12},{\"content\":\" #[test]\\n fn counts() {\\n let c = count(\\\"one two\\\\nthree\\\\n\\\");\\n assert_eq!(c, Counts { lines: 2, words: 3, bytes: 14 });\\n }\",\"highlights\":\"string:52,18;keyword:16,2,20,3;number:111,1,9,1,9,2;function:19,6,21,5,30,10;type:95,6;attr:4,7\",\"ranges\":[{\"byteEnd\":12,\"byteStart\":7,\"line\":28},{\"byteEnd\":21,\"byteStart\":16,\"line\":29},{\"byteEnd\":27,\"byteStart\":22,\"line\":30}],\"startLine\":27},{\"content\":\" fn a_last_line_without_a_newline() {\\n assert_eq!(count(\\\"a\\\\nb\\\").lines, 2);\\n }\",\"highlights\":\"string:66,6;keyword:4,2;number:81,1;function:7,29,13,10\",\"ranges\":[{\"byteEnd\":24,\"byteStart\":19,\"line\":35}],\"startLine\":34}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Rust\",\"path\":\"src/lib.rs\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"use std::io::Read;\\nuse tally::count;\\n\",\"highlights\":\"keyword:0,3,16,3;type:13,4\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":2}],\"startLine\":1},{\"content\":\" };\\n let c = count(&text);\\n let name = path.as_deref().unwrap_or(\\\"-\\\");\",\"highlights\":\"string:74,3;keyword:11,3,23,3;function:19,5,29,8,3,9\",\"ranges\":[{\"byteEnd\":17,\"byteStart\":12,\"line\":14}],\"startLine\":13}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Rust\",\"path\":\"src/main.rs\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"\\ntally reads the whole input before counting. Inputs are small, and one\\npass over a string is simpler than a streaming reader.\",\"highlights\":\"\",\"ranges\":[{\"byteEnd\":40,\"byteStart\":35,\"line\":3}],\"startLine\":2},{\"content\":\" input[File or stdin] --> read[Read it whole]\\n read --> count{Count}\\n count --> lines\\n count --> words\\n count --> bytes\\n lines & words & bytes --> row[One row, lined up]\",\"highlights\":\"attr:8,13,11,13,112,17\",\"ranges\":[{\"byteEnd\":16,\"byteStart\":11,\"line\":9},{\"byteEnd\":22,\"byteStart\":17,\"line\":9},{\"byteEnd\":7,\"byteStart\":2,\"line\":10},{\"byteEnd\":7,\"byteStart\":2,\"line\":11},{\"byteEnd\":7,\"byteStart\":2,\"line\":12}],\"startLine\":8}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Markdown\",\"path\":\"docs/DESIGN.md\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"//! Splitting text into the things tally counts.\\n\",\"highlights\":\"comment:0,49\",\"ranges\":[{\"byteEnd\":46,\"byteStart\":41,\"line\":1}],\"startLine\":1},{\"content\":\"pub fn words(line: &str) -> usize {\\n line.split_whitespace().count()\\n}\",\"highlights\":\"keyword:0,3,1,2;function:7,5,33,16,3,5;type:20,3,5,5\",\"ranges\":[{\"byteEnd\":33,\"byteStart\":28,\"line\":5}],\"startLine\":4},{\"content\":\"\\n/// The lines of `text`. A last line without a newline still counts, and\\n/// empty input has none.\",\"highlights\":\"comment:1,98\",\"ranges\":[{\"byteEnd\":66,\"byteStart\":61,\"line\":8}],\"startLine\":7},{\"content\":\" fn empty_input_has_no_lines() {\\n assert_eq!(super::lines(\\\"\\\").count(), 0);\\n }\",\"highlights\":\"string:68,2;keyword:4,2,49,5;number:81,1;function:7,24,13,10\",\"ranges\":[{\"byteEnd\":41,\"byteStart\":36,\"line\":18}],\"startLine\":17}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Rust\",\"path\":\"src/parse.rs\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"\\nCounts lines, words and bytes, like `wc`, with output that lines up.\\n\",\"highlights\":\"string:37,4\",\"ranges\":[{\"byteEnd\":5,\"byteStart\":0,\"line\":3}],\"startLine\":2}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"Markdown\",\"path\":\"README.md\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}},{\"chunks\":[{\"content\":\"edition = \\\"2024\\\"\\ndescription = \\\"Counts lines, words and bytes\\\"\\nlicense = \\\"MIT\\\"\",\"highlights\":\"string:10,6,15,31,11,5;type:0,7,10,11,35,7\",\"ranges\":[{\"byteEnd\":20,\"byteStart\":15,\"line\":5}],\"startLine\":4}],\"commit\":\"aae0fe0316b38d65d0c88c17c026786348223d7d\",\"language\":\"TOML\",\"path\":\"Cargo.toml\",\"repo\":{\"createdAt\":\"2026-10-09T10:00:00.000Z\",\"description\":\"Counts lines, words and bytes, with output that lines up\",\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"name\":\"tally\",\"owner\":{\"did\":\"did:plc:abe24xewga4qdbzjcxmuzdt3\",\"handle\":\"alice.test\"}}}],\"languages\":[{\"name\":\"Rust\",\"color\":\"#dea584\",\"files\":3},{\"name\":\"Markdown\",\"color\":\"#083fa1\",\"files\":2},{\"name\":\"TOML\",\"color\":\"#9c4221\",\"files\":1}],\"matchCount\":29}"
"fileCount": { "type": "integer", "minimum": 0, "description": "How many files the query found in all, of which files are the best." },
"matchCount": { "type": "integer", "minimum": 0, "description": "How many matches the query found in all." }
"matchCount": { "type": "integer", "minimum": 0, "description": "How many matches the query found in all." },
"languages": { "type": "array", "items": { "type": "ref", "ref": "#languageCount" }, "description": "The languages of the files found, counting those its lang: filters leave out, most files first: of the first 1000 files at most." }
}
}
}
@@ -40,6 +41,16 @@
"chunks": { "type": "array", "items": { "type": "ref", "ref": "#chunk" }, "description": "Runs of lines holding matches, in order. Empty when only the path matched." }
}
},
"languageCount": {
"type": "object",
"description": "A language files were found in, and how many.",
{#if code.kind === 'off'}<Empty title="Code search is off here">This server searches no code.</Empty>
{:else if code.kind === 'missing'}<Empty title="No repository {code.repo}">Check its owner and name, or <a href={everywhere}>search all of knotless</a>.</Empty>
{:else if code.kind === 'bad'}<Empty title="That search can’t be read">{code.message}</Empty>
{:else if code.kind === 'found'}<Empty title="No code found">{#if within}Nothing in {within[1]}/{within[2]} matches. <a href={everywhere}>Search all of knotless</a> instead.{:else}Only each repository’s default branch is searched. <a href={of('repositories')}>Search repositories</a> instead.{/if}</Empty>
{:else if code.kind === 'found'}<Empty title="No code found">{#if picked && languages.length}No {languages.find((l) => l.name.toLowerCase() === picked)?.name ?? picked} file matches. <a href={of('code', unpicked)}>Search every language</a> instead.{:else if within}Nothing in {within[1]}/{within[2]} matches. <a href={everywhere}>Search all of knotless</a> instead.{:else}Only each repository’s default branch is searched. <a href={of('repositories')}>Search repositories</a> instead.{/if}</Empty>
{:else}<Empty title="Search code">Type what to look for, as a word, "quoted text" or /a regex/. Add repo:owner/name to search one repository.</Empty>{/if}