Skip to content

Commit

Permalink
Redraw UI when returning from external editor
Browse files Browse the repository at this point in the history
Forces _tui_ to redraw the whole app when returning from the external editor. This is acheived by creating a static channel for sending "app commands".
  • Loading branch information
jonstodle committed Jun 9, 2020
1 parent 3a4b31d commit 71deeda
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 2 deletions.
8 changes: 8 additions & 0 deletions src/components/commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::{
textinput::TextInputComponent, visibility_blocking,
CommandBlocking, CommandInfo, Component, DrawableComponent,
};
use crate::poll::QueueEvent;
use crate::strings::COMMIT_EDITOR_MSG;
use crate::{
get_app_config_path,
Expand Down Expand Up @@ -133,6 +134,13 @@ impl CommitComponent {
crate::poll::SHOULD_DO_POLL
.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
Command::new(command).args(editor).status()?;
// safety: this is set during app setup, and _should_ never be mutated again
unsafe {
crate::COMMANDS_CHANNEL
.as_ref()
.unwrap()
.send(QueueEvent::FullRedraw)?
}
crate::poll::SHOULD_DO_POLL
.fetch_add(1, std::sync::atomic::Ordering::SeqCst);

Expand Down
19 changes: 17 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![forbid(unsafe_code)]
// #![forbid(unsafe_code)]
#![deny(clippy::cargo)]
//TODO: remove once crossterm upgraded to current mio:
//https://github.com/crossterm-rs/crossterm/issues/432
Expand Down Expand Up @@ -29,7 +29,7 @@ use clap::{
crate_authors, crate_description, crate_name, crate_version,
App as ClapApp, Arg,
};
use crossbeam_channel::{tick, unbounded, Receiver, Select};
use crossbeam_channel::{tick, unbounded, Receiver, Select, Sender};
use crossterm::{
terminal::{
disable_raw_mode, enable_raw_mode, EnterAlternateScreen,
Expand Down Expand Up @@ -58,6 +58,8 @@ use tui::{
static TICK_INTERVAL: Duration = Duration::from_secs(5);
static SPINNER_INTERVAL: Duration = Duration::from_millis(50);

static mut COMMANDS_CHANNEL: Option<Sender<QueueEvent>> = None;

fn main() -> Result<()> {
process_cmdline()?;

Expand All @@ -75,6 +77,12 @@ fn main() -> Result<()> {

let mut terminal = start_terminal(io::stdout())?;

let (tx_commands, rx_commands) = unbounded();
// safety: the app hasn't started running yet, so this variable is not yet in use
unsafe {
COMMANDS_CHANNEL = Some(tx_commands);
}

let (tx_git, rx_git) = unbounded();

let mut app = App::new(&tx_git);
Expand All @@ -94,6 +102,7 @@ fn main() -> Result<()> {
&rx_git,
&ticker,
&spinner_ticker,
&rx_commands,
)?;

{
Expand All @@ -110,6 +119,9 @@ fn main() -> Result<()> {
needs_draw = false;
spinner.update()
}
QueueEvent::FullRedraw => {
terminal.resize(terminal.size()?)?
}
}
}

Expand Down Expand Up @@ -161,6 +173,7 @@ fn select_event(
rx_git: &Receiver<AsyncNotification>,
rx_ticker: &Receiver<Instant>,
rx_spinner: &Receiver<Instant>,
rx_commands: &Receiver<QueueEvent>,
) -> Result<Vec<QueueEvent>> {
let mut events: Vec<QueueEvent> = Vec::new();

Expand All @@ -170,6 +183,7 @@ fn select_event(
sel.recv(rx_git);
sel.recv(rx_ticker);
sel.recv(rx_spinner);
sel.recv(rx_commands);

let oper = sel.select();
let index = oper.index();
Expand All @@ -185,6 +199,7 @@ fn select_event(
3 => oper
.recv(rx_spinner)
.map(|_| events.push(QueueEvent::SpinnerUpdate)),
4 => oper.recv(rx_commands).map(|ev| events.push(ev)),
_ => return Err(anyhow!("unknown select source")),
}?;

Expand Down
1 change: 1 addition & 0 deletions src/poll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub enum QueueEvent {
SpinnerUpdate,
GitEvent(AsyncNotification),
InputEvent(Event),
FullRedraw,
}

static MAX_POLL_DURATION: Duration = Duration::from_secs(2);
Expand Down

0 comments on commit 71deeda

Please sign in to comment.