Skip to content

Commit 9ec67ec

Browse files
committed
Show entire trailing information in register/stack
* Remove use of Table and replace it with Span/Text. In this way each row can have a diff length in every column instead of relying on all the other rows.
1 parent 185f2ae commit 9ec67ec

File tree

5 files changed

+89
-68
lines changed

5 files changed

+89
-68
lines changed

images/screenshot.png

-1.2 KB
Loading

src/snapshots/heretek__tests__render_app.snap

+6-6
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ snapshot_kind: text
1414
" rdi ➛ 0x1 "
1515
" rbp ➛ <rbp_0> ➛ <rbp_1> ➛ <rbp_2> ➛ 0x00 "
1616
"Stack───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"
17-
" <stack_0> ➛ <stack_6> ➛ <stack_6_0> ➛ <stack_6_1> ➛ <rbp_1> ➛ <rbp_2> ➛ 0x00 "
18-
" <stack_1> ➛ 0x40f022 ➛ malloc "
19-
" <stack_2> ➛ 0x494b00 ➛ sbb $0x0,%al "
20-
" <stack_3> ➛ 0x4a40e8 ➛ DW.ref.__gcc_pe "
17+
" <stack_0> ➛ <stack_6> ➛ <stack_6_0> ➛ <stack_6_1> ➛ <rbp_1> ➛ <rbp_2> ➛ 0x00 "
18+
" <stack_1> ➛ 0x40f022 ➛ malloc "
19+
" <stack_2> ➛ 0x494b00 ➛ sbb $0x0,%al "
20+
" <stack_3> ➛ 0x4a40e8 ➛ DW.ref.__gcc_personality_v0 "
2121
" <stack_4> ➛ 0x00 "
22-
" <stack_5> ➛ 0x4ab198 ➛ 0x00 "
23-
" <stack_6> ➛ <stack_6_0> ➛ <stack_6_1> ➛ <rbp_1> ➛ <rbp_2> ➛ 0x00 "
22+
" <stack_5> ➛ 0x4ab198 ➛ 0x00 "
23+
" <stack_6> ➛ <stack_6_0> ➛ <stack_6_1> ➛ <rbp_1> ➛ <rbp_2> ➛ 0x00 "
2424
" <stack_7> ➛ 0x01 "
2525
"Instructions (main)─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"
2626
" 0x401823 this+1e pop %rbp "

src/ui/mod.rs

+25-18
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use ratatui::layout::Constraint::{Fill, Length, Min};
22
use ratatui::layout::Layout;
33
use ratatui::style::Color;
44
use ratatui::style::Style;
5-
use ratatui::widgets::Cell;
5+
use ratatui::text::Span;
66
use ratatui::Frame;
77

88
use crate::deref::Deref;
@@ -108,24 +108,25 @@ pub fn ui(f: &mut Frame, app: &mut App) {
108108
}
109109

