11from typing import Dict , TypedDict
22
3+ import json
4+ from pathlib import Path
35import typer
46
57from states .global_state import debug , verbose_flag
@@ -12,63 +14,95 @@ class CommandInfo(TypedDict):
1214 notes : str
1315
1416
15- COMMANDS : Dict [str , CommandInfo ] = {
16- "ls" : {
17- "description" : (
18- "List information about the files in the current directory (the default). "
19- "Options can be used to modify the output format, sort order, and more."
20- ),
21- "usage" : "ls [OPTION]... [FILE]..." ,
22- "example" : "ls -la /var/log" ,
23- "notes" : (
24- "- `-l` : use a long listing format\n "
25- "- `-a` : show hidden files (starting with `.`)\n "
26- "- `-h` : with -l, print sizes in human-readable format (e.g., 1K, 234M)"
27- ),
28- },
29- "grep" : {
30- "description" : (
31- "Search input files for lines containing a match to the given PATTERN. "
32- "Often used for filtering log files or searching through code."
33- ),
34- "usage" : "grep [OPTION]... PATTERN [FILE]..." ,
35- "example" : 'grep -R "TODO" .' ,
36- "notes" : (
37- "- `-i` : ignore case distinctions\n "
38- "- `-R` : recursively search subdirectories\n "
39- "- `-n` : show line numbers of matches"
40- ),
41- },
42- "cat" : {
43- "description" : (
44- "Concatenate files and print on the standard output. "
45- "Often used to quickly view file contents."
46- ),
47- "usage" : "cat [OPTION]... [FILE]..." ,
48- "example" : "cat /etc/passwd" ,
49- "notes" : (
50- "- `-n` : number all output lines\n "
51- "- `-b` : number non-blank lines\n "
52- "- Use with pipes: `cat file.txt | grep pattern`"
53- ),
54- },
55- "mkdir" : {
56- "description" : (
57- "Create directories if they do not already exist. "
58- "By default, it creates a single directory."
59- ),
60- "usage" : "mkdir [OPTION]... DIRECTORY..." ,
61- "example" : "mkdir -p projects/python/app" ,
62- "notes" : (
63- "- `-p` : create parent directories as needed\n "
64- "- `-v` : print a message for each created directory"
65- ),
66- },
67- }
17+ def _load_commands_from_json () -> Dict [str , CommandInfo ] | None :
18+ data_path = Path (__file__ ).parent .parent / "data" / "commands.json"
19+ if not data_path .exists ():
20+ return None
21+ try :
22+ data = json .loads (data_path .read_text (encoding = "utf-8" ))
23+ result : Dict [str , CommandInfo ] = {}
24+ for item in data :
25+ key = item .get ("name" )
26+ if not key :
27+ continue
28+ result [key ] = {
29+ "description" : item .get ("description" , "" ),
30+ "usage" : item .get ("usage" , "" ),
31+ "example" : item .get ("example" , "" ),
32+ "notes" : item .get ("notes" , "" ),
33+ }
34+ return result
35+ except Exception :
36+ return None
37+
38+
39+ # Try to load a generated commands index, otherwise fall back to the baked-in dataset
40+ _LOADED_COMMANDS = _load_commands_from_json ()
41+
42+
43+ COMMANDS : Dict [str , CommandInfo ]
44+
45+ if _LOADED_COMMANDS is not None :
46+ COMMANDS = _LOADED_COMMANDS
47+ else :
48+ # fallback in-code registry
49+ COMMANDS = {
50+ "ls" : {
51+ "description" : (
52+ "List information about the files in the current directory (the default). "
53+ "Options can be used to modify the output format, sort order, and more."
54+ ),
55+ "usage" : "ls [OPTION]... [FILE]..." ,
56+ "example" : "ls -la /var/log" ,
57+ "notes" : (
58+ "- `-l` : use a long listing format\n "
59+ "- `-a` : show hidden files (starting with `.`)\n "
60+ "- `-h` : with -l, print sizes in human-readable format (e.g., 1K, 234M)"
61+ ),
62+ },
63+ "grep" : {
64+ "description" : (
65+ "Search input files for lines containing a match to the given PATTERN. "
66+ "Often used for filtering log files or searching through code."
67+ ),
68+ "usage" : "grep [OPTION]... PATTERN [FILE]..." ,
69+ "example" : 'grep -R "TODO" .' ,
70+ "notes" : (
71+ "- `-i` : ignore case distinctions\n "
72+ "- `-R` : recursively search subdirectories\n "
73+ "- `-n` : show line numbers of matches"
74+ ),
75+ },
76+ "cat" : {
77+ "description" : (
78+ "Concatenate files and print on the standard output. "
79+ "Often used to quickly view file contents."
80+ ),
81+ "usage" : "cat [OPTION]... [FILE]..." ,
82+ "example" : "cat /etc/passwd" ,
83+ "notes" : (
84+ "- `-n` : number all output lines\n "
85+ "- `-b` : number non-blank lines\n "
86+ "- Use with pipes: `cat file.txt | grep pattern`"
87+ ),
88+ },
89+ "mkdir" : {
90+ "description" : (
91+ "Create directories if they do not already exist. "
92+ "By default, it creates a single directory."
93+ ),
94+ "usage" : "mkdir [OPTION]... DIRECTORY..." ,
95+ "example" : "mkdir -p projects/python/app" ,
96+ "notes" : (
97+ "- `-p` : create parent directories as needed\n "
98+ "- `-v` : print a message for each created directory"
99+ ),
100+ },
101+ }
68102
69103
70104def show (
71- command : str = typer .Argument (..., help = "Linux command to show details for" )
105+ command : str = typer .Argument (..., help = "Linux command to show details for" ),
72106) -> None :
73107 """
74108 Display description, usage, examples, and notes for a given Linux command.
@@ -79,7 +113,7 @@ def show(
79113
80114 if not info :
81115 typer .secho (
82- f"✖ Unknown command '{ command } '. Try one of: { ', ' .join (sorted (COMMANDS ))} " ,
116+ f"Unknown command '{ command } '. Try one of: { ', ' .join (sorted (COMMANDS ))} " ,
83117 err = True ,
84118 fg = typer .colors .RED ,
85119 )
0 commit comments