Skip to content

Commit b7b711a

Browse files
committed
Refactorings and bug fixes
1 parent 806aea5 commit b7b711a

File tree

12 files changed

+91
-99
lines changed

12 files changed

+91
-99
lines changed

src/app.rs

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ impl App {
447447
}
448448
}
449449
AppEvent::Listen => {
450+
self.channels.reset();
450451
self.listening_status = ListenStatus::Listening;
451452
self.view_current = SelectedView::Listen;
452453
self.session_view.mode = SessionViewMode::Current;
@@ -554,6 +555,10 @@ impl App {
554555
AppEvent::Disconnect => {
555556
let _ = self.client.lock().await.deref_mut().disonnect().await;
556557
self.listening_status = ListenStatus::Refusing;
558+
559+
// capture any remaining stdout/stderr
560+
self.channels.savepoint(self.history.offset).await;
561+
self.focus_current_channel();
557562
self.sender
558563
.send(AppEvent::ChangeSessionViewMode(SessionViewMode::History))
559564
.await?;
@@ -568,7 +573,8 @@ impl App {
568573
}
569574
}
570575
AppEvent::NextChannel => {
571-
self.session_view.eval_state.channel = (self.session_view.eval_state.channel + 1) % self.channels.count()
576+
self.session_view.eval_state.channel = (self.session_view.eval_state.channel + 1) % self.channels.count();
577+
self.focus_current_channel();
572578
},
573579
AppEvent::NotifyError(message) => {
574580
self.notification = Notification::error(message);
@@ -811,28 +817,6 @@ impl App {
811817
entry.push(stack);
812818
}
813819

814-
// *xdebug* only evalutes expressions on the current stack frame
815-
let eval = if !self.session_view.eval_state.input.to_string().is_empty() {
816-
let response = self
817-
.client
818-
.lock()
819-
.await
820-
.eval(
821-
self.session_view.eval_state.input.to_string(),
822-
self.session_view.stack_depth(),
823-
)
824-
.await?;
825-
826-
Some(EvalEntry{
827-
expr: self.session_view.eval_state.input.to_string(),
828-
response
829-
})
830-
} else {
831-
None
832-
};
833-
834-
entry.eval = eval;
835-
836820
self.session_view.reset();
837821
self.history.push(entry);
838822
self.channels.savepoint(self.history.offset).await;
@@ -877,6 +861,10 @@ impl App {
877861
self.session_view
878862
.scroll_to_line(entry.source(self.session_view.stack_depth()).line_no)
879863
}
864+
self.focus_current_channel();
865+
}
866+
867+
fn focus_current_channel(&mut self) {
880868
if let Some(c) = self.channels.channel_by_offset(self.session_view.eval_state.channel) { self.focus_channel(c.name.clone()) }
881869
}
882870

src/channel.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,7 @@ impl Channel {
9696
content[0..*offset].lines().map(|s|s.to_string()).collect()
9797
}
9898
Entry::Vacant(_) => {
99-
match self.current_offset {
100-
// if we previously resolved a snapshot then use that
101-
Some(current_offset) => {
102-
content[0..current_offset].lines().map(|s|s.to_string()).collect()
103-
},
104-
None => {
105-
content.lines().map(|s|s.to_string()).collect()
106-
}
107-
}
99+
vec![]
108100
}
109101
};
110102
}

src/php_process.rs

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::{process::Stdio, str::from_utf8};
2-
use tokio::io::AsyncReadExt;
2+
use tokio::io::{AsyncReadExt, Stdout};
33

4+
use tokio::process::{ChildStderr, ChildStdout};
45
use tokio::select;
56
use tokio::sync::mpsc::Receiver;
67
use tokio::{io::BufReader, process::Command, sync::mpsc::Sender, task};
@@ -13,22 +14,16 @@ pub enum ProcessEvent {
1314
Stop,
1415
}
1516

