aboutsummaryrefslogtreecommitdiffhomepage
path: root/cmdline.cpp
blob: e0159ec38ac4893e8e1c73cdd1ce7269363a3ea4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <string.h>

#include <glib.h>
#include <glib/gprintf.h>

#include "sciteco.h"
#include "parser.h"
#include "undo.h"

static gchar *macro_echo(const gchar *macro, const gchar *prefix = "");

gchar *cmdline = NULL;

void
cmdline_keypress(gchar key)
{
	gchar insert[255] = "";
	gint old_cmdline_len = 0;
	gchar *echo;

	/*
	 * Process immediate editing commands
	 */
	switch (key) {
	case '\b':
		if (!cmdline || !*cmdline)
			break;
		old_cmdline_len = strlen(cmdline);

		undo.pop(old_cmdline_len);
		cmdline[old_cmdline_len-1] = '\0';
		macro_pc--;
		break;
	default:
		insert[0] = key;
		insert[1] = '\0';
	}

	/*
	 * Parse/execute characters
	 */
	if (cmdline) {
		old_cmdline_len = strlen(cmdline);
		cmdline = (gchar *)g_realloc(cmdline, old_cmdline_len +
						      strlen(insert) + 1);
	} else {
		cmdline = (gchar *)g_malloc(2);
		*cmdline = '\0';
	}

	for (gchar *p = insert; *p; p++) {
		strcat(cmdline, (gchar[]){key, '\0'});

		if (!macro_execute(cmdline)) {
			cmdline[old_cmdline_len] = '\0';
			break;
		}
	}

	/*
	 * Echo command line
	 */
	echo = macro_echo(cmdline, "*");
	cmdline_display(echo);
	g_free(echo);
}

static gchar *
macro_echo(const gchar *macro, const gchar *prefix)
{
	gchar *result, *rp;

	if (!macro)
		return g_strdup(prefix);

	result = (gchar *)g_malloc(strlen(prefix) + strlen(macro)*5 + 1);
	rp = g_stpcpy(result, prefix);

	for (const gchar *p = macro; *p; p++) {
		switch (*p) {
		case '\x1B':
			*rp++ = '$';
			break;
		case '\r':
			rp = g_stpcpy(rp, "<CR>");
			break;
		case '\n':
			rp = g_stpcpy(rp, "<LF>");
			break;
		case '\t':
			rp = g_stpcpy(rp, "<TAB>");
			break;
		default:
			if (IS_CTL(*p)) {
				*rp++ = '^';
				*rp++ = CTL_ECHO(*p);
			} else {
				*rp++ = *p;
			}
		}
	}
	*rp = '\0';

	return result;
}