Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ main
----

- Improved property rendering
- Introduced theme concept
- Introduced themes (including solarized and solarized dark)
- Show value of variables on current line
- Support `extended_properties` #5

Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Debug-TUI
=========

Interactive XDebug step debugger for your terminal with vim-like key bindings.
Interactive [Xdebug](https://xdebug.org) step-debugging client your terminal.

![Screenshot](https://github.com/user-attachments/assets/9f938d2b-717b-4816-bb35-9f317f82a0a3)

Expand Down Expand Up @@ -38,11 +38,12 @@ Prefix with number to repeat:
- `-` decrease context depth
- `tab` switch pane
- `enter` toggle pane focus (full screen)
- `t` rotate the theme
- `?` Show help

## Setting Breakpoints

`xdebug-tui` has no mechanism for setting a breakpoint but you can use the
`debug-tui` has no mechanism for setting a breakpoint but you can use the
function `xdebug_break()` in your code:

```php
Expand Down
4 changes: 2 additions & 2 deletions php/test.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

$arra😸ay = [
$array = [
'int' => 123,
'float' => 123.4,
'string' => "string",
Expand All @@ -14,7 +14,7 @@
];
$a = 2;
$foo = $a;
$foo = $arra😸ay;
$foo = $array;

$bar = $foo;

Expand Down
6 changes: 5 additions & 1 deletion src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ impl App {
counter: 0,
context_depth: 4,

theme: Theme::Dark,
theme: Theme::SolarizedDark,
server_status: None,
command_input: Input::default(),
command_response: None,
Expand Down Expand Up @@ -380,6 +380,10 @@ impl App {
AppEvent::PushInputPlurality(char) => self.input_plurality.push(char),
AppEvent::Input(key_event) => {
match key_event.code {
KeyCode::Char('t') => {
self.theme = self.theme.next();
self.notification = Notification::info(format!("Switched to theme: {:?}", self.theme));
},
KeyCode::Char('?') => {
self.sender.send(AppEvent::ChangeView(CurrentView::Help)).await.unwrap();
},
Expand Down
1 change: 1 addition & 0 deletions src/event/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub enum AppEvent {
ScrollStack(i16),
PushInputPlurality(char),
ContextDepth(i8),
NextTheme,
}

pub type EventSender = Sender<AppEvent>;
Expand Down
111 changes: 106 additions & 5 deletions src/theme.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,63 @@
use ratatui::style::{Color, Style};
use ratatui::style::Color;
use ratatui::style::Style;

#[derive(Debug)]
pub enum Theme {
Dark,
SolarizedDark,
SolarizedLight,
}

impl Theme {
pub fn next(&self) -> Theme {
match self {
Theme::Dark => Self::SolarizedDark,
Theme::SolarizedDark => Self::SolarizedLight,
Theme::SolarizedLight => Self::Dark,
}
}
pub fn scheme(&self) -> Scheme {
match self {
Theme::Dark => Scheme{
Theme::SolarizedLight => {
let mut scheme = Self::SolarizedDark.scheme();
scheme.background = Style::default().bg(Solarized::Base3.to_color());

scheme.widget_active = Style::default().fg(Solarized::Green.to_color()).bg(Solarized::Base2.to_color());
scheme.widget_inactive = Style::default().fg(Solarized::Base03.to_color()).bg(Solarized::Base3.to_color());
scheme.source_line = scheme.source_line.fg(Solarized::Base00.to_color());
scheme.source_line_highlight = scheme.source_line_highlight.bg(Solarized::Base2.to_color()).fg(Solarized::Base01.to_color());

scheme.widget_mode_debug = scheme.widget_mode_debug.fg(Solarized::Base03.to_color()).bg(Solarized::Base3.to_color());
scheme.widget_mode_history = scheme.widget_mode_debug.bg(Solarized::Base3.to_color()).fg(Solarized::Red.to_color());

return scheme;
}
Theme::SolarizedDark => Scheme{
syntax_variable: Style::default().fg(Solarized::Base00.to_color()),
syntax_type: Style::default().fg(Solarized::Cyan.to_color()),
syntax_type_object: Style::default().fg(Solarized::Orange.to_color()),
syntax_literal: Style::default().fg(Solarized::Blue.to_color()),
syntax_literal_string: Style::default().fg(Solarized::Green.to_color()),
syntax_label: Style::default().fg(Solarized::Base00.to_color()),
syntax_brace: Style::default().fg(Solarized::Base01.to_color()),
notification_info: Style::default().fg(Solarized::Green.to_color()),
notification_error: Style::default().fg(Solarized::Red.to_color()),
pane_border_active: Style::default().fg(Solarized::Base01.to_color()),
pane_border_inactive: Style::default().fg(Solarized::Base02.to_color()),
source_line: Style::default().fg(Solarized::Base1.to_color()),
source_line_no: Style::default().fg(Solarized::Yellow.to_color()),
source_line_highlight: Style::default().bg(Solarized::Base02.to_color()).fg(Solarized::Base3.to_color()),
source_annotation: Style::default().fg(Solarized::Magenta.to_color()),
stack_line: Style::default().fg(Solarized::Base1.to_color()),

widget_active: Style::default().fg(Solarized::Base02.to_color()).bg(Solarized::Green.to_color()),
widget_inactive: Style::default().fg(Solarized::Base1.to_color()).bg(Solarized::Base03.to_color()),
widget_mode_debug: Style::default().fg(Solarized::Base1.to_color()).bg(Solarized::Base03.to_color()),
widget_mode_history: Style::default().fg(Solarized::Red.to_color()).bg(Solarized::Base03.to_color()),

background: Style::default().bg(Color::Black),
},
Theme::Dark => Scheme {
syntax_variable: Style::default().fg(Color::LightBlue),
syntax_type: Style::default().fg(Color::LightRed),
syntax_type_object: Style::default().fg(Color::LightMagenta),
Expand All @@ -22,18 +72,25 @@ impl Theme {
pane_border_active: Style::default().fg(Color::Green),
pane_border_inactive: Style::default().fg(Color::DarkGray),

source_line: Style::default(),
source_line: Style::default().fg(Color::White),
source_line_no: Style::default().fg(Color::Yellow),
source_line_highlight: Style::default().bg(Color::Blue),
source_annotation: Style::default().fg(Color::DarkGray),

stack_line: Style::default().fg(Color::White),

widget_active: Style::default().fg(Color::Black).bg(Color::Green),
widget_inactive: Style::default().fg(Color::Black).bg(Color::Yellow),
widget_mode_debug: Style::default().bg(Color::Blue),
widget_mode_history: Style::default().bg(Color::Red),
background: Style::default().bg(Color::Black),
},
}
}
}

pub struct Scheme {
pub background: Style,
pub syntax_variable: Style,
pub syntax_type: Style,
pub syntax_type_object: Style,
Expand All @@ -54,9 +111,53 @@ pub struct Scheme {
pub source_annotation: Style,

pub stack_line: Style,
}

pub enum Role {
pub widget_active: Style,
pub widget_inactive: Style,
pub widget_mode_debug: Style,
pub widget_mode_history: Style,
}

pub enum Role {}

pub enum Solarized {
Base03,
Base02,
Base01,
Base00,
Base0,
Base1,
Base2,
Base3,
Yellow,
Orange,
Red,
Magenta,
Violet,
Blue,
Cyan,
Green,
}

impl Solarized {
fn to_color(&self) -> Color {
match self {
Solarized::Base03 => Color::Rgb(0, 43, 54),
Solarized::Base02 => Color::Rgb(7, 54, 66),
Solarized::Base01 => Color::Rgb(88, 110, 117),
Solarized::Base00 => Color::Rgb(101, 123, 131),
Solarized::Base0 => Color::Rgb(131, 148, 150),
Solarized::Base1 => Color::Rgb(147, 161, 161),
Solarized::Base2 => Color::Rgb(238, 232, 213),
Solarized::Base3 => Color::Rgb(253, 246, 227),
Solarized::Yellow => Color::Rgb(181, 137, 0),
Solarized::Orange => Color::Rgb(203, 75, 22),
Solarized::Red => Color::Rgb(220, 50, 47),
Solarized::Magenta => Color::Rgb(211, 54, 130),
Solarized::Violet => Color::Rgb(108, 113, 196),
Solarized::Blue => Color::Rgb(38, 139, 210),
Solarized::Cyan => Color::Rgb(42, 161, 152),
Solarized::Green => Color::Rgb(133, 153, 0),
}
}
}
1 change: 1 addition & 0 deletions src/view/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Key mappings (prefix with number to repeat):
[K] scroll up 10
[+] increase context depth
[-] decrease context depth
[t] rotate the theme
[enter] toggle pane focus (full screen)

Legend:
Expand Down
70 changes: 30 additions & 40 deletions src/view/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@ use crate::notification::NotificationLevel;
use ratatui::layout::Constraint;
use ratatui::layout::Layout;
use ratatui::layout::Rect;
use ratatui::style::Color;
use ratatui::style::Modifier;
use ratatui::style::Style;
use ratatui::style::Stylize;
use ratatui::text::Line;
use ratatui::text::Span;
use ratatui::widgets::Clear;
use ratatui::widgets::Block;
use ratatui::widgets::Paragraph;
use ratatui::Frame;

Expand All @@ -28,17 +25,14 @@ impl View for LayoutView {
}

fn draw(app: &App, f: &mut Frame, area: Rect) {
let constraints = vec![
Constraint::Length(1),
Constraint::Min(4),
];
let constraints = vec![Constraint::Length(1), Constraint::Min(4)];

let rows = Layout::default()
.margin(0)
.constraints(constraints)
.split(area);

f.render_widget(Clear::default(), rows[0]);
f.render_widget(Block::default().style(app.theme().background), area);
f.render_widget(status_widget(app), rows[0]);

match app.view_current {
Expand All @@ -54,47 +48,43 @@ fn status_widget(app: &App) -> Paragraph {
Span::styled(
format!(
" 󱘖 {} ",
if app.is_connected { "".to_string() } else { app.config.listen.to_string() }
if app.is_connected {
"connected".to_string()
} else {
app.config.listen.to_string()
}
),
Style::default()
.add_modifier(Modifier::BOLD)
.bg(match app.is_connected {
false => Color::Yellow,
true => Color::Green,
})
.fg(match app.is_connected {
false => Color::Black,
true => Color::Black,
}),
match app.is_connected {
false => app.theme().widget_inactive,
true => app.theme().widget_active,
},
),
Span::styled(
format!("  {:<3} ", app.history.current().map_or("n/a".to_string(), |entry| {
entry.stack.depth().to_string()
})),
Style::default()
.bg(Color::Magenta)
.bold()
.fg(Color::White),

format!(
"  {:<3} ",
app.history.current().map_or("n/a".to_string(), |entry| {
entry.stack.depth().to_string()
})
),
app.theme().widget_inactive,
),
Span::styled(
(match app.session_view.mode {
SessionViewMode::Current => match app.is_connected {
true => format!("  {} / ∞", app.history.offset + 1),
false => "  0 / 0".to_string(),
},
SessionViewMode::History => format!(
SessionViewMode::Current => match app.is_connected {
true => format!("  {} / ∞", app.history.offset + 1),
false => "  0 / 0".to_string(),
},
SessionViewMode::History => format!(
"  {} / {} history [p] to go back [n] to go forwards [b] to return",
app.history.offset + 1,
app.history.len()
),
}).to_string(),
Style::default().bg(
match app.session_view.mode {
SessionViewMode::Current => Color::Blue,
SessionViewMode::History => Color::Red,
}
),
})
.to_string(),
match app.session_view.mode {
SessionViewMode::Current => app.theme().widget_mode_debug,
SessionViewMode::History => app.theme().widget_mode_history,
},
),
Span::styled(
match app.notification.is_visible() {
Expand Down
2 changes: 0 additions & 2 deletions src/view/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use ratatui::layout::Layout;
use ratatui::layout::Rect;
use ratatui::widgets::Block;
use ratatui::widgets::Borders;
use ratatui::widgets::Clear;
use ratatui::Frame;

pub struct SessionView {}
Expand Down Expand Up @@ -131,7 +130,6 @@ fn build_pane_widget(frame: &mut Frame, app: &App, pane: &Pane, area: Rect, inde
);

frame.render_widget(&block, area);
frame.render_widget(Clear::default(), block.inner(area));

match pane.component_type {
ComponentType::Source => {
Expand Down