16-
pub fn process_manager_start(
17-
receiver: Receiver<ProcessEvent>,
18-
parent_sender: Sender<AppEvent>,
19-
) {
17+
pub fn process_manager_start(receiver: Receiver<ProcessEvent>, parent_sender: Sender<AppEvent>) {
2018
task::spawn(async move {
2119
match process_manager_loop(receiver, parent_sender.clone()).await {
2220
Ok(_) => (),
2321
Err(e) => {
2422
parent_sender
25-
.send(AppEvent::ChannelLog(
26-
"notice".to_string(),
27-
e.to_string(),
28-
))
23+
.send(AppEvent::ChannelLog("notice".to_string(), e.to_string()))
2924
.await
3025
.unwrap_or_default();
31-
},
26+
}
3227
};
3328
});
3429
}
@@ -39,10 +34,12 @@ async fn process_manager_loop(
3934
) -> Result<(), anyhow::Error> {
4035
loop {
4136
let cmd = receiver.recv().await;
37+
4238
let event = match cmd {
4339
Some(event) => event,
4440
None => continue,
4541
};
42+
4643
let args = match event {
4744
ProcessEvent::Start(args) => args,
4845
ProcessEvent::Stop => continue,
@@ -61,58 +58,35 @@ async fn process_manager_loop(
6158
.args(&args[1..])
6259
.spawn()?;
6360

64-
let mut stdoutreader = BufReader::new(process.stdout.take().unwrap());
65-
let mut stderrreader = BufReader::new(process.stderr.take().unwrap());
6661

6762
let sender = parent_sender.clone();
6863

69-
let io_task = task::spawn(async move {
70-
loop {
71-
let mut stdout_buff = [0; 255];
72-
let mut stderr_buff = [0; 255];
73-
74-
select! {
75-
read = stdoutreader.read(&mut stdout_buff) => {
76-
if let Ok(s) = from_utf8(&stdout_buff[..read.unwrap()]) {
77-
if s.is_empty() {
78-
return;
79-
}
80-
sender
81-
.send(AppEvent::ChannelLog("stdout".to_string(), s.to_string()))
82-
.await.unwrap_or_default();
83-
};
84-
},
85-
read = stderrreader.read(&mut stderr_buff) => {
86-
if let Ok(s) = from_utf8(&stderr_buff[..read.unwrap()]) {
87-
if s.is_empty() {
88-
return;
89-
}
90-
sender
91-
.send(
92-
AppEvent::ChannelLog("stderr".to_string(), s.to_string())
93-
).await.unwrap_or_default();
94-
};
95-
},
96-
};
97-
}
98-
});
64+
let io_task = task::spawn(io_loop(
65+
process.stdout.take().unwrap(),
66+
process.stderr.take().unwrap(),
67+
sender
68+
));
9969

10070
let sender = parent_sender.clone();
71+
10172
loop {
10273
select! {
10374
exit_code = process.wait() => {
104-
if let Ok(exit_code) = exit_code {
105-
if exit_code.code().unwrap_or_default() != 0 {
106-
let _ = sender.send(
107-
AppEvent::NotifyError(
108-
format!(
109-
"Process '{:?}' exited with code {}",
110-
args,
111-
exit_code.code().unwrap_or_default()
112-
)
75+
let exit_code = match exit_code {
76+
Ok(e) => e,
77+
// if we
78+
Err(_) => break,
79+
};
80+
if exit_code.code().unwrap_or_default() != 0 {
81+
let _ = sender.send(
82+
AppEvent::NotifyError(
83+
format!(
84+
"Process '{:?}' exited with code {}",
85+
args,
86+
exit_code.code().unwrap_or_default()
11387
)
114-
).await;
115-
}
88+
)
89+
).await;
11690
}
11791
break;
11892
},
@@ -134,3 +108,41 @@ async fn process_manager_loop(
134108
}
135109
}
136110
}
111+
112+
async fn io_loop(
113+
stdout: ChildStdout,
114+
stderr: ChildStderr,
115+
sender: Sender<AppEvent>,
116+
) {
117+
118+
let mut stdoutreader = BufReader::new(stdout);
119+
let mut stderrreader = BufReader::new(stderr);
120+
loop {
121+
let mut stdout_buff = [0; 255];
122+
let mut stderr_buff = [0; 255];
123+
124+
select! {
125+
read = stdoutreader.read(&mut stdout_buff) => {
126+
if let Ok(s) = from_utf8(&stdout_buff[..read.unwrap()]) {
127+
if s.is_empty() {
128+
return;
129+
}
130+
sender
131+
.send(AppEvent::ChannelLog("stdout".to_string(), s.to_string()))
132+
.await.unwrap_or_default();
133+
};
134+
},
135+
read = stderrreader.read(&mut stderr_buff) => {
136+
if let Ok(s) = from_utf8(&stderr_buff[..read.unwrap()]) {
137+
if s.is_empty() {
138+
return;
139+
}
140+
sender
141+
.send(
142+
AppEvent::ChannelLog("stderr".to_string(), s.to_string())
143+
).await.unwrap_or_default();
144+
};
145+
},
146+
};
147+
}
148+
}

src/view/context.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl View for ContextComponent {
4545
}
4646
}
4747

48-
fn draw(app: &App, frame: &mut Frame, _inner_area: Rect, area: Rect) {
48+
fn draw(app: &App, frame: &mut Frame, inner_area: Rect, _area: Rect) {
4949
let entry = match app.history.current() {
5050
Some(e) => e,
5151
None => return,
@@ -61,18 +61,18 @@ impl View for ContextComponent {
6161
.constraints([Constraint::Length(
6262
if app.session_view.context_filter.show { 3 } else { 0 }
6363
), Constraint::Min(1)]);
64-
let areas = layout.split(area);
64+
let areas = layout.split(inner_area);
6565

6666
frame.render_widget(Paragraph::new(Line::from(vec![
6767
Span::raw(app.session_view.context_filter.input.value()).style(app.theme().text_input),
6868
])
6969
).block(Block::default().borders(Borders::all())), areas[0]);
7070

7171
if app.session_view.context_filter.show {
72-
let width = area.width.max(3);
72+
let width = inner_area.width.max(3);
7373
let scroll = app.session_view.context_filter.input.visual_scroll(width as usize);
7474
let x = app.session_view.context_filter.input.visual_cursor().max(scroll) - scroll + 1;
75-
frame.set_cursor_position((area.x + x as u16, area.y + 1));
75+
frame.set_cursor_position((inner_area.x + x as u16, inner_area.y + 1));
7676
}
7777

7878
let mut filter_path = app.session_view.context_filter.segments().clone();

src/view/eval.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ impl View for EvalDialog {
102102
}
103103
}
104104

105-
fn draw(app: &App, frame: &mut Frame, _inner_area: Rect, area: Rect) {
106-
let darea = centered_rect_absolute(area.width - 10, 3, area);
105+
fn draw(app: &App, frame: &mut Frame, inner_area: Rect, _area: Rect) {
106+
let darea = centered_rect_absolute(inner_area.width - 10, 3, inner_area);
107107
frame.render_widget(Clear, darea);
108108
frame.render_widget(
109109
Paragraph::new(Line::from(vec![Span::raw(

src/view/help.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ impl View for HelpView {
2121
}
2222
}
2323

24-
fn draw(_app: &App, frame: &mut Frame, _inner_area: Rect, area: Rect) {
24+
fn draw(_app: &App, frame: &mut Frame, inner_area: Rect, _area: Rect) {
2525

26-
frame.render_widget(Paragraph::new(help()), area);
26+
frame.render_widget(Paragraph::new(help()), inner_area);
2727

2828
}
2929
}

src/view/layout.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ impl View for LayoutView {
2727
None
2828
}
2929

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

3333
let rows = Layout::default()

src/view/listen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ impl View for ListenView {
1313
None
1414
}
1515

16-
fn draw(app: &App, frame: &mut Frame, _inner_area: Rect, area: Rect) {
16+
fn draw(app: &App, frame: &mut Frame, area: Rect, _outer_area: Rect) {
1717

1818
let block = Block::default()
1919
.borders(Borders::all())

src/view/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use ratatui::Frame;
1717

1818
pub trait View {
1919
fn handle(app: &mut App, event: AppEvent) -> Option<AppEvent>;
20-
fn draw(app: &App, frame: &mut Frame, inner_area: Rect, area: Rect);
20+
fn draw(app: &App, frame: &mut Frame, area: Rect, outer_area: Rect);
2121
}
2222

2323
#[derive(Debug)]

src/view/session.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ impl View for SessionView {
104104
delegate_event_to_pane(app, event)
105105
}
106106

107-
fn draw(app: &App, frame: &mut Frame, _inner_area: ratatui::prelude::Rect, area: Rect) {
107+
fn draw(app: &App, frame: &mut Frame, area: ratatui::prelude::Rect, _area: Rect) {
108108
if app.session_view.full_screen {
109109
build_pane_widget(
110110
frame,

0 commit comments

Comments
 (0)