@@ -4,7 +4,7 @@ use objdiff_core::{
4
4
diff:: {
5
5
DiffObjConfig , ObjectDiff , SymbolDiff ,
6
6
data:: BYTES_PER_ROW ,
7
- display:: { ContextItem , HoverItem , HoverItemColor , SymbolFilter , SymbolNavigationKind } ,
7
+ display:: { ContextItem , HoverItem , HoverItemColor , SymbolFilter , SymbolNavigationKind , display_row } ,
8
8
} ,
9
9
obj:: { Object , Symbol } ,
10
10
} ;
@@ -64,6 +64,26 @@ impl<'a> DiffColumnContext<'a> {
64
64
pub fn id ( & self ) -> Option < & str > { self . symbol . map ( |( symbol, _, _) | symbol. name . as_str ( ) ) }
65
65
}
66
66
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
+
67
87
#[ must_use]
68
88
pub fn diff_view_ui (
69
89
ui : & mut Ui ,
@@ -208,16 +228,35 @@ pub fn diff_view_ui(
208
228
209
229
// Third row
210
230
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
+ } ) ;
221
260
} else if left_ctx. status . success && !left_ctx. has_symbol ( ) {
222
261
ui. horizontal ( |ui| {
223
262
let mut search = state. search . clone ( ) ;
@@ -374,6 +413,20 @@ pub fn diff_view_ui(
374
413
{
375
414
ret = Some ( DiffViewAction :: SelectingRight ( symbol_ref. clone ( ) ) ) ;
376
415
}
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
+ }
377
430
}
378
431
} else if right_ctx. status . success && !right_ctx. has_symbol ( ) {
379
432
let mut search = state. search . clone ( ) ;
0 commit comments