cmd_man.v

2.1 KB · raw

1//! `koh man` — the manual, built into the binary.2//!3//! The page lives in `docs/koh3-man.txt` and is embedded at build time, so a4//! `koh` copied to another machine still carries its own documentation. With a5//! command name it prints just that command's part; otherwise the whole page,6//! through the pager on a terminal.78module cli910import os11import src.fmt1213const manual = $embed_file('../../docs/koh3-man.txt').to_string()1415pub fn cmd_man(raw []string) int {16	args := parse('man', raw, Options{}) or { return usage_error(err.msg()) }17	mut text := manual18	if args.positional.len > 0 {19		name := args.positional_at(0)20		text = section_of(name) or {21			eprintln('  ${fmt.red(fmt.glyph_fail)} the manual has no "${name}" — try "koh man" for the whole page')22			return 223		}24	}25	page(text)26	return 027}2829// section_of returns the part of the COMMANDS section that documents one30// command: from its synopsis to the next command's.31fn section_of(name string) ?string {32	lines := manual.split_into_lines()33	mut start := -134	for i, line in lines {35		if line.starts_with('    koh ') && line.contains(' ${name}') {36			start = i37			break38		}39	}40	if start < 0 {41		return none42	}43	mut end := lines.len44	for i := start + 1; i < lines.len; i++ {45		trimmed := lines[i].trim_space()46		if trimmed.starts_with('koh ') && lines[i].starts_with('    ') {47			end = i48			break49		}50		if lines[i].starts_with('OPTIONS') || lines[i].starts_with('ENVIRONMENT') {51			end = i52			break53		}54	}55	return lines[start..end].join('\n')56}5758// page hands the text to the pager on a terminal, and prints it plainly when59// the output is going somewhere else. The pager gets a temporary file because60// that is the one interface every pager understands.61fn page(text string) {62	pager := os.getenv('PAGER')63	if os.is_atty(1) != 0 && pager != '' {64		path := os.join_path(os.temp_dir(), 'koh-man-${os.getpid()}.txt')65		os.write_file(path, text) or {66			print(text)67			return68		}69		// The path is one we built from the temp dir and our own pid, so it70		// carries nothing the shell could interpret.71		os.execute('${pager} ${path}')72		os.rm(path) or {}73		return74	}75	print(text)76	if !text.ends_with('\n') {77		println('')78	}79}