[mw-devel] [Git][arthur/mw][master] Implement tab completion for mw.command.foo

Andrew Price welshbyte at sucs.org
Mon Feb 18 04:50:28 GMT 2019


Andrew Price pushed to branch master at Justin Mitchell / mw


Commits:
30bbacf8 by Andrew Price at 2019-02-18T04:46:40Z
Implement tab completion for mw.command.foo

Also fix and simplify the implementation of mw.command

Fixes #34

- - - - -


3 changed files:

- src/client/alias.c
- src/client/js-duk.c
- src/client/js.h


Changes:

=====================================
src/client/alias.c
=====================================
@@ -10,6 +10,7 @@
 #include "intl.h"
 #include "userio.h"
 
+#include "js.h"
 #include "alias.h"
 alias *alias_list = NULL;
 alias *bind_list = NULL;
@@ -176,24 +177,33 @@ char *list_bind(const char *text, int state)
 char *list_bind_rl(const char *text, int state)
 {
 	static alias *bind;
-	static int	len;
-	char		*name;
+	static int js_idx;
+	static int len;
+	char *completion;
+	const char *name;
 
-	if (state == 0)
-	{
+	if (state == 0) {
 		bind = bind_list;
+		js_idx = 0;
 		len = strlen(text);
 		len--;
 	}
 
 	text++;
 
-	while (bind != NULL)
-	{
+	while (bind != NULL) {
 		name = bind->from;
 		bind = bind->next;
-		if ((len == 0) || !strncasecmp(name, text, len))
-			return dupstr(name, ",");
+		if ((len == 0) || !strncasecmp(name, text, len)) {
+			asprintf(&completion, ",%s", name);
+			return completion;
+		}
+	}
+	while ((name = js_command_name_get(js_idx++)) != NULL) {
+		if ((len == 0) || !strncasecmp(name, text, len)) {
+			asprintf(&completion, ",%s", name);
+			return completion;
+		}
 	}
 	return NULL;
 }


=====================================
src/client/js-duk.c
=====================================
@@ -1132,51 +1132,6 @@ static void define_store_object(const char *name)
 	duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE);
 }
 
-static duk_ret_t js_command_get(duk_context *cx)
-{
-	const char *key = duk_get_string(cx, 1);
-
-	duk_push_this(cx);
-	(void)duk_get_prop_string(cx, -1, key);
-	return 1;
-}
-
-static duk_ret_t js_command_set(duk_context *cx)
-{
-	(void)duk_require_string(cx, 1);
-	duk_require_callable(cx, 2);
-
-	duk_push_this(cx); /* Target object */
-	duk_dup(cx, 1); /* Command name */
-	duk_dup(cx, 2); /* Handler */
-	duk_def_prop(cx, -3, DUK_DEFPROP_HAVE_VALUE|DUK_DEFPROP_SET_CONFIGURABLE);
-	return 0;
-}
-
-static duk_ret_t js_command_has(duk_context *cx)
-{
-	const char *key = duk_get_string(cx, 1);
-
-	duk_push_this(cx);
-	return duk_has_prop_string(cx, -1, key);
-}
-
-static duk_ret_t js_command_delete(duk_context *cx)
-{
-	const char *key = duk_get_string(cx, 1);
-
-	duk_push_this(cx);
-	return duk_del_prop_string(cx, -1, key);
-}
-
-static const duk_function_list_entry command_handlers[] = {
-	{ "get", js_command_get, 3 },
-	{ "set", js_command_set, 4 },
-	{ "has", js_command_has, 2 },
-	{ "deleteProperty", js_command_delete, 2 },
-	{ NULL, NULL, 0 }
-};
-
 /* The owning object must be at the top of the stack when calling this */
 static void define_command_object(void)
 {
@@ -1184,16 +1139,14 @@ static void define_command_object(void)
 	duk_push_string(ctx, "command"); /* To be used by duk_def_prop() below */
 	duk_push_object(ctx); /* command object */
 	duk_push_object(ctx); /* Handler object */
-	duk_put_function_list(ctx, -1, command_handlers);
 	duk_push_proxy(ctx, 0); /* Stack is now [ "command", proxy ] */
 
 	/* Define the command object in the parent object */
 	duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE);
 }
 
-int js_handle_command(const char *name, int argc, const char **argv)
+static int js_push_command_object(void)
 {
-	duk_require_stack(ctx, argc + 5);
 	if (!duk_get_global_string(ctx, "mw")) {
 		fprintf(stderr, "mwjs error: failed to lookup mw namespace\n");
 		duk_pop(ctx);
@@ -1208,6 +1161,15 @@ int js_handle_command(const char *name, int argc, const char **argv)
 		fprintf(stderr, "mwjs error: 'mw.command' is not an object\n");
 		return -1;
 	}
+	return 0;
+}
+
+int js_handle_command(const char *name, int argc, const char **argv)
+{
+	duk_require_stack(ctx, argc + 5);
+	if (js_push_command_object())
+		return -1;
+
 	if (!duk_get_prop_string(ctx, -1, name)) {
 		duk_pop_3(ctx);
 		return 1;
@@ -1228,6 +1190,25 @@ int js_handle_command(const char *name, int argc, const char **argv)
 	return 0;
 }
 
+const char *js_command_name_get(int x)
+{
+	char *name = NULL;
+	int i = 0;
+
+	if (js_push_command_object())
+		return NULL;
+
+	duk_enum(ctx, -1, 0);
+	while (name == NULL && duk_next(ctx, -1, 0)) {
+		const char *str = duk_get_string(ctx, -1);
+		if (i++ == x)
+			name = strdup(str);
+		duk_pop(ctx);
+	}
+	duk_pop(ctx);
+	return name;
+}
+
 /* The owning object must be at the top of the stack when calling this */
 static void define_func(const char *name, duk_c_function func, int nargs)
 {


=====================================
src/client/js.h
=====================================
@@ -24,4 +24,6 @@ enum bindtype {
 	K_BIND_INPUT
 };
 
+const char *js_command_name_get(int x);
+
 #endif /* JS_H */



View it on GitLab: https://projects.sucs.org/arthur/mw/commit/30bbacf89bf911c2c84d4c7fa0d15b2ee2b3089e

-- 
View it on GitLab: https://projects.sucs.org/arthur/mw/commit/30bbacf89bf911c2c84d4c7fa0d15b2ee2b3089e
You're receiving this email because of your account on projects.sucs.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sucs.org/pipermail/mw-devel/attachments/20190218/385b17b9/attachment-0001.html>


More information about the mw-devel mailing list