Repository: jqlang/jq

Problem statement:
Can't specify FIELD_COLOR in JQ_COLORS env var
**Describe the bug**
Thanks to https://github.com/stedolan/jq/pull/1397 there is a way to specify the colours used in the `jq` output, but it's not possible to change the FIELD_COLOR (used for dictionary keys for example).

**To Reproduce**
`JQ_COLORS="1;30:0;31:0;32:0;33:0;34:1;35:1;36" ./jq -Cn '[{"a":true,"b":false},123,null]'
[{"a":true,"b":false},123,null]`

<img width="685" alt="not-all-red" src="https://user-images.githubusercontent.com/43142559/46801226-5749b880-cd5a-11e8-9744-d56942a7431d.png">


**Expected behavior**
Another field in the env var to override the color of field names.

**Environment (please complete the following information):**
 - OS and Version: macOS 10.14
 - jq version 1.6rc1

Can't specify FIELD_COLOR in JQ_COLORS env var
**Describe the bug**
Thanks to https://github.com/stedolan/jq/pull/1397 there is a way to specify the colours used in the `jq` output, but it's not possible to change the FIELD_COLOR (used for dictionary keys for example).

**To Reproduce**
`JQ_COLORS="1;30:0;31:0;32:0;33:0;34:1;35:1;36" ./jq -Cn '[{"a":true,"b":false},123,null]'
[{"a":true,"b":false},123,null]`

<img width="685" alt="not-all-red" src="https://user-images.githubusercontent.com/43142559/46801226-5749b880-cd5a-11e8-9744-d56942a7431d.png">


**Expected behavior**
Another field in the env var to override the color of field names.

**Environment (please complete the following information):**
 - OS and Version: macOS 10.14
 - jq version 1.6rc1

Set field color using JQ_COLORS
This should address #1739.

