aboutsummaryrefslogtreecommitdiff
path: root/client/rl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'client/rl.cpp')
-rw-r--r--client/rl.cpp37
1 files changed, 36 insertions, 1 deletions
diff --git a/client/rl.cpp b/client/rl.cpp
index 3f93e99..b8113aa 100644
--- a/client/rl.cpp
+++ b/client/rl.cpp
@@ -38,6 +38,7 @@ void rl_printf(const char *fmt, ...) {
}
static void cli_cmd(char* cmd) {
+ cmd += strspn(cmd, IFS); // skip leading whitespace
char* line = consume_token(cmd, IFS);
for (size_t i = 0; i < cmds_length; i++) {
@@ -66,9 +67,31 @@ static char* rl_completion_entries(const char *text, int state) {
return NULL;
}
+static char** rl_attempted_completion(const char * text, int start, int end) {
+ // do not suggest filenames
+ rl_attempted_completion_over = 1;
+
+ // if first word in line buffer -> complete commands from cmds[]
+ size_t cmd_start = strspn(rl_line_buffer, IFS);
+ if (start == cmd_start)
+ return rl_completion_matches(text, rl_completion_entries);
+
+ // else, check specialized completion functions
+ size_t cmd_len = strcspn(rl_line_buffer + cmd_start, IFS);
+ for (size_t i = 0; i < cmds_length; i++) {
+ cmd_t cmd = cmds[i];
+ if (cmd.complete == NULL) continue;
+ if (strncmp(cmd.name, rl_line_buffer + cmd_start, cmd_len) != 0) continue;
+ return cmd.complete(text, start, end);
+ }
+
+ // else, no completion available
+ return NULL;
+}
+
int cli_main() {
char* input = NULL;
- rl_completion_entry_function = rl_completion_entries;
+ rl_attempted_completion_function = rl_attempted_completion;
while (1) {
if (input != NULL) free(input);
@@ -84,3 +107,15 @@ int cli_main() {
return EXIT_SUCCESS;
}
+int rl_word(const char * line, int cursor) {
+ int word = -1;
+ for (int i = 0; line[i] != '\0';) {
+ i += strspn(line + i, IFS);
+ int len = strcspn(line + i, IFS);
+ word++;
+ i += len;
+ if (i > cursor) break;
+ }
+ return word;
+}
+