4
4
import sys
5
5
import os
6
6
import re
7
- from argparse import ArgumentParser
7
+ from argparse import ArgumentParser , Namespace
8
8
from pathlib import Path
9
9
from zipfile import ZipFile
10
10
from datetime import datetime
13
13
from urllib .parse import quote
14
14
from urllib .request import urlopen , Request
15
15
from urllib .error import HTTPError , URLError
16
- from termcolor import colored
17
16
import ssl
18
- import shtab
19
17
import shutil
20
18
19
+ # Third party imports
20
+ from termcolor import colored
21
+ import shtab
22
+
23
+
21
24
__version__ = "3.4.1"
22
25
__client_specification__ = "2.3"
23
26
@@ -571,6 +574,115 @@ def clear_cache(language: Optional[List[str]] = None) -> None:
571
574
print (f"No cache directory found for language { language } " )
572
575
573
576
577
+ def interactive_mode (options : Namespace ) -> None :
578
+ """Interactive mode for browsing/searching tldr pages."""
579
+ try :
580
+ import readline
581
+ except ImportError :
582
+ pass
583
+
584
+ print (colored ("tldr interactive mode. Type 'help' for commands, 'quit' to exit." , 'green' , attrs = ['bold' ]))
585
+
586
+ # Use the flags/options provided by the user, not just defaults
587
+ # If options.platform is a list (from argparse), flatten it to a string if needed
588
+ session_platform = options .platform if options .platform else get_platform_list ()
589
+ if isinstance (session_platform , list ) and len (session_platform ) == 1 :
590
+ session_platform = session_platform
591
+
592
+ session_language = options .language if options .language else get_language_list ()
593
+ if isinstance (session_language , list ) and len (session_language ) == 1 :
594
+ session_language = session_language
595
+
596
+ # If user passed --platform or --language, always use those as the starting values
597
+ # and allow them to be changed in the session
598
+ while True :
599
+ try :
600
+ user_input = input (colored ("tldr> " , 'cyan' , attrs = ['bold' ])).strip ()
601
+ if not user_input :
602
+ continue
603
+ parts = user_input .split ()
604
+ cmd = parts [0 ].lower ()
605
+ args = parts [1 :]
606
+
607
+ if cmd in ('quit' , 'exit' , 'q' ):
608
+ print ("Exiting interactive mode." )
609
+ break
610
+ elif cmd in ('help' , 'h' ):
611
+ print (
612
+ "Commands:\n "
613
+ " help Show this help\n "
614
+ " list List available commands\n "
615
+ " search <term> Search commands\n "
616
+ " show <command> Show documentation for a command\n "
617
+ " platform [name] Show or set platform\n "
618
+ " language [code] Show or set language\n "
619
+ " update Update cache\n "
620
+ " clear Clear cache\n "
621
+ " quit Exit interactive mode\n "
622
+ )
623
+ elif cmd == 'list' :
624
+ cmds = get_commands (session_platform , session_language )
625
+ if not cmds :
626
+ print (colored ("No commands found. Try 'update'." , 'red' ))
627
+ else :
628
+ unique = sorted (set (c .split (' (' )[0 ] for c in cmds ))
629
+ print ("Available commands:" )
630
+ print ('\n ' .join (' ' + cmd for cmd in unique ))
631
+ elif cmd == 'search' :
632
+ if not args :
633
+ print ("Usage: search <term>" )
634
+ continue
635
+ term = ' ' .join (args ).lower ()
636
+ cmds = get_commands (session_platform , session_language )
637
+ found = sorted (set (c .split (' (' )[0 ] for c in cmds if term in c .lower ()))
638
+ if found :
639
+ print ("Matches:" )
640
+ print ('\n ' .join (' ' + cmd for cmd in found ))
641
+ else :
642
+ print (colored ("No matches found." , 'yellow' ))
643
+ elif cmd == 'show' :
644
+ if not args :
645
+ print ("Usage: show <command>" )
646
+ continue
647
+ command = '-' .join (args ).lower ()
648
+ results = get_page_for_every_platform (command , None , session_platform , session_language )
649
+ if not results :
650
+ print (colored (f"No documentation for '{ command } '." , 'red' ))
651
+ else :
652
+ output (results [0 ][0 ], "long" , plain = False )
653
+ elif cmd == 'platform' :
654
+ if args :
655
+ platform_arg = args [0 ].lower ()
656
+ if platform_arg in OS_DIRECTORIES :
657
+ session_platform = [platform_arg ]
658
+ print (f"Platform set to: { platform_arg } " )
659
+ else :
660
+ print (f"Invalid platform: { platform_arg } ." )
661
+ print (f"Valid platforms are: { ', ' .join (OS_DIRECTORIES )} " )
662
+ else :
663
+ print (f"Current platform: { session_platform [0 ]} " )
664
+ elif cmd == 'language' :
665
+ if args :
666
+ session_language = [args [0 ]]
667
+ print (f"Language set to: { args [0 ]} " )
668
+ else :
669
+ print (f"Current language: { session_language [0 ]} " )
670
+ elif cmd == 'update' :
671
+ update_cache (language = session_language )
672
+ elif cmd == 'clear' :
673
+ clear_cache (language = session_language )
674
+ else :
675
+ command = '-' .join (user_input .split ()).lower ()
676
+ results = get_page_for_every_platform (command , None , session_platform , session_language )
677
+ if not results :
678
+ print (colored (f"No documentation for '{ command } '." , 'red' ))
679
+ else :
680
+ output (results [0 ][0 ], "long" , plain = False )
681
+ except (KeyboardInterrupt , EOFError ):
682
+ print ("\n Exiting interactive mode." )
683
+ break
684
+
685
+
574
686
def create_parser () -> ArgumentParser :
575
687
parser = ArgumentParser (
576
688
prog = "tldr" ,
@@ -645,6 +757,10 @@ def create_parser() -> ArgumentParser:
645
757
action = 'store_true' ,
646
758
help = 'Just print the plain page file.' )
647
759
760
+ parser .add_argument ('-i' , '--interactive' ,
761
+ action = 'store_true' ,
762
+ help = 'Start tldr in interactive mode' )
763
+
648
764
parser .add_argument ('--short-options' ,
649
765
default = False ,
650
766
action = "store_true" ,
@@ -673,7 +789,6 @@ def create_parser() -> ArgumentParser:
673
789
674
790
def main () -> None :
675
791
parser = create_parser ()
676
-
677
792
options = parser .parse_args ()
678
793
679
794
display_option_length = "long"
@@ -696,6 +811,11 @@ def main() -> None:
696
811
if options .color is False :
697
812
os .environ ["FORCE_COLOR" ] = "true"
698
813
814
+ # Call interactive_mode if requested, before any other logic
815
+ if options .interactive :
816
+ interactive_mode (options )
817
+ return
818
+
699
819
if options .update :
700
820
update_cache (language = options .language )
701
821
return
0 commit comments