@ -6152,15 +6152,52 @@ fn extend_to_word(cx: &mut Context) {
}
fn jump_to_label ( cx : & mut Context , labels : Vec < Range > , behaviour : Movement ) {
let doc = doc ! ( cx . editor ) ;
let alphabet = & cx . editor . config ( ) . jump_label_alphabet ;
if labels . is_empty ( ) {
return ;
}
let alphabet_char = | i | {
let mut res = Tendril ::new ( ) ;
res . push ( alphabet [ i ] ) ;
res
let doc = doc ! ( cx . editor ) ;
let alphabet = & cx . editor . config ( ) . jump_label_alphabet ;
let follow_blacklist = & cx . editor . config ( ) . jump_label_follow_blacklist ;
let jump_label_lookup = follow_blacklist . get_allow_list ( alphabet ) ;
let partial_sums = jump_label_lookup
. alphabet
. iter ( )
. map ( | c | jump_label_lookup . follow_whitelist . get ( c ) . unwrap ( ) )
. map ( | v | v . len ( ) )
. fold ( vec! [ 0 ] , | mut acc , curr | {
acc . push ( acc . last ( ) . unwrap ( ) + curr ) ;
acc
} ) ;
let make_jump_label = | i | {
// finding, based on the total number of overlays generated so far, what the index into the
// first characters and second characters respectively should be.
let first_i = partial_sums . iter ( ) . take_while ( | p | p < = & & i ) . count ( ) - 1 ;
let second_i = i - partial_sums
. get ( first_i )
. unwrap_or_else ( | | panic! ( "first_i outside of partial_sums indices." ) ) ;
let first = * jump_label_lookup . alphabet . get ( first_i ) . unwrap_or_else ( | | {
panic! (
"alphabet_char called with i ({}) greater than the number of valid pairs ({})." ,
i ,
partial_sums . last ( ) . unwrap ( )
)
} ) ;
let second = jump_label_lookup . follow_whitelist . get ( & first )
. unwrap_or_else ( | | {
panic! ( "there should not be any first chars created which don't have entries in follow_whitelist." )
} ) [ second_i ] ;
let mut first_res = Tendril ::new ( ) ;
let mut second_res = Tendril ::new ( ) ;
first_res . push ( first ) ;
second_res . push ( second ) ;
( first_res , second_res )
} ;
// Add label for each jump candidate to the View as virtual text.
@ -6169,15 +6206,18 @@ fn jump_to_label(cx: &mut Context, labels: Vec<Range>, behaviour: Movement) {
. iter ( )
. enumerate ( )
. flat_map ( | ( i , range ) | {
let ( first_grapheme , second_grapheme ) = make_jump_label ( i ) ;
[
Overlay ::new ( range . from ( ) , alphabet_char ( i / alphabet . len ( ) ) ) ,
Overlay ::new ( range . from ( ) , first_grapheme ) ,
Overlay ::new (
graphemes ::next_grapheme_boundary ( text , range . from ( ) ) ,
alphabet_char( i % alphabet . len ( ) ) ,
second_grapheme ,
) ,
]
} )
. collect ( ) ;
overlays . sort_unstable_by_key ( | overlay | overlay . char_idx ) ;
let ( view , doc ) = current ! ( cx . editor ) ;
doc . set_jump_labels ( view . id , overlays ) ;
@ -6188,15 +6228,17 @@ fn jump_to_label(cx: &mut Context, labels: Vec<Range>, behaviour: Movement) {
let view = view . id ;
let doc = doc . id ( ) ;
cx . on_next_key ( move | cx , event | {
let alphabet = & cx . editor . config ( ) . jump_label_alphabet ;
let Some ( i ) = event
. char ( )
. and_then ( | ch | alphabet . iter ( ) . position ( | & it | it = = ch ) )
else {
let Some ( ( first_ch , i ) ) = event . char ( ) . and_then ( | ch | {
jump_label_lookup
. alphabet
. iter ( )
. position ( | & it | it = = ch )
. map ( | i | ( ch , i ) )
} ) else {
doc_mut ! ( cx . editor , & doc ) . remove_jump_labels ( view ) ;
return ;
} ;
let outer = i * alphabet . len ( ) ;
let outer = partial_sums[ i ] ;
// Bail if the given character cannot be a jump label.
if outer > labels . len ( ) {
doc_mut ! ( cx . editor , & doc ) . remove_jump_labels ( view ) ;
@ -6204,13 +6246,17 @@ fn jump_to_label(cx: &mut Context, labels: Vec<Range>, behaviour: Movement) {
}
cx . on_next_key ( move | cx , event | {
doc_mut ! ( cx . editor , & doc ) . remove_jump_labels ( view ) ;
let alphabet = & cx . editor . config ( ) . jump_label_alphabet ;
let Some ( inner ) = event
. char ( )
. and_then ( | ch | alphabet . iter ( ) . position ( | & it | it = = ch ) )
else {
let Some ( inner ) = event . char ( ) . and_then ( | ch | {
jump_label_lookup
. follow_whitelist
. get ( & first_ch )
. unwrap_or ( & vec! [ ] )
. iter ( )
. position ( | & it | it = = ch )
} ) else {
return ;
} ;
if let Some ( mut range ) = labels . get ( outer + inner ) . copied ( ) {
range = if behaviour = = Movement ::Extend {
let anchor = if range . anchor < range . head {
@ -6242,7 +6288,13 @@ fn jump_to_word(cx: &mut Context, behaviour: Movement) {
// Calculate the jump candidates: ranges for any visible words with two or
// more characters.
let alphabet = & cx . editor . config ( ) . jump_label_alphabet ;
let jump_label_limit = alphabet . len ( ) * alphabet . len ( ) ;
let follow_blacklist = & cx . editor . config ( ) . jump_label_follow_blacklist ;
let jump_label_lookup = follow_blacklist . get_allow_list ( alphabet ) ;
let jump_label_limit = jump_label_lookup
. follow_whitelist
. values ( )
. map ( | v | v . len ( ) )
. sum ( ) ;
let mut words = Vec ::with_capacity ( jump_label_limit ) ;
let ( view , doc ) = current_ref ! ( cx . editor ) ;
let text = doc . text ( ) . slice ( .. ) ;