Skip to content

Commit

Permalink
Merge pull request #69 from sigmaSd/autosync
Browse files Browse the repository at this point in the history
Implement Autosync
sigmaSd authored Sep 29, 2020
2 parents 11dc313 + af807d2 commit 0b59dfd
Showing 5 changed files with 450 additions and 162 deletions.
244 changes: 233 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ dirs-next = "1.0.1"
once_cell = "1.4.1"
toml = "0.5.6"
serde = { version = "1.0.116", features = ["derive"] }
notify = "4.0.15"

[target.'cfg(unix)'.dependencies]
nix = "0.18.0"
351 changes: 202 additions & 149 deletions src/irust.rs
Original file line number Diff line number Diff line change
@@ -96,163 +96,216 @@ impl IRust {
enable_raw_mode()?;
self.prepare()?;

let (tx, rx) = channel();
watch(tx.clone());
let input_thread = input_read(tx);

loop {
// flush queued output after each key
// some events that have an inner input loop like ctrl-r/ ctrl-d require flushing inside their respective handler function
self.raw_terminal.flush()?;

// handle input event
if let Ok(key_event) = read() {
match key_event {
Event::Mouse(_) => (),
Event::Resize(width, height) => {
// ctrlc so we can ignore a lot of position adjusting
// TODO fix this
self.handle_ctrl_c()?;
self.cursor = Cursor::new(width.into(), height.into());
}
Event::Key(key_event) => match key_event {
KeyEvent {
code: KeyCode::Char(c),
modifiers: NO_MODIFIER,
}
| KeyEvent {
code: KeyCode::Char(c),
modifiers: SHIFT_KEYMODIFIER,
} => {
match rx.recv() {
Ok(IRustEvent::Input(ev)) => {
self.handle_input_event(ev)?;
input_thread.thread().unpark();
}
Ok(IRustEvent::Notify(_ev)) => {
self.sync()?;
}
Err(_e) => (),
}
}
}

fn handle_input_event(&mut self, ev: crossterm::event::Event) -> Result<(), IRustError> {
// handle input event
match ev {
Event::Mouse(_) => (),
Event::Resize(width, height) => {
// ctrlc so we can ignore a lot of position adjusting
// TODO fix this
self.handle_ctrl_c()?;
self.cursor = Cursor::new(width.into(), height.into());
}
Event::Key(key_event) => match key_event {
KeyEvent {
code: KeyCode::Char(c),
modifiers: NO_MODIFIER,
}
| KeyEvent {
code: KeyCode::Char(c),
modifiers: SHIFT_KEYMODIFIER,
} => {
self.handle_character(c)?;
}
KeyEvent {
code: KeyCode::Char('e'),
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_e()?;
}
KeyEvent {
code: KeyCode::Enter,
..
} => {
self.handle_enter(false)?;
}
KeyEvent {
code: KeyCode::Tab, ..
} => {
self.handle_tab()?;
}
KeyEvent {
code: KeyCode::BackTab,
..
} => {
self.handle_back_tab()?;
}
KeyEvent {
code: KeyCode::Left,
modifiers: NO_MODIFIER,
} => {
self.handle_left()?;
}
KeyEvent {
code: KeyCode::Right,
modifiers: NO_MODIFIER,
} => {
self.handle_right()?;
}
KeyEvent {
code: KeyCode::Up, ..
} => {
self.handle_up()?;
}
KeyEvent {
code: KeyCode::Down,
..
} => {
self.handle_down()?;
}
KeyEvent {
code: KeyCode::Backspace,
..
} => {
self.handle_backspace()?;
}
KeyEvent {
code: KeyCode::Char('c'),
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_c()?;
}
KeyEvent {
code: KeyCode::Char('d'),
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_d()?;
}
KeyEvent {
code: KeyCode::Char('z'),
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_z()?;
}
KeyEvent {
code: KeyCode::Char('l'),
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_l()?;
}
KeyEvent {
code: KeyCode::Char('r'),
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_r()?;
}
KeyEvent {
code: KeyCode::Char('\r'),
modifiers: ALT_KEYMODIFIER,
} => {
self.handle_alt_enter()?;
}
KeyEvent {
code: KeyCode::Home,
..
} => {
self.handle_home_key()?;
}
KeyEvent {
code: KeyCode::End, ..
} => {
self.handle_end_key()?;
}
KeyEvent {
code: KeyCode::Left,
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_left();
}
KeyEvent {
code: KeyCode::Right,
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_right();
}
KeyEvent {
code: KeyCode::Delete,
..
} => {
self.handle_del()?;
}
keyevent => {
// Handle AltGr on windows
if keyevent
.modifiers
.contains(CTRL_KEYMODIFIER | ALT_KEYMODIFIER)
{
if let KeyCode::Char(c) = keyevent.code {
self.handle_character(c)?;
}
KeyEvent {
code: KeyCode::Char('e'),
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_e()?;
}
KeyEvent {
code: KeyCode::Enter,
..
} => {
self.handle_enter(false)?;
}
KeyEvent {
code: KeyCode::Tab, ..
} => {
self.handle_tab()?;
}
KeyEvent {
code: KeyCode::BackTab,
..
} => {
self.handle_back_tab()?;
}
KeyEvent {
code: KeyCode::Left,
modifiers: NO_MODIFIER,
} => {
self.handle_left()?;
}
KeyEvent {
code: KeyCode::Right,
modifiers: NO_MODIFIER,
} => {
self.handle_right()?;
}
KeyEvent {
code: KeyCode::Up, ..
} => {
self.handle_up()?;
}
KeyEvent {
code: KeyCode::Down,
..
} => {
self.handle_down()?;
}
KeyEvent {
code: KeyCode::Backspace,
..
} => {
self.handle_backspace()?;
}
KeyEvent {
code: KeyCode::Char('c'),
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_c()?;
}
KeyEvent {
code: KeyCode::Char('d'),
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_d()?;
}
KeyEvent {
code: KeyCode::Char('z'),
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_z()?;
}
KeyEvent {
code: KeyCode::Char('l'),
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_l()?;
}
KeyEvent {
code: KeyCode::Char('r'),
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_r()?;
}
KeyEvent {
code: KeyCode::Char('\r'),
modifiers: ALT_KEYMODIFIER,
} => {
self.handle_alt_enter()?;
}
KeyEvent {
code: KeyCode::Home,
..
} => {
self.handle_home_key()?;
}
KeyEvent {
code: KeyCode::End, ..
} => {
self.handle_end_key()?;
}
KeyEvent {
code: KeyCode::Left,
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_left();
}
KeyEvent {
code: KeyCode::Right,
modifiers: CTRL_KEYMODIFIER,
} => {
self.handle_ctrl_right();
}
KeyEvent {
code: KeyCode::Delete,
..
} => {
self.handle_del()?;
}
keyevent => {
// Handle AltGr on windows
if keyevent
.modifiers
.contains(CTRL_KEYMODIFIER | ALT_KEYMODIFIER)
{
if let KeyCode::Char(c) = keyevent.code {
self.handle_character(c)?;
}
}
}
},
}
}
}
},
}
Ok(())
}
}
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use std::sync::mpsc::channel;
use std::sync::mpsc::Sender;
use std::time::Duration;

fn watch(tx: Sender<IRustEvent>) {
std::thread::spawn(move || loop {
let (local_tx, local_rx) = channel();
let mut watcher: RecommendedWatcher =
Watcher::new(local_tx, Duration::from_secs(2)).expect("Watcher Thread paniced");

watcher
.watch(&*cargo_cmds::MAIN_FILE_EXTERN, RecursiveMode::Recursive)
.expect("Error while trying to watch main_extern file for changes");

if let Ok(ev) = local_rx.recv() {
tx.send(IRustEvent::Notify(ev))
.expect("Error sending notify event to IRust main thread");
}
});
}

use std::thread;
fn input_read(tx: Sender<IRustEvent>) -> std::thread::JoinHandle<()> {
std::thread::spawn(move || loop {
if let Ok(ev) = read() {
tx.send(IRustEvent::Input(ev))
.expect("Error reading input event");
thread::park();
}
})
}

pub enum IRustEvent {
Input(crossterm::event::Event),
Notify(notify::DebouncedEvent),
}
2 changes: 1 addition & 1 deletion src/irust/parser.rs
Original file line number Diff line number Diff line change
@@ -337,7 +337,7 @@ impl IRust {
}
}

fn sync(&mut self) -> Result<Printer, IRustError> {
pub fn sync(&mut self) -> Result<Printer, IRustError> {
match self.repl.update_from_main_file() {
Ok(_) => Ok(Printer::new(PrinterItem::new(
SUCCESS.to_string(),
14 changes: 13 additions & 1 deletion src/irust/repl.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,19 @@ impl Repl {
}

pub fn update_from_main_file(&mut self) -> Result<(), IRustError> {
let main_file = std::fs::read_to_string(&*MAIN_FILE_EXTERN)?;
let mut try_n = 0;
let main_file = loop {
let main_file = std::fs::read_to_string(&*MAIN_FILE_EXTERN)?;
if !main_file.is_empty() || try_n > 1 {
break main_file;
} else {
// Some editors trancuate the file before saving (exp: vscode)
// Give them some time
use std::time::Duration;
std::thread::sleep(Duration::from_secs(1));
try_n += 1;
}
};
let lines_num = main_file.lines().count();
if lines_num < 2 {
return Err(IRustError::Custom(

0 comments on commit 0b59dfd

Please sign in to comment.