hirc

IRC client
Log | Files | Refs

commit cc5e34a83e8cb8c2867cdd76610ccd26277c9f16
parent 604ed6a27d1cf55643b747cb5f65bad5c325badc
Author: hhvn <dev@hhvn.uk>
Date:   Wed, 15 Dec 2021 17:55:37 +0000

s/commands.c s/ui.c s/hist.c s/struct.h: /scroll for main window

Diffstat:
Msrc/commands.c | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/hist.c | 7++++++-
Msrc/struct.h | 1+
Msrc/ui.c | 21++++++++++++++-------
4 files changed, 77 insertions(+), 8 deletions(-)

diff --git a/src/commands.c b/src/commands.c @@ -21,6 +21,8 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <limits.h> +#include <ctype.h> #include <regex.h> #include <pwd.h> #include <sys/types.h> @@ -47,6 +49,7 @@ static void command_echo(struct Server *server, char *str); static void command_grep(struct Server *server, char *str); static void command_clear(struct Server *server, char *str); static void command_alias(struct Server *server, char *str); +static void command_scroll(struct Server *server, char *str); static char *command_optarg; enum { @@ -138,6 +141,11 @@ struct Command commands[] = { "usage: /alias [<alias> [cmd [...]]]", " /alias -delete <alias>", "Add or remove an alias that expands to a command.", NULL}}, + {"scroll", command_scroll, 0, { + "usage: /scroll [-buflist] [-nicklist] [-|+]lines", + "Scroll a window (main by default).", + "Positive scrolls up, negative down, 0 resets and tracks", + "Probably most useful with /bind", NULL}}, {NULL, NULL}, }; @@ -876,6 +884,54 @@ command_clear(struct Server *server, char *str) { windows[Win_main].refresh = 1; } +static void +command_scroll(struct Server *server, char *str) { + int ret, winid = Win_main; + long diff; + enum { opt_buflist, opt_nicklist }; + static struct CommandOpts opts[] = { + {"buflist", CMD_NARG, opt_buflist}, + {"nicklist", CMD_NARG, opt_nicklist}, + {NULL, 0, 0}, + }; + + if (!str) + goto narg; + + while (!(*str == '-' && isdigit(*(str+1))) && (ret = command_getopt(&str, opts)) != opt_done) { + switch (ret) { + case opt_error: + return; + case opt_buflist: + winid = Win_buflist; + break; + case opt_nicklist: + winid = Win_nicklist; + break; + } + + if (*str == '-' && isdigit(*(str+1))) + break; + } + + if (!*str) + goto narg; + + diff = strtol(str, NULL, 10); + if (diff == 0 || diff == LONG_MIN) + windows[winid].scroll = -1; /* no scroll, tracking */ + else if (windows[winid].scroll >= 0) + windows[winid].scroll += diff; + else + windows[winid].scroll = diff; + + windows[winid].refresh = 1; + return; + +narg: + ui_error("/scroll requires argument", NULL); +} + int command_getopt(char **str, struct CommandOpts *opts) { char *opt; diff --git a/src/hist.c b/src/hist.c @@ -123,8 +123,13 @@ hist_add(struct HistInfo *histinfo, struct Nick *from, histinfo->history = new; /* TODO: this triggers way too often, need to have some sort of delay */ - if (selected.history == histinfo) + if (selected.history == histinfo) { + if (options & HIST_SELF) + windows[Win_main].scroll = -1; + else if (windows[Win_main].scroll >= 0) + windows[Win_main].scroll += 1; windows[Win_main].refresh = 1; + } if (options & HIST_LOG) { if (histinfo->server) diff --git a/src/struct.h b/src/struct.h @@ -210,6 +210,7 @@ struct Window { int x, y; int h, w; int refresh; + int scroll; enum WindowLocation location; void (*handler)(void); WINDOW *window; diff --git a/src/ui.c b/src/ui.c @@ -53,11 +53,11 @@ static unsigned short colourmap[HIRC_COLOURS] = { }; struct Window windows[Win_last] = { - [Win_dummy] = {.handler = NULL}, - [Win_main] = {.handler = ui_draw_main}, - [Win_input] = {.handler = ui_draw_input}, - [Win_nicklist] = {.handler = ui_draw_nicklist}, - [Win_buflist] = {.handler = ui_draw_buflist}, + [Win_dummy] = {.handler = NULL, .scroll = -1}, + [Win_main] = {.handler = ui_draw_main, .scroll = -1}, + [Win_input] = {.handler = ui_draw_input, .scroll = -1}, + [Win_nicklist] = {.handler = ui_draw_nicklist, .scroll = -1}, + [Win_buflist] = {.handler = ui_draw_buflist, .scroll = -1}, }; struct { @@ -284,6 +284,7 @@ ui_init(void) { use_default_colors(); raw(); noecho(); + nonl(); /* get ^j */ input.string[0] = '\0'; memset(input.history, 0, sizeof(input.history)); @@ -432,7 +433,8 @@ ui_read(void) { if (input.string[input.counter]) input.counter++; break; - case '\n': + case KEY_ENTER: + case '\r': command_eval(input.string); /* free checks for null */ free(input.history[INPUT_HIST_MAX - 1]); @@ -1089,11 +1091,15 @@ void ui_draw_main(void) { struct History *p; int y, lines; + int i; ui_wclear(&windows[Win_main]); + for (i=0, p = selected.history->history; p && p->next && i < windows[Win_main].scroll; i++) + p = p->next; + y = windows[Win_main].h; - for (p = selected.history->history; p && y > 0; p = p->next) { + for (; p && y > 0; p = p->next) { if (!(p->options & HIST_SHOW)) continue; if (ui_hist_len(&windows[Win_main], p, &lines) <= 0) @@ -1133,6 +1139,7 @@ ui_select(struct Server *server, struct Channel *channel) { windows[Win_nicklist].location = HIDDEN; else windows[Win_nicklist].location = config_getl("nicklist.location"); + windows[Win_main].scroll = -1; ui_redraw(); }