Skip to content

Commit bbe8250

Browse files
rsashankkingjunoyuktasarode
committed
buttons: Add CodeBlockButton class.
This class inherits from urwid.Button and enables the creation of code block buttons that copy code to the clipboard when activated. Co-authored-by: kingjuno <[email protected]> Co-authored-by: yuktasarode <[email protected]>
1 parent ad98796 commit bbe8250

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

zulipterminal/ui_tools/buttons.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,73 @@ def handle_narrow_link(self) -> None:
676676
self.controller.exit_popup()
677677

678678

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+
679746
class EditModeButton(urwid.Button):
680747
def __init__(self, *, controller: Any, width: int) -> None:
681748
self.controller = controller

0 commit comments

Comments
 (0)