comparison nnchat.c @ 189:b0d64dde62af

Fix username tab completion. Should now work like in Irssi, though the problem with usernames with whitespace still exists.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 16 Nov 2010 19:28:31 +0200
parents 6b399b7ce40b
children df284de8b118
comparison
equal deleted inserted replaced
188:6b399b7ce40b 189:b0d64dde62af
730 if (editWin) redrawwin(editWin); 730 if (editWin) redrawwin(editWin);
731 } 731 }
732 732
733 BOOL performTabCompletion(nn_editbuf_t *buf) 733 BOOL performTabCompletion(nn_editbuf_t *buf)
734 { 734 {
735 static char *previous = NULL; 735 static char *previous = NULL, *pattern = NULL;
736 static char *pattern = NULL; 736 BOOL again = FALSE, hasSeparator = FALSE, newPattern = FALSE, hasSpace = FALSE;
737 char *str = buf->data;
737 int mode = 0; 738 int mode = 0;
738 BOOL again = FALSE; 739 ssize_t endPos, startPos = buf->pos;
739 char *str = buf->data; 740
740 ssize_t endPos = 0, startPos = buf->pos; 741 /* previous word */
741 742 if (startPos >= 2 && str[startPos - 1] == ' ' && str[startPos - 2] != ' ') {
742 if (startPos > 1 && str[startPos - 1] == ' ') {
743 startPos -= 2; 743 startPos -= 2;
744 if (str[startPos] == optNickSep)
745 startPos--;
746 if (startPos <= 0 || str[startPos] == ' ')
747 return FALSE;
748 endPos = startPos; 744 endPos = startPos;
749 while (startPos > 0 && str[startPos - 1] != ' ') startPos--; 745 while (startPos > 0 && str[startPos - 1] != ' ') startPos--;
750 mode = 1; 746 mode = 1;
751 } else 747 } else
752 if (str[startPos - 1] != ' ' && (startPos == buf->len || str[startPos] == ' ')) { 748 /* middle of a word, new pattern */
753 char *npattern; 749 if (startPos < buf->len && str[startPos] != ' ') {
754
755 endPos = startPos; 750 endPos = startPos;
756 while (startPos > 0 && str[startPos - 1] != ' ') startPos--; 751 while (startPos > 0 && str[startPos - 1] != ' ') startPos--;
757 while (endPos < buf->len && str[endPos] != ' ') endPos++; 752 while (endPos < buf->len - 1 && str[endPos + 1] != ' ') endPos++;
758 while (endPos > 0 && str[endPos] == ' ') endPos--; 753 newPattern = TRUE;
759 if (str[endPos] == optNickSep) 754 mode = 2;
755 } else
756 /* previous word, new pattern */
757 if (startPos >= 1 && str[startPos - 1] != ' ') {
758 startPos -= 1;
759 endPos = startPos;
760 while (startPos > 0 && str[startPos - 1] != ' ') startPos--;
761 newPattern = TRUE;
762 mode = 3;
763 } else {
764 if (optDebug)
765 printMsg("no mode\n");
766 return FALSE;
767 }
768
769 if (str[endPos] == optNickSep) {
770 endPos--;
771 if (startPos > 0) {
772 if (optDebug)
773 printMsg("str[endPos] == optNickSep && startPos > 0 (%d)\n", startPos);
760 return FALSE; 774 return FALSE;
761 775 }
776 hasSeparator = TRUE;
777 }
778
779 if (buf->pos > 0 && str[buf->pos - 1] == ' ')
780 hasSpace = TRUE;
781 if (buf->pos <= buf->len && str[buf->pos] == ' ')
782 hasSpace = TRUE;
783
784 if (newPattern) {
762 /* Get pattern, check if it matches previous pattern and set 'again' flag */ 785 /* Get pattern, check if it matches previous pattern and set 'again' flag */
763 npattern = nn_editbuf_get_string(buf, startPos, endPos); 786 char *npattern = nn_editbuf_get_string(buf, startPos, endPos);
764 if (pattern && npattern && strcasecmp(npattern, pattern) == 0) 787 if (pattern && npattern && strcasecmp(npattern, pattern) == 0)
765 again = TRUE; 788 again = TRUE;
766 th_free(pattern); pattern = npattern; 789
790 th_free(pattern);
791 pattern = npattern;
792
767 if (!again) { 793 if (!again) {
768 th_free(previous); 794 th_free(previous);
769 previous = NULL; 795 previous = NULL;
770 } 796 }
771 mode = 2; 797 }
772 } 798
773 799 if (optDebug) {
774 if (optDebug) 800 printMsg("sPos=%d, ePos=%d <-> bPos=%d, bufLen=%d : pat='%s' (again=%s, hassep=%s, hasspc=%s, newpat=%s, mode=%d)\n",
775 printMsg("sPos=%d, ePos=%d <-> bLen=%d : pat='%s' (mode=%d, again=%s)\n", 801 startPos, endPos, buf->pos, buf->len, pattern,
776 startPos, endPos, buf->len, pattern, mode, again ? "yes" : "no"); 802 again ? "yes" : "no",
803 hasSeparator ? "yes" : "no",
804 hasSpace ? "yes" : "no",
805 newPattern ? "yes" : "no", mode);
806 }
777 807
778 if (pattern) { 808 if (pattern) {
779 nn_user_t *user = nn_user_match(nnUsers, pattern, previous, again); 809 nn_user_t *user = nn_user_match(nnUsers, pattern, previous, again);
780 810
781 if (user) { 811 if (user) {
788 nn_editbuf_delete(buf, startPos); 818 nn_editbuf_delete(buf, startPos);
789 819
790 for (i = startPos; *c; i++, c++) 820 for (i = startPos; *c; i++, c++)
791 nn_editbuf_insert(buf, i, *c); 821 nn_editbuf_insert(buf, i, *c);
792 822
793 if (previous == NULL || again) { 823 if (!hasSeparator && startPos == 0) {
794 if (startPos == 0) { 824 nn_editbuf_insert(buf, i++, optNickSep);
795 nn_editbuf_insert(buf, i++, optNickSep); 825 startPos++;
796 startPos++; 826 }
797 } 827 if (hasSeparator)
828 startPos++;
829 if (!hasSpace)
798 nn_editbuf_insert(buf, i++, ' '); 830 nn_editbuf_insert(buf, i++, ' ');
799 } 831
800 nn_editbuf_setpos(buf, startPos + 2 + strlen(user->name)); 832 nn_editbuf_setpos(buf, startPos + 1 + strlen(user->name));
801 833
802 th_free(previous); 834 th_free(previous);
803 previous = th_strdup(user->name); 835 previous = th_strdup(user->name);
804 836
805 return TRUE; 837 return TRUE;