As far as I can tell, this works and passes the test suite (which I updated to test this specific addition). There is a chance that the code changes are not perfect; for example I'm not sure how much sense it makes to have introduced an enum member `JV_KIND_FIELD` for this (although it keeps the code mostly regular).
Make field colors configurable
Allow object key colors to be configured with the "JQ_COLORS" environment variable. This is a updated version of a [GitHub pull request created by David
Haguenauer](https://github.com/stedolan/jq/pull/1791). Since the prebuilt manual already needed to be updated, this change also fixes in omission in <https://github.com/stedolan/jq/commit/cf61515> in which "39" in "JQ_COLORS" should have been replaced with "37".


Hints:
Absolutely agreed, the field color is the only one I need to change to be readable.

Edit: After looking at the code, it doesn't look too hard to implement. Let me know if PR is welcome or if this is an unwanted behavior.
@jdel Yes, PRs are welcome.  This wouldn't be difficult to implement, no.
Please also fix the [manual](https://stedolan.github.io/jq/manual/); it only defines colors up to 37, but the default uses 39 (which should be 37)
is this abandoned?    I'm looking for customizing some jq output colors just realized it doesn't change field_colors;  wonder    why the PR is stuck more than a year not merging?
Absolutely agreed, the field color is the only one I need to change to be readable.

Edit: After looking at the code, it doesn't look too hard to implement. Let me know if PR is welcome or if this is an unwanted behavior.
@jdel Yes, PRs are welcome.  This wouldn't be difficult to implement, no.
Please also fix the [manual](https://stedolan.github.io/jq/manual/); it only defines colors up to 37, but the default uses 39 (which should be 37)
is this abandoned?    I'm looking for customizing some jq output colors just realized it doesn't change field_colors;  wonder    why the PR is stuck more than a year not merging?

[![Coverage Status](https://coveralls.io/builds/21156156/badge)](https://coveralls.io/builds/21156156)

Coverage remained the same at 84.457% when pulling **0d53abc635a6d331522e756d8e0fe23d7760496e on haguenau:feature/set-field-color** into **4b4fefa254346524c787b862e35e4fbb70e01e95 on stedolan:master**.

Interesting.  Obviously there is no use for this new "kind" other than as an index into the array of colors.  I'll think about it.  Thanks for your contribution!
Cool. Please don't hesitate to let me know if you see changes that you think would make sense.
@nicowilliams , would you be willing to merge an updated version of this patch or even https://github.com/stedolan/jq/pull/1977?
I'm attaching a patch that's a updated version of this PR for anyone that builds jq themselves. Thanks, @haguenau, for the original code.

[jq-src-JQ_COLORS-field-color.patch.txt](https://github.com/stedolan/jq/files/4111565/jq-src-JQ_COLORS-field-color.patch.txt)

EDIT: I noticed that in cf615152e192729541db6c06f0c009e2898b1c4e, jq.1.prebuilt was not updated with the new default scheme.
is this abandoned?
Depends on what you mean by abandoned. I'm still using this patch, and the last time I synchronized my copy of jq with the upstream repo (December), the patch still applied cleanly, so I haven't needed to post any updates here.
> is this abandoned?

I see commits on the repo as recently as a month and a half ago... guessing the dev's are just busy / this isn't a high priority for them. I'm not familar with travis builds but I see that it has something flagged for:

> continuous-integration/travis-ci/pr — The Travis CI build could not complete due to an error"

It could be something as simple as that holding things back.

Anyway, I hope folks are able to make it happen too... can't stand the hard-to-read dark blue key/property names on my  terminal. Even if the default was a bright purple, that would at least have decent contrast on light and dark backgrounds. Obviously customizing would be better but I probably wouldn't have bothered to look this up / subscribe to the ticket and PR if the defaults were more reasonable :-)

Guess it's back to `alias jq='/usr/bin/jq --monochrome-output'` for me until this makes it in / someone posts idiot-proof build instructions that I can follow for patching lol
I have not followed jq development very closely since submitting this pull request two years ago. I must admit I do not fully understand [nicowilliam's reasons for having to think more about this](https://github.com/stedolan/jq/pull/1791#issuecomment-455642415); I assume the change is somehow unclean.

If there is interest, I would be happy to look into reworking the change so that it applies successfully to the current code.
I would, too, be very interested in hearing counter-arguments against this. The hard-coded field color is very difficult to read on a dark background, and dark backgrounds are pretty common in what I would assume jq's user base is.

Changing the field color is also something quite a few people request in https://stackoverflow.com/questions/51338701/how-do-i-customize-the-colors-used-by-jq-c
Really looking into getting this merge, Can I offer any help with it?.
Added to the next release milestone. Needs rebasing though.
I'll open a PR later today with my latest version of the patch.
> I'll open a PR later today with my latest version of the patch.

Much appreciated. Given how old this pull request is, I expect a lot
of changes would be needed to make it up to date, so I am very happy
to see you offer to take care of this.

I've opened https://github.com/jqlang/jq/pull/2638.
Taking a careful look into this patch, I finally understand why this is hard to merge. This patch adds `JV_KIND_FIELD` to `jv_kind`, but this is not what `jv_kind` is intended. This enum type is a basic and core type of JSON representation in jq, and such a new value shouldn't be added just for colors. So I propose; do not touch `jv_kind` and `color_kinds`, but `color_bufs` can have 8 (==`sizeof(color_kinds)/sizeof(color_kinds[0]) + 1`) entries, and `FIELD_COLOR` can be `colors[sizeof(color_kinds)/sizeof(color_kinds[0])]` or simply `colors[7]`.
I also wrote a script called jqcolors that's analagous to dircolors that I could include in a separate PR if you'd accept it: <https://github.com/ericpruitt/emus/blob/master/scripts/jqcolors>.

Example file:
```
~$ cat .jqcolors
STRING  0           # Default
ARRAY   0           # Default
OBJECT  0           # Default
FIELD   1;37        # Bold White

# XTerm colors are used for these tokens to make the text bright -- having the
# red, green and/or blue channels maxed out -- without being bold.
NULL    0;38;5;226  # Yellow
FALSE   0;38;5;196  # Red
TRUE    0;38;5;46   # Green
NUMBER  0;38;5;201  # Magenta
```

Patch:
diff --git a/docs/content/manual/manual.yml b/docs/content/manual/manual.yml
index 9dbd1b19ed..dbbb9fafbb 100644
--- a/docs/content/manual/manual.yml
+++ b/docs/content/manual/manual.yml
@@ -3471,9 +3471,10 @@ sections:
         - color for strings
         - color for arrays
         - color for objects
+        - color for object keys
 
       The default color scheme is the same as setting
-      `"JQ_COLORS=1;30:0;37:0;37:0;37:0;32:1;37:1;37"`.
+      `JQ_COLORS="1;30:0;37:0;37:0;37:0;32:1;37:1;37:1;34"`.
 
       This is not a manual for VT100/ANSI escapes.  However, each of
       these color specifications should consist of two numbers separated
diff --git a/jq.1.prebuilt b/jq.1.prebuilt
index 37f40341a0..20ea9c75a2 100644
--- a/jq.1.prebuilt
+++ b/jq.1.prebuilt
@@ -3711,10 +3711,13 @@ color for arrays
 .IP "\(bu" 4
 color for objects
 .
+.IP "\(bu" 4
+color for object keys
+.
 .IP "" 0
 .
 .P
-The default color scheme is the same as setting \fB"JQ_COLORS=1;30:0;37:0;37:0;37:0;32:1;37:1;37"\fR\.
+The default color scheme is the same as setting \fBJQ_COLORS="1;30:0;37:0;37:0;37:0;32:1;37:1;37:1;34"\fR\.
 .
 .P
 This is not a manual for VT100/ANSI escapes\. However, each of these color specifications should consist of two numbers separated by a semi\-colon, where the first number is one of these:
diff --git a/src/jv_print.c b/src/jv_print.c
index 2e781bb8b4..d1db88aa89 100644
--- a/src/jv_print.c
+++ b/src/jv_print.c
@@ -25,16 +25,14 @@
 #define COLRESET (ESC "[0m")
 
 // Color table. See https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
-// for how to choose these.
-static const jv_kind color_kinds[] =
-  {JV_KIND_NULL,   JV_KIND_FALSE, JV_KIND_TRUE, JV_KIND_NUMBER,
-   JV_KIND_STRING, JV_KIND_ARRAY, JV_KIND_OBJECT};
-static char color_bufs[sizeof(color_kinds)/sizeof(color_kinds[0])][16];
+// for how to choose these. The order is same as jv_kind definition, and
+// the last color is used for object keys.
+static char color_bufs[8][16];
 static const char *color_bufps[8];
 static const char* def_colors[] =
   {COL("1;30"),    COL("0;37"),      COL("0;37"),     COL("0;37"),
-   COL("0;32"),      COL("1;37"),     COL("1;37")};
-#define FIELD_COLOR COL("34;1")
+   COL("0;32"),    COL("1;37"),      COL("1;37"),     COL("1;34")};
+#define FIELD_COLOR (colors[7])
 
 static const char **colors = def_colors;
 
@@ -194,14 +192,9 @@ static void jv_dump_term(struct dtoa_context* C, jv x, int flags, int indent, FI
   char buf[JVP_DTOA_FMT_MAX_LEN];
   const char* color = 0;
   double refcnt = (flags & JV_PRINT_REFCOUNT) ? jv_get_refcnt(x) - 1 : -1;
-  if (flags & JV_PRINT_COLOR) {
-    for (unsigned i=0; i<sizeof(color_kinds)/sizeof(color_kinds[0]); i++) {
-      if (jv_get_kind(x) == color_kinds[i]) {
-        color = colors[i];
-        put_str(color, F, S, flags & JV_PRINT_ISATTY);
-        break;
-      }
-    }
+  if ((flags & JV_PRINT_COLOR) && jv_get_kind(x) != JV_KIND_INVALID) {
+    color = colors[(int)jv_get_kind(x) - 1];
+    put_str(color, F, S, flags & JV_PRINT_ISATTY);
   }
   if (indent > MAX_PRINT_DEPTH) {
     put_str("<skipped: too deep>", F, S, flags & JV_PRINT_ISATTY);


Test patch:
diff --git a/tests/shtest b/tests/shtest
index 8af791ae2e..cf616fa20a 100755
--- a/tests/shtest
+++ b/tests/shtest
@@ -325,29 +325,55 @@ if [ "$($VALGRIND $Q $JQ -n '{"a":"xyz"} | halt_error(1)' 2>&1)" != '{"a":"xyz"}
 fi
 
 # Check $JQ_COLORS
+unset JQ_COLORS
+
+## Default colors, null input
 $JQ -Ccn . > $d/color
 printf '\033[1;30mnull\033[0m\n' > $d/expect
 cmp $d/color $d/expect
+
+## Set non-default color, null input
 JQ_COLORS='4;31' $JQ -Ccn . > $d/color
 printf '\033[4;31mnull\033[0m\n' > $d/expect
 cmp $d/color $d/expect
-JQ_COLORS='1;30:0;31:0;32:0;33:0;34:1;35:1;36' \
+
+## Default colors, complex input
+$JQ -Ccn '[{"a":true,"b":false},123,null]' > $d/color
+{
+  printf '\033[1;37m[\033[1;37m{'
+  printf '\033[0m\033[1;34m"a"\033['
+  printf '0m\033[1;37m:\033[0m\033['
+  printf '0;37mtrue\033[0m\033[1'
+  printf ';37m,\033[0m\033[1;34m'
+  printf '"b"\033[0m\033[1;37m:\033'
+  printf '[0m\033[0;37mfalse\033'
+  printf '[0m\033[1;37m\033[1;37'
+  printf 'm}\033[0m\033[1;37m,\033['
+  printf '0;37m123\033[0m\033[1;'
+  printf '37m,\033[1;30mnull\033'
+  printf '[0m\033[1;37m\033[1;37'
+  printf 'm]\033[0m\n'
+} > $d/expect
+cmp $d/color $d/expect
+
+## Set non-default colors, complex input
+JQ_COLORS='1;30:0;31:0;32:0;33:0;34:1;35:1;36:1;30' \
   $JQ -Ccn '[{"a":true,"b":false},123,null]' > $d/color
-(
-printf '\033[1;35m[\033[1;36m{'
-printf '\033[0m\033[34;1m"a"\033['
-printf '0m\033[1;36m:\033[0m\033['
-printf '0;32mtrue\033[0m\033[1'
-printf ';36m,\033[0m\033[34;1m'
-printf '"b"\033[0m\033[1;36m:\033'
-printf '[0m\033[0;31mfalse\033'
-printf '[0m\033[1;36m\033[1;36'
-printf 'm}\033[0m\033[1;35m,\033['
-printf '0;33m123\033[0m\033[1;'
-printf '35m,\033[1;30mnull\033'
-printf '[0m\033[1;35m\033[1;35'
-printf 'm]\033[0m\n'
-) > $d/expect
+{
+  printf '\033[1;35m[\033[1;36m{'
+  printf '\033[0m\033[1;30m"a"\033['
+  printf '0m\033[1;36m:\033[0m\033['
+  printf '0;32mtrue\033[0m\033[1'
+  printf ';36m,\033[0m\033[1;30m'
+  printf '"b"\033[0m\033[1;36m:\033'
+  printf '[0m\033[0;31mfalse\033'
+  printf '[0m\033[1;36m\033[1;36'
+  printf 'm}\033[0m\033[1;35m,\033['
+  printf '0;33m123\033[0m\033[1;'
+  printf '35m,\033[1;30mnull\033'
+  printf '[0m\033[1;35m\033[1;35'
+  printf 'm]\033[0m\n'
+} > $d/expect
 cmp $d/color $d/expect
 
 # Check garbage in JQ_COLORS.  We write each color sequence into a 16