Browse Source

klish plugin: klish_prompt() symbol

Serj Kalichev 1 year ago
parent
commit
11c74061a2
4 changed files with 76 additions and 13 deletions
  1. 3 1
      examples/simple/example.xml
  2. 71 12
      plugins/klish/misc.c
  3. 1 0
      plugins/klish/plugin_init.c
  4. 1 0
      plugins/klish/private.h

+ 3 - 1
examples/simple/example.xml

@@ -18,7 +18,9 @@
 
 <ENTRY name="main" mode="switch" container="true">
 
-<ENTRY name="prompt" purpose="prompt" value="&gt; "/>
+<ENTRY name="prompt" purpose="prompt">
+	<ACTION sym="prompt">%u@%h&gt; </ACTION>
+</ENTRY>
 
 <ENTRY name="exit" help="Exit view">
 	<ENTRY name="COMMAND" purpose="ptype" ref="/COMMAND"/>

+ 71 - 12
plugins/klish/misc.c

@@ -8,9 +8,12 @@
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
 
 #include <faux/str.h>
 #include <faux/list.h>
+#include <faux/sysdb.h>
 #include <klish/kcontext.h>
 #include <klish/ksession.h>
 #include <klish/kpath.h>
@@ -27,12 +30,9 @@ int klish_nop(kcontext_t *context)
 // Symbol for testing purposes
 int klish_tsym(kcontext_t *context)
 {
-	const kaction_t *action = NULL;
 	const char *script = NULL;
 
-	action = (kaction_t *)faux_list_data(kcontext_action_iter(context));
-
-	script = kaction_script(action);
+	script = kcontext_script(context);
 	if (faux_str_is_empty(script)) {
 		printf("[<empty>]\n");
 		fprintf(stderr, "Empty item\n");
@@ -48,12 +48,9 @@ int klish_tsym(kcontext_t *context)
 // Print content of ACTION script
 int klish_printl(kcontext_t *context)
 {
-	const kaction_t *action = NULL;
 	const char *script = NULL;
 
-	action = (kaction_t *)faux_list_data(kcontext_action_iter(context));
-
-	script = kaction_script(action);
+	script = kcontext_script(context);
 	if (faux_str_is_empty(script))
 		script = "";
 
@@ -66,12 +63,9 @@ int klish_printl(kcontext_t *context)
 // Print content of ACTION script. Without additional '/n'
 int klish_print(kcontext_t *context)
 {
-	const kaction_t *action = NULL;
 	const char *script = NULL;
 
-	action = (kaction_t *)faux_list_data(kcontext_action_iter(context));
-
-	script = kaction_script(action);
+	script = kcontext_script(context);
 	if (faux_str_is_empty(script))
 		script = "";
 
@@ -98,3 +92,68 @@ int klish_pwd(kcontext_t *context)
 
 	return 0;
 }
+
+
+// Template for easy prompt string generation
+int klish_prompt(kcontext_t *context)
+{
+	const char *script = NULL;
+	const char *start = NULL;
+	const char *pos = NULL;
+	char *prompt = NULL;
+	bool_t is_macro = BOOL_FALSE;
+
+	script = kcontext_script(context);
+	if (faux_str_is_empty(script))
+		return 0;
+	pos = script;
+	start = script;
+
+	while (*pos != '\0') {
+
+		if (is_macro) {
+			switch (*pos) {
+			// Percent symbol itself
+			case '%': {
+				faux_str_cat(&prompt, "%");
+				break;
+				}
+			// Hostname
+			case 'h': {
+				struct utsname buf;
+				if (uname(&buf) == 0)
+					faux_str_cat(&prompt, buf.nodename);
+				break;
+				}
+			// Username
+			case 'u': {
+				char *user = getenv("USER");
+				if (user) {
+					faux_str_cat(&prompt, user);
+					break;
+				}
+				user = faux_sysdb_name_by_uid(getuid());
+				if (user)
+					faux_str_cat(&prompt, user);
+				faux_str_free(user);
+				break;
+				}
+			}
+			is_macro = BOOL_FALSE;
+			start = pos + 1;
+		} else if (*pos == '%') {
+			is_macro = BOOL_TRUE;
+			if (pos > start)
+				faux_str_catn(&prompt, start, pos - start);
+		}
+		pos++;
+	}
+	if (pos > start)
+		faux_str_catn(&prompt, start, pos - start);
+
+	printf("%s", prompt);
+	faux_str_free(prompt);
+	fflush(stdout);
+
+	return 0;
+}

+ 1 - 0
plugins/klish/plugin_init.c

@@ -34,6 +34,7 @@ int kplugin_klish_init(kcontext_t *context)
 	kplugin_add_syms(plugin, ksym_new("printl", klish_printl));
 	kplugin_add_syms(plugin, ksym_new_ext("pwd", klish_pwd,
 		KSYM_PERMANENT, KSYM_SYNC));
+	kplugin_add_syms(plugin, ksym_new("prompt", klish_prompt));
 
 	// Navigation
 	// Navigation must be permanent (no dry-run) and sync. Because unsync

+ 1 - 0
plugins/klish/private.h

@@ -17,6 +17,7 @@ int klish_tsym(kcontext_t *context);
 int klish_print(kcontext_t *context);
 int klish_printl(kcontext_t *context);
 int klish_pwd(kcontext_t *context);
+int klish_prompt(kcontext_t *context);
 
 // Navigation
 int klish_nav(kcontext_t *context);