8001f6686656
rewrite the manual short and plain-spoken, correct its stale claims, and make koh man <command> return the whole entry with examples (3.0.71)
- time
- 2026-09-26 14:04 UTC · 2 weeks ago
- machine
- Junes-MacBook-Pro.local
- agent
- claude-opus-5-5
- session
- koh man
- parent
- 6554688b6256
↓ koh-8001f668.tar.gzatlas at this save
files changed4 files
VERSION+1 −1src/cli/cmd_man.v+23 −15tests/cli_test.v+3 −0v.mod+1 −1src/cli/cmd_man.v+23 −15
@@ -27,13 +27,17 @@2727 return 02828 }2929 30-// section_of returns the part of the COMMANDS section that documents one31-// command: from its synopsis to the next command's.30+// section_of returns one command's entry from the COMMANDS section: its31+// synopsis lines, which may name several commands, down to the next entry.3232 fn section_of(name string) ?string {3333 lines := manual.split_into_lines()3434 mut start := -135+ mut in_commands := false3536 for i, line in lines {36- if line.starts_with(' koh ') && line.contains(' ${name}') {37+ if line == 'COMMANDS' {38+ in_commands = true39+ } else if in_commands && is_synopsis(line)40+ && (line.starts_with(' koh ${name} ') || line == ' koh ${name}') {3741 start = i3842 break3943 }@@ -41,19 +45,23 @@4145 if start < 0 {4246 return none4347 }44- mut end := lines.len45- for i := start + 1; i < lines.len; i++ {46- trimmed := lines[i].trim_space()47- if trimmed.starts_with('koh ') && lines[i].starts_with(' ') {48- end = i49- break50- }51- if lines[i].starts_with('OPTIONS') || lines[i].starts_with('ENVIRONMENT') {52- end = i53- break54- }48+ for start > 0 && is_synopsis(lines[start - 1]) {49+ start--5550 }56- return lines[start..end].join('\n')51+ mut end := start52+ for end < lines.len && is_synopsis(lines[end]) {53+ end++54+ }55+ // The body is indented eight columns; anything shallower starts the next56+ // entry, group or section.57+ for end < lines.len && (lines[end] == '' || lines[end].starts_with(' ')) {58+ end++59+ }60+ return lines[start..end].join('\n').trim_right('\n ')61+}62+63+fn is_synopsis(line string) bool {64+ return line.starts_with(' koh ')5765 }5866 5967 // page shows the manual in Koh 2's colours, through the built-in pager when ittests/cli_test.v+3 −0
@@ -897,6 +897,9 @@897897 assert strip.code == 0898898 assert strip.out.contains('strip')899899 assert !strip.out.contains('koh save ')900+ steal := run_home(dir, home, 'man', 'steal').out901+ assert steal.starts_with(' koh steal') && steal.contains('koh steal my-project')902+ assert run_home(dir, home, 'man', 'init').out.trim_space() == "koh init\n Create `.koh` here, and a starter `.kohignore` if there isn't one."900903 assert run_home(dir, home, 'man', 'nonsense').code == 2901904 legacy := temp_repo('legacy')902905 defer { os.rmdir_all(legacy) or {} }v.mod+1 −1
@@ -1,6 +1,6 @@11 Module {22 name: 'koh3'3- version: '3.0.70'3+ version: '3.0.71'44 description: 'One SQLite file per repo, one line of history.'55 license: 'MIT'66 }