diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/command.c | 30 | ||||
-rw-r--r-- | src/gui/gui-buffer.c | 201 | ||||
-rw-r--r-- | src/gui/gui.h | 1 |
3 files changed, 227 insertions, 5 deletions
diff --git a/src/common/command.c b/src/common/command.c index 3347be88b..66c7f1f22 100644 --- a/src/common/command.c +++ b/src/common/command.c @@ -65,12 +65,27 @@ t_weechat_command weechat_commands[] = " move: move buffer in the list (may be relative, for example -1)\n" " close: close buffer (optional arg is part message, for a channel)\n" " list: list open buffers (no parameter implies this list)\n" - " notify: set notify level for buffer (0=never, 1=highlight, 2=1+msg, 3=2+join/part)\n" - " (when executed on server buffer, this sets default notify level for whole server)\n" + " notify: set notify level for buffer (0=never, 1=highlight, 2=1+msg, " + "3=2+join/part)\n" + " (when executed on server buffer, this sets default notify " + "level for whole server)\n" + " scroll: scroll in history (may be relative, and may end by a letter: " + "s=sec, m=min, h=hour, d=day, M=month, y=year); if there is " + "only letter, then scroll to beginning of this item\n\n" + " number: jump to buffer by number\n" "server,\n" - "channel: jump to buffer by server and/or channel name\n" - " number: jump to buffer by number"), - "move|close|list|notify|%S|%C %S|%C", 0, MAX_ARGS, 0, NULL, weechat_cmd_buffer }, + "channel: jump to buffer by server and/or channel name\n\n" + "Examples:\n" + " move buffer: /buffer move 5\n" + " close buffer: /buffer close this is part msg\n" + " set notify: /buffer notify 2\n" + " scroll 1 day up: /buffer scroll 1d == /buffer scroll -1d == /buffer scroll -24h\n" + "scroll to beginning\n" + " of this day: /buffer scroll d\n" + " scroll 15 min down: /buffer scroll +15m\n" + " scroll 20 msgs up: /buffer scroll -20\n" + " jump to #weechat: /buffer #weechat"), + "move|close|list|notify|scroll|%S|%C %S|%C", 0, MAX_ARGS, 0, NULL, weechat_cmd_buffer }, { "builtin", N_("launch WeeChat/IRC builtin command (do not look at plugins handlers or aliases)"), N_("command"), N_("command: command to execute (a '/' is automatically added if not found at beginning of command)\n"), @@ -1380,6 +1395,11 @@ weechat_cmd_buffer (t_irc_server *server, t_irc_channel *channel, } } } + else if (ascii_strcasecmp (argv[0], "scroll") == 0) + { + if (argc >= 2) + gui_buffer_scroll (window, argv[1]); + } else { /* jump to buffer by number or server/channel name */ diff --git a/src/gui/gui-buffer.c b/src/gui/gui-buffer.c index 267478c45..3de88052a 100644 --- a/src/gui/gui-buffer.c +++ b/src/gui/gui-buffer.c @@ -1190,6 +1190,207 @@ gui_buffer_search_stop (t_gui_window *window) } /* + * gui_buffer_scroll: scroll buffer by # messages or time + */ + +void +gui_buffer_scroll (t_gui_window *window, char *scroll) +{ + int direction, stop, count_msg; + char time_letter, saved_char; + time_t old_date, diff_date; + char *error; + long number; + t_gui_line *ptr_line; + struct tm *date_tmp, line_date, old_line_date; + + if (window->buffer->lines) + { + direction = -1; + number = 0; + time_letter = ' '; + + // search direction + if (scroll[0] == '-') + { + direction = -1; + scroll++; + } + else if (scroll[0] == '+') + { + direction = +1; + scroll++; + } + + // search number and letter + char *pos = scroll; + while (pos && pos[0] && isdigit (pos[0])) + { + pos++; + } + if (pos) + { + if (pos == scroll) + { + if (pos[0]) + time_letter = scroll[0]; + } + else + { + if (pos[0]) + time_letter = pos[0]; + saved_char = pos[0]; + pos[0] = '\0'; + error = NULL; + number = strtol (scroll, &error, 10); + if (!error || (error[0] != '\0')) + number = 0; + pos[0] = saved_char; + } + } + + /* at least number or letter has to he given */ + if ((number == 0) && (time_letter == ' ')) + return; + + // do the scroll! + stop = 0; + count_msg = 0; + if (direction < 0) + ptr_line = (window->start_line) ? + window->start_line : window->buffer->last_line; + else + ptr_line = (window->start_line) ? + window->start_line : window->buffer->lines; + + old_date = ptr_line->date; + date_tmp = localtime (&old_date); + memcpy (&old_line_date, date_tmp, sizeof (struct tm)); + + while (ptr_line) + { + ptr_line = (direction < 0) ? ptr_line->prev_line : ptr_line->next_line; + + if (ptr_line) + { + if (time_letter == ' ') + { + count_msg++; + if (count_msg >= number) + stop = 1; + } + else + { + date_tmp = localtime (&(ptr_line->date)); + memcpy (&line_date, date_tmp, sizeof (struct tm)); + if (old_date > ptr_line->date) + diff_date = old_date - ptr_line->date; + else + diff_date = ptr_line->date - old_date; + switch (time_letter) + { + case 's': /* seconds */ + if (number == 0) + { + /* stop if line has different second */ + if ((line_date.tm_sec != old_line_date.tm_sec) + || (line_date.tm_min != old_line_date.tm_min) + || (line_date.tm_hour != old_line_date.tm_hour) + || (line_date.tm_mday != old_line_date.tm_mday) + || (line_date.tm_mon != old_line_date.tm_mon) + || (line_date.tm_year != old_line_date.tm_year)) + if (line_date.tm_sec != old_line_date.tm_sec) + stop = 1; + } + else if (diff_date >= number) + stop = 1; + break; + case 'm': /* minutes */ + if (number == 0) + { + /* stop if line has different minute */ + if ((line_date.tm_min != old_line_date.tm_min) + || (line_date.tm_hour != old_line_date.tm_hour) + || (line_date.tm_mday != old_line_date.tm_mday) + || (line_date.tm_mon != old_line_date.tm_mon) + || (line_date.tm_year != old_line_date.tm_year)) + stop = 1; + } + else if (diff_date >= number * 60) + stop = 1; + break; + case 'h': /* hours */ + if (number == 0) + { + /* stop if line has different hour */ + if ((line_date.tm_hour != old_line_date.tm_hour) + || (line_date.tm_mday != old_line_date.tm_mday) + || (line_date.tm_mon != old_line_date.tm_mon) + || (line_date.tm_year != old_line_date.tm_year)) + stop = 1; + } + else if (diff_date >= number * 60 * 60) + stop = 1; + break; + case 'd': /* days */ + if (number == 0) + { + /* stop if line has different day */ + if ((line_date.tm_mday != old_line_date.tm_mday) + || (line_date.tm_mon != old_line_date.tm_mon) + || (line_date.tm_year != old_line_date.tm_year)) + stop = 1; + } + else if (diff_date >= number * 60 * 60 * 24) + stop = 1; + break; + case 'M': /* months */ + if (number == 0) + { + /* stop if line has different month */ + if ((line_date.tm_mon != old_line_date.tm_mon) + || (line_date.tm_year != old_line_date.tm_year)) + stop = 1; + } + /* we consider month is 30 days, who will find I'm too + lazy to code exact date diff ? ;) */ + else if (diff_date >= number * 60 * 60 * 24 * 30) + stop = 1; + break; + case 'y': /* years */ + if (number == 0) + { + /* stop if line has different year */ + if (line_date.tm_year != old_line_date.tm_year) + stop = 1; + } + /* we consider year is 365 days, who will find I'm too + lazy to code exact date diff ? ;) */ + else if (diff_date >= number * 60 * 60 * 24 * 365) + stop = 1; + break; + } + } + if (stop) + { + window->start_line = ptr_line; + window->start_line_pos = 0; + window->first_line_displayed = + (window->start_line == window->buffer->lines); + gui_chat_draw (window->buffer, 1); + gui_status_draw (window->buffer, 0); + return; + } + } + } + if (direction < 0) + gui_window_scroll_top (window); + else + gui_window_scroll_bottom (window); + } +} + +/* * gui_buffer_print_log: print buffer infos in log (usually for crash dump) */ diff --git a/src/gui/gui.h b/src/gui/gui.h index 3a022bffd..8afb5d79c 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -105,6 +105,7 @@ extern void gui_buffer_search_start (t_gui_window *); extern void gui_buffer_search_restart (t_gui_window *); extern void gui_buffer_search_stop (t_gui_window *); extern int gui_buffer_search_text (t_gui_window *); +extern void gui_buffer_scroll (t_gui_window *, char *); extern void gui_buffer_print_log (t_gui_buffer *); /* panel */ |