1
#include "cache.h"
2
+#include "color.h"
3
+#include "config.h"
4
#include "pkt-line.h"
5
#include "sideband.h"
6
+#include "help.h"
7
+
8
+struct keyword_entry {
9
+ /*
10
+ * We use keyword as config key so it should be a single alphanumeric word.
11
+ */
12
+ const char *keyword;
13
+ char color[COLOR_MAXLEN];
14
+};
15
+
16
+static struct keyword_entry keywords[] = {
17
+ { "hint", GIT_COLOR_YELLOW },
18
+ { "warning", GIT_COLOR_BOLD_YELLOW },
19
+ { "success", GIT_COLOR_BOLD_GREEN },
20
+ { "error", GIT_COLOR_BOLD_RED },
21
+};
22
+
23
+/* Returns a color setting (GIT_COLOR_NEVER, etc). */
24
+static int use_sideband_colors(void)
25
+{
26
+ static int use_sideband_colors_cached = -1;
27
+
28
+ const char *key = "color.remote";
29
+ struct strbuf sb = STRBUF_INIT;
30
+ char *value;
31
+ int i;
32
+
33
+ if (use_sideband_colors_cached >= 0)
34
+ return use_sideband_colors_cached;
35
+
36
+ if (!git_config_get_string(key, &value)) {
37
+ use_sideband_colors_cached = git_config_colorbool(key, value);
38
+ } else if (!git_config_get_string("color.ui", &value)) {
39
+ use_sideband_colors_cached = git_config_colorbool("color.ui", value);
40
+ } else {
41
+ use_sideband_colors_cached = GIT_COLOR_AUTO;
42
+ }
43
+
44
+ for (i = 0; i < ARRAY_SIZE(keywords); i++) {
45
+ strbuf_reset(&sb);
46
+ strbuf_addf(&sb, "%s.%s", key, keywords[i].keyword);
47
+ if (git_config_get_string(sb.buf, &value))
48
+ continue;
49
+ if (color_parse(value, keywords[i].color))
50
+ continue;
51
+ }
52
+ strbuf_release(&sb);
53
+ return use_sideband_colors_cached;
54
+}
55
+
56
+void list_config_color_sideband_slots(struct string_list *list, const char *prefix)
57
+{
58
+ int i;
59
+
60
+ for (i = 0; i < ARRAY_SIZE(keywords); i++)
61
+ list_config_item(list, prefix, keywords[i].keyword);
62
+}
63
+
64
+/*
65
+ * Optionally highlight one keyword in remote output if it appears at the start
66
+ * of the line. This should be called for a single line only, which is
67
+ * passed as the first N characters of the SRC array.
68
+ */
69
+static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n)
70
+{
71
+ int i;
72
+
73
+ if (!want_color_stderr(use_sideband_colors())) {
74
+ strbuf_add(dest, src, n);
75
+ return;
76
+ }
77
+
78
+ while (isspace(*src)) {
79
+ strbuf_addch(dest, *src);
80
+ src++;
81
+ n--;
82
+ }
83
+
84
+ for (i = 0; i < ARRAY_SIZE(keywords); i++) {
85
+ struct keyword_entry *p = keywords + i;
86
+ int len = strlen(p->keyword);
87
+ /*
88
+ * Match case insensitively, so we colorize output from existing
89
+ * servers regardless of the case that they use for their
90
+ * messages. We only highlight the word precisely, so
91
+ * "successful" stays uncolored.
92
+ */
93
+ if (!strncasecmp(p->keyword, src, len) && !isalnum(src[len])) {
94
+ strbuf_addstr(dest, p->color);
95
+ strbuf_add(dest, src, len);
96
+ strbuf_addstr(dest, GIT_COLOR_RESET);
97
+ n -= len;
98
+ src += len;
99
+ break;
100
+ }
101
+ }
102
+
103
+ strbuf_add(dest, src, n);
104
+
105
+}
106
+
107
108
/*
109
* Receive multiplexed output stream over git native protocol.
151
len--;
152
switch (band) {
153
case 3:
51
- strbuf_addf(&outbuf, "%s%s%s", outbuf.len ? "\n" : "",
52
- DISPLAY_PREFIX, buf + 1);
154
+ strbuf_addf(&outbuf, "%s%s", outbuf.len ? "\n" : "",
155
+ DISPLAY_PREFIX);
156
+ maybe_colorize_sideband(&outbuf, buf + 1, len);
157
+
158
retval = SIDEBAND_REMOTE_ERROR;
159
break;
160
case 2:
174
if (!outbuf.len)
175
strbuf_addstr(&outbuf, DISPLAY_PREFIX);
176
if (linelen > 0) {
72
- strbuf_addf(&outbuf, "%.*s%s%c",
73
- linelen, b, suffix, *brk);
74
- } else {
75
- strbuf_addch(&outbuf, *brk);
177
+ maybe_colorize_sideband(&outbuf, b, linelen);
178
+ strbuf_addstr(&outbuf, suffix);
179
}
180
+
181
+ strbuf_addch(&outbuf, *brk);
182
xwrite(2, outbuf.buf, outbuf.len);
183
strbuf_reset(&outbuf);
184
185
b = brk + 1;
186
}
187
83
- if (*b)
84
- strbuf_addf(&outbuf, "%s%s", outbuf.len ?
85
- "" : DISPLAY_PREFIX, b);
188
+ if (*b) {
189
+ strbuf_addstr(&outbuf, outbuf.len ?
190
+ "" : DISPLAY_PREFIX);
191
+ maybe_colorize_sideband(&outbuf, b, strlen(b));
192
+ }
193
break;
194
case 1:
195
write_or_die(out, buf + 1, len);