Fix create mode, refactor readers, fix init focus

pull/3/head
Arijit Basu 3 years ago
parent c2bc8aee20
commit c0ca596539
No known key found for this signature in database
GPG Key ID: 7D7BF809E7378863

2
Cargo.lock generated

@ -1123,7 +1123,7 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]] [[package]]
name = "xplr" name = "xplr"
version = "0.2.11" version = "0.2.12"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"criterion", "criterion",

@ -1,6 +1,6 @@
[package] [package]
name = "xplr" name = "xplr"
version = "0.2.11" # Update app.rs version = "0.2.12" # Update app.rs
authors = ["Arijit Basu <sayanarijit@gmail.com>"] authors = ["Arijit Basu <sayanarijit@gmail.com>"]
edition = "2018" edition = "2018"
description = "An experimental, minimal, configurable TUI file explorer, stealing ideas from nnn and fzf." description = "An experimental, minimal, configurable TUI file explorer, stealing ideas from nnn and fzf."

@ -13,7 +13,7 @@ use std::fs;
use std::io; use std::io;
use std::path::PathBuf; use std::path::PathBuf;
pub const VERSION: &str = "v0.2.11"; // Update Cargo.toml pub const VERSION: &str = "v0.2.12"; // Update Cargo.toml
pub const TEMPLATE_TABLE_ROW: &str = "TEMPLATE_TABLE_ROW"; pub const TEMPLATE_TABLE_ROW: &str = "TEMPLATE_TABLE_ROW";

