summaryrefslogtreecommitdiff
path: root/lib/autocomplete.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <petermikkelsen10@gmail.com>2026-04-01 22:24:22 +0200
committerPeter Mikkelsen <petermikkelsen10@gmail.com>2026-04-04 19:51:35 +0200
commita809bc0f49ee4c6e777f39d1f80ee57862a0fcab (patch)
tree5187dbd9b83205aac62d1f48252025b6e2d158a9 /lib/autocomplete.c
Initial import of the code into gitv0.1
Diffstat (limited to 'lib/autocomplete.c')
-rw-r--r--lib/autocomplete.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/lib/autocomplete.c b/lib/autocomplete.c
new file mode 100644
index 0000000..12a8cdc
--- /dev/null
+++ b/lib/autocomplete.c
@@ -0,0 +1,94 @@
+/* Aplwc - A Programming Language With Constraints
+ *
+ * Copyright (C) 2026 Peter Mikkelsen <petermikkelsen10@gmail.com>
+ *
+ * This file is part of aplwc.
+ *
+ * Aplwc is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Aplwc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with aplwc. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <aplwc.h>
+#include "aplwc_internal.h"
+
+struct completion_state {
+ const struct aplwc *aplwc;
+ int num;
+ const char *word;
+ const int wordlen;
+};
+
+static char **generate(struct aplwc *, const char *, char *(*)(struct completion_state *));
+static char *completions_syscmd(struct completion_state *);
+
+char **
+aplwc_autocomplete(struct aplwc *aplwc, const char *line, int start, int end)
+{
+ int len = end-start;
+ char *word = malloc(sizeof(char) * len+1);
+ char **completions = NULL;
+
+ memcpy(word, line+start, len);
+ word[len] = 0;
+
+ if(start == 0 && word[0] == ')')
+ completions = generate(aplwc, word, completions_syscmd);
+ free(word);
+
+ return completions;
+}
+
+static char **
+generate(struct aplwc *aplwc, const char *word, char *(*fn)(struct completion_state *))
+{
+ char **completions = NULL;
+ struct completion_state state = {
+ .aplwc = aplwc,
+ .num = 0,
+ .word = word,
+ .wordlen = strlen(word),
+ };
+
+ char *c;
+ int index = 0;
+ while(c = fn(&state)){
+ index++;
+ completions = realloc(completions, sizeof(*completions) * (index + 1));
+ completions[index-1] = c;
+ completions[index] = NULL;
+ }
+
+ return completions;
+}
+
+static char *
+completions_syscmd(struct completion_state *state)
+{
+ struct aplwc_syscmd *syscmd;
+
+ while(syscmd = state->aplwc->syscmds[state->num++]){
+ const char *name = syscmd->name;
+ if(strncmp(name, state->word+1, state->wordlen-1) == 0){
+ int len = strlen(name);
+ char *result = malloc(sizeof(char) * (len + 2));
+ result[0] = ')';
+ memcpy(result+1, name, sizeof(char) * (len+1));
+ return result;
+ }
+ }
+
+ return NULL;
+}