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