Skip to content

Commit 2c97025

Browse files
committed
Function diff: Implement "Go to line number"
1 parent 7834185 commit 2c97025

4 files changed

Lines changed: 72 additions & 0 deletions

File tree

objdiff-gui/src/hotkeys.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,9 @@ const CHANGE_BASE_SHORTCUT: KeyboardShortcut = KeyboardShortcut::new(Modifiers::
106106
pub fn consume_change_base_shortcut(ctx: &Context) -> bool {
107107
ctx.input_mut(|i| i.consume_shortcut(&CHANGE_BASE_SHORTCUT))
108108
}
109+
110+
const GO_TO_SHORTCUT: KeyboardShortcut = KeyboardShortcut::new(Modifiers::CTRL, Key::G);
111+
112+
pub fn consume_go_to_shortcut(ctx: &Context) -> bool {
113+
ctx.input_mut(|i| i.consume_shortcut(&GO_TO_SHORTCUT))
114+
}

objdiff-gui/src/views/diff.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,28 @@ fn get_asm_text(
116116
asm_text
117117
}
118118

119+
fn try_scroll_to_line_number(
120+
scroll_to_line_number: Option<u32>,
121+
obj: &Object,
122+
diff: &ObjectDiff,
123+
symbol_idx: usize,
124+
) -> Option<DiffViewAction> {
125+
let target_line = scroll_to_line_number?;
126+
let symbol = obj.symbols.get(symbol_idx)?;
127+
let section_index = symbol.section?;
128+
let section = &obj.sections[section_index];
129+
for (ins_idx, ins_row) in diff.symbols[symbol_idx].instruction_rows.iter().enumerate() {
130+
if let Some(ins_ref) = ins_row.ins_ref
131+
&& let Some(current_line) =
132+
section.line_info.range(..=ins_ref.address).last().map(|(_, &b)| b)
133+
&& current_line == target_line
134+
{
135+
return Some(DiffViewAction::ScrollToRow(ins_idx));
136+
}
137+
}
138+
None
139+
}
140+
119141
#[must_use]
120142
pub fn diff_view_ui(
121143
ui: &mut Ui,
@@ -450,6 +472,23 @@ pub fn diff_view_ui(
450472
{
451473
ret = Some(DiffViewAction::SelectingRight(symbol_ref.clone()));
452474
}
475+
needs_separator = true;
476+
}
477+
if state.current_view == View::FunctionDiff {
478+
if needs_separator {
479+
ui.separator();
480+
}
481+
let mut goto_line_text = state.function_state.go_to_line_text.clone();
482+
let response = TextEdit::singleline(&mut goto_line_text)
483+
.hint_text("Go to line number")
484+
.desired_width(100.0)
485+
.ui(ui);
486+
if hotkeys::consume_go_to_shortcut(ui.ctx()) {
487+
response.request_focus();
488+
}
489+
if response.changed() {
490+
ret = Some(DiffViewAction::SetGoToText(goto_line_text));
491+
}
453492
}
454493
} else if right_ctx.status.success && !right_ctx.has_symbol() {
455494
let mut search = state.search.clone();
@@ -492,6 +531,14 @@ pub fn diff_view_ui(
492531
ui.label("Instruction count mismatch");
493532
return;
494533
}
534+
if let Some(action) = try_scroll_to_line_number(
535+
state.function_state.scroll_to_line_number,
536+
right_obj,
537+
right_diff,
538+
right_symbol_idx,
539+
) {
540+
ret = Some(action);
541+
}
495542
let instructions_len = left_symbol_diff.instruction_rows.len();
496543
render_table(
497544
ui,
@@ -711,6 +758,14 @@ fn diff_col_ui(
711758
},
712759
);
713760
} else {
761+
if let Some(action) = try_scroll_to_line_number(
762+
state.function_state.scroll_to_line_number,
763+
obj,
764+
diff,
765+
symbol_idx,
766+
) {
767+
ret = Some(action);
768+
}
714769
render_table(
715770
ui,
716771
available_width / 2.0,

objdiff-gui/src/views/function_diff.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ pub struct FunctionViewState {
2525
left_highlight: HighlightKind,
2626
right_highlight: HighlightKind,
2727
pub scroll_to_row: Option<usize>,
28+
pub scroll_to_line_number: Option<u32>,
29+
pub go_to_line_text: String,
2830
}
2931

3032
impl FunctionViewState {

objdiff-gui/src/views/symbol_diff.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ pub enum DiffViewAction {
8383
SetShowDataFlow(bool),
8484
// Scrolls a row of the function view table into view.
8585
ScrollToRow(usize),
86+
/// Sets the text of the line number jump field and try to scroll that line into view.
87+
SetGoToText(String),
8688
}
8789

8890
#[derive(Debug, Clone, Default, Eq, PartialEq)]
@@ -198,6 +200,7 @@ impl DiffViewState {
198200
// Clear the scroll flags to prevent it from scrolling continuously.
199201
self.symbol_state.autoscroll_to_highlighted_symbols = false;
200202
self.function_state.scroll_to_row = None;
203+
self.function_state.scroll_to_line_number = None;
201204

202205
let Some(action) = action else {
203206
return;
@@ -368,6 +371,12 @@ impl DiffViewState {
368371
DiffViewAction::ScrollToRow(row) => {
369372
self.function_state.scroll_to_row = Some(row);
370373
}
374+
DiffViewAction::SetGoToText(text) => {
375+
if let Ok(line_num) = text.trim().parse::<u32>() {
376+
self.function_state.scroll_to_line_number = Some(line_num);
377+
}
378+
self.function_state.go_to_line_text = text;
379+
}
371380
}
372381
}
373382

0 commit comments

Comments
 (0)