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