@ -280,6 +280,7 @@ impl Default for KeyBindings {
- Call: - Call:
command: bash command: bash
args: [] args: []
- Explore
/: /:
help: search help: search
@ -521,7 +522,7 @@ impl Default for Config {
name: create name: create
key_bindings: key_bindings:
on_key: on_key:
f: enter:
help: create file help: create file
messages: messages:
- Call: - Call:
@ -534,7 +535,7 @@ impl Default for Config {
- SwitchMode: default - SwitchMode: default
- Explore - Explore
d: ctrl-d:
help: create directory help: create directory
messages: messages:
- Call: - Call:

@ -0,0 +1,35 @@
use crate::app::Task;
use crate::app::{ExternalMsg, InternalMsg, MsgIn};
use crate::input::Key;
use crossterm::event::{self, Event};
use std::sync::mpsc::{Receiver, Sender};
use std::thread;
pub fn keep_reading(tx_msg_in: Sender<Task>, rx_event_reader: Receiver<bool>) {
thread::spawn(move || {
let mut is_paused = false;
loop {
if let Some(paused) = rx_event_reader.try_recv().ok() {
is_paused = paused;
};
if !is_paused {
if event::poll(std::time::Duration::from_millis(1)).unwrap() {
match event::read().unwrap() {
Event::Key(key) => {
let key = Key::from_event(key);
let msg = MsgIn::Internal(InternalMsg::HandleKey(key));
tx_msg_in.send(Task::new(0, msg, Some(key))).unwrap();
}
Event::Resize(_, _) => {
let msg = MsgIn::External(ExternalMsg::Refresh);
tx_msg_in.send(Task::new(0, msg, None)).unwrap();
}
_ => {}
}
}
}
}
});
}

@ -3,3 +3,5 @@ pub mod config;
pub mod explorer; pub mod explorer;
pub mod input; pub mod input;
pub mod ui; pub mod ui;
pub mod pipe_reader;
pub mod event_reader;

@ -1,19 +1,18 @@
use anyhow::Result; use anyhow::Result;
use crossterm::event::Event;
use crossterm::terminal as term; use crossterm::terminal as term;
use crossterm::{event, execute}; use crossterm::execute;
use handlebars::Handlebars; use handlebars::Handlebars;
use std::fs; use std::fs;
use std::io::prelude::*; use std::io::prelude::*;
use std::path::PathBuf;
use std::sync::mpsc; use std::sync::mpsc;
use std::thread;
use std::time::Duration;
use termion::get_tty; use termion::get_tty;
use tui::backend::CrosstermBackend; use tui::backend::CrosstermBackend;
use tui::Terminal; use tui::Terminal;
use xplr::app; use xplr::app;
use xplr::event_reader;
use xplr::explorer; use xplr::explorer;
use xplr::input::Key; use xplr::pipe_reader;
use xplr::ui; use xplr::ui;
fn main() -> Result<()> { fn main() -> Result<()> {
@ -36,10 +35,7 @@ fn main() -> Result<()> {
let mut result = Ok(()); let mut result = Ok(());
let mut output = None; let mut output = None;
let (tx_key, rx) = mpsc::channel(); let (tx_msg_in, rx_msg_in) = mpsc::channel();
let tx_init = tx_key.clone();
let tx_pipe = tx_key.clone();
let tx_explorer = tx_key.clone();
term::enable_raw_mode()?; term::enable_raw_mode()?;
let mut stdout = get_tty()?; let mut stdout = get_tty()?;
@ -50,54 +46,17 @@ fn main() -> Result<()> {
let mut terminal = Terminal::new(backend)?; let mut terminal = Terminal::new(backend)?;
terminal.hide_cursor()?; terminal.hide_cursor()?;
let (tx, rx_key) = mpsc::channel(); let focused_path = std::env::args().skip(1).next().and_then(|p| {
thread::spawn(move || { PathBuf::from(p)
let mut is_paused = false; .file_name()
loop { .map(|n| n.to_string_lossy().to_string())
if let Some(paused) = rx_key.try_recv().ok() {
is_paused = paused;
};
if !is_paused {
if event::poll(std::time::Duration::from_millis(1)).unwrap() {
match event::read().unwrap() {
Event::Key(key) => {
let key = Key::from_event(key);
let msg = app::MsgIn::Internal(app::InternalMsg::HandleKey(key));
tx_key.send(app::Task::new(0, msg, Some(key))).unwrap();
}
Event::Resize(_, _) => {
let msg = app::MsgIn::External(app::ExternalMsg::Refresh);
tx_key.send(app::Task::new(0, msg, None)).unwrap();
}
_ => {}
}
}
}
}
}); });
explorer::explore(app.pwd().clone(), focused_path, tx_msg_in.clone());
let pipe_msg_in = app.pipes().msg_in.clone(); pipe_reader::keep_reading(app.pipes().msg_in.clone(), tx_msg_in.clone());
thread::spawn(move || loop {
let in_str = fs::read_to_string(&pipe_msg_in).unwrap_or_default();
if !in_str.is_empty() {
let msgs = in_str
.lines()
.filter_map(|s| serde_yaml::from_str::<app::ExternalMsg>(s.trim()).ok());
msgs.for_each(|msg| {
tx_pipe
.send(app::Task::new(2, app::MsgIn::External(msg), None))
.unwrap();
});
fs::write(&pipe_msg_in, "").unwrap();
};
thread::sleep(Duration::from_millis(10));
});
explorer::explore(app.pwd().clone(), std::env::args().skip(1).next(), tx_init); let (tx_event_reader, rx_event_reader) = mpsc::channel();
event_reader::keep_reading(tx_msg_in.clone(), rx_event_reader);
let mut last_pwd = app.pwd().clone(); let mut last_pwd = app.pwd().clone();
'outer: while result.is_ok() { 'outer: while result.is_ok() {
@ -126,7 +85,7 @@ fn main() -> Result<()> {
explorer::explore( explorer::explore(
app.pwd().clone(), app.pwd().clone(),
app.focused_node().map(|n| n.relative_path.clone()), app.focused_node().map(|n| n.relative_path.clone()),
tx_explorer.clone(), tx_msg_in.clone(),
); );
} }
@ -135,7 +94,7 @@ fn main() -> Result<()> {
explorer::explore( explorer::explore(
app.pwd().clone(), app.pwd().clone(),
app.focused_node().map(|n| n.relative_path.clone()), app.focused_node().map(|n| n.relative_path.clone()),
tx_explorer.clone(), tx_msg_in.clone(),
); );
last_pwd = app.pwd().to_owned(); last_pwd = app.pwd().to_owned();
}; };
@ -166,7 +125,7 @@ fn main() -> Result<()> {
} }
app::MsgOut::Call(cmd) => { app::MsgOut::Call(cmd) => {
tx.send(true)?; tx_event_reader.send(true)?;
terminal.clear()?; terminal.clear()?;
term::disable_raw_mode()?; term::disable_raw_mode()?;
execute!(terminal.backend_mut(), term::LeaveAlternateScreen)?; execute!(terminal.backend_mut(), term::LeaveAlternateScreen)?;
@ -232,13 +191,13 @@ fn main() -> Result<()> {
terminal.hide_cursor()?; terminal.hide_cursor()?;
execute!(terminal.backend_mut(), term::EnterAlternateScreen)?; execute!(terminal.backend_mut(), term::EnterAlternateScreen)?;
term::enable_raw_mode()?; term::enable_raw_mode()?;
tx.send(false)?; tx_event_reader.send(false)?;
terminal.draw(|f| ui::draw(f, &app, &hb))?; terminal.draw(|f| ui::draw(f, &app, &hb))?;
} }
}; };
} }
for task in rx.try_iter() { for task in rx_msg_in.try_iter() {
app = app.enqueue(task); app = app.enqueue(task);
} }

@ -0,0 +1,24 @@
use crate::app::{ExternalMsg, MsgIn, Task};
use serde_yaml;
use std::fs;
use std::sync::mpsc::Sender;
use std::thread;
use std::time::Duration;
pub fn keep_reading(pipe: String, tx: Sender<Task>) {
thread::spawn(move || loop {
let in_str = fs::read_to_string(&pipe).unwrap_or_default();
if !in_str.is_empty() {
let msgs = in_str
.lines()
.filter_map(|s| serde_yaml::from_str::<ExternalMsg>(s.trim()).ok());
msgs.for_each(|msg| {
tx.send(Task::new(2, MsgIn::External(msg), None)).unwrap();
});
fs::write(&pipe, "").unwrap();
};
thread::sleep(Duration::from_millis(10));
});
}
Loading…
Cancel
Save