@@ -397,6 +397,24 @@ def __init__(self, parser_name: str | None, settings: dict[str, Any]) -> None:
397397 "help" : "Append the last parse results to the file in save_parses_to" ,
398398 "handler" : self .cmd_save_parse ,
399399 },
400+ "parse-results" : {
401+ "help" : "Show the current parse results JSON" ,
402+ "handler" : self .cmd_parse_results ,
403+ },
404+ "tag" : {
405+ "help" : (
406+ "Add a boolean tag (name=true) to the current parse results' "
407+ "extra dict"
408+ ),
409+ "handler" : self .cmd_tag ,
410+ },
411+ "tags" : {
412+ "help" : (
413+ "List keys in the current parse results' extra dict whose "
414+ "value is True"
415+ ),
416+ "handler" : self .cmd_tags ,
417+ },
400418 "edges" : {
401419 "help" : "Show in-memory edges (count and source file)" ,
402420 "handler" : self .cmd_edges ,
@@ -974,6 +992,89 @@ def cmd_save_parse(self, args: list) -> bool:
974992 )
975993 return False
976994
995+ def cmd_parse_results (self , args : list ) -> bool :
996+ if not self .last_parse_result :
997+ self .console .print (
998+ "[yellow]No parse results.[/yellow] [dim]Parse some text first.[/dim]"
999+ )
1000+ return False
1001+ payload = [r .to_dict () for r in self .last_parse_result ]
1002+ self .console .print (
1003+ json .dumps (payload , indent = 2 , ensure_ascii = False , default = str )
1004+ )
1005+ return False
1006+
1007+ def _choose_parse_indices (self ) -> list [int ] | None :
1008+ """Return indices into self.last_parse_result to act on, or None on abort."""
1009+ assert self .last_parse_result is not None
1010+ n = len (self .last_parse_result )
1011+ if n == 1 :
1012+ return [0 ]
1013+ try :
1014+ answer = self .session .prompt (
1015+ f"{ n } parse results. (a)ll or index 0..{ n - 1 } : "
1016+ ).strip ()
1017+ except (KeyboardInterrupt , EOFError ):
1018+ self .console .print ("[dim](aborted)[/dim]" )
1019+ return None
1020+ if answer .lower () in ("a" , "all" ):
1021+ return list (range (n ))
1022+ try :
1023+ idx = int (answer )
1024+ except ValueError :
1025+ self .console .print (
1026+ f"[red]Error:[/red] expected 'all' or an integer in [0, { n - 1 } ]"
1027+ )
1028+ return None
1029+ if not 0 <= idx < n :
1030+ self .console .print (
1031+ f"[red]Error:[/red] index { idx } out of range [0, { n - 1 } ]"
1032+ )
1033+ return None
1034+ return [idx ]
1035+
1036+ def cmd_tag (self , args : list ) -> bool :
1037+ if len (args ) != 1 :
1038+ self .console .print ("[dim]Usage:[/dim] [cyan]/tag <name>[/cyan]" )
1039+ return False
1040+ name = args [0 ]
1041+ if not self .last_parse_result :
1042+ self .console .print (
1043+ "[yellow]No parse results.[/yellow] [dim]Parse some text first.[/dim]"
1044+ )
1045+ return False
1046+ indices = self ._choose_parse_indices ()
1047+ if indices is None :
1048+ return False
1049+ for i in indices :
1050+ self .last_parse_result [i ].extra [name ] = True
1051+ self .console .print (
1052+ f"[green]✓[/green] Tagged [cyan]'{ name } '[/cyan] on "
1053+ f"[cyan]{ len (indices )} [/cyan] result(s)"
1054+ )
1055+ return False
1056+
1057+ def cmd_tags (self , args : list ) -> bool :
1058+ if not self .last_parse_result :
1059+ self .console .print (
1060+ "[yellow]No parse results.[/yellow] [dim]Parse some text first.[/dim]"
1061+ )
1062+ return False
1063+ indices = self ._choose_parse_indices ()
1064+ if indices is None :
1065+ return False
1066+ if len (indices ) == 1 :
1067+ extra = self .last_parse_result [indices [0 ]].extra
1068+ keys = [k for k , v in extra .items () if v is True ]
1069+ self .console .print (", " .join (keys ) if keys else "[dim](none)[/dim]" )
1070+ else :
1071+ for i in indices :
1072+ extra = self .last_parse_result [i ].extra
1073+ keys = [k for k , v in extra .items () if v is True ]
1074+ rendered = ", " .join (keys ) if keys else "[dim](none)[/dim]"
1075+ self .console .print (f"[cyan][{ i } ][/cyan] { rendered } " )
1076+ return False
1077+
9771078 def _build_tok_pos_tree (self , edge : Hyperedge ) -> Hyperedge :
9781079 """Build a tok_pos mirror tree where each atom is replaced by its
9791080 ``tok_pos`` (or ``-1`` for synthetic atoms with no position)."""
0 commit comments