@@ -132,10 +132,9 @@ impl CommitList {
132132 commits
133133 }
134134
135- ///
136- pub fn copy_commit_hash ( & self ) -> Result < ( ) > {
137- let marked = self . marked . as_slice ( ) ;
138- let yank: Option < String > = match marked {
135+ /// Build string of marked or selected (if none are marked) commit ids
136+ fn concat_selected_commit_ids ( & self ) -> Option < String > {
137+ match self . marked . as_slice ( ) {
139138 [ ] => self
140139 . items
141140 . iter ( )
@@ -144,24 +143,19 @@ impl CommitList {
144143 . saturating_sub ( self . items . index_offset ( ) ) ,
145144 )
146145 . map ( |e| e. id . to_string ( ) ) ,
147- [ ( _idx, commit) ] => Some ( commit. to_string ( ) ) ,
148- [ first, .., last] => {
149- let marked_consecutive =
150- marked. windows ( 2 ) . all ( |w| w[ 0 ] . 0 + 1 == w[ 1 ] . 0 ) ;
151-
152- let yank = if marked_consecutive {
153- format ! ( "{}^..{}" , first. 1 , last. 1 )
154- } else {
155- marked
156- . iter ( )
157- . map ( |( _idx, commit) | commit. to_string ( ) )
158- . join ( " " )
159- } ;
160- Some ( yank)
161- }
162- } ;
146+ marked => Some (
147+ marked
148+ . iter ( )
149+ . map ( |( _idx, commit) | commit. to_string ( ) )
150+ . join ( " " ) ,
151+ ) ,
152+ }
153+ }
163154
164- if let Some ( yank) = yank {
155+ /// Copy currently marked or selected (if none are marked) commit ids
156+ /// to clipboard
157+ pub fn copy_commit_hash ( & self ) -> Result < ( ) > {
158+ if let Some ( yank) = self . concat_selected_commit_ids ( ) {
165159 crate :: clipboard:: copy_string ( & yank) ?;
166160 self . queue . push ( InternalEvent :: ShowInfoMsg (
167161 strings:: copy_success ( & yank) ,
@@ -893,8 +887,36 @@ impl Component for CommitList {
893887
894888#[ cfg( test) ]
895889mod tests {
890+ use asyncgit:: sync:: CommitInfo ;
891+
896892 use super :: * ;
897893
894+ impl Default for CommitList {
895+ fn default ( ) -> Self {
896+ Self {
897+ title : String :: from ( "" ) . into_boxed_str ( ) ,
898+ selection : 0 ,
899+ highlighted_selection : Option :: None ,
900+ highlights : Option :: None ,
901+ tags : Option :: None ,
902+ items : ItemBatch :: default ( ) ,
903+ commits : IndexSet :: default ( ) ,
904+ marked : Vec :: default ( ) ,
905+ scroll_top : Cell :: default ( ) ,
906+ local_branches : BTreeMap :: default ( ) ,
907+ remote_branches : BTreeMap :: default ( ) ,
908+ theme : SharedTheme :: default ( ) ,
909+ key_config : SharedKeyConfig :: default ( ) ,
910+ scroll_state : ( Instant :: now ( ) , 0.0 ) ,
911+ current_size : Cell :: default ( ) ,
912+ repo : RepoPathRef :: new ( sync:: RepoPath :: Path (
913+ std:: path:: PathBuf :: default ( ) ,
914+ ) ) ,
915+ queue : Queue :: default ( ) ,
916+ }
917+ }
918+ }
919+
898920 #[ test]
899921 fn test_string_width_align ( ) {
900922 assert_eq ! ( string_width_align( "123" , 3 ) , "123" ) ;
@@ -916,4 +938,121 @@ mod tests {
916938 "Jon Grythe Stødle "
917939 ) ;
918940 }
941+
942+ /// Build a commit list with a few commits loaded
943+ fn build_commit_list_with_some_commits ( ) -> CommitList {
944+ let mut items = ItemBatch :: default ( ) ;
945+ let basic_commit_info = CommitInfo {
946+ message : String :: default ( ) ,
947+ time : 0 ,
948+ author : String :: default ( ) ,
949+ id : CommitId :: default ( ) ,
950+ } ;
951+ // This just creates a sequence of fake ordered ids
952+ // 0000000000000000000000000000000000000000
953+ // 0000000000000000000000000000000000000001
954+ // 0000000000000000000000000000000000000002
955+ // ...
956+ items. set_items (
957+ 0 ,
958+ ( 0 ..10 )
959+ . map ( |idx| CommitInfo {
960+ id : CommitId :: from_str_unchecked ( & format ! (
961+ "{:040}" ,
962+ idx
963+ ) )
964+ . unwrap ( ) ,
965+ ..basic_commit_info. clone ( )
966+ } )
967+ . collect ( ) ,
968+ None ,
969+ ) ;
970+ CommitList {
971+ items : items,
972+ selection : 4 , // Randomly select one commit
973+ ..Default :: default ( )
974+ }
975+ }
976+
977+ /// Build a value for cl.marked based on indices into cl.items
978+ fn build_marked_from_indices (
979+ cl : & CommitList ,
980+ marked_indices : & [ usize ] ,
981+ ) -> Vec < ( usize , CommitId ) > {
982+ marked_indices
983+ . iter ( )
984+ . map ( |idx| ( * idx, cl. items . iter ( ) . nth ( * idx) . unwrap ( ) . id ) )
985+ . collect ( )
986+ }
987+
988+ #[ test]
989+ fn test_copy_commit_list_empty ( ) {
990+ assert_eq ! (
991+ CommitList :: default ( ) . concat_selected_commit_ids( ) ,
992+ None
993+ ) ;
994+ }
995+
996+ #[ test]
997+ fn test_copy_commit_none_marked ( ) {
998+ let cl = CommitList {
999+ selection : 4 ,
1000+ ..build_commit_list_with_some_commits ( )
1001+ } ;
1002+ assert_eq ! (
1003+ cl. concat_selected_commit_ids( ) ,
1004+ Some ( String :: from(
1005+ "0000000000000000000000000000000000000004"
1006+ ) )
1007+ ) ;
1008+ }
1009+
1010+ #[ test]
1011+ fn test_copy_commit_one_marked ( ) {
1012+ let cl = build_commit_list_with_some_commits ( ) ;
1013+ let cl = CommitList {
1014+ marked : build_marked_from_indices ( & cl, & vec ! [ 2 ] ) ,
1015+ ..cl
1016+ } ;
1017+ assert_eq ! (
1018+ cl. concat_selected_commit_ids( ) ,
1019+ Some ( String :: from(
1020+ "0000000000000000000000000000000000000002" ,
1021+ ) )
1022+ ) ;
1023+ }
1024+
1025+ #[ test]
1026+ fn test_copy_commit_range_marked ( ) {
1027+ let cl = build_commit_list_with_some_commits ( ) ;
1028+ let cl = CommitList {
1029+ marked : build_marked_from_indices ( & cl, & vec ! [ 4 , 5 , 6 , 7 ] ) ,
1030+ ..cl
1031+ } ;
1032+ assert_eq ! (
1033+ cl. concat_selected_commit_ids( ) ,
1034+ Some ( String :: from( concat!(
1035+ "0000000000000000000000000000000000000004 " ,
1036+ "0000000000000000000000000000000000000005 " ,
1037+ "0000000000000000000000000000000000000006 " ,
1038+ "0000000000000000000000000000000000000007"
1039+ ) ) )
1040+ ) ;
1041+ }
1042+
1043+ #[ test]
1044+ fn test_copy_commit_random_marked ( ) {
1045+ let cl = build_commit_list_with_some_commits ( ) ;
1046+ let cl = CommitList {
1047+ marked : build_marked_from_indices ( & cl, & vec ! [ 4 , 7 ] ) ,
1048+ ..cl
1049+ } ;
1050+ assert_eq ! (
1051+ cl. concat_selected_commit_ids( ) ,
1052+ Some ( String :: from( concat!(
1053+ "0000000000000000000000000000000000000004 " ,
1054+ "0000000000000000000000000000000000000007"
1055+ ) ) )
1056+ ) ;
1057+ }
9191058}
0 commit comments