110110
/// Apply color to val
111-
pub fn apply_val_color(cell: &mut Cell, is_stack: bool, is_heap: bool, is_text: bool) {
111+
pub fn apply_val_color(span: &mut Span, is_stack: bool, is_heap: bool, is_text: bool) {
112112
// TOOD: remove clone
113113
if is_stack {
114-
*cell = cell.clone().style(Style::new().fg(STACK_COLOR))
114+
*span = span.clone().style(Style::new().fg(STACK_COLOR))
115115
} else if is_heap {
116-
*cell = cell.clone().style(Style::new().fg(HEAP_COLOR))
116+
*span = span.clone().style(Style::new().fg(HEAP_COLOR))
117117
} else if is_text {
118-
*cell = cell.clone().style(Style::new().fg(TEXT_COLOR))
118+
*span = span.clone().style(Style::new().fg(TEXT_COLOR))
119119
}
120120
}
121121

122-
/// Add deref value to cells
123-
pub fn add_deref_to_cell(
122+
/// Add deref value to span
123+
pub fn add_deref_to_span(
124124
deref: &Deref,
125-
cells: &mut Vec<Cell>,
125+
spans: &mut Vec<Span>,
126126
app: &App,
127127
filepath: &str,
128128
longest_cells: &mut usize,
129+
width: usize,
129130
) {
130131
for (i, v) in deref.map.iter().enumerate() {
131132
// check if ascii if last deref
@@ -136,27 +137,33 @@ pub fn add_deref_to_cell(
136137
.all(|a| a.is_ascii_alphabetic() || a.is_ascii_graphic() || a.is_ascii_whitespace())
137138
{
138139
if let Ok(s) = std::str::from_utf8(&bytes) {
139-
let cell = Cell::from(format!("➛ \"{}\"", s)).style(Style::new().fg(YELLOW));
140-
cells.push(cell);
140+
let cell = Span::from(format!("➛ \"{}\"", s)).style(Style::new().fg(YELLOW));
141+
spans.push(cell);
141142
continue;
142143
}
143144
}
144145
}
145146

146147
// if not, it's a value
147-
let mut cell = Cell::from(format!("➛ 0x{:02x}", v));
148+
let hex_string = format!("0x{:02x}", v);
149+
let hex_width = hex_string.len();
150+
let padding_width = width.saturating_sub(hex_width);
151+
let mut span =
152+
Span::from(format!("➛ {}{:padding$}", hex_string, "", padding = padding_width));
148153
let (is_stack, is_heap, is_text) = app.classify_val(*v, filepath);
149-
apply_val_color(&mut cell, is_stack, is_heap, is_text);
150-
cells.push(cell);
154+
apply_val_color(&mut span, is_stack, is_heap, is_text);
155+
spans.push(span);
151156
}
152157
if deref.repeated_pattern {
153-
cells.push(Cell::from("➛ [loop detected]").style(Style::new().fg(GRAY)));
158+
spans.push(Span::from("➛ [loop detected]").style(Style::new().fg(GRAY)));
154159
}
155160
if !deref.final_assembly.is_empty() {
156-
cells
157-
.push(Cell::from(format!("➛ {}", deref.final_assembly)).style(Style::new().fg(ORANGE)));
161+
spans.push(
162+
Span::from(format!("➛ {:width$}", deref.final_assembly, width = width))
163+
.style(Style::new().fg(ORANGE)),
164+
);
158165
}
159-
if cells.len() > *longest_cells {
160-
*longest_cells = cells.len();
166+
if spans.len() > *longest_cells {
167+
*longest_cells = spans.len();
161168
}
162169
}

src/ui/registers.rs

+37-24
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use std::path::PathBuf;
22
use std::sync::atomic::Ordering;
33

4-
use super::{add_deref_to_cell, ORANGE, PURPLE, RED};
4+
use super::{add_deref_to_span, apply_val_color, ORANGE, PURPLE, RED};
55

6-
use ratatui::layout::Constraint;
76
use ratatui::prelude::Stylize;
8-
use ratatui::widgets::{Block, Borders, Cell, Table};
9-
use ratatui::{layout::Rect, style::Style, widgets::Row, Frame};
7+
use ratatui::text::{Line, Span, Text};
8+
use ratatui::widgets::{Block, Borders, Paragraph};
9+
use ratatui::{layout::Rect, style::Style, Frame};
1010

1111
use crate::register::RegisterStorage;
1212
use crate::App;
@@ -15,7 +15,7 @@ use crate::App;
1515
pub fn draw_registers(app: &App, f: &mut Frame, register: Rect) {
1616
let block = Block::default().borders(Borders::TOP).title("Registers".fg(ORANGE));
1717

18-
let mut rows = vec![];
18+
let mut lines = vec![];
1919
let mut longest_register_name = 0;
2020
let mut longest_extra_val = 0;
2121

@@ -25,8 +25,17 @@ pub fn draw_registers(app: &App, f: &mut Frame, register: Rect) {
2525
return;
2626
}
2727

28+
// find longest register name
29+
// TODO: cache this
2830
let reg_changed_lock = app.register_changed.lock().unwrap();
2931
let filepath_lock = app.filepath.lock().unwrap();
32+
for RegisterStorage { name, register: _, deref: _ } in regs.iter() {
33+
if longest_register_name < name.len() {
34+
longest_register_name = name.len();
35+
}
36+
}
37+
let width: usize = if app.thirty_two_bit.load(Ordering::Relaxed) { 11 } else { 19 };
38+
3039
let empty = PathBuf::from("");
3140
let binding = filepath_lock.as_ref().unwrap_or(&empty);
3241
let filepath = binding.to_string_lossy();
@@ -38,44 +47,48 @@ pub fn draw_registers(app: &App, f: &mut Frame, register: Rect) {
3847
if let Some(reg_value) = &reg.value {
3948
if let Ok(val) = u64::from_str_radix(&reg_value[2..], 16) {
4049
let changed = reg_changed_lock.contains(&(i as u8));
41-
if longest_register_name < name.len() {
42-
longest_register_name = name.len();
43-
}
44-
let mut reg_name =
45-
Cell::from(format!(" {name}")).style(Style::new().fg(PURPLE));
50+
let mut reg_name = Span::from(format!(
51+
" {name:width$}",
52+
width = longest_register_name - 2
53+
))
54+
.style(Style::new().fg(PURPLE));
4655
let (is_stack, is_heap, is_text) = app.classify_val(val, &filepath);
4756

4857
let mut extra_derefs = Vec::new();
49-
add_deref_to_cell(
58+
add_deref_to_span(
5059
deref,
5160
&mut extra_derefs,
5261
app,
5362
&filepath,
5463
&mut longest_extra_val,
64+
width,
5565
);
5666

57-
let mut cell = Cell::from(format!("➛ {}", reg.value.clone().unwrap()));
58-
super::apply_val_color(&mut cell, is_stack, is_heap, is_text);
67+
let hex_string = format!("{}", reg.value.as_ref().unwrap());
68+
let hex_width = hex_string.len();
69+
let padding_width = width.saturating_sub(hex_width);
70+
let mut span = Span::from(format!(
71+
"➛ {}{:padding$}",
72+
hex_string,
73+
"",
74+
padding = padding_width
75+
));
76+
apply_val_color(&mut span, is_stack, is_heap, is_text);
5977

6078
// Apply color to reg name
6179
if changed {
6280
reg_name = reg_name.style(Style::new().fg(RED));
6381
}
64-
let mut row = vec![reg_name, cell];
65-
row.append(&mut extra_derefs);
66-
rows.push(Row::new(row));
82+
let mut line = Line::from(vec![reg_name, span]);
83+
line.spans.append(&mut extra_derefs);
84+
lines.push(line);
6785
}
6886
}
6987
}
7088
}
7189
}
7290

73-
let mut widths = vec![Constraint::Length(longest_register_name as u16)];
74-
if app.thirty_two_bit.load(Ordering::Relaxed) {
75-
widths.append(&mut vec![Constraint::Length(11); longest_extra_val + 1]);
76-
} else {
77-
widths.append(&mut vec![Constraint::Length(20); longest_extra_val + 1]);
78-
}
79-
let table = Table::new(rows, widths).block(block);
80-
f.render_widget(table, register);
91+
let text = Text::from(lines);
92+
let paragraph = Paragraph::new(text).block(block);
93+
f.render_widget(paragraph, register);
8194
}

src/ui/stack.rs

+21-20
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
use std::sync::atomic::Ordering;
22

3-
use ratatui::layout::Constraint;
43
use ratatui::prelude::Stylize;
5-
use ratatui::widgets::{Block, Borders, Cell, Table};
6-
use ratatui::{layout::Rect, style::Style, widgets::Row, Frame};
4+
use ratatui::text::{Line, Span, Text};
5+
use ratatui::widgets::{Block, Borders, Paragraph};
6+
use ratatui::{layout::Rect, style::Style, Frame};
77

8-
use super::{add_deref_to_cell, ORANGE, PURPLE};
8+
use super::{add_deref_to_span, ORANGE, PURPLE};
99

1010
use crate::App;
1111

1212
pub fn draw_stack(app: &App, f: &mut Frame, stack: Rect) {
13-
let mut rows = vec![];
13+
let block = Block::default().borders(Borders::TOP).title("Stack".fg(ORANGE));
14+
let mut lines = vec![];
1415
let mut longest_cells = 0;
16+
let width: usize = if app.thirty_two_bit.load(Ordering::Relaxed) { 11 } else { 19 };
17+
1518
if let Ok(stack) = app.stack.lock() {
1619
let mut entries: Vec<_> = stack.clone().into_iter().collect();
1720
entries.sort_by(|a, b| a.0.cmp(&b.0));
@@ -20,22 +23,20 @@ pub fn draw_stack(app: &App, f: &mut Frame, stack: Rect) {
2023
let binding = filepath_lock.as_ref().unwrap();
2124
let filepath = binding.to_string_lossy();
2225

23-
let addr = Cell::from(format!(" 0x{:02x}", addr)).style(Style::new().fg(PURPLE));
24-
let mut cells = vec![addr];
25-
add_deref_to_cell(values, &mut cells, app, &filepath, &mut longest_cells);
26-
let row = Row::new(cells);
27-
rows.push(row);
26+
let hex_string = format!("0x{:02x}", addr);
27+
let hex_width = hex_string.len();
28+
let padding_width = (width - 4).saturating_sub(hex_width);
29+
let span =
30+
Span::from(format!(" {}{:padding$}", hex_string, "", padding = padding_width))
31+
.style(Style::new().fg(PURPLE));
32+
let mut spans = vec![span];
33+
add_deref_to_span(values, &mut spans, app, &filepath, &mut longest_cells, width);
34+
let line = Line::from(spans);
35+
lines.push(line);
2836
}
2937
}
3038

31-
let mut widths = vec![Constraint::Length(16)];
32-
if app.thirty_two_bit.load(Ordering::Relaxed) {
33-
widths.append(&mut vec![Constraint::Length(20); longest_cells + 1]);
34-
} else {
35-
widths.append(&mut vec![Constraint::Length(20); longest_cells + 1]);
36-
}
37-
let table = Table::new(rows, widths)
38-
.block(Block::default().borders(Borders::TOP).title("Stack".fg(ORANGE)));
39-
40-
f.render_widget(table, stack);
39+
let text = Text::from(lines);
40+
let paragraph = Paragraph::new(text).block(block);
41+
f.render_widget(paragraph, stack);
4142
}

0 commit comments

Comments
 (0)