src/buddy_chat.c

changeset 2385
883dabd877db
parent 2384
c7249c80fbc4
child 2386
1b79255087be
equal deleted inserted replaced
2384:c7249c80fbc4 2385:883dabd877db
436 436
437 aol_icon(invite->window); 437 aol_icon(invite->window);
438 438
439 } 439 }
440 gtk_widget_show(invite); 440 gtk_widget_show(invite);
441 }
442
443 void tab_complete(struct conversation *c)
444 {
445 int pos = GTK_EDITABLE(c->entry)->current_pos;
446 int start = pos;
447 int most_matched = -1;
448 char *entered, *partial = NULL;
449 char *text;
450 GList *matches = NULL;
451 GList *nicks = c->in_room;
452
453 /* if there's nothing there just return */
454 if (!start)
455 return;
456
457 text = gtk_editable_get_chars(GTK_EDITABLE(c->entry), 0, pos);
458
459 /* if we're at the end of ": " we need to move back 2 spaces */
460 if (start >= 2 && text[start - 1] == ' ' && text[start - 2] == ':')
461 start -= 2;
462
463 /* find the start of the word that we're tabbing */
464 while (start > 0 && text[start - 1] != ' ')
465 start--;
466
467 entered = text + start;
468 if (chat_options & OPT_CHAT_OLD_STYLE_TAB) {
469 if (strlen(entered) >= 2 && !strncmp(": ", entered + strlen(entered) - 2, 2))
470 entered[strlen(entered) - 2] = 0;
471 }
472
473 if (!strlen(entered)) {
474 g_free(text);
475 return;
476 }
477
478 debug_printf("checking tab-completion for %s\n", entered);
479
480 while (nicks) {
481 char *nick = nicks->data;
482 /* this checks to see if the current nick could be a completion */
483 if (g_strncasecmp(nick, entered, strlen(entered))) {
484 if (nick[0] != '+' && nick[0] != '@') {
485 nicks = nicks->next;
486 continue;
487 }
488 if (g_strncasecmp(nick + 1, entered, strlen(entered))) {
489 if (nick[0] != '@' && nick[1] != '+') {
490 nicks = nicks->next;
491 continue;
492 }
493 if (g_strncasecmp(nick + 2, entered, strlen(entered))) {
494 nicks = nicks->next;
495 continue;
496 }
497 else
498 nick += 2;
499 } else
500 nick++;
501 }
502 /* if we're here, it's a possible completion */
503 debug_printf("possible completion: %s\n", nick);
504
505 /* if we're doing old-style, just fill in the completion */
506 if (chat_options & OPT_CHAT_OLD_STYLE_TAB) {
507 gtk_editable_delete_text(GTK_EDITABLE(c->entry), start, pos);
508 if (strlen(nick) == strlen(entered)) {
509 nicks = nicks->next ? nicks->next : c->in_room;
510 nick = nicks->data;
511 if (*nick == '@')
512 nick++;
513 if (*nick == '+')
514 nick++;
515 }
516
517 if (start == 0) {
518 char *tmp = g_strdup_printf("%s: ", nick);
519 int t = start;
520 gtk_editable_insert_text(GTK_EDITABLE(c->entry), tmp, strlen(tmp), &start);
521 if (t == start) {
522 t = start + strlen(tmp);
523 gtk_editable_set_position(GTK_EDITABLE(c->entry), t);
524 }
525 g_free(tmp);
526 } else {
527 int t = start;
528 gtk_editable_insert_text(GTK_EDITABLE(c->entry), nick, strlen(nick), &start);
529 if (t == start) {
530 t = start + strlen(nick);
531 gtk_editable_set_position(GTK_EDITABLE(c->entry), t);
532 }
533 }
534 g_free(text);
535 return;
536 }
537
538 /* we're only here if we're doing new style */
539 if (most_matched == -1) {
540 /* this will only get called once, since from now on most_matched is >= 0 */
541 most_matched = strlen(nick);
542 partial = g_strdup(nick);
543 } else if (most_matched) {
544 while (g_strncasecmp(nick, partial, most_matched))
545 most_matched--;
546 partial[most_matched] = 0;
547 }
548 matches = g_list_append(matches, nick);
549
550 nicks = nicks->next;
551 }
552 /* we're only here if we're doing new style */
553
554 /* if there weren't any matches, return */
555 if (!matches) {
556 /* if matches isn't set partials won't be either */
557 g_free(text);
558 return;
559 }
560
561 gtk_editable_delete_text(GTK_EDITABLE(c->entry), start, pos);
562 if (!matches->next) {
563 /* there was only one match. fill it in. */
564 if (start == 0) {
565 char *tmp = g_strdup_printf("%s: ", (char *)matches->data);
566 int t = start;
567 gtk_editable_insert_text(GTK_EDITABLE(c->entry), tmp, strlen(tmp), &start);
568 if (t == start) {
569 t = start + strlen(tmp);
570 gtk_editable_set_position(GTK_EDITABLE(c->entry), t);
571 }
572 g_free(tmp);
573 } else {
574 gtk_editable_insert_text(GTK_EDITABLE(c->entry), matches->data, strlen(matches->data), &start);
575 }
576 matches = g_list_remove(matches, matches->data);
577 } else {
578 /* there were lots of matches, fill in as much as possible and display all of them */
579 char *addthis = g_malloc0(1);
580 int t = start;
581 while (matches) {
582 char *tmp = addthis;
583 addthis = g_strconcat(tmp, matches->data, " ", NULL);
584 g_free(tmp);
585 matches = g_list_remove(matches, matches->data);
586 }
587 write_to_conv(c, addthis, WFLAG_NOLOG, NULL, time(NULL));
588 gtk_editable_insert_text(GTK_EDITABLE(c->entry), partial, strlen(partial), &start);
589 if (t == start) {
590 t = start + strlen(partial);
591 gtk_editable_set_position(GTK_EDITABLE(c->entry), t);
592 }
593 g_free(addthis);
594 }
595
596 g_free(text);
597 g_free(partial);
441 } 598 }
442 599
443 gboolean meify(char *message) 600 gboolean meify(char *message)
444 { 601 {
445 /* read /me-ify : if the message (post-HTML) starts with /me, remove 602 /* read /me-ify : if the message (post-HTML) starts with /me, remove

mercurial