Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid consuming CPU when waiting for input. #651

Merged
merged 2 commits into from
Nov 1, 2023
Merged
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
119 changes: 58 additions & 61 deletions src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -725,77 +725,74 @@
}
}

if event::poll(Duration::from_millis(100))? {
let mut latest_resize = None;

// There could be multiple events queued up!
// pasting text, resizes, blocking this thread (e.g. during debugging)
// We should be able to handle all of them as quickly as possible without causing unnecessary output steps.
while event::poll(Duration::from_millis(POLL_WAIT))? {
match event::read()? {
Event::Resize(x, y) => {
latest_resize = Some((x, y));
}
enter @ Event::Key(KeyEvent {
code: KeyCode::Enter,
modifiers: KeyModifiers::NONE,
..
}) => {
let enter = ReedlineRawEvent::convert_from(enter);
match enter {
Some(enter) => {
crossterm_events.push(enter);
// Break early to check if the input is complete and
// can be send to the hosting application. If
// multiple complete entries are submitted, events
// are still in the crossterm queue for us to
// process.
paste_enter_state = crossterm_events.len() > EVENTS_THRESHOLD;
break;
}
None => continue,
}
let mut latest_resize = None;

Check warning on line 728 in src/engine.rs

View check run for this annotation

Codecov / codecov/patch

src/engine.rs#L728

Added line #L728 was not covered by tests
loop {
match event::read()? {
Event::Resize(x, y) => {
latest_resize = Some((x, y));
}
enter @ Event::Key(KeyEvent {
code: KeyCode::Enter,
modifiers: KeyModifiers::NONE,
..
}) => {
let enter = ReedlineRawEvent::convert_from(enter);
if let Some(enter) = enter {
crossterm_events.push(enter);
// Break early to check if the input is complete and
// can be send to the hosting application. If
// multiple complete entries are submitted, events
// are still in the crossterm queue for us to
// process.
paste_enter_state = crossterm_events.len() > EVENTS_THRESHOLD;
break;

Check warning on line 748 in src/engine.rs

View check run for this annotation

Codecov / codecov/patch

src/engine.rs#L730-L748

Added lines #L730 - L748 were not covered by tests
}
x => {
let raw_event = ReedlineRawEvent::convert_from(x);
match raw_event {
Some(evt) => crossterm_events.push(evt),
None => continue,
}
}
x => {
let raw_event = ReedlineRawEvent::convert_from(x);
if let Some(evt) = raw_event {
crossterm_events.push(evt);

Check warning on line 754 in src/engine.rs

View check run for this annotation

Codecov / codecov/patch

src/engine.rs#L751-L754

Added lines #L751 - L754 were not covered by tests
}
}
}

if let Some((x, y)) = latest_resize {
reedline_events.push(ReedlineEvent::Resize(x, y));
// There could be multiple events queued up!
// pasting text, resizes, blocking this thread (e.g. during debugging)
// We should be able to handle all of them as quickly as possible without causing unnecessary output steps.
if !event::poll(Duration::from_millis(POLL_WAIT))? {
break;

Check warning on line 763 in src/engine.rs

View check run for this annotation

Codecov / codecov/patch

src/engine.rs#L762-L763

Added lines #L762 - L763 were not covered by tests
}
}

// Accelerate pasted text by fusing `EditCommand`s
//
// (Text should only be `EditCommand::InsertChar`s)
let mut last_edit_commands = None;
for event in crossterm_events.drain(..) {
match (&mut last_edit_commands, self.edit_mode.parse_event(event)) {
(None, ReedlineEvent::Edit(ec)) => {
last_edit_commands = Some(ec);
}
(None, other_event) => {
reedline_events.push(other_event);
}
(Some(ref mut last_ecs), ReedlineEvent::Edit(ec)) => {
last_ecs.extend(ec);
}
(ref mut a @ Some(_), other_event) => {
reedline_events.push(ReedlineEvent::Edit(a.take().unwrap()));
if let Some((x, y)) = latest_resize {
reedline_events.push(ReedlineEvent::Resize(x, y));
}

Check warning on line 769 in src/engine.rs

View check run for this annotation

Codecov / codecov/patch

src/engine.rs#L767-L769

Added lines #L767 - L769 were not covered by tests

reedline_events.push(other_event);
}
// Accelerate pasted text by fusing `EditCommand`s
//
// (Text should only be `EditCommand::InsertChar`s)
let mut last_edit_commands = None;
for event in crossterm_events.drain(..) {
match (&mut last_edit_commands, self.edit_mode.parse_event(event)) {
(None, ReedlineEvent::Edit(ec)) => {
last_edit_commands = Some(ec);
}
(None, other_event) => {
reedline_events.push(other_event);
}
(Some(ref mut last_ecs), ReedlineEvent::Edit(ec)) => {
last_ecs.extend(ec);
}
(ref mut a @ Some(_), other_event) => {
reedline_events.push(ReedlineEvent::Edit(a.take().unwrap()));

reedline_events.push(other_event);

Check warning on line 789 in src/engine.rs

View check run for this annotation

Codecov / codecov/patch

src/engine.rs#L774-L789

Added lines #L774 - L789 were not covered by tests
}
}
if let Some(ec) = last_edit_commands {
reedline_events.push(ReedlineEvent::Edit(ec));
}
};
}
if let Some(ec) = last_edit_commands {
reedline_events.push(ReedlineEvent::Edit(ec));
}

Check warning on line 795 in src/engine.rs

View check run for this annotation

Codecov / codecov/patch

src/engine.rs#L793-L795

Added lines #L793 - L795 were not covered by tests

for event in reedline_events.drain(..) {
match self.handle_event(prompt, event)? {
Expand Down