📄 fkeys.c
字号:
{ if (d1 && d1[0]) { if (tab_nick_comp (wid, 1) == -1) return 1; else return 2; } else { if (tab_nick_comp (wid, 0) == -1) return 1; else return 2; }}static intkey_action_comp_chng (GtkWidget * wid, GdkEventKey * ent, char *d1, char *d2, struct session *sess){ if (d1 && d1[0] != 0) nick_comp_chng (wid, 1); else nick_comp_chng (wid, 0); return 2;}static intkey_action_replace (GtkWidget * wid, GdkEventKey * ent, char *d1, char *d2, struct session *sess){ replace_handle (wid); return 1;}static intkey_action_move_tab_left (GtkWidget * wid, GdkEventKey * ent, char *d1, char *d2, struct session *sess){ wins_move_leftorright (sess->gui->window, TRUE); return 2; /* don't allow default action */}static intkey_action_move_tab_right (GtkWidget * wid, GdkEventKey * ent, char *d1, char *d2, struct session *sess){ wins_move_leftorright (sess->gui->window, FALSE); return 2; /* -''- */}static intkey_action_put_history (GtkWidget * wid, GdkEventKey * ent, char *d1, char *d2, struct session *sess){ history_add (&sess->history, gtk_entry_get_text (GTK_ENTRY (wid))); gtk_entry_set_text (GTK_ENTRY (wid), ""); return 2; /* -''- */}/* -------- */#define STATE_SHIFT GDK_SHIFT_MASK#define STATE_ALT GDK_MOD1_MASK#define STATE_CTRL GDK_CONTROL_MASKstatic voidreplace_handle (GtkWidget *t){ char *text, *postfix_pnt; struct popup *pop; GSList *list = replace_list; char word[256]; char postfix[256]; char outbuf[4096]; int c, len, xlen; text = gtk_entry_get_text (GTK_ENTRY (t)); len = strlen (text); for (c = len - 1; c > 0; c--) { if (text[c] == ' ') break; } if (text[c] == ' ') c++; xlen = c; if (len - c >= (sizeof (word) - 12)) return; if (len - c < 1) return; memcpy (word, &text[c], len - c); word[len - c] = 0; len = strlen (word); if (word[0] == '\'' && word[len] == '\'') return; postfix_pnt = NULL; for (c = 0; c < len; c++) { if (word[c] == '\'') { postfix_pnt = &word[c + 1]; word[c] = 0; break; } } if (postfix_pnt != NULL) { if (strlen (postfix_pnt) > sizeof (postfix) - 12) return; strcpy (postfix, postfix_pnt); } while (list) { pop = (struct popup *) list->data; if (strcmp (pop->name, word) == 0) { memcpy (outbuf, text, xlen); outbuf[xlen] = 0; if (postfix_pnt == NULL) snprintf (word, sizeof (word), "%s", pop->cmd); else snprintf (word, sizeof (word), "%s%s", pop->cmd, postfix); strcat (outbuf, word); gtk_entry_set_text (GTK_ENTRY (t), outbuf); return; } list = list->next; }}static struct session *find_session_from_inputgad (GtkWidget * w){ GSList *list = sess_list; struct session *sess; /* First find the session from the widget */ while (list) { sess = (struct session *) list->data; if (sess->gui->inputgad == w) return sess; list = list->next; } /*Erm, we didn't find ANY valid session, HELP! */ return NULL;}static intnick_comp_get_nick (char *tx, char *n){ int c, len = strlen (tx); for (c = 0; c < len; c++) { if (tx[c] == ':' || tx[c] == ',' || tx[c] == prefs.nick_suffix[0]) { n[c] = 0; return 0; } if (tx[c] == ' ' || tx[c] == '.' || tx[c] == 0) return -1; n[c] = tx[c]; } return -1;}static voidnick_comp_chng (GtkWidget * t, int updown){ struct session *sess; struct User *user, *last = NULL; char *text, nick[64]; int len, slen; GSList *list; sess = find_session_from_inputgad (t); if (sess == NULL) return; text = gtk_entry_get_text (GTK_ENTRY (t)); if (nick_comp_get_nick (text, nick) == -1) return; len = strlen (nick); list = sess->userlist; while (list) { user = (struct User *) list->data; slen = strlen (user->nick); if (len != slen) { last = user; list = list->next; continue; } if (strncasecmp (user->nick, nick, len) == 0) { if (updown == 0) { if (list->next == NULL) return; user->weight--; ((struct User *) list->next->data)->weight++; snprintf (nick, sizeof (nick), "%s%c ", ((struct User *) list->next->data)->nick, prefs.nick_suffix[0]); } else { if (last == NULL) return; user->weight--; last->weight++; snprintf (nick, sizeof (nick), "%s%c ", last->nick, prefs.nick_suffix[0]); } gtk_entry_set_text (GTK_ENTRY (t), nick); return; } last = user; list = list->next; }}static voidtab_comp_find_common (char *a, char *b){ int c; int alen = strlen (a), blen = strlen (b), len; if (blen > alen) len = alen; else len = blen; for (c = 0; c < len; c++) { if (a[c] != b[c]) { a[c] = 0; return; } } a[c] = 0;}static voidtab_comp_cmd (GtkWidget * t){ char *text, *last = NULL, *cmd, *postfix = NULL; GSList *list = command_list; struct popup *pop; int len, i, slen; struct session *sess; char buf[2048]; char lcmd[2048]; text = gtk_entry_get_text (GTK_ENTRY (t)); sess = find_session_from_inputgad (t); text++; len = strlen (text); if (len == 0) return; for (i = 0; i < len; i++) { if (text[i] == ' ') { postfix = &text[i + 1]; text[i] = 0; len = strlen (text); break; } } while (list) { pop = (struct popup *) list->data; slen = strlen (pop->name); if (len > slen) { list = list->next; continue; } if (strncasecmp (pop->name, text, len) == 0) { if (last == NULL) { last = pop->name; snprintf (lcmd, sizeof (lcmd), "%s", last); } else if (last > (char *) 1) { snprintf (buf, sizeof (buf), "%s %s ", last, pop->name); PrintText (sess, buf); last = (void *) 1; tab_comp_find_common (lcmd, pop->name); } else if (last == (void *) 1) { PrintText (sess, pop->name); tab_comp_find_common (lcmd, pop->name); } } list = list->next; } i = 0; while (xc_cmds[i].name != NULL) { cmd = xc_cmds[i].name; slen = strlen (cmd); if (len > slen) { i++; continue; } if (strncasecmp (cmd, text, len) == 0) { if (last == NULL) { last = cmd; snprintf (lcmd, sizeof (lcmd), "%s", last); } else if (last > (char *) 1) { snprintf (buf, sizeof (buf), "%s %s ", last, cmd); PrintText (sess, buf); last = (void *) 1; tab_comp_find_common (lcmd, cmd); } else if (last == (void *) 1) { PrintText (sess, cmd); tab_comp_find_common (lcmd, cmd); } } i++; } if (last == NULL) return; if (last == (void *) 1) PrintText (sess, "\n"); if (last > (char *) 1) { if (strlen (last) > (sizeof (buf) - 1)) return; if (postfix == NULL) snprintf (buf, sizeof (buf), "/%s ", last); else snprintf (buf, sizeof (buf), "/%s %s", last, postfix); gtk_entry_set_text (GTK_ENTRY (t), buf); return; } else if (strlen (lcmd) > (sizeof (buf) - 1)) return; if (postfix == NULL) snprintf (buf, sizeof (buf), "/%s", lcmd); else snprintf (buf, sizeof (buf), "/%s %s", lcmd, postfix); gtk_entry_set_text (GTK_ENTRY (t), buf);}/* In the following 'b4' is *before* the text (just say b4 and before out loud) and c5 is *after* (because c5 is next after b4, get it??) --AGL */static inttab_nick_comp_next (struct session *sess, GtkWidget * wid, char *b4, char *nick, char *c5, int shift){ struct User *user = 0, *last = NULL; char buf[4096]; GSList *list; list = sess->userlist; while (list) { user = (struct User *) list->data; if (strcmp (user->nick, nick) == 0) break; last = user; list = list->next; } if (!list) return 0; if (shift) { if (last) snprintf (buf, 4096, "%s %s%s", b4, last->nick, c5); else snprintf (buf, 4096, "%s %s%s", b4, nick, c5); } else { if (list->next) snprintf (buf, 4096, "%s %s%s", b4, ((struct User *) list->next->data)->nick, c5); else { if (sess->userlist) snprintf (buf, 4096, "%s %s%s", b4, ((struct User *) sess->userlist->data)->nick, c5); else snprintf (buf, 4096, "%s %s%s", b4, nick, c5); } } gtk_entry_set_text (GTK_ENTRY (wid), buf); return 1;}static inttab_nick_comp (GtkWidget *t, int shift){ struct session *sess; struct User *user = NULL, *match_user = NULL; char *text, not_nick_chars[16] = ""; int len, slen, first = 0, i, j, match_count = 0, match_pos = 0; char buf[2048], nick_buf[2048] = {0}, *b4 = NULL, *c5 = NULL, *match_text = NULL, match_char = -1, *nick = NULL, *current_nick = NULL; GSList *list = NULL, *match_list = NULL, *first_match = NULL; text = gtk_entry_get_text (GTK_ENTRY (t)); sess = find_session_from_inputgad (t); if (sess == NULL) return 0; if (sess->type == SESS_DIALOG) return 0; len = strlen (text); if (!strchr (text, ' ')) { if (text[0] == '/') { tab_comp_cmd (t); return 0; } } /* Is the text more than just a nick? */ sprintf(not_nick_chars, " .?%c", prefs.nick_suffix[0]); if (strcspn (text, not_nick_chars) != strlen (text)) { /* If we're doing old-style nick completion and the text input widget * contains a string of the format: "nicknameSUFFIX" or "nicknameSUFFIX ", * where SUFFIX is the Nickname Completion Suffix character, then cycle * through the available nicknames. */ if (prefs.old_nickcompletion) { char * space = strchr(text, ' '); if ((!space || space == &text[len - 1]) && text[len - (space ? 2 : 1)] == prefs.nick_suffix[0]) { /* This causes the nickname to cycle. */ nick_comp_chng(t, shift); return 0; } } j = GTK_EDITABLE (t)->current_pos; /* !! FIXME !! */ if (len - j < 0) return 0; b4 = (char *) malloc (len + 1); c5 = (char *) malloc (len + 1); memmove (c5, &text[j], len - j); c5[len - j] = 0; memcpy (b4, text, len + 1); for (i = j - 1; i > -1; i--) { if (b4[i] == ' ') { b4[i] = 0; break; } b4[i] = 0; } memmove (text, &text[i + 1], (j - i) + 1); text[(j - i) - 1] = 0; if (tab_nick_comp_next (sess, t, b4, text, c5, shift)) { free (b4); free (c5); return 1; } first = 0; } else first = 1; len = strlen (text); if (text[0] == 0) return -1; list = sess->userlist; /* make a list of matches */ while (list) { user = (struct User *) list->data; slen = strlen (user->nick); if (len > slen) { list = list->next; continue; } if (strncasecmp (user->nick, text, len) == 0) match_list = g_slist_prepend (match_list, user->nick); list = list->next; } match_list = g_slist_reverse (match_list); /* faster then _append */ match_count = g_slist_length (match_list); /* no matches, return */ if (match_count == 0) { if (!first) { free (b4); free (c5); } return 0; } first_match = match_list; match_pos = len; /* if we have more then 1 match, we want to act like readline and grab common chars */ if (!prefs.old_nickcompletion && match_count > 1) { while (1) { while (match_list) { current_nick = (char *) malloc (strlen ((char *) match_list->data) + 1); strcpy (current_nick, (char *) match_list->data); if (match_char == -1) { match_char = current_nick[match_pos]; match_list = g_slist_next (match_list); free (current_nick); continue; } if (tolower (current_nick[match_pos]) != tolower (match_char)) { match_text = (char *) malloc (match_pos); current_nick[match_pos] = '\0'; strcpy (match_text, current_nick); free (current_nick); match_pos = -1; break; } match_list = g_slist_next (match_list); free (current_nick); } if (match_pos == -1) break; match_list = first_match; match_char = -1; ++match_pos; } match_list = first_match; } else match_user = (struct User *) match_list->data; /* no match, if we found more common chars among matches, display them in entry */ if (match_user == NULL) { while (match_list) { nick = (char *) match_list->data; sprintf (nick_buf, "%s%s ", nick_buf, nick); match_list = g_slist_next (match_list); } PrintText (sess, nick_buf); if (first) snprintf (buf, sizeof (buf), "%s", match_text); else { snprintf (buf, sizeof (buf), "%s %s%s", b4, match_text, c5); GTK_EDITABLE (t)->current_pos = strlen (b4) + strlen (match_text); free (b4); free (c5); } free (match_text); } else { if (first) snprintf (buf, sizeof (buf), "%s%c ", match_user->nick, prefs.nick_suffix[0]); else { snprintf (buf, sizeof (buf), "%s %s%s", b4, match_user->nick, c5); GTK_EDITABLE (t)->current_pos = strlen (b4) + strlen (match_user->nick); free (b4); free (c5); } } gtk_entry_set_text (GTK_ENTRY (t), buf); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -