#include #include #include #include "addrs.h" #include "edbox.h" #include "screen.h" #include "irc.h" #define COMP_S1 1 #define COMP_PM 2 #define COMP_CHAN 3 #define MAX_PM_NICKS 10 static char search_pos = 0, in_progress = 0; static char prefix[33]; char comp_pm_nicks[MAX_PM_NICKS][25]; char comp_pm_chans[MAX_PM_NICKS][25]; char comp_chan_nicks[MAX_PM_NICKS][25]; char (*list)[25] = comp_pm_nicks; char (*add_to)[25] = comp_pm_nicks; static char pm_nick_pos = 0; /* insertion point for _add() */ static void add_list(const char *n) { int i; for(i = 0; i < 25; i++) if(strncmp(n, add_to[i], 24) == 0) return; /* we already got this one */ strncpy(add_to[pm_nick_pos], n, 24); pm_nick_pos++; pm_nick_pos %= MAX_PM_NICKS; } void comp_add_pm_nick(const char *n) { add_to = comp_pm_nicks; add_list(n); } void comp_add_pm_chan(const char *n) { add_to = comp_pm_chans; add_list(n); } char match(const char *p, const char *q) { int len; while(*p == '#') p++; while(*q == '#') q++; len = strlen(p); if(!len) return 0; while(len--) { if(tolower(*p) != tolower(*q)) return 0; p++, q++; } return 1; } void scrape_nick(char *p) { char i; if(*p == '<' || *p == 0xbc) { /* normal or inverse < in column 0 is a nick */ p++; } else if(*p == '*' && p[1] == ' ') { p += 2; /* /me action, skip the "* " */ } else { return; } if(*p & 0x80) /* skip highlighted own nick! */ return; for(i = 0; i < 24; i++) { switch(p[i]) { case '>': case 0xbe: /* inverse > */ case ' ': list[pm_nick_pos++][i] = 0; return; /* found one, terminate and return */ case 0: list[pm_nick_pos][0] = 0; return; /* if it ends with a null, it's not a nick */ default: list[pm_nick_pos][i] = p[i]; break; } } list[pm_nick_pos][0] = 0; } void find_chan_nicks(void) { signed char i; char *p; add_to = comp_chan_nicks; pm_nick_pos = 0; for(i = 22; i >= 0; i--) { p = screen_bot_addrs[scr_current] + 40 * i; scrape_nick(p); if(pm_nick_pos == MAX_PM_NICKS) return; } for(i = 24; i >= 0; i--) { scrape_nick(p); p = screen_top_addrs[scr_current] + 40 * i; if(pm_nick_pos == MAX_PM_NICKS) return; } } void comp_complete_done(void) { in_progress = 0; } void comp_continue(void) { search_pos %= MAX_PM_NICKS; while(search_pos < MAX_PM_NICKS) { if(match(prefix, list[search_pos])) { edbox_set(list[search_pos]); edbox_space(); search_pos++; return; } search_pos++; } edbox_set(prefix); /* no space here */ comp_complete_done(); } void comp_start(void) { char *p; if(scr_current == SCR_SERVER) { p = last_chan; list = comp_pm_chans; } else if(scr_current == SCR_PRIV) { p = last_pm_nick; list = comp_pm_nicks; } else if(scr_names[scr_current][0] == '#') { p = last_pm_nick; // XXX: there should be a last_hilite_nick! find_chan_nicks(); list = comp_chan_nicks; } /* just insert the last nick/chan if there's nothing to search for */ if(!edbox_len) { if(*p) { edbox_set(p); edbox_space(); } } else { in_progress = COMP_PM; search_pos = 0; strncpy(prefix, edit_box, 24); comp_continue(); } } void comp_complete(void) { if(in_progress) comp_continue(); else comp_start(); }