@@ -914,6 +914,9 @@ pub struct RoomInfo {
914914 /// The display names for users in this room.
915915 pub display_names : HashMap < OwnedUserId , String > ,
916916
917+ /// Tab completion for the display names in this room.
918+ pub display_name_completion : CompletionMap < String , OwnedUserId > ,
919+
917920 /// The last time the room was rendered, used to detect if it is currently open.
918921 pub draw_last : Option < Instant > ,
919922}
@@ -935,6 +938,7 @@ impl Default for RoomInfo {
935938 fetch_last : Default :: default ( ) ,
936939 users_typing : Default :: default ( ) ,
937940 display_names : Default :: default ( ) ,
941+ display_name_completion : Default :: default ( ) ,
938942 draw_last : Default :: default ( ) ,
939943 }
940944 }
@@ -1960,7 +1964,9 @@ impl Completer<IambInfo> for IambCompleter {
19601964 match content {
19611965 IambBufferId :: Command ( CommandType :: Command ) => complete_cmdbar ( text, cursor, store) ,
19621966 IambBufferId :: Command ( CommandType :: Search ) => vec ! [ ] ,
1963- IambBufferId :: Room ( _, _, RoomFocus :: MessageBar ) => complete_msgbar ( text, cursor, store) ,
1967+ IambBufferId :: Room ( room_id, _, RoomFocus :: MessageBar ) => {
1968+ complete_msgbar ( text, cursor, store, room_id)
1969+ } ,
19641970 IambBufferId :: Room ( _, _, RoomFocus :: Scrollback ) => vec ! [ ] ,
19651971
19661972 IambBufferId :: DirectList => vec ! [ ] ,
@@ -1991,12 +1997,19 @@ fn complete_users(text: &EditRope, cursor: &mut Cursor, store: &ChatStore) -> Ve
19911997}
19921998
19931999/// Tab completion within the message bar.
1994- fn complete_msgbar ( text : & EditRope , cursor : & mut Cursor , store : & ChatStore ) -> Vec < String > {
2000+ fn complete_msgbar (
2001+ text : & EditRope ,
2002+ cursor : & mut Cursor ,
2003+ store : & mut ChatStore ,
2004+ room_id : & RoomId ,
2005+ ) -> Vec < String > {
19952006 let id = text
19962007 . get_prefix_word_mut ( cursor, & MATRIX_ID_WORD )
19972008 . unwrap_or_else ( EditRope :: empty) ;
19982009 let id = Cow :: from ( & id) ;
19992010
2011+ let info = store. rooms . get_or_default ( room_id. to_owned ( ) ) ;
2012+
20002013 match id. chars ( ) . next ( ) {
20012014 // Complete room aliases.
20022015 Some ( '#' ) => {
@@ -2028,12 +2041,29 @@ fn complete_msgbar(text: &EditRope, cursor: &mut Cursor, store: &ChatStore) -> V
20282041
20292042 // Complete usernames for @ and empty strings.
20302043 Some ( '@' ) | None => {
2031- store
2032- . presences
2033- . complete ( id. as_ref ( ) )
2044+ // spec says to mention with display name in anchor text
2045+ let mut users: HashSet < _ > = info
2046+ . display_name_completion
2047+ . complete ( id. strip_prefix ( '@' ) . unwrap ( ) )
20342048 . into_iter ( )
2035- . map ( |i| format ! ( "[{}]({})" , i, i. matrix_to_uri( ) ) )
2036- . collect ( )
2049+ . map ( |n| {
2050+ format ! (
2051+ "[{}]({})" ,
2052+ n,
2053+ info. display_name_completion. get( & n) . unwrap( ) . matrix_to_uri( )
2054+ )
2055+ } )
2056+ . collect ( ) ;
2057+
2058+ users. extend ( store. presences . complete ( id. as_ref ( ) ) . into_iter ( ) . map ( |i| {
2059+ format ! (
2060+ "[{}]({})" ,
2061+ info. display_names. get( & i) . unwrap_or( & i. to_string( ) ) ,
2062+ i. matrix_to_uri( )
2063+ )
2064+ } ) ) ;
2065+
2066+ users. into_iter ( ) . collect ( )
20372067 } ,
20382068
20392069 // Unknown sigil.
@@ -2314,23 +2344,30 @@ pub mod tests {
23142344 #[ tokio:: test]
23152345 async fn test_complete_msgbar ( ) {
23162346 let store = mock_store ( ) . await ;
2317- let store = store. application ;
2347+ let mut store = store. application ;
2348+ let room_id = TEST_ROOM1_ID . clone ( ) ;
23182349
23192350 let text = EditRope :: from ( "going for a walk :walk " ) ;
23202351 let mut cursor = Cursor :: new ( 0 , 22 ) ;
2321- let res = complete_msgbar ( & text, & mut cursor, & store) ;
2352+ let res = complete_msgbar ( & text, & mut cursor, & mut store, & room_id ) ;
23222353 assert_eq ! ( res, vec![ ":walking:" , ":walking_man:" , ":walking_woman:" ] ) ;
23232354 assert_eq ! ( cursor, Cursor :: new( 0 , 17 ) ) ;
23242355
23252356 let text = EditRope :: from ( "hello @user1 " ) ;
23262357 let mut cursor = Cursor :: new ( 0 , 12 ) ;
2327- let res = complete_msgbar ( & text, & mut cursor, & store) ;
2358+ let res = complete_msgbar ( & text, & mut cursor, & mut store, & room_id ) ;
23282359 assert_eq ! ( res, vec" ] ) ;
23292360 assert_eq ! ( cursor, Cursor :: new( 0 , 6 ) ) ;
23302361
2362+ let text = EditRope :: from ( "hello @user2 " ) ;
2363+ let mut cursor = Cursor :: new ( 0 , 12 ) ;
2364+ let res = complete_msgbar ( & text, & mut cursor, & mut store, & room_id) ;
2365+ assert_eq ! ( res, vec" ] ) ;
2366+ assert_eq ! ( cursor, Cursor :: new( 0 , 6 ) ) ;
2367+
23312368 let text = EditRope :: from ( "see #room " ) ;
23322369 let mut cursor = Cursor :: new ( 0 , 9 ) ;
2333- let res = complete_msgbar ( & text, & mut cursor, & store) ;
2370+ let res = complete_msgbar ( & text, & mut cursor, & mut store, & room_id ) ;
23342371 assert_eq ! ( res, vec" ] ) ;
23352372 assert_eq ! ( cursor, Cursor :: new( 0 , 4 ) ) ;
23362373 }
0 commit comments