@@ -251,7 +251,13 @@ impl HintState {
251251 term : & rio_backend:: crosswords:: Crosswords < T > ,
252252 hint : Rc < Hint > ,
253253 ) {
254- // Scan the visible area for OSC 8 hyperlinks
254+ // Walk the visible region looking for OSC 8 hyperlink spans.
255+ //
256+ // After the cell repack, hyperlinks live in the per-grid
257+ // `extras_table`. Each cell carries an `extras_id: u16`; cells
258+ // in the same hyperlink span share that id. We compare ids
259+ // (cheap u16 compare) to find the start and end of each span,
260+ // then look up the URI once via `Crosswords::cell_hyperlink`.
255261 let grid = & term. grid ;
256262 let display_offset = grid. display_offset ( ) ;
257263 let visible_lines = grid. screen_lines ( ) ;
@@ -262,46 +268,42 @@ impl HintState {
262268 continue ;
263269 }
264270
265- let mut col = Column ( 0 ) ;
266- while col < grid. columns ( ) {
267- let cell = & grid[ line] [ col] ;
268-
269- if let Some ( hyperlink) = cell. hyperlink ( ) {
270- // Find the extent of this hyperlink
271- let start_col = col;
272- let mut end_col = col;
273-
274- // Scan forward to find the end of the hyperlink
275- while end_col < grid. columns ( ) {
276- let next_cell = & grid[ line] [ end_col] ;
277- if next_cell. hyperlink ( ) . as_ref ( ) == Some ( & hyperlink) {
278- end_col += 1 ;
279- } else {
280- break ;
281- }
271+ let mut col = 0usize ;
272+ let cols = grid. columns ( ) ;
273+ while col < cols {
274+ let id = match term. cell_hyperlink_id ( line, Column ( col) ) {
275+ Some ( id) => id,
276+ None => {
277+ col += 1 ;
278+ continue ;
282279 }
280+ } ;
283281
284- let mut uri = hyperlink. uri ( ) . to_string ( ) ;
282+ // Found the start of a hyperlink span. Walk forward
283+ // until the extras_id changes.
284+ let start_col = col;
285+ let mut end_col = col;
286+ while end_col < cols
287+ && term. cell_hyperlink_id ( line, Column ( end_col) ) == Some ( id)
288+ {
289+ end_col += 1 ;
290+ }
285291
286- // Apply post-processing if enabled
292+ // Look up the URI once for the whole span.
293+ if let Some ( hyperlink) = term. cell_hyperlink ( line, Column ( start_col) ) {
294+ let mut uri = hyperlink. uri ( ) . to_string ( ) ;
287295 if hint. post_processing {
288296 uri = post_process_hyperlink_uri ( & uri) ;
289297 }
290-
291- let hint_match = HintMatch {
298+ self . matches . push ( HintMatch {
292299 text : uri,
293- start : Pos :: new ( line, start_col) ,
294- end : Pos :: new ( line, end_col - 1 ) ,
300+ start : Pos :: new ( line, Column ( start_col) ) ,
301+ end : Pos :: new ( line, Column ( end_col - 1 ) ) ,
295302 hint : hint. clone ( ) ,
296- } ;
297-
298- self . matches . push ( hint_match) ;
299-
300- // Skip to the end of this hyperlink
301- col = end_col;
302- } else {
303- col += 1 ;
303+ } ) ;
304304 }
305+
306+ col = end_col;
305307 }
306308 }
307309 }
@@ -316,7 +318,7 @@ impl HintState {
316318
317319 for col in 0 ..grid. columns ( ) {
318320 let cell = & grid[ line] [ Column ( col) ] ;
319- text. push ( cell. c ) ;
321+ text. push ( cell. c ( ) ) ;
320322 }
321323
322324 text. trim_end ( ) . to_string ( )
0 commit comments