1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-23 02:13:01 +01:00

add line history with up/down keys

This commit is contained in:
Jfreegman 2013-12-11 00:10:09 -05:00
parent ccc0640dab
commit 9a5a598c5a
8 changed files with 148 additions and 5 deletions

View File

@ -342,9 +342,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
else if (key == KEY_END) { /* END key: move cursor to end of line */ else if (key == KEY_END) { /* END key: move cursor to end of line */
if (ctx->pos != ctx->len) { if (ctx->pos != ctx->len) {
ctx->pos = ctx->len; ctx->pos = ctx->len;
int end_y = (ctx->len / x2) + (y2 - CURS_Y_OFFSET); mv_curs_end(self->window, ctx->len, y2, x2);
int end_x = ctx->len % x2;
wmove(self->window, end_y, end_x);
} }
} }
@ -370,6 +368,22 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
} }
} }
else if (key == KEY_UP) { /* fetches previous item in history */
if (ctx->hst_pos >= 0) {
fetch_hist_item(ctx->line, &ctx->pos, &ctx->len, ctx->ln_history, &ctx->hst_tot,
&ctx->hst_pos, LN_HIST_MV_UP);
mv_curs_end(self->window, ctx->len, y2, x2);
}
}
else if (key == KEY_DOWN) { /* fetches next item in history */
if (ctx->hst_pos < ctx->hst_tot) {
fetch_hist_item(ctx->line, &ctx->pos, &ctx->len, ctx->ln_history, &ctx->hst_tot,
&ctx->hst_pos, LN_HIST_MV_DWN);
mv_curs_end(self->window, ctx->len, y2, x2);
}
}
else if (key == '\t') { /* TAB key: command */ else if (key == '\t') { /* TAB key: command */
if (ctx->len > 1 && ctx->line[0] == '/') { if (ctx->len > 1 && ctx->line[0] == '/') {
int diff = complete_line(ctx->line, &ctx->pos, &ctx->len, chat_cmd_list, AC_NUM_CHAT_COMMANDS, int diff = complete_line(ctx->line, &ctx->pos, &ctx->len, chat_cmd_list, AC_NUM_CHAT_COMMANDS,
@ -414,6 +428,9 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
wclrtobot(self->window); wclrtobot(self->window);
bool close_win = false; bool close_win = false;
if (!string_is_empty(line))
add_line_to_hist(ctx->line, ctx->len, ctx->ln_history, &ctx->hst_tot, &ctx->hst_pos);
if (line[0] == '/') { if (line[0] == '/') {
if (close_win = !strcmp(line, "/close")) { if (close_win = !strcmp(line, "/close")) {
int f_num = self->num; int f_num = self->num;

View File

@ -15,6 +15,7 @@
#include "misc_tools.h" #include "misc_tools.h"
#include "groupchat.h" #include "groupchat.h"
#include "prompt.h" #include "prompt.h"
#include "toxic_strings.h"
extern char *DATA_FILE; extern char *DATA_FILE;
extern int store_data(Tox *m, char *path); extern int store_data(Tox *m, char *path);
@ -308,6 +309,22 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key)
} }
} }
else if (key == KEY_UP) { /* fetches previous item in history */
if (ctx->hst_pos >= 0) {
fetch_hist_item(ctx->line, &ctx->pos, &ctx->len, ctx->ln_history, &ctx->hst_tot,
&ctx->hst_pos, LN_HIST_MV_UP);
mv_curs_end(self->window, ctx->len, y2, x2);
}
}
else if (key == KEY_DOWN) { /* fetches next item in history */
if (ctx->hst_pos < ctx->hst_tot) {
fetch_hist_item(ctx->line, &ctx->pos, &ctx->len, ctx->ln_history, &ctx->hst_tot,
&ctx->hst_pos, LN_HIST_MV_DWN);
mv_curs_end(self->window, ctx->len, y2, x2);
}
}
else if (key == '\t') { /* TAB key: completes peer name */ else if (key == '\t') { /* TAB key: completes peer name */
if (ctx->len > 0) { if (ctx->len > 0) {
int diff; int diff;
@ -371,6 +388,9 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key)
wclrtobot(self->window); wclrtobot(self->window);
bool close_win = false; bool close_win = false;
if (!string_is_empty(line))
add_line_to_hist(ctx->line, ctx->len, ctx->ln_history, &ctx->hst_tot, &ctx->hst_pos);
if (line[0] == '/') { if (line[0] == '/') {
if (close_win = strcmp(line, "/close") == 0) { if (close_win = strcmp(line, "/close") == 0) {
set_active_window(0); set_active_window(0);

View File

@ -185,3 +185,11 @@ bool valid_nick(uint8_t *nick)
return true; return true;
} }
/* Moves cursor to the end of the line in given window */
void mv_curs_end(WINDOW *w, size_t len, int max_y, int max_x)
{
int end_y = (len / max_x) + (max_y - CURS_Y_OFFSET);
int end_x = len % max_x;
wmove(w, end_y, end_x);
}

View File

@ -43,3 +43,6 @@ int qsort_strcasecmp_hlpr(const void *nick1, const void *nick2);
- cannot start with a space - cannot start with a space
- must not contain contiguous spaces */ - must not contain contiguous spaces */
bool valid_nick(uint8_t *nick); bool valid_nick(uint8_t *nick);
/* Moves the cursor to the end of the line in given window */
void mv_curs_end(WINDOW *w, size_t len, int max_y, int max_x);

View File

@ -163,8 +163,25 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key)
else if (key == KEY_RIGHT) { else if (key == KEY_RIGHT) {
if (prt->pos < prt->len) if (prt->pos < prt->len)
++prt->pos; ++prt->pos;
}
} else if (key == '\t') { /* TAB key: completes command */ else if (key == KEY_UP) { /* fetches previous item in history */
if (prt->hst_pos >= 0) {
wmove(self->window, prt->orig_y, X_OFST);
fetch_hist_item(prt->line, &prt->pos, &prt->len, prt->ln_history, &prt->hst_tot,
&prt->hst_pos, LN_HIST_MV_UP);
}
}
else if (key == KEY_DOWN) { /* fetches next item in history */
if (prt->hst_pos < prt->hst_tot) {
wmove(self->window, prt->orig_y, X_OFST);
fetch_hist_item(prt->line, &prt->pos, &prt->len, prt->ln_history, &prt->hst_tot,
&prt->hst_pos, LN_HIST_MV_DWN);
}
}
else if (key == '\t') { /* TAB key: completes command */
if (prt->len > 1 && prt->line[0] == '/') if (prt->len > 1 && prt->line[0] == '/')
complete_line(prt->line, &prt->pos, &prt->len, glob_cmd_list, AC_NUM_GLOB_COMMANDS, complete_line(prt->line, &prt->pos, &prt->len, glob_cmd_list, AC_NUM_GLOB_COMMANDS,
MAX_CMDNAME_SIZE); MAX_CMDNAME_SIZE);
@ -190,6 +207,9 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key)
if (wcs_to_mbs_buf(line, prt->line, MAX_STR_SIZE) == -1) if (wcs_to_mbs_buf(line, prt->line, MAX_STR_SIZE) == -1)
memset(&line, 0, sizeof(line)); memset(&line, 0, sizeof(line));
if (!string_is_empty(line))
add_line_to_hist(prt->line, prt->len, prt->ln_history, &prt->hst_tot, &prt->hst_pos);
execute(self->window, self, m, line, GLOBAL_COMMAND_MODE); execute(self->window, self, m, line, GLOBAL_COMMAND_MODE);
reset_buf(prt->line, &prt->pos, &prt->len); reset_buf(prt->line, &prt->pos, &prt->len);
} }

View File

@ -7,6 +7,7 @@
#include "toxic_windows.h" #include "toxic_windows.h"
#include "misc_tools.h" #include "misc_tools.h"
#include "toxic_strings.h"
/* Adds char to buffer at pos */ /* Adds char to buffer at pos */
void add_char_to_buf(wchar_t *buf, size_t *pos, size_t *len, wint_t ch) void add_char_to_buf(wchar_t *buf, size_t *pos, size_t *len, wint_t ch)
@ -88,6 +89,53 @@ void reset_buf(wchar_t *buf, size_t *pos, size_t *len)
*len = 0; *len = 0;
} }
/* adds a line to the ln_history buffer at hst_pos and sets hst_pos to end of history.
Assumes entries are of size MAX_STR_SIZE */
void add_line_to_hist(const wchar_t *buf, size_t len, void *ln_history, int *hst_tot, int *hst_pos)
{
if (len > MAX_STR_SIZE)
return;
wchar_t *hst = (wchar_t *) ln_history;
/* If history is full make room for newest entry and don't increment hst_tot */
if (*hst_tot == MAX_LINE_HIST) {
int i;
for (i = 0; i < MAX_LINE_HIST - 1; ++i)
wmemcpy(&hst[MAX_STR_SIZE * i], &hst[MAX_STR_SIZE * (i + 1)], MAX_STR_SIZE);
} else {
++(*hst_tot);
}
*hst_pos = *hst_tot;
wmemcpy(&hst[(*hst_tot - 1) * MAX_STR_SIZE], buf, len + 1);
}
/* copies history item at hst_pos to buf. Sets pos and len to the len of the history item.
hst_pos is decremented or incremented depending on key_dir.
Assumes history entries are of size MAX_STR_SIZE */
void fetch_hist_item(wchar_t *buf, size_t *pos, size_t *len, const void *ln_history, int *hst_tot,
int *hst_pos, int key_dir)
{
if (key_dir == LN_HIST_MV_UP) {
if (--(*hst_pos) < 0)
++(*hst_pos);
} else {
if (++(*hst_pos) == *hst_tot)
--(*hst_pos);
}
wchar_t *hst = (wchar_t *) ln_history;
const wchar_t *hst_line = &hst[*hst_pos * MAX_STR_SIZE];
size_t h_len = wcslen(hst_line);
wmemcpy(buf, hst_line, h_len + 1);
*pos = h_len;
*len = h_len;
}
/* looks for the first instance in list that begins with the last entered word in buf according to pos, /* looks for the first instance in list that begins with the last entered word in buf according to pos,
then fills buf with the complete word. e.g. "Hello jo" would complete the buffer then fills buf with the complete word. e.g. "Hello jo" would complete the buffer
with "Hello john". with "Hello john".
@ -160,7 +208,7 @@ int complete_line(wchar_t *buf, size_t *pos, size_t *len, const void *list, int
if (char_to_wcs_buf(newbuf, ubuf, MAX_STR_SIZE) == -1) if (char_to_wcs_buf(newbuf, ubuf, MAX_STR_SIZE) == -1)
return -1; return -1;
wmemcpy(buf, newbuf, MAX_STR_SIZE); wcscpy(buf, newbuf);
*len += (size_t) diff; *len += (size_t) diff;
*pos += (size_t) diff; *pos += (size_t) diff;

View File

@ -29,3 +29,18 @@ void reset_buf(wchar_t *buf, size_t *pos, size_t *len);
Returns the difference between the old len and new len of buf on success, -1 if error */ Returns the difference between the old len and new len of buf on success, -1 if error */
int complete_line(wchar_t *buf, size_t *pos, size_t *len, const void *list, int n_items, int size); int complete_line(wchar_t *buf, size_t *pos, size_t *len, const void *list, int n_items, int size);
enum {
LN_HIST_MV_UP,
LN_HIST_MV_DWN,
};
/* adds a line to the ln_history buffer at hst_pos and sets hst_pos to last history item.
Assumes entries are of size MAX_STR_SIZE */
void add_line_to_hist(const wchar_t *buf, size_t len, void *hst, int *hst_tot, int *hst_pos);
/* copies history item at hst_pos to buf. Sets pos and len to the len of the history item.
hst_pos is decremented or incremented depending on key_dir.
Assumes history entries are of size MAX_STR_SIZE */
void fetch_hist_item(wchar_t *buf, size_t *pos, size_t *len, const void *ln_history, int *hst_tot,
int *hst_pos, int key_dir);

View File

@ -110,11 +110,18 @@ struct StatusBar {
bool is_online; bool is_online;
}; };
#define MAX_LINE_HIST 64
/* chat and groupchat window/buffer holder */ /* chat and groupchat window/buffer holder */
struct ChatContext { struct ChatContext {
wchar_t line[MAX_STR_SIZE]; wchar_t line[MAX_STR_SIZE];
size_t pos; size_t pos;
size_t len; size_t len;
wchar_t ln_history[MAX_LINE_HIST][MAX_STR_SIZE];
int hst_pos;
int hst_tot;
WINDOW *history; WINDOW *history;
WINDOW *linewin; WINDOW *linewin;
WINDOW *sidebar; WINDOW *sidebar;
@ -128,6 +135,11 @@ struct PromptBuf {
bool at_bottom; /* true if line end is at bottom of window */ bool at_bottom; /* true if line end is at bottom of window */
int orig_y; /* y axis point of line origin */ int orig_y; /* y axis point of line origin */
bool scroll; /* used for prompt window hack to determine when to scroll down */ bool scroll; /* used for prompt window hack to determine when to scroll down */
wchar_t ln_history[MAX_LINE_HIST][MAX_STR_SIZE];
int hst_pos;
int hst_tot;
WINDOW *linewin; WINDOW *linewin;
}; };