From 66b2f0793f236dccd3269ae1c3cbfe2293f7fb3d Mon Sep 17 00:00:00 2001 From: nc Date: Mon, 20 Jul 2020 18:30:32 -0400 Subject: 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... --- Cargo.toml | 1 + src/app/impl_self.rs | 12 +++++++----- src/app/impl_view.rs | 8 ++++---- src/app/mod.rs | 4 +++- src/main.rs | 9 ++++++++- 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" directories = "3.0.1" clap = "2.33" notify = "4.0" +signal-hook = "0.1.16" [dependencies.cursive] 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::*; use std::path::PathBuf; use std::sync::mpsc::channel; use std::time::Duration; +use std::sync::{RwLock, Arc}; use chrono::Local; use cursive::direction::Absolute; @@ -23,13 +24,14 @@ impl App { let (tx, rx) = channel(); let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap(); watcher.watch(utils::auto_habit_file(), RecursiveMode::Recursive); + return App { habits: vec![], focus: 0, _file_watcher: watcher, file_event_recv: rx, view_month_offset: 0, - message: "Type :add to get started, Ctrl-L to dismiss".into(), + message: Arc::new(RwLock::new("Type :add to get started, Ctrl-L to dismiss".into())), }; } @@ -41,7 +43,7 @@ impl App { let old_len = self.habits.len(); self.habits.retain(|h| h.name() != name); if old_len == self.habits.len() { - self.message + self.message.write().unwrap() .set_message(format!("Could not delete habit `{}`", name)) } } @@ -114,7 +116,7 @@ impl App { } pub fn clear_message(&mut self) { - self.message.clear(); + self.message.write().unwrap().clear(); } pub fn status(&self) -> StatusLine { @@ -236,8 +238,8 @@ impl App { Command::Blank => {} }, Err(e) => { - self.message.set_message(e.to_string()); - self.message.set_kind(MessageKind::Error); + self.message.write().unwrap().set_message(e.to_string()); + self.message.write().unwrap().set_kind(MessageKind::Error); } } } 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 { printer.print(offset, &status.1); // right status offset = offset.map_x(|_| 0).map_y(|_| self.max_size().y - 1); - printer.with_style(Color::from(self.message.kind()), |p| { - p.print(offset, self.message.contents()) + printer.with_style(Color::from(self.message.read().unwrap().kind()), |p| { + p.print(offset, self.message.read().unwrap().contents()) }); } @@ -161,8 +161,8 @@ impl View for App { return EventResult::Consumed(None); } Event::CtrlChar('l') => { - self.message.clear(); - self.message.set_kind(MessageKind::Info); + self.message.write().unwrap().clear(); + self.message.write().unwrap().set_kind(MessageKind::Info); return EventResult::Consumed(None); } 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}; use crate::habit::HabitWrapper; +use std::sync::{RwLock, Arc}; + mod impl_self; mod impl_view; mod message; @@ -20,7 +22,7 @@ pub struct App { file_event_recv: Receiver, focus: usize, view_month_offset: u32, - message: Message, + pub message: Arc>, } 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() { ), } } else { - let mut s = termion().unwrap(); let app = App::load_state(); + let m = app.message.clone(); + unsafe { signal_hook::register(signal_hook::SIGINT, move || { + std::fs::File::create("killed").unwrap(); + m.write().unwrap().set_message("Use the :q command to quit"); + }) }.unwrap(); + + let mut s = termion().unwrap(); + let layout = NamedView::new( "Frame", LinearLayout::vertical().child(NamedView::new("Main", app)), -- cgit v1.2.3 From 19de1653985520258bd081e32275c48e2ac98f5b Mon Sep 17 00:00:00 2001 From: nc Date: Mon, 20 Jul 2020 18:44:31 -0400 Subject: remove debug code, add cargo.lock --- Cargo.lock | 1 + src/main.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index ade0cc4..5075c64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -271,6 +271,7 @@ dependencies = [ "notify", "serde", "serde_json", + "signal-hook", "typetag", ] diff --git a/src/main.rs b/src/main.rs index ca1b653..d733f97 100644 --- a/src/main.rs +++ b/src/main.rs @@ -53,7 +53,6 @@ fn main() { let app = App::load_state(); let m = app.message.clone(); unsafe { signal_hook::register(signal_hook::SIGINT, move || { - std::fs::File::create("killed").unwrap(); m.write().unwrap().set_message("Use the :q command to quit"); }) }.unwrap(); @@ -67,6 +66,7 @@ fn main() { s.add_global_callback(':', |s| open_command_window(s)); s.set_theme(theme::theme_gen()); + s.run(); } } -- cgit v1.2.3 From 20f7419c3d6d70ba8cfd996490020a5e1f2ad06d Mon Sep 17 00:00:00 2001 From: nc Date: Tue, 28 Jul 2020 19:16:32 -0400 Subject: add ctrlc to on_event trigger --- src/app/impl_view.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/impl_view.rs b/src/app/impl_view.rs index acc387e..b735003 100644 --- a/src/app/impl_view.rs +++ b/src/app/impl_view.rs @@ -165,6 +165,10 @@ impl View for App { self.message.write().unwrap().set_kind(MessageKind::Info); return EventResult::Consumed(None); } + Event::CtrlChar('c') => { + self.message.write().unwrap().set_message("Use the :q command to quit"); + return EventResult::Consumed(None); + } /* Every keybind that is not caught by App trickles * down to the focused habit. We sift back to today -- cgit v1.2.3 From ee9be05579d87ca99f153d20995af3273385b564 Mon Sep 17 00:00:00 2001 From: nc Date: Wed, 5 Aug 2020 22:08:51 -0400 Subject: Override Ctrl-C by disabling callback in Cursive Thanks to @gyscos for the explanation in #22! Also removed extraneous code that's no longer needed. --- Cargo.lock | 1 - Cargo.toml | 1 - src/app/impl_self.rs | 1 - src/app/impl_view.rs | 3 ++- src/main.rs | 9 +++------ 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5075c64..ade0cc4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -271,7 +271,6 @@ dependencies = [ "notify", "serde", "serde_json", - "signal-hook", "typetag", ] diff --git a/Cargo.toml b/Cargo.toml index c97e2a4..9cf3639 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,6 @@ typetag = "0.1.4" directories = "3.0.1" clap = "2.33" notify = "4.0" -signal-hook = "0.1.16" [dependencies.cursive] version = "0.15" diff --git a/src/app/impl_self.rs b/src/app/impl_self.rs index 325c53f..c2a24cf 100644 --- a/src/app/impl_self.rs +++ b/src/app/impl_self.rs @@ -24,7 +24,6 @@ impl App { let (tx, rx) = channel(); let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap(); watcher.watch(utils::auto_habit_file(), RecursiveMode::Recursive); - return App { habits: vec![], focus: 0, diff --git a/src/app/impl_view.rs b/src/app/impl_view.rs index b735003..1261208 100644 --- a/src/app/impl_view.rs +++ b/src/app/impl_view.rs @@ -85,6 +85,7 @@ impl View for App { if self.habits.is_empty() { return EventResult::Ignored; } + let m = self.message.clone(); match e { Event::Key(Key::Right) | Event::Key(Key::Tab) | Event::Char('l') => { self.set_focus(Absolute::Right); @@ -166,7 +167,7 @@ impl View for App { return EventResult::Consumed(None); } Event::CtrlChar('c') => { - self.message.write().unwrap().set_message("Use the :q command to quit"); + m.write().unwrap().set_message("Use the :q command to quit"); return EventResult::Consumed(None); } diff --git a/src/main.rs b/src/main.rs index d733f97..3ec964a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,13 +50,11 @@ fn main() { ), } } else { + let mut s = termion().unwrap(); let app = App::load_state(); - let m = app.message.clone(); - unsafe { signal_hook::register(signal_hook::SIGINT, move || { - m.write().unwrap().set_message("Use the :q command to quit"); - }) }.unwrap(); - let mut s = termion().unwrap(); + // prevent Ctrl-C from killing the app and allow the app to override it. + s.clear_global_callbacks(cursive::event::Event::CtrlChar('c')); let layout = NamedView::new( "Frame", @@ -66,7 +64,6 @@ fn main() { s.add_global_callback(':', |s| open_command_window(s)); s.set_theme(theme::theme_gen()); - s.run(); } } -- cgit v1.2.3 From 976ea0282d373c4d08187a78a7b46a09d66f7918 Mon Sep 17 00:00:00 2001 From: nc Date: Wed, 5 Aug 2020 23:56:06 -0400 Subject: revert --- src/app/impl_self.rs | 11 +++++------ src/app/impl_view.rs | 13 ++++--------- src/app/mod.rs | 4 +--- src/main.rs | 4 ---- 4 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/app/impl_self.rs b/src/app/impl_self.rs index c2a24cf..744f906 100644 --- a/src/app/impl_self.rs +++ b/src/app/impl_self.rs @@ -5,7 +5,6 @@ use std::io::prelude::*; use std::path::PathBuf; use std::sync::mpsc::channel; use std::time::Duration; -use std::sync::{RwLock, Arc}; use chrono::Local; use cursive::direction::Absolute; @@ -30,7 +29,7 @@ impl App { _file_watcher: watcher, file_event_recv: rx, view_month_offset: 0, - message: Arc::new(RwLock::new("Type :add to get started, Ctrl-L to dismiss".into())), + message: "Type :add to get started, Ctrl-L to dismiss".into(), }; } @@ -42,7 +41,7 @@ impl App { let old_len = self.habits.len(); self.habits.retain(|h| h.name() != name); if old_len == self.habits.len() { - self.message.write().unwrap() + self.message .set_message(format!("Could not delete habit `{}`", name)) } } @@ -115,7 +114,7 @@ impl App { } pub fn clear_message(&mut self) { - self.message.write().unwrap().clear(); + self.message.clear(); } pub fn status(&self) -> StatusLine { @@ -237,8 +236,8 @@ impl App { Command::Blank => {} }, Err(e) => { - self.message.write().unwrap().set_message(e.to_string()); - self.message.write().unwrap().set_kind(MessageKind::Error); + self.message.set_message(e.to_string()); + self.message.set_kind(MessageKind::Error); } } } diff --git a/src/app/impl_view.rs b/src/app/impl_view.rs index 1261208..892b00c 100644 --- a/src/app/impl_view.rs +++ b/src/app/impl_view.rs @@ -39,8 +39,8 @@ impl View for App { printer.print(offset, &status.1); // right status offset = offset.map_x(|_| 0).map_y(|_| self.max_size().y - 1); - printer.with_style(Color::from(self.message.read().unwrap().kind()), |p| { - p.print(offset, self.message.read().unwrap().contents()) + printer.with_style(Color::from(self.message.kind()), |p| { + p.print(offset, self.message.contents()) }); } @@ -85,7 +85,6 @@ impl View for App { if self.habits.is_empty() { return EventResult::Ignored; } - let m = self.message.clone(); match e { Event::Key(Key::Right) | Event::Key(Key::Tab) | Event::Char('l') => { self.set_focus(Absolute::Right); @@ -162,12 +161,8 @@ impl View for App { return EventResult::Consumed(None); } Event::CtrlChar('l') => { - self.message.write().unwrap().clear(); - self.message.write().unwrap().set_kind(MessageKind::Info); - return EventResult::Consumed(None); - } - Event::CtrlChar('c') => { - m.write().unwrap().set_message("Use the :q command to quit"); + self.message.clear(); + self.message.set_kind(MessageKind::Info); return EventResult::Consumed(None); } diff --git a/src/app/mod.rs b/src/app/mod.rs index bce6e79..2aecb33 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -5,8 +5,6 @@ use notify::{DebouncedEvent, RecommendedWatcher}; use crate::habit::HabitWrapper; -use std::sync::{RwLock, Arc}; - mod impl_self; mod impl_view; mod message; @@ -22,7 +20,7 @@ pub struct App { file_event_recv: Receiver, focus: usize, view_month_offset: u32, - pub message: Arc>, + message: Message, } impl Default for App { diff --git a/src/main.rs b/src/main.rs index 3ec964a..d96119e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,10 +52,6 @@ fn main() { } else { let mut s = termion().unwrap(); let app = App::load_state(); - - // prevent Ctrl-C from killing the app and allow the app to override it. - s.clear_global_callbacks(cursive::event::Event::CtrlChar('c')); - let layout = NamedView::new( "Frame", LinearLayout::vertical().child(NamedView::new("Main", app)), -- cgit v1.2.3 From 9777930868591abdf4a533e4059cc4fd08898521 Mon Sep 17 00:00:00 2001 From: nc Date: Wed, 5 Aug 2020 23:59:40 -0400 Subject: include only minimal code changes to add ctrl-c capturing functionality --- src/app/impl_view.rs | 4 ++++ src/main.rs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/app/impl_view.rs b/src/app/impl_view.rs index 892b00c..5f313f7 100644 --- a/src/app/impl_view.rs +++ b/src/app/impl_view.rs @@ -165,6 +165,10 @@ impl View for App { self.message.set_kind(MessageKind::Info); return EventResult::Consumed(None); } + Event::CtrlChar('c') => { + self.message.set_message("Use the :q command to quit"); + return EventResult::Consumed(None); + } /* Every keybind that is not caught by App trickles * down to the focused habit. We sift back to today diff --git a/src/main.rs b/src/main.rs index d96119e..3ec964a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,6 +52,10 @@ fn main() { } else { let mut s = termion().unwrap(); let app = App::load_state(); + + // prevent Ctrl-C from killing the app and allow the app to override it. + s.clear_global_callbacks(cursive::event::Event::CtrlChar('c')); + let layout = NamedView::new( "Frame", LinearLayout::vertical().child(NamedView::new("Main", app)), -- cgit v1.2.3 From 78685f7cdca15a191a5d086321368e475b0c2ab2 Mon Sep 17 00:00:00 2001 From: nc Date: Thu, 6 Aug 2020 14:51:26 -0400 Subject: Revert "include only minimal code changes to add ctrl-c capturing functionality" This reverts commit 9777930868591abdf4a533e4059cc4fd08898521. --- src/app/impl_view.rs | 4 ---- src/main.rs | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/app/impl_view.rs b/src/app/impl_view.rs index 5f313f7..892b00c 100644 --- a/src/app/impl_view.rs +++ b/src/app/impl_view.rs @@ -165,10 +165,6 @@ impl View for App { self.message.set_kind(MessageKind::Info); return EventResult::Consumed(None); } - Event::CtrlChar('c') => { - self.message.set_message("Use the :q command to quit"); - return EventResult::Consumed(None); - } /* Every keybind that is not caught by App trickles * down to the focused habit. We sift back to today diff --git a/src/main.rs b/src/main.rs index 3ec964a..d96119e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -52,10 +52,6 @@ fn main() { } else { let mut s = termion().unwrap(); let app = App::load_state(); - - // prevent Ctrl-C from killing the app and allow the app to override it. - s.clear_global_callbacks(cursive::event::Event::CtrlChar('c')); - let layout = NamedView::new( "Frame", LinearLayout::vertical().child(NamedView::new("Main", app)), -- cgit v1.2.3 From 92b4ecd7006f68f87dff3130b85c00dddacead85 Mon Sep 17 00:00:00 2001 From: nc Date: Sat, 8 Aug 2020 10:09:52 -0400 Subject: try to unconditionally save after s.run() completes --- src/main.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main.rs b/src/main.rs index d96119e..1d9efb4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -61,5 +61,12 @@ fn main() { s.set_theme(theme::theme_gen()); s.run(); + + let app = std::rc::Rc::try_unwrap(s.find_name::>("Main").unwrap() + .get_mut() + .into_owner() + .into_owner()).ok().unwrap().into_inner(); + app.save_state(); + } } -- cgit v1.2.3 From 62158c5f142a1838b030c0583c9467a3cb46358b Mon Sep 17 00:00:00 2001 From: nc Date: Sat, 8 Aug 2020 12:47:08 -0400 Subject: use call_on_name which works and is simpler --- src/main.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1d9efb4..14ddf03 100644 --- a/src/main.rs +++ b/src/main.rs @@ -62,11 +62,6 @@ fn main() { s.set_theme(theme::theme_gen()); s.run(); - let app = std::rc::Rc::try_unwrap(s.find_name::>("Main").unwrap() - .get_mut() - .into_owner() - .into_owner()).ok().unwrap().into_inner(); - app.save_state(); - + s.call_on_name("Main", |app: &mut App| app.save_state()); } } -- cgit v1.2.3