comparison nnchat.c @ 113:2a53156e7e12

Yay, tab-completion cycling now works (except for usernames with whitespaces, of course ...)
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 24 Oct 2010 21:38:47 +0300
parents c4865ac2386c
children 256cca8cc086
comparison
equal deleted inserted replaced
112:c4865ac2386c 113:2a53156e7e12
639 scrollok(mainWin, 1); 639 scrollok(mainWin, 1);
640 640
641 return TRUE; 641 return TRUE;
642 } 642 }
643 643
644 void performTabCompletion(nn_editbuf_t *buf) 644 /*
645 Different tab completion scenarios:
646
647 Line start
648 "foo<tab>" ->
649 * store "foo" as pattern
650 * find match: "Foobar"
651 * replace "foo" with match
652
653 "Foobar: <tab>" ->
654 * ": " -> cycle to next match
655 * "Foorulez"
656 * replace "Foobar: " with "Foorulez: "
657
658 Same when completing in middle of line, but " " instead of ": ".
659 */
660 BOOL performTabCompletion(nn_editbuf_t *buf)
645 { 661 {
646 static char *previous = NULL; 662 static char *previous = NULL;
647 static char *matsi = NULL; 663 static char *pattern = NULL;
648 char *b = buf->data; 664 int mode = 0;
649 ssize_t pos2 = 0, pos1 = buf->pos; 665 char *str = buf->data;
650 666 ssize_t endPos = 0, startPos = buf->pos;
651 if (pos1 > 0) pos1--; 667
652 668 if (startPos > 1 && str[startPos - 1] == ' ') {
653 if (pos1 > 0 && b[pos1 - 1] == ':') { 669 startPos -= 2;
654 pos1 -= 2; 670 if (str[startPos] == ':')
655 pos2 = pos1; 671 startPos--;
656 while (pos1 > 0 && b[pos1 - 1] != ' ') pos1--; 672 if (startPos <= 0 || str[startPos] == ' ')
673 return FALSE;
674 endPos = startPos;
675 while (startPos > 0 && str[startPos - 1] != ' ') startPos--;
676 mode = 1;
657 } else 677 } else
658 if (b[pos1] != ' ' && b[pos1] != ':') { 678 if (str[startPos - 1] != ' ' && (startPos == buf->len || str[startPos] == ' ')) {
659 pos2 = pos1; 679 endPos = startPos;
660 while (pos1 > 0 && b[pos1 - 1] != ' ') pos1--; 680 while (startPos > 0 && str[startPos - 1] != ' ') startPos--;
661 while (pos2 < buf->len && b[pos2] != ' ') pos2++; 681 while (endPos < buf->len && str[endPos] != ' ') endPos++;
662 while (pos2 > 0 && b[pos2] == ' ') pos2--; 682 while (endPos > 0 && str[endPos] == ' ') endPos--;
663 th_free(matsi); 683 if (str[endPos] == ':')
664 matsi = nn_editbuf_get_string(buf, pos1, pos2); 684 return FALSE;
685 th_free(pattern);
686 pattern = nn_editbuf_get_string(buf, startPos, endPos);
665 th_free(previous); previous = NULL; 687 th_free(previous); previous = NULL;
666 } 688 mode = 2;
667 689 }
668 if (matsi) { 690 // printMsg("%d, %d <-> %d : '%s' (%d)\n", startPos, endPos, buf->len, pattern, mode);
669 nn_user_t *user = nn_user_match(nnUsers, matsi, previous); 691
670 // printMsg("pattern '%s'\n", matsi); 692 if (pattern) {
693 nn_user_t *user = nn_user_match(nnUsers, pattern, previous);
671 694
672 if (user) { 695 if (user) {
673 int i; 696 int i;
674 char *c = user->name; 697 char *c = user->name;
675 // printMsg("match '%s'\n", user->name); 698 // printMsg("match '%s'\n", user->name);
676 699
677 for (i = pos1; i <= pos2; i++) 700 for (i = startPos; i <= endPos; i++)
678 nn_editbuf_delete(buf, pos1); 701 nn_editbuf_delete(buf, startPos);
679 702
680 for (i = pos1; *c; i++, c++) 703 for (i = startPos; *c; i++, c++)
681 nn_editbuf_insert(buf, i, *c); 704 nn_editbuf_insert(buf, i, *c);
682 705
683 if (previous == NULL) { 706 if (previous == NULL) {
684 nn_editbuf_insert(buf, i+1, ':'); 707 if (startPos == 0) {
685 nn_editbuf_insert(buf, i+2, ' '); 708 nn_editbuf_insert(buf, i++, ':');
709 startPos++;
710 }
711 nn_editbuf_insert(buf, i++, ' ');
686 } 712 }
687 nn_editbuf_setpos(buf, pos1 + 2 + strlen(user->name)); 713 nn_editbuf_setpos(buf, startPos + 2 + strlen(user->name));
688 714
689 th_free(previous); 715 th_free(previous);
690 previous = th_strdup(user->name); 716 previous = th_strdup(user->name);
691 } 717
692 } 718 return TRUE;
719 }
720 }
721
722 return FALSE;
693 } 723 }
694 724
695 int main(int argc, char *argv[]) 725 int main(int argc, char *argv[])
696 { 726 {
697 int tmpSocket = -1, curVis = ERR, updateCount = 0; 727 int tmpSocket = -1, curVis = ERR, updateCount = 0;