diff options
author | nc <[email protected]> | 2020-07-20 23:30:32 +0100 |
---|---|---|
committer | nc <[email protected]> | 2020-07-20 23:30:32 +0100 |
commit | 66b2f0793f236dccd3269ae1c3cbfe2293f7fb3d (patch) | |
tree | 0e1a2604d9d395bda8d8eaae12353014b6adc836 | |
parent | 2a3be003015bac9c6a13549029b9fb4595e88384 (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.toml | 1 | ||||
-rw-r--r-- | src/app/impl_self.rs | 12 | ||||
-rw-r--r-- | src/app/impl_view.rs | 8 | ||||
-rw-r--r-- | src/app/mod.rs | 4 | ||||
-rw-r--r-- | src/main.rs | 9 |
5 files changed, 23 insertions, 11 deletions
@@ -19,6 +19,7 @@ typetag = "0.1.4" | |||
19 | directories = "3.0.1" | 19 | directories = "3.0.1" |
20 | clap = "2.33" | 20 | clap = "2.33" |
21 | notify = "4.0" | 21 | notify = "4.0" |
22 | signal-hook = "0.1.16" | ||
22 | 23 | ||
23 | [dependencies.cursive] | 24 | [dependencies.cursive] |
24 | version = "0.15" | 25 | version = "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::*; | |||
5 | use std::path::PathBuf; | 5 | use std::path::PathBuf; |
6 | use std::sync::mpsc::channel; | 6 | use std::sync::mpsc::channel; |
7 | use std::time::Duration; | 7 | use std::time::Duration; |
8 | use std::sync::{RwLock, Arc}; | ||
8 | 9 | ||
9 | use chrono::Local; | 10 | use chrono::Local; |
10 | use cursive::direction::Absolute; | 11 | use 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 | ||
6 | use crate::habit::HabitWrapper; | 6 | use crate::habit::HabitWrapper; |
7 | 7 | ||
8 | use std::sync::{RwLock, Arc}; | ||
9 | |||
8 | mod impl_self; | 10 | mod impl_self; |
9 | mod impl_view; | 11 | mod impl_view; |
10 | mod message; | 12 | mod 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 | ||
26 | impl Default for App { | 28 | impl 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)), |