comparison main.c @ 450:a8373a1ce1eb

Implement command tab completion.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 26 May 2012 05:09:40 +0300
parents 7d9fa9f7caf1
children 733396469e5d
comparison
equal deleted inserted replaced
449:7d9fa9f7caf1 450:a8373a1ce1eb
1154 size_t len; 1154 size_t len;
1155 int (*handler)(nn_conn_t *, char *buf); 1155 int (*handler)(nn_conn_t *, char *buf);
1156 } nn_usercmd_t; 1156 } nn_usercmd_t;
1157 1157
1158 1158
1159 static nn_usercmd_t userCmds[] = 1159 static nn_usercmd_t userCmdsTable[] =
1160 { 1160 {
1161 // Server side commands, we just implement completion 1161 // Server side commands, we just implement completion
1162 { "me", CMDARG_STRING, 0, NULL }, 1162 { "/me", CMDARG_STRING, 0, NULL },
1163 { "status", CMDARG_STRING, 0, NULL }, 1163 { "/status", CMDARG_STRING, 0, NULL },
1164 { "list", CMDARG_NONE, 0, nncmd_list_all_users }, 1164 { "/list", CMDARG_NONE, 0, nncmd_list_all_users },
1165 1165
1166 // List internal username list 1166 // List internal username list
1167 { "who", CMDARG_NONE, 0, nncmd_names }, 1167 { "/who", CMDARG_NONE, 0, nncmd_names },
1168 { "names", CMDARG_NONE, 0, nncmd_names }, 1168 { "/names", CMDARG_NONE, 0, nncmd_names },
1169 1169
1170 { "w", CMDARG_NICK, 0, nncmd_open_profile }, 1170 { "/w", CMDARG_NICK, 0, nncmd_open_profile },
1171 { "profile", CMDARG_NICK, 0, nncmd_open_profile }, 1171 { "/profile", CMDARG_NICK, 0, nncmd_open_profile },
1172 1172
1173 { "query", CMDARG_NICK, 0, nncmd_open_query }, 1173 { "/query", CMDARG_NICK, 0, nncmd_open_query },
1174 { "close", CMDARG_OPTIONAL, 0, nncmd_close_query }, 1174 { "/close", CMDARG_OPTIONAL, 0, nncmd_close_query },
1175 { "win", CMDARG_OPTIONAL, 0, nncmd_window_info }, 1175 { "/win", CMDARG_OPTIONAL, 0, nncmd_window_info },
1176 1176
1177 { "ignore", CMDARG_NICK, 0, nncmd_ignore }, 1177 { "/ignore", CMDARG_NICK, 0, nncmd_ignore },
1178 { "color", CMDARG_STRING, 0, nncmd_set_color }, 1178 { "/color", CMDARG_STRING, 0, nncmd_set_color },
1179 { "save", CMDARG_NONE, 0, nncmd_save_config }, 1179 { "/save", CMDARG_NONE, 0, nncmd_save_config },
1180 }; 1180 };
1181 1181
1182 static const int nuserCmds = sizeof(userCmds) / sizeof(userCmds[0]); 1182 static qlist_t *userCmds = NULL;
1183
1184
1185 void nn_usercmd_init()
1186 {
1187 size_t i;
1188 for (i = 0; i < sizeof(userCmdsTable) / sizeof(userCmdsTable[0]); i++)
1189 {
1190 th_llist_append(&userCmds, &userCmdsTable[i]);
1191 userCmdsTable[i].len = strlen(userCmdsTable[i].name);
1192 }
1193 }
1183 1194
1184 1195
1185 int nn_handle_command(nn_conn_t *conn, char *buf) 1196 int nn_handle_command(nn_conn_t *conn, char *buf)
1186 { 1197 {
1187 static BOOL userCmdsInit = FALSE; 1198 qlist_t *curr;
1188 int i; 1199
1189 1200 for (curr = userCmds; curr != NULL; curr = curr->next)
1190 // Initialize command structure 1201 {
1191 if (!userCmdsInit) 1202 nn_usercmd_t *cmd = curr->data;
1192 { 1203
1193 for (i = 0; i < nuserCmds; i++) 1204 if (!th_strncasecmp(buf, cmd->name, cmd->len))
1194 userCmds[i].len = strlen(userCmds[i].name); 1205 {
1195 1206 char *nbuf = str_trim_left(buf + cmd->len);
1196 userCmdsInit = TRUE;
1197 }
1198
1199
1200 for (i = 0; i < nuserCmds; i++)
1201 {
1202 nn_usercmd_t *cmd = &userCmds[i];
1203 if (!th_strncasecmp(buf + 1, cmd->name, cmd->len))
1204 {
1205 char *nbuf = str_trim_left(buf + 1 + cmd->len);
1206 1207
1207 switch (cmd->flags) 1208 switch (cmd->flags)
1208 { 1209 {
1209 case CMDARG_NICK: 1210 case CMDARG_NICK:
1210 case CMDARG_STRING: 1211 case CMDARG_STRING:
1211 if (!nbuf[0]) 1212 if (!nbuf[0])
1212 { 1213 {
1213 printMsgQ(currWin, "Command: /%s requires an argument.\n", cmd->name); 1214 printMsgQ(currWin, "Command %s requires an argument.\n", cmd->name);
1214 return 1; 1215 return 1;
1215 } 1216 }
1216 break; 1217 break;
1217 1218
1218 case CMDARG_NONE: 1219 case CMDARG_NONE:
1219 if (nbuf[0]) 1220 if (nbuf[0])
1220 { 1221 {
1221 printMsgQ(currWin, "Command: /%s does not take arguments.\n", cmd->name); 1222 printMsgQ(currWin, "Command %s does not take arguments.\n", cmd->name);
1222 return 1; 1223 return 1;
1223 } 1224 }
1224 break; 1225 break;
1225 1226
1226 case CMDARG_OPTIONAL: 1227 case CMDARG_OPTIONAL:
1249 printMsgQ(currWin, "Unknown command: %s\n", buf); 1250 printMsgQ(currWin, "Unknown command: %s\n", buf);
1250 return 1; 1251 return 1;
1251 } 1252 }
1252 1253
1253 1254
1255 static nn_usercmd_t *nn_usercmd_match_do(qlist_t *list, const char *pattern, size_t len)
1256 {
1257 qlist_t *node;
1258 for (node = list; node != NULL; node = node->next)
1259 {
1260 nn_usercmd_t *cmd = node->data;
1261 if (len <= strlen(cmd->name) && th_strncasecmp(cmd->name, pattern, len) == 0)
1262 return cmd;
1263 }
1264 return NULL;
1265 }
1266
1267
1268 nn_usercmd_t *nn_usercmd_match(qlist_t *list, const char *pattern, const char *current, BOOL again)
1269 {
1270 nn_usercmd_t *curr;
1271 size_t len;
1272
1273 if (list == NULL || pattern == NULL) return NULL;
1274
1275 len = strlen(pattern);
1276
1277 if (current != NULL)
1278 {
1279 qlist_t *node;
1280 for (node = list; node != NULL; node = node->next)
1281 {
1282 curr = node->data;
1283 if (th_strcasecmp(curr->name, current) == 0)
1284 {
1285 if (again)
1286 return curr;
1287
1288 if ((curr = nn_usercmd_match_do(node->next, pattern, len)) != NULL)
1289 return curr;
1290 }
1291 }
1292 }
1293
1294 if ((curr = nn_usercmd_match_do(list, pattern, len)) != NULL)
1295 return curr;
1296
1297 return NULL;
1298 }
1299
1300
1254 int nn_handle_input(nn_conn_t *conn, char *buf, size_t bufLen) 1301 int nn_handle_input(nn_conn_t *conn, char *buf, size_t bufLen)
1255 { 1302 {
1256 BOOL result; 1303 BOOL result;
1257 char *tmp; 1304 char *tmp;
1258 1305
1432 if (!pattern) 1479 if (!pattern)
1433 return FALSE; 1480 return FALSE;
1434 1481
1435 if (isCommand) 1482 if (isCommand)
1436 { 1483 {
1437 /* 1484 nn_usercmd_t *cmd = nn_usercmd_match(userCmds, pattern, previous, again);
1438 int i; 1485 if (cmd)
1439 for (i = 0; i < nuserCmds; i++) 1486 {
1440 { 1487 size_t i;
1441 if (nncmd_match(pattern, 1488 nn_tabcomplete_replace(buf, &i, startPos, endPos, cmd->name);
1442 } 1489
1443 */ 1490 if (!hasSpace)
1491 nn_editbuf_insert(buf, i++, ' ');
1492
1493 nn_tabcomplete_finish(buf, &previous, startPos, cmd->name);
1494 return TRUE;
1495 }
1444 } 1496 }
1445 else 1497 else
1446 { 1498 {
1447 nn_user_t *user = nn_userhash_match(nnUsers, pattern, previous, again); 1499 nn_user_t *user = nn_userhash_match(nnUsers, pattern, previous, again);
1448 1500
1868 optUserNameEnc = nn_dblencode_str(optUserName); 1920 optUserNameEnc = nn_dblencode_str(optUserName);
1869 tmpStr = nn_dblencode_str(optSite); 1921 tmpStr = nn_dblencode_str(optSite);
1870 nn_conn_send_msg_v(conn, optUserNameEnc, "%%2Flogin%%20%%2Dsite%%20%s%%20%%2Dpassword%%20%s", tmpStr, optPassword); 1922 nn_conn_send_msg_v(conn, optUserNameEnc, "%%2Flogin%%20%%2Dsite%%20%s%%20%%2Dpassword%%20%s", tmpStr, optPassword);
1871 th_free(tmpStr); 1923 th_free(tmpStr);
1872 1924
1925 // Initialize user commands
1926 nn_usercmd_init();
1927
1873 // Initialize random numbers 1928 // Initialize random numbers
1874 prevTime = time(NULL); 1929 prevTime = time(NULL);
1875 srandom((int) prevTime); 1930 srandom((int) prevTime);
1876 1931
1877 if (cursesInit) 1932 if (cursesInit)