Mercurial > hg > nnchat
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; |