Skip to content

Commit 8d52c0f

Browse files
committed
Update diff.rs
1 parent 2ad0898 commit 8d52c0f

File tree

1 file changed

+64
-11
lines changed

1 file changed

+64
-11
lines changed

objdiff-gui/src/views/diff.rs

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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]
6888
pub 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

Comments
 (0)