mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-12 23:33:03 +01:00
add tab auto-complete function for groupchat names
This commit is contained in:
parent
3804233c21
commit
4c27df32b0
@ -308,6 +308,22 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key)
|
||||
}
|
||||
}
|
||||
|
||||
else if (key == '\t') { /* TAB key: completes peer name */
|
||||
if (ctx->len >= 2) {
|
||||
int diff = complete_line(ctx->line, &ctx->pos, &ctx->len, groupchats[self->num].peer_names,
|
||||
groupchats[self->num].num_peers, TOX_MAX_NAME_LENGTH);
|
||||
|
||||
if (diff != -1 && (ctx->len < (x2 * (CHATBOX_HEIGHT - 1)-1))) {
|
||||
if (x + diff > x2 - 1) {
|
||||
int ofst = (x + diff - 1) - (x2 - 1);
|
||||
wmove(self->window, y+1, ofst);
|
||||
} else {
|
||||
wmove(self->window, y, x+diff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Scroll peerlist up and down one position if list overflows window */
|
||||
else if (key == KEY_NPAGE) {
|
||||
int L = y2 - CHATBOX_HEIGHT - SDBAR_OFST;
|
||||
|
103
src/misc_tools.c
103
src/misc_tools.c
@ -57,7 +57,36 @@ int string_is_empty(char *string)
|
||||
return string[0] == '\0';
|
||||
}
|
||||
|
||||
/* convert wide characters to null terminated string */
|
||||
/* convert a multibyte string to a wide character string (must provide buffer) */
|
||||
int char_to_wcs_buf(wchar_t *buf, const uint8_t *string, size_t n)
|
||||
{
|
||||
size_t len = mbstowcs(NULL, string, 0) + 1;
|
||||
|
||||
if (n < len)
|
||||
return -1;
|
||||
|
||||
if ((len = mbstowcs(buf, string, n)) == (size_t) -1)
|
||||
return -1;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* converts wide character string into a multibyte string.
|
||||
Same thing as wcs_to_char() but caller must provide its own buffer */
|
||||
int wcs_to_char_buf(uint8_t *buf, const wchar_t *string, size_t n)
|
||||
{
|
||||
size_t len = wcstombs(NULL, string, 0) + 1;
|
||||
|
||||
if (n < len)
|
||||
return -1;
|
||||
|
||||
if ((len = wcstombs(buf, string, n)) == (size_t) -1)
|
||||
return -1;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* convert wide characters to multibyte string */
|
||||
uint8_t *wcs_to_char(wchar_t *string)
|
||||
{
|
||||
uint8_t *ret = NULL;
|
||||
@ -66,8 +95,10 @@ uint8_t *wcs_to_char(wchar_t *string)
|
||||
if (len != (size_t) -1) {
|
||||
ret = malloc(++len);
|
||||
|
||||
if (ret != NULL)
|
||||
wcstombs(ret, string, len);
|
||||
if (ret != NULL) {
|
||||
if (wcstombs(ret, string, len) == (size_t) -1)
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
ret = malloc(2);
|
||||
|
||||
@ -86,7 +117,7 @@ uint8_t *wcs_to_char(wchar_t *string)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* convert a wide char to null terminated string */
|
||||
/* convert a wide char to multibyte string */
|
||||
char *wc_to_char(wchar_t ch)
|
||||
{
|
||||
static char ret[MB_LEN_MAX + 1];
|
||||
@ -251,3 +282,67 @@ void reset_buf(wchar_t *buf, size_t *pos, size_t *len)
|
||||
*pos = 0;
|
||||
*len = 0;
|
||||
}
|
||||
|
||||
/* 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
|
||||
with "Hello john". It shouldn't matter where pos is within buf.
|
||||
|
||||
list is a pointer to the list of strings being compared, n_items is the number of items
|
||||
in the list, and size is the size of each item in the list.
|
||||
|
||||
Returns the difference between the old len and new len of buf */
|
||||
int complete_line(wchar_t *buf, size_t *pos, size_t *len, const uint8_t *list, int n_items, int size)
|
||||
{
|
||||
if (*pos <= 0 || *len < 2 || *len > MAX_STR_SIZE)
|
||||
return -1;
|
||||
|
||||
uint8_t ubuf[MAX_STR_SIZE];
|
||||
|
||||
if (wcs_to_char_buf(ubuf, buf, MAX_STR_SIZE) == -1)
|
||||
return -1;
|
||||
|
||||
/* isolate substring from space behind pos to pos */
|
||||
uint8_t tmp[MAX_STR_SIZE];
|
||||
snprintf(tmp, sizeof(tmp), "%s", ubuf);
|
||||
tmp[*pos] = '\0';
|
||||
uint8_t *sub = strrchr(tmp, ' ');
|
||||
|
||||
if (!sub++)
|
||||
sub = tmp;
|
||||
|
||||
const uint8_t *match;
|
||||
int i;
|
||||
|
||||
/* look for a match in list */
|
||||
for (i = 0; i < n_items; ++i) {
|
||||
if (match = strstr(&list[i*size], sub))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!match)
|
||||
return -1;
|
||||
|
||||
/* put match in correct spot in buf */
|
||||
int s_len = strlen(sub);
|
||||
int m_len = strlen(match);
|
||||
int strt = *pos - s_len;
|
||||
|
||||
uint8_t tmpend[MAX_STR_SIZE];
|
||||
strcpy(tmpend, &ubuf[*pos]);
|
||||
strcpy(&ubuf[strt], match);
|
||||
strcpy(&ubuf[strt+m_len], tmpend);
|
||||
|
||||
/* convert to widechar and copy back to original buf */
|
||||
wchar_t newbuf[MAX_STR_SIZE];
|
||||
|
||||
if (char_to_wcs_buf(newbuf, ubuf, MAX_STR_SIZE) == -1)
|
||||
return -1;
|
||||
|
||||
int diff = m_len - s_len;
|
||||
*len += diff;
|
||||
*pos += diff;
|
||||
|
||||
wmemcpy(buf, newbuf, MAX_STR_SIZE);
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
@ -16,10 +16,17 @@ void print_time(WINDOW *window);
|
||||
/* Returns 1 if the string is empty, 0 otherwise */
|
||||
int string_is_empty(char *string);
|
||||
|
||||
/* convert wide characters to null terminated string */
|
||||
/* convert a multibyte string to a wide character string (must provide buffer) */
|
||||
int char_to_wcs_buf(wchar_t *buf, const uint8_t *string, size_t n);
|
||||
|
||||
/* converts wide character string into a multibyte string.
|
||||
Same thing as wcs_to_char() but caller must provide its own buffer */
|
||||
int wcs_to_char_buf(uint8_t *buf, const wchar_t *string, size_t n);
|
||||
|
||||
/* convert wide characters to multibyte string string */
|
||||
uint8_t *wcs_to_char(wchar_t *string);
|
||||
|
||||
/* convert a wide char to null terminated string */
|
||||
/* convert a wide char to multibyte string string */
|
||||
char *wc_to_char(wchar_t ch);
|
||||
|
||||
/* Returns true if connection has timed out, false otherwise */
|
||||
@ -58,3 +65,12 @@ void kill_buf(wchar_t *buf, size_t *pos, size_t *len);
|
||||
|
||||
/* nulls buf and sets pos and len to 0 */
|
||||
void reset_buf(wchar_t *buf, size_t *pos, size_t *len);
|
||||
|
||||
/* looks for the first instance in list that begins with the last entered word in buf,
|
||||
then completes the word. e.g. "Hello jo" would complete the buffer with "Hello john".
|
||||
|
||||
list is a pointer to the list of strings being compared, n_items is the number of items
|
||||
in the list, and size is the size of each item in the list.
|
||||
|
||||
Returns the difference between the old len and new len of buf */
|
||||
int complete_line(wchar_t *buf, size_t *pos, size_t *len, const uint8_t *list, int n_items, int size);
|
@ -221,7 +221,7 @@ void set_next_window(int ch)
|
||||
ToxWindow *inf = active_window;
|
||||
|
||||
while (true) {
|
||||
if (ch == '\t' || ch == T_KEY_NEXT) {
|
||||
if (ch == T_KEY_NEXT) {
|
||||
if (++active_window > end)
|
||||
active_window = windows;
|
||||
} else if (--active_window < windows)
|
||||
@ -348,7 +348,7 @@ void draw_active_window(Tox *m)
|
||||
ch = getch();
|
||||
#endif
|
||||
|
||||
if (ch == '\t' || ch == KEY_BTAB || ch == T_KEY_NEXT || ch == T_KEY_PREV)
|
||||
if (ch == T_KEY_NEXT || ch == T_KEY_PREV)
|
||||
set_next_window((int) ch);
|
||||
else if (ch != ERR)
|
||||
a->onKey(a, m, ch);
|
||||
|
Loading…
Reference in New Issue
Block a user