diff options
-rw-r--r-- | catgirl.1 | 2 | ||||
-rw-r--r-- | ui.c | 28 |
2 files changed, 21 insertions, 9 deletions
diff --git a/catgirl.1 b/catgirl.1 index f11cae0..eb7310d 100644 --- a/catgirl.1 +++ b/catgirl.1 @@ -254,6 +254,8 @@ Cycle through unread windows. Insert a blank line in the window. .It Ic M- Ns Ar n Switch to window by number 0\(en9. +.It Ic M-u +Scroll to first unread line. .El . .Ss IRC Formatting diff --git a/ui.c b/ui.c index 050ec2e..9abfffc 100644 --- a/ui.c +++ b/ui.c @@ -71,10 +71,11 @@ struct Window { size_t id; struct Buffer buffer; WINDOW *pad; + bool mark; enum Heat heat; - int unread; + int unreadCount; + int unreadLines; int scroll; - bool mark; struct Window *prev; struct Window *next; }; @@ -200,6 +201,7 @@ static void errExit(void) { X(KeyMetaD, "\33d") \ X(KeyMetaF, "\33f") \ X(KeyMetaM, "\33m") \ + X(KeyMetaU, "\33u") \ X(KeyMetaSlash, "\33/") \ X(KeyFocusIn, "\33[I") \ X(KeyFocusOut, "\33[O") \ @@ -347,7 +349,7 @@ static void statusUpdate(void) { int num; const struct Window *window; for (num = 0, window = windows.head; window; ++num, window = window->next) { - if (!window->unread && window != windows.active) continue; + if (!window->unreadCount && window != windows.active) continue; int unread; char buf[256]; snprintf( @@ -355,10 +357,10 @@ static void statusUpdate(void) { idColors[window->id], (window == windows.active ? "\26" : ""), num, idNames[window->id], &unread, (window->heat > Warm ? White : idColors[window->id]), - window->unread, + window->unreadCount, idColors[window->id] ); - if (!window->unread) buf[unread] = '\0'; + if (!window->unreadCount) buf[unread] = '\0'; statusAdd(buf); } wclrtoeol(status); @@ -368,9 +370,9 @@ static void statusUpdate(void) { snprintf( buf, sizeof(buf), "%s %s%n (%d)", self.network, idNames[windows.active->id], - &unread, windows.active->unread + &unread, windows.active->unreadCount ); - if (!windows.active->unread) buf[unread] = '\0'; + if (!windows.active->unreadCount) buf[unread] = '\0'; putp(to_status_line); putp(buf); putp(from_status_line); @@ -380,7 +382,7 @@ static void statusUpdate(void) { static void unmark(struct Window *window) { if (!window->scroll) { window->heat = Cold; - window->unread = 0; + window->unreadCount = 0; window->mark = false; } statusUpdate(); @@ -396,6 +398,11 @@ static void windowScroll(struct Window *window, int n) { if (!window->scroll) unmark(window); } +static void windowScrollUnread(struct Window *window) { + window->scroll = 0; + windowScroll(window, window->unreadLines - PAGE_LINES); +} + static int wordWidth(const char *str) { size_t len = strcspn(str, " "); int width = 0; @@ -466,8 +473,9 @@ void uiWrite(size_t id, enum Heat heat, const time_t *src, const char *str) { int lines = 1; waddch(window->pad, '\n'); + if (window->mark && !window->unreadCount) window->unreadLines = 0; if (window->mark && heat > Cold) { - if (!window->unread++) { + if (!window->unreadCount++) { lines++; waddch(window->pad, '\n'); } @@ -475,6 +483,7 @@ void uiWrite(size_t id, enum Heat heat, const time_t *src, const char *str) { statusUpdate(); } lines += wordWrap(window->pad, str); + if (window->mark) window->unreadLines += lines; if (window->scroll) windowScroll(window, lines); if (heat > Warm) beep(); } @@ -689,6 +698,7 @@ static void keyCode(int code) { break; case KeyMetaD: edit(id, EditDeleteNextWord, 0); break; case KeyMetaF: edit(id, EditNextWord, 0); break; case KeyMetaM: waddch(window->pad, '\n'); + break; case KeyMetaU: windowScrollUnread(window); break; case KEY_BACKSPACE: edit(id, EditDeletePrev, 0); break; case KEY_DC: edit(id, EditDeleteNext, 0); |