@@ -4,7 +4,7 @@ use objdiff_core::{
44 diff:: {
55 DiffObjConfig , ObjectDiff , SymbolDiff ,
66 data:: BYTES_PER_ROW ,
7- display:: { ContextItem , HoverItem , HoverItemColor , SymbolFilter , SymbolNavigationKind } ,
7+ display:: { ContextItem , HoverItem , HoverItemColor , SymbolFilter , SymbolNavigationKind , display_row } ,
88 } ,
99 obj:: { Object , Symbol } ,
1010} ;
@@ -64,6 +64,26 @@ impl<'a> DiffColumnContext<'a> {
6464 pub fn id ( & self ) -> Option < & str > { self . symbol . map ( |( symbol, _, _) | symbol. name . as_str ( ) ) }
6565}
6666
67+ /// Obtains the assembly text for a given symbol diff, suitable for copying to clipboard.
68+ fn get_asm_text ( obj : & Object , symbol_diff : & SymbolDiff , symbol_idx : usize , diff_config : & DiffObjConfig ) -> String {
69+ let mut asm_text = String :: new ( ) ;
70+
71+ for ins_row in & symbol_diff. instruction_rows {
72+ let mut line = String :: new ( ) ;
73+ let result = display_row ( obj, symbol_idx, ins_row, diff_config, |segment| {
74+ line. push_str ( & segment. text ) ;
75+ Ok ( ( ) )
76+ } ) ;
77+
78+ if result. is_ok ( ) {
79+ asm_text. push_str ( & line) ;
80+ asm_text. push ( '\n' ) ;
81+ }
82+ }
83+
84+ asm_text
85+ }
86+
6787#[ must_use]
6888pub fn diff_view_ui (
6989 ui : & mut Ui ,
@@ -208,16 +228,35 @@ pub fn diff_view_ui(
208228
209229 // Third row
210230 if left_ctx. has_symbol ( ) && right_ctx. has_symbol ( ) {
211- if ( state. current_view == View :: FunctionDiff
212- && ui
213- . button ( "Change target" )
214- . on_hover_text_at_pointer ( "Choose a different symbol to use as the target" )
215- . clicked ( )
216- || hotkeys:: consume_change_target_shortcut ( ui. ctx ( ) ) )
217- && let Some ( symbol_ref) = state. symbol_state . right_symbol . as_ref ( )
218- {
219- ret = Some ( DiffViewAction :: SelectingLeft ( symbol_ref. clone ( ) ) ) ;
220- }
231+ ui. horizontal ( |ui| {
232+ if state. current_view == View :: FunctionDiff
233+ && ui
234+ . button ( "Change target" )
235+ . on_hover_text_at_pointer ( "Choose a different symbol to use as the target" )
236+ . clicked ( )
237+ || hotkeys:: consume_change_target_shortcut ( ui. ctx ( ) )
238+ {
239+ if let Some ( symbol_ref) = state. symbol_state . right_symbol . as_ref ( ) {
240+ ret = Some ( DiffViewAction :: SelectingLeft ( symbol_ref. clone ( ) ) ) ;
241+ }
242+ }
243+
244+ // Copy target ASM button.
245+ if state. current_view == View :: FunctionDiff {
246+ if let Some ( ( _, symbol_diff, symbol_idx) ) = left_ctx. symbol {
247+ if let Some ( ( obj, _) ) = left_ctx. obj {
248+ if ui
249+ . button ( "Copy ASM" )
250+ . on_hover_text_at_pointer ( "Copy assembly to clipboard" )
251+ . clicked ( )
252+ {
253+ let asm_text = get_asm_text ( obj, symbol_diff, symbol_idx, diff_config) ;
254+ ui. ctx ( ) . copy_text ( asm_text) ;
255+ }
256+ }
257+ }
258+ }
259+ } ) ;
221260 } else if left_ctx. status . success && !left_ctx. has_symbol ( ) {
222261 ui. horizontal ( |ui| {
223262 let mut search = state. search . clone ( ) ;
@@ -374,6 +413,20 @@ pub fn diff_view_ui(
374413 {
375414 ret = Some ( DiffViewAction :: SelectingRight ( symbol_ref. clone ( ) ) ) ;
376415 }
416+
417+ /// Copy base ASM button.
418+ if let Some ( ( _, symbol_diff, symbol_idx) ) = right_ctx. symbol {
419+ if let Some ( ( obj, _) ) = right_ctx. obj {
420+ if ui
421+ . button ( "Copy ASM" )
422+ . on_hover_text_at_pointer ( "Copy assembly to clipboard" )
423+ . clicked ( )
424+ {
425+ let asm_text = get_asm_text ( obj, symbol_diff, symbol_idx, diff_config) ;
426+ ui. ctx ( ) . copy_text ( asm_text) ;
427+ }
428+ }
429+ }
377430 }
378431 } else if right_ctx. status . success && !right_ctx. has_symbol ( ) {
379432 let mut search = state. search . clone ( ) ;
0 commit comments