aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornc <[email protected]>2020-07-20 23:30:32 +0100
committernc <[email protected]>2020-07-20 23:30:32 +0100
commit66b2f0793f236dccd3269ae1c3cbfe2293f7fb3d (patch)
tree0e1a2604d9d395bda8d8eaae12353014b6adc836
parent2a3be003015bac9c6a13549029b9fb4595e88384 (diff)
Add RwLock around messages. Catch SIGINT and print that :q is the way to quit.
Note that this doesn't actually capture Ctrl-C. I'm not sure how it works but termion somehow swollows Ctrl-C so and circumvents the signal handler...
-rw-r--r--Cargo.toml1
-rw-r--r--src/app/impl_self.rs12
-rw-r--r--src/app/impl_view.rs8
-rw-r--r--src/app/mod.rs4
-rw-r--r--src/main.rs9
5 files changed, 23 insertions, 11 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 9cf3639..c97e2a4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -19,6 +19,7 @@ typetag = "0.1.4"
19directories = "3.0.1" 19directories = "3.0.1"
20clap = "2.33" 20clap = "2.33"
21notify = "4.0" 21notify = "4.0"
22signal-hook = "0.1.16"
22 23
23[dependencies.cursive] 24[dependencies.cursive]
24version = "0.15" 25version = "0.15"
diff --git a/src/app/impl_self.rs b/src/app/impl_self.rs
index 744f906..325c53f 100644
--- a/src/app/impl_self.rs
+++ b/src/app/impl_self.rs
@@ -5,6 +5,7 @@ use std::io::prelude::*;
5use std::path::PathBuf; 5use std::path::PathBuf;
6use std::sync::mpsc::channel; 6use std::sync::mpsc::channel;
7use std::time::Duration; 7use std::time::Duration;
8use std::sync::{RwLock, Arc};
8 9
9use chrono::Local; 10use chrono::Local;
10use cursive::direction::Absolute; 11use cursive::direction::Absolute;
@@ -23,13 +24,14 @@ impl App {
23 let (tx, rx) = channel(); 24 let (tx, rx) = channel();
24 let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap(); 25 let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap();
25 watcher.watch(utils::auto_habit_file(), RecursiveMode::Recursive); 26 watcher.watch(utils::auto_habit_file(), RecursiveMode::Recursive);
27
26 return App { 28 return App {
27 habits: vec![], 29 habits: vec![],
28 focus: 0, 30 focus: 0,
29 _file_watcher: watcher, 31 _file_watcher: watcher,
30 file_event_recv: rx, 32 file_event_recv: rx,
31 view_month_offset: 0, 33 view_month_offset: 0,
32 message: "Type :add <habit-name> <goal> to get started, Ctrl-L to dismiss".into(), 34 message: Arc::new(RwLock::new("Type :add <habit-name> <goal> to get started, Ctrl-L to dismiss".into())),
33 }; 35 };
34 } 36 }
35 37
@@ -41,7 +43,7 @@ impl App {
41 let old_len = self.habits.len(); 43 let old_len = self.habits.len();
42 self.habits.retain(|h| h.name() != name); 44 self.habits.retain(|h| h.name() != name);
43 if old_len == self.habits.len() { 45 if old_len == self.habits.len() {
44 self.message 46 self.message.write().unwrap()
45 .set_message(format!("Could not delete habit `{}`", name)) 47 .set_message(format!("Could not delete habit `{}`", name))
46 } 48 }
47 } 49 }
@@ -114,7 +116,7 @@ impl App {
114 } 116 }
115 117
116 pub fn clear_message(&mut self) { 118 pub fn clear_message(&mut self) {
117 self.message.clear(); 119 self.message.write().unwrap().clear();
118 } 120 }
119 121
120 pub fn status(&self) -> StatusLine { 122 pub fn status(&self) -> StatusLine {
@@ -236,8 +238,8 @@ impl App {
236 Command::Blank => {} 238 Command::Blank => {}
237 }, 239 },
238 Err(e) => { 240 Err(e) => {
239 self.message.set_message(e.to_string()); 241 self.message.write().unwrap().set_message(e.to_string());
240 self.message.set_kind(MessageKind::Error); 242 self.message.write().unwrap().set_kind(MessageKind::Error);
241 } 243 }
242 } 244 }
243 } 245 }
diff --git a/src/app/impl_view.rs b/src/app/impl_view.rs
index 892b00c..acc387e 100644
--- a/src/app/impl_view.rs
+++ b/src/app/impl_view.rs
@@ -39,8 +39,8 @@ impl View for App {
39 printer.print(offset, &status.1); // right status 39 printer.print(offset, &status.1); // right status
40 40
41 offset = offset.map_x(|_| 0).map_y(|_| self.max_size().y - 1); 41 offset = offset.map_x(|_| 0).map_y(|_| self.max_size().y - 1);
42 printer.with_style(Color::from(self.message.kind()), |p| { 42 printer.with_style(Color::from(self.message.read().unwrap().kind()), |p| {
43 p.print(offset, self.message.contents()) 43 p.print(offset, self.message.read().unwrap().contents())
44 }); 44 });
45 } 45 }
46 46
@@ -161,8 +161,8 @@ impl View for App {
161 return EventResult::Consumed(None); 161 return EventResult::Consumed(None);
162 } 162 }
163 Event::CtrlChar('l') => { 163 Event::CtrlChar('l') => {
164 self.message.clear(); 164 self.message.write().unwrap().clear();
165 self.message.set_kind(MessageKind::Info); 165 self.message.write().unwrap().set_kind(MessageKind::Info);
166 return EventResult::Consumed(None); 166 return EventResult::Consumed(None);
167 } 167 }
168 168
diff --git a/src/app/mod.rs b/src/app/mod.rs
index 2aecb33..bce6e79 100644
--- a/src/app/mod.rs
+++ b/src/app/mod.rs
@@ -5,6 +5,8 @@ use notify::{DebouncedEvent, RecommendedWatcher};
5 5
6use crate::habit::HabitWrapper; 6use crate::habit::HabitWrapper;
7 7
8use std::sync::{RwLock, Arc};
9
8mod impl_self; 10mod impl_self;
9mod impl_view; 11mod impl_view;
10mod message; 12mod message;
@@ -20,7 +22,7 @@ pub struct App {
20 file_event_recv: Receiver<DebouncedEvent>, 22 file_event_recv: Receiver<DebouncedEvent>,
21 focus: usize, 23 focus: usize,
22 view_month_offset: u32, 24 view_month_offset: u32,
23 message: Message, 25 pub message: Arc<RwLock<Message>>,
24} 26}
25 27
26impl Default for App { 28impl Default for App {
diff --git a/src/main.rs b/src/main.rs
index d96119e..ca1b653 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -50,8 +50,15 @@ fn main() {
50 ), 50 ),
51 } 51 }
52 } else { 52 } else {
53 let mut s = termion().unwrap();
54 let app = App::load_state(); 53 let app = App::load_state();
54 let m = app.message.clone();
55 unsafe { signal_hook::register(signal_hook::SIGINT, move || {
56 std::fs::File::create("killed").unwrap();
57 m.write().unwrap().set_message("Use the :q command to quit");
58 }) }.unwrap();
59
60 let mut s = termion().unwrap();
61
55 let layout = NamedView::new( 62 let layout = NamedView::new(
56 "Frame", 63 "Frame",
57 LinearLayout::vertical().child(NamedView::new("Main", app)), 64 LinearLayout::vertical().child(NamedView::new("Main", app)),