mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-22 21:23:01 +01:00
add line history with up/down keys
This commit is contained in:
parent
ccc0640dab
commit
9a5a598c5a
23
src/chat.c
23
src/chat.c
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
}
|
@ -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);
|
||||||
|
22
src/prompt.c
22
src/prompt.c
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user