summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--catgirl.113
-rw-r--r--chat.c4
-rw-r--r--chat.h29
-rw-r--r--scripts/notify-send.scpt9
-rw-r--r--ui.c34
5 files changed, 72 insertions, 17 deletions
diff --git a/catgirl.1 b/catgirl.1
index 672abfc..b7a9559 100644
--- a/catgirl.1
+++ b/catgirl.1
@@ -1,4 +1,4 @@
-.Dd February 11, 2020
+.Dd February 12, 2020
.Dt CATGIRL 1
.Os
.
@@ -11,6 +11,7 @@
.Op Fl Rev
.Op Fl C Ar copy
.Op Fl H Ar hash
+.Op Fl N Ar send
.Op Fl O Ar open
.Op Fl S Ar bind
.Op Fl a Ar auth
@@ -66,6 +67,16 @@ The default is the first available of
Set the initial value of
the nick color hash function.
.
+.It Fl N Ar util , Cm notify = Ar util
+Send notifications using a utility.
+Use more than once to add arguments to
+.Ar util .
+Two additional arguments are passed to
+.Ar util :
+a title and a description,
+appropriate for
+.Xr notify-send 1 .
+.
.It Fl O Ar util , Cm open = Ar util
Set the utility used by
.Ic /open .
diff --git a/chat.c b/chat.c
index c0950fb..dbd2784 100644
--- a/chat.c
+++ b/chat.c
@@ -94,11 +94,12 @@ int main(int argc, char *argv[]) {
const char *user = NULL;
const char *real = NULL;
- const char *Opts = "!C:H:O:RS:a:c:eh:j:k:n:p:r:s:u:vw:";
+ const char *Opts = "!C:H:N:O:RS:a:c:eh:j:k:n:p:r:s:u:vw:";
const struct option LongOpts[] = {
{ "insecure", no_argument, NULL, '!' },
{ "copy", required_argument, NULL, 'C' },
{ "hash", required_argument, NULL, 'H' },
+ { "notify", required_argument, NULL, 'N' },
{ "open", required_argument, NULL, 'O' },
{ "restrict", no_argument, NULL, 'R' },
{ "bind", required_argument, NULL, 'S' },
@@ -124,6 +125,7 @@ int main(int argc, char *argv[]) {
break; case '!': insecure = true;
break; case 'C': utilPush(&urlCopyUtil, optarg);
break; case 'H': hashInit = strtoul(optarg, NULL, 0);
+ break; case 'N': utilPush(&uiNotifyUtil, optarg);
break; case 'O': utilPush(&urlOpenUtil, optarg);
break; case 'R': self.restricted = true;
break; case 'S': bind = optarg;
diff --git a/chat.h b/chat.h
index ed6dc2f..fb7bf61 100644
--- a/chat.h
+++ b/chat.h
@@ -146,7 +146,22 @@ const char *commandIsNotice(size_t id, const char *input);
const char *commandIsAction(size_t id, const char *input);
void commandComplete(void);
+enum { UtilCap = 16 };
+struct Util {
+ size_t argc;
+ const char *argv[UtilCap];
+};
+
+static inline void utilPush(struct Util *util, const char *arg) {
+ if (1 + util->argc < UtilCap) {
+ util->argv[util->argc++] = arg;
+ } else {
+ errx(EX_CONFIG, "too many utility arguments");
+ }
+}
+
enum Heat { Cold, Warm, Hot };
+extern struct Util uiNotifyUtil;
void uiInit(void);
void uiShow(void);
void uiHide(void);
@@ -196,20 +211,6 @@ void completeClear(size_t id);
size_t completeID(const char *str);
enum Color completeColor(size_t id, const char *str);
-enum { UtilCap = 16 };
-struct Util {
- size_t argc;
- const char *argv[UtilCap];
-};
-
-static inline void utilPush(struct Util *util, const char *arg) {
- if (1 + util->argc < UtilCap) {
- util->argv[util->argc++] = arg;
- } else {
- errx(EX_CONFIG, "too many utility arguments");
- }
-}
-
extern struct Util urlOpenUtil;
extern struct Util urlCopyUtil;
void urlScan(size_t id, const char *nick, const char *mesg);
diff --git a/scripts/notify-send.scpt b/scripts/notify-send.scpt
new file mode 100644
index 0000000..5630440
--- /dev/null
+++ b/scripts/notify-send.scpt
@@ -0,0 +1,9 @@
+#!/usr/bin/osascript
+
+on run argv
+ if count of argv is 2 then
+ display notification (item 2 of argv) with title (item 1 of argv)
+ else
+ display notification (item 1 of argv)
+ end if
+end run
diff --git a/ui.c b/ui.c
index 97f81b3..0bf619d 100644
--- a/ui.c
+++ b/ui.c
@@ -530,6 +530,35 @@ static int wordWrap(WINDOW *win, const char *str) {
return lines;
}
+struct Util uiNotifyUtil;
+static void notify(size_t id, const char *str) {
+ if (!uiNotifyUtil.argc) return;
+
+ struct Util util = uiNotifyUtil;
+ utilPush(&util, idNames[id]);
+ size_t len = 0;
+ char buf[1024] = "";
+ while (*str && len < sizeof(buf)) {
+ size_t run;
+ struct Style style = Reset;
+ styleParse(&style, &str, &run);
+ len += snprintf(&buf[len], sizeof(buf) - len, "%.*s", (int)run, str);
+ str += run;
+ }
+ utilPush(&util, buf);
+
+ pid_t pid = fork();
+ if (pid < 0) err(EX_OSERR, "fork");
+ if (pid) return;
+
+ close(STDIN_FILENO);
+ dup2(procPipe[1], STDOUT_FILENO);
+ dup2(procPipe[1], STDERR_FILENO);
+ execvp(util.argv[0], (char *const *)util.argv);
+ warn("%s", util.argv[0]);
+ _exit(EX_CONFIG);
+}
+
void uiWrite(size_t id, enum Heat heat, const time_t *src, const char *str) {
struct Window *window = windowFor(id);
time_t clock = (src ? *src : time(NULL));
@@ -548,7 +577,10 @@ void uiWrite(size_t id, enum Heat heat, const time_t *src, const char *str) {
lines += wordWrap(window->pad, str);
window->unreadLines += lines;
if (window->scroll) windowScroll(window, lines);
- if (heat > Warm) beep();
+ if (window->mark && heat > Warm) {
+ beep();
+ notify(id, str);
+ }
}
void uiFormat(