@@ -676,6 +676,73 @@ def handle_narrow_link(self) -> None:
676
676
self .controller .exit_popup ()
677
677
678
678
679
+ class CodeBlockButton (urwid .Button ):
680
+ def __init__ (
681
+ self ,
682
+ * ,
683
+ controller : Any ,
684
+ caption : str ,
685
+ code_block_list : List [Tuple [str , str ]],
686
+ display_attr : Optional [str ],
687
+ index : int ,
688
+ ) -> None :
689
+ self .controller = controller
690
+ self .model = self .controller .model
691
+ self .view = self .controller .view
692
+ self .caption = caption
693
+ self .code_block_list = code_block_list
694
+ self .index = index
695
+
696
+ super ().__init__ ("" )
697
+
698
+ self .extract_display_code (code_block_list )
699
+ if self .display_code :
700
+ self .code_block_width = len (max (self .display_code , key = len ))
701
+ self .update_widget (self .display_code , display_attr )
702
+ urwid .connect_signal (
703
+ self , "click" , lambda button : self .copy_to_clipboard (code_block_list )
704
+ )
705
+
706
+ def update_widget (
707
+ self , display_code : List [Tuple [str , str ]], display_attr : Optional [str ] = None
708
+ ) -> None :
709
+ """
710
+ Overrides the existing button widget for custom styling.
711
+ """
712
+ # Set cursor position next to length of code to avoid the cursor.
713
+ icon = urwid .SelectableIcon (
714
+ display_code ,
715
+ cursor_position = len ("" .join ([code [1 ] for code in display_code ])) + 1 ,
716
+ )
717
+ self ._w = urwid .AttrMap (icon , display_attr , focus_map = "selected" )
718
+
719
+ def copy_to_clipboard (self , code_block_list : List [Tuple [str , str ]]) -> None :
720
+ block = code_block_list [:]
721
+ self .copy_code = "" .join (snip [1 ] for snip in block )
722
+ self .controller .copy_to_clipboard (self .copy_code , f"Code Block { self .index } " )
723
+
724
+ def extract_display_code (self , code_block_list : List [Tuple [str , str ]]) -> None :
725
+ """
726
+ Extracts and assigns two lines of code from code_block_list
727
+ to summarize and display on the button.
728
+ """
729
+ block = code_block_list [:]
730
+ no_of_lines = 0
731
+ for index , snip in enumerate (block ):
732
+ no_of_lines += 1 if "\n " in snip [1 ] else 0
733
+ if no_of_lines == 2 :
734
+ self .display_code = block [:index ] + [("pygments:w" , "..." )]
735
+ break
736
+ if no_of_lines < 2 :
737
+ self .display_code = block
738
+ if self .display_code :
739
+ self .display_code [- 1 ] = (
740
+ self .display_code [- 1 ][0 ],
741
+ self .display_code [- 1 ][1 ].rstrip ("\n " ),
742
+ )
743
+ self .display_code = [("pygments:w" , self .caption )] + self .display_code
744
+
745
+
679
746
class EditModeButton (urwid .Button ):
680
747
def __init__ (self , * , controller : Any , width : int ) -> None :
681
748
self .controller = controller
0 commit comments