Repository: xonsh/xonsh

Issue:
"Invalid ANSI color sequence" warning on startup
`xonfig` output:
```
$ xonfig
+------------------+-----------------+
| xonsh            | 0.9.9           |
| Python           | 3.7.4           |
| PLY              | 3.11            |
| have readline    | True            |
| prompt toolkit   | 2.0.9           |
| shell type       | prompt_toolkit2 |
| pygments         | 2.4.2           |
| on posix         | True            |
| on linux         | False           |
| on darwin        | True            |
| on windows       | False           |
| on cygwin        | False           |
| on msys2         | False           |
| is superuser     | False           |
| default encoding | utf-8           |
| xonsh encoding   | utf-8           |
| encoding errors  | surrogateescape |
+------------------+-----------------+
```

Giving xonsh another try, looks like there are still `LS_COLORS` issues. Here's what I get on startup:

```
$ xonsh
/usr/local/Cellar/xonsh/0.9.9/libexec/lib/python3.7/site-packages/xonsh/__amalgam__.py:7117: RuntimeWarning: Invalid ANSI color sequence "target", using "NO_COLOR" instead.
  warnings.warn(msg, RuntimeWarning)
```

I gave my LS_COLORS values [last time this came up](https://github.com/xonsh/xonsh/issues/3034). Please let me know if I can do anything to help diagnose. Thanks.


Discussion:
Hey @kbd thanks for reporting this!  And sorry for the delay in getting to it.

The warning that's firing looks a little weird to me.  Can you try commenting out your `LS_COLORS` and confirm that that is the source of the error?

The warning also seems to indicate that you have an escape code named `target` -- does that show up in any of your RC files?
@gforsyth, you can see it [here](https://github.com/trapd00r/LS_COLORS/blob/6fe816f95860e33523b79c2c768d229b546379b3/LS_COLORS#L44). Such a value is indeed valid according to `dircolors --print-database`:
```
...
LINK 01;36 # symbolic link. (If you set this to 'target' instead of a
           # numerical value, the color is as for the file pointed to.)
...
```
Oh.  That is defintely not implemented.

Resolving patch:
diff --git a/xonsh/environ.py b/xonsh/environ.py
--- a/xonsh/environ.py
+++ b/xonsh/environ.py
@@ -184,7 +184,8 @@ def to_debug(x):
 
 class LsColors(cabc.MutableMapping):
     """Helps convert to/from $LS_COLORS format, respecting the xonsh color style.
-    This accepts the same inputs as dict().
+    This accepts the same inputs as dict(). The link ``target`` is represented
+    by the special ``"TARGET"`` color.
     """
 
     default_settings = {
@@ -368,7 +369,12 @@ def detype(self):
                     key
                     + "="
                     + ";".join(
-                        [ansi_color_name_to_escape_code(v, cmap=style) for v in val]
+                        [
+                            "target"
+                            if v == "TARGET"
+                            else ansi_color_name_to_escape_code(v, cmap=style)
+                            for v in val
+                        ]
                     )
                     for key, val in sorted(self._d.items())
                 ]
@@ -408,10 +414,13 @@ def fromstring(cls, s):
             key, eq, esc = item.partition("=")
             if not eq:
                 # not a valid item
-                continue
-            data[key] = ansi_color_escape_code_to_name(
-                esc, "default", reversed_style=reversed_default
-            )
+                pass
+            elif esc == "target":
+                data[key] = ("TARGET",)
+            else:
+                data[key] = ansi_color_escape_code_to_name(
+                    esc, "default", reversed_style=reversed_default
+                )
         obj._d = data
         return obj
 


Test patch:
diff --git a/tests/test_environ.py b/tests/test_environ.py
--- a/tests/test_environ.py
+++ b/tests/test_environ.py
@@ -19,6 +19,7 @@
     DEFAULT_VALUES,
     default_env,
     make_args_env,
+    LsColors,
 )
 
 from tools import skip_if_on_unix
@@ -292,3 +293,9 @@ def test_delitem_default():
     assert env[a_key] == a_value
     del env[a_key]
     assert env[a_key] == a_value
+
+
+def test_lscolors_target():
+    lsc = LsColors.fromstring("ln=target")
+    assert lsc["ln"] == ("TARGET",)
+    assert lsc.detype() == "ln=target"