Skip to content

defensive get_selection#6470

Merged
willmcgugan merged 1 commit into
mainfrom
defensive-selection
Apr 5, 2026
Merged

defensive get_selection#6470
willmcgugan merged 1 commit into
mainfrom
defensive-selection

Conversation

@willmcgugan

@willmcgugan willmcgugan commented Apr 5, 2026

Copy link
Copy Markdown
Member

Reported in toad

╭───────────────────────────────────────── Traceback (most recent call last) ──────────────────────────────────────
│ /Users/visionik/.local/share/uv/tools/batrachian-toad/lib/python3.14/site-packages/toad/app.py:680 in            
│ on_text_selected                                                                                                 
│                                                                                                                  
│   677 │   @on(events.TextSelected)                                                                               
│   678 │   async def on_text_selected(self) -> None:                                                              
│   679 │   │   if self.settings.get("ui.auto_copy", bool):                                                        
│ ❱ 680 │   │   │   if (selection := self.screen.get_selected_text()) is not None:                                 
│   681 │   │   │   │   self.copy_to_clipboard(selection)                                                          
│   682 │   │   │   │   self.notify(                                                                               
│   683 │   │   │   │   │   "Copied selection to clipboard (see settings)",                                        
│                                                                                                                  
│ ╭──────────────────────────────────────────────────── locals ────────────────────────────────────────────────────
│ │ self = ToadApp(title='ToadApp', classes={'-dark-mode', '-show-sessions-bar'}, pseudo_classes={'focus', 'dark'})
│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│                                                                                                                  
│ /Users/visionik/.local/share/uv/tools/batrachian-toad/lib/python3.14/site-packages/textual/screen.py:979 in      
│ get_selected_text                                                                                                
│                                                                                                                  
│    976 │   │   │   # Filter out widgets that may have been removed since the text was selected                   
│    977 │   │   │   if (                                                                                          
│    978 │   │   │   │   widget.is_attached                                                                        
│ ❱  979 │   │   │   │   and (selected_text_in_widget := widget.get_selection(selection))                          
│    980 │   │   │   │   is not None                                                                               
│    981 │   │   │   ):                                                                                            
│    982 │   │   │   │   widget_text.extend(selected_text_in_widget)                                               
│                                                                                                                  
│ ╭───────────────────────────────── locals ──────────────────────────────────╮                                    
│ │   selection = Selection(start=Offset(x=44, y=15), end=None)               │                                    
│ │        self = MainScreen(id='session-1', classes='-wide')                 │                                    
│ │      widget = MarkdownParagraph(name='paragraph_open', classes='level-0') │                                    
│ │ widget_text = []                                                          │                                    
│ ╰───────────────────────────────────────────────────────────────────────────╯                                    
│                                                                                                                  
│ /Users/visionik/.local/share/uv/tools/batrachian-toad/lib/python3.14/site-packages/textual/widget.py:4230 in     
│ get_selection                                                                                                    
│                                                                                                                  
│   4227 │   │   │   text = str(visual)                                                                            
│   4228 │   │   else:                                                                                             
│   4229 │   │   │   return None                                                                                   
│ ❱ 4230 │   │   return selection.extract(text), "\n"                                                              
│   4231 │                                                                                                         
│   4232 │   def selection_updated(self, selection: Selection | None) -> None:                                     
│   4233 │   │   """Called when the selection is updated.                                                          
│                                                                                                                  
│ ╭──────────────────────────────────────────────── locals ────────────────────────────────────────────────╮       
│ │ selection = Selection(start=Offset(x=44, y=15), end=None)                                              │       
│ │      self = MarkdownParagraph(name='paragraph_open', classes='level-0')                                │       
│ │      text = 'If you are looking for the specific logic of how Anthropic is integrated, src/an'+46      │       
│ │    visual = Content(                                                                                   │       
│ │             │   'If you are looking for the specific logic of how Anthropic is integrated, src/an'+46, │       
│ │             │   spans=[Span(74, 88, style='.code_inline'), Span(74, 88, style='.strong')]              │       
│ │             )                                                                                          │       
│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────╯       
│                                                                                                                  
│ /Users/visionik/.local/share/uv/tools/batrachian-toad/lib/python3.14/site-packages/textual/selection.py:66 in    
│ extract                                                                                                          
│                                                                                                                  
│    63 │   │   │   selection.extend(mid_lines)                                                                    
│    64 │   │   │   selection.append(last_line[:end_offset])                                                       
│    65 │   │   else:                                                                                              
│ ❱  66 │   │   │   return lines[start_line][start_offset:end_offset]                                              
│    67 │   │   return "\n".join(selection)                                                                        
│    68 │                                                                                                          
│    69 │   def get_span(self, y: int) -> tuple[int, int] | None:                                                  
│                                                                                                                  
│ ╭───────────────────────────────────────────────── locals ─────────────────────────────────────────────────╮     
│ │       end_line = 1                                                                                       │     
│ │     end_offset = 126                                                                                     │     
│ │          lines = ['If you are looking for the specific logic of how Anthropic is integrated, src/an'+46] │     
│ │ selected_lines = []                                                                                      │     
│ │      selection = []                                                                                      │     
│ │           self = Selection(start=Offset(x=44, y=15), end=None)                                           │     
│ │     start_line = 15                                                                                      │     
│ │   start_offset = 44                                                                                      │     
│ │           text = 'If you are looking for the specific logic of how Anthropic is integrated, src/an'+46   │     
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯     
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
IndexError: list index out of range

Thanks for trying out Toad!
Please head to Discussions to share your experiences (good or bad).
https://github.com/batrachianai/toad/discussions
message.txt
12 KB

@willmcgugan willmcgugan merged commit 23bf10e into main Apr 5, 2026
23 checks passed
@willmcgugan willmcgugan deleted the defensive-selection branch April 5, 2026 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant