@@ -124,7 +124,6 @@ fn cover_or_next<I: Iterator<Item = (Range<usize>, Range<usize>)>>(
124124 candidates : Option < I > ,
125125 caret : DisplayPoint ,
126126 map : & DisplaySnapshot ,
127- range_filter : Option < & dyn Fn ( Range < usize > , Range < usize > ) -> bool > ,
128127) -> Option < CandidateWithRanges > {
129128 let caret_offset = caret. to_offset ( map, Bias :: Left ) ;
130129 let mut covering = vec ! [ ] ;
@@ -135,11 +134,6 @@ fn cover_or_next<I: Iterator<Item = (Range<usize>, Range<usize>)>>(
135134 for ( open_range, close_range) in ranges {
136135 let start_off = open_range. start ;
137136 let end_off = close_range. end ;
138- if let Some ( range_filter) = range_filter
139- && !range_filter ( open_range. clone ( ) , close_range. clone ( ) )
140- {
141- continue ;
142- }
143137 let candidate = CandidateWithRanges {
144138 candidate : CandidateRange {
145139 start : start_off. to_display_point ( map) ,
@@ -214,16 +208,35 @@ fn find_mini_delimiters(
214208 let visible_line_range = get_visible_line_range ( & line_range) ;
215209
216210 let snapshot = & map. buffer_snapshot ( ) ;
217- let excerpt = snapshot. excerpt_containing ( offset..offset) ?;
211+ let mut excerpt = snapshot. excerpt_containing ( offset..offset) ?;
218212 let buffer = excerpt. buffer ( ) ;
213+ let buffer_offset = excerpt. map_offset_to_buffer ( offset) ;
219214
220215 let bracket_filter = |open : Range < usize > , close : Range < usize > | {
221216 is_valid_delimiter ( buffer, open. start , close. start )
222217 } ;
223218
224219 // Try to find delimiters in visible range first
225- let ranges = map. buffer_snapshot ( ) . bracket_ranges ( visible_line_range) ;
226- if let Some ( candidate) = cover_or_next ( ranges, display_point, map, Some ( & bracket_filter) ) {
220+ let ranges = map
221+ . buffer_snapshot ( )
222+ . bracket_ranges ( visible_line_range)
223+ . map ( |ranges| {
224+ ranges. filter_map ( move |( open, close) | {
225+ // Convert the ranges from multibuffer space to buffer space as
226+ // that is what `is_valid_delimiter` expects, otherwise it might
227+ // panic as the values might be out of bounds.
228+ let buffer_open = excerpt. map_range_to_buffer ( open. clone ( ) ) ;
229+ let buffer_close = excerpt. map_range_to_buffer ( close. clone ( ) ) ;
230+
231+ if is_valid_delimiter ( buffer, buffer_open. start , buffer_close. start ) {
232+ Some ( ( open, close) )
233+ } else {
234+ None
235+ }
236+ } )
237+ } ) ;
238+
239+ if let Some ( candidate) = cover_or_next ( ranges, display_point, map) {
227240 return Some (
228241 DelimiterRange {
229242 open : candidate. open_range ,
@@ -234,8 +247,8 @@ fn find_mini_delimiters(
234247 }
235248
236249 // Fall back to innermost enclosing brackets
237- let ( open_bracket, close_bracket) =
238- buffer . innermost_enclosing_bracket_ranges ( offset..offset , Some ( & bracket_filter) ) ?;
250+ let ( open_bracket, close_bracket) = buffer
251+ . innermost_enclosing_bracket_ranges ( buffer_offset..buffer_offset , Some ( & bracket_filter) ) ?;
239252
240253 Some (
241254 DelimiterRange {
@@ -1736,8 +1749,10 @@ pub fn surrounding_markers(
17361749
17371750#[ cfg( test) ]
17381751mod test {
1752+ use editor:: { Editor , EditorMode , MultiBuffer , test:: editor_test_context:: EditorTestContext } ;
17391753 use gpui:: KeyBinding ;
17401754 use indoc:: indoc;
1755+ use text:: Point ;
17411756
17421757 use crate :: {
17431758 object:: { AnyBrackets , AnyQuotes , MiniBrackets } ,
@@ -3185,6 +3200,78 @@ mod test {
31853200 }
31863201 }
31873202
3203+ #[ gpui:: test]
3204+ async fn test_minibrackets_multibuffer ( cx : & mut gpui:: TestAppContext ) {
3205+ // Initialize test context with the TypeScript language loaded, so we
3206+ // can actually get brackets definition.
3207+ let mut cx = VimTestContext :: new ( cx, true ) . await ;
3208+
3209+ // Update `b` to `MiniBrackets` so we can later use it when simulating
3210+ // keystrokes.
3211+ cx. update ( |_, cx| {
3212+ cx. bind_keys ( [ KeyBinding :: new ( "b" , MiniBrackets , None ) ] ) ;
3213+ } ) ;
3214+
3215+ let ( editor, cx) = cx. add_window_view ( |window, cx| {
3216+ let multi_buffer = MultiBuffer :: build_multi (
3217+ [
3218+ ( "111\n 222\n 333\n 444\n " , vec ! [ Point :: row_range( 0 ..2 ) ] ) ,
3219+ ( "111\n a {bracket} example\n " , vec ! [ Point :: row_range( 0 ..2 ) ] ) ,
3220+ ] ,
3221+ cx,
3222+ ) ;
3223+
3224+ // In order for the brackets to actually be found, we need to update
3225+ // the language used for the second buffer. This is something that
3226+ // is handled automatically when simply using `VimTestContext::new`
3227+ // but, since this is being set manually, the language isn't
3228+ // automatically set.
3229+ let editor = Editor :: new ( EditorMode :: full ( ) , multi_buffer. clone ( ) , None , window, cx) ;
3230+ let buffer_ids = multi_buffer. read ( cx) . excerpt_buffer_ids ( ) ;
3231+ if let Some ( buffer) = multi_buffer. read ( cx) . buffer ( buffer_ids[ 1 ] ) {
3232+ buffer. update ( cx, |buffer, cx| {
3233+ buffer. set_language ( Some ( language:: rust_lang ( ) ) , cx) ;
3234+ } )
3235+ } ;
3236+
3237+ editor
3238+ } ) ;
3239+
3240+ let mut cx = EditorTestContext :: for_editor_in ( editor. clone ( ) , cx) . await ;
3241+
3242+ cx. assert_excerpts_with_selections ( indoc ! { "
3243+ [EXCERPT]
3244+ ˇ111
3245+ 222
3246+ [EXCERPT]
3247+ 111
3248+ a {bracket} example
3249+ "
3250+ } ) ;
3251+
3252+ cx. simulate_keystrokes ( "j j j j f r" ) ;
3253+ cx. assert_excerpts_with_selections ( indoc ! { "
3254+ [EXCERPT]
3255+ 111
3256+ 222
3257+ [EXCERPT]
3258+ 111
3259+ a {bˇracket} example
3260+ "
3261+ } ) ;
3262+
3263+ cx. simulate_keystrokes ( "d i b" ) ;
3264+ cx. assert_excerpts_with_selections ( indoc ! { "
3265+ [EXCERPT]
3266+ 111
3267+ 222
3268+ [EXCERPT]
3269+ 111
3270+ a {ˇ} example
3271+ "
3272+ } ) ;
3273+ }
3274+
31883275 #[ gpui:: test]
31893276 async fn test_minibrackets_trailing_space ( cx : & mut gpui:: TestAppContext ) {
31903277 let mut cx = NeovimBackedTestContext :: new ( cx) . await ;
0 commit comments