A note-taking app inspired by nb
1import { colors } from "@cliffy/ansi/colors";
2import { Command, ValidationError } from "@cliffy/command";
3import { maxOf } from "@std/collections";
4
5import { search } from "../search.ts";
6import { print } from "../utils.ts";
7import { Hsh } from "../hsh.ts";
8import { iconForEntry } from "../entry.ts";
9
10function register(cmd: Command, hsh: Hsh) {
11 cmd
12 .command("search", "search notebook")
13 .alias("q")
14 .option("-a, --all", "search across all notebooks", { default: false })
15 .option("-e, --regexp", "search by regex", { default: false })
16 .option("-t, --tag <tag>", "include tags", { collect: true })
17 .option("-T, --title-only", "only show entry titles", { default: false })
18 .arguments("[...terms:string]")
19 .action(async ({ all, regexp, titleOnly, tag }, ...terms: string[]) => {
20 if (terms.length === 0 && (tag?.length ?? 0) === 0) {
21 throw new ValidationError("at least one term or tag must be specified");
22 }
23 const notebooks = all ? hsh.allNotebooks() : [hsh.getNotebook()];
24 const matches = await search(
25 notebooks,
26 [...terms, ...(tag ?? []).map((t) => `#${t}`)],
27 !regexp,
28 );
29 for (const match of matches) {
30 print(
31 `[${
32 colors.cyan(
33 match.entry.folders.length > 0
34 ? `${match.entry.folders.join("/")}/`
35 : "",
36 )
37 }${colors.cyan(match.entry.filename)}] ${
38 iconForEntry(match.entry)
39 }${match.entry.title}`,
40 );
41 if (titleOnly) continue;
42 print("-".repeat(Deno.consoleSize().columns));
43 const width = Math.log10(maxOf(match.matches, (m) => m.line)!) + 1;
44 for (const line of match.matches) {
45 print(
46 `${
47 colors.green(line.line.toString().padStart(width))
48 }: ${line.text}`,
49 );
50 }
51 print();
52 }
53 });
54}
55
56export default { register };