diff --git a/src/builtin_set_color.cpp b/src/builtin_set_color.cpp
index 22c9d9d2e..576013136 100644
--- a/src/builtin_set_color.cpp
+++ b/src/builtin_set_color.cpp
@@ -33,15 +33,53 @@
 
 class parser_t;
 
-static void print_colors(io_streams_t &streams) {
-    outputter_t outp;
+static void print_modifiers(outputter_t &outp, bool bold, bool underline, bool italics, bool dim, bool reverse, rgb_color_t bg) {
+    if (bold && enter_bold_mode) {
+        // These casts are needed to work with different curses implementations.
+        writembs_nofail(outp, tparm(const_cast<char *>(enter_bold_mode)));
+    }
 
+    if (underline && enter_underline_mode) {
+        writembs_nofail(outp, enter_underline_mode);
+    }
+
+    if (italics && enter_italics_mode) {
+        writembs_nofail(outp, enter_italics_mode);
+    }
+
+    if (dim && enter_dim_mode) {
+        writembs_nofail(outp, enter_dim_mode);
+    }
+
+    if (reverse && enter_reverse_mode) {
+        writembs_nofail(outp, enter_reverse_mode);
+    } else if (reverse && enter_standout_mode) {
+        writembs_nofail(outp, enter_standout_mode);
+    }
+    if (!bg.is_none() && bg.is_normal()) {
+        writembs_nofail(outp, tparm(const_cast<char *>(exit_attribute_mode)));
+    }
+
+}
+
+
+static void print_colors(io_streams_t &streams, bool bold, bool underline, bool italics, bool dim, bool reverse, rgb_color_t bg) {
+    outputter_t outp;
     for (const auto &color_name : rgb_color_t::named_color_names()) {
         if (!streams.out_is_redirected && isatty(STDOUT_FILENO)) {
+            print_modifiers(outp, bold, underline, italics, dim, reverse, bg);
             rgb_color_t color = rgb_color_t(color_name);
             outp.set_color(color, rgb_color_t::none());
+            if (!bg.is_none()) {
+                outp.write_color(bg, false /* not is_fg */);
+            }
         }
         outp.writestr(color_name);
+        if (!bg.is_none()) {
+            // If we have a background, stop it after the color
+            // or it goes to the end of the line and looks ugly.
+            writembs_nofail(outp, tparm(const_cast<char *>(exit_attribute_mode)));
+        }
         outp.writech(L'\n');
     }  // conveniently, 'normal' is always the last color so we don't need to reset here
 
@@ -96,7 +134,7 @@ maybe_t<int> builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t
     }
 
     const wchar_t *bgcolor = nullptr;
-    bool bold = false, underline = false, italics = false, dim = false, reverse = false;
+    bool bold = false, underline = false, italics = false, dim = false, reverse = false, print = false;
 
     // Parse options to obtain the requested operation and the modifiers.
     int opt;
@@ -132,8 +170,8 @@ maybe_t<int> builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t
                 break;
             }
             case 'c': {
-                print_colors(streams);
-                return STATUS_CMD_OK;
+                print = true;
+                break;
             }
             case ':': {
                 // We don't error here because "-b" is the only option that requires an argument,
@@ -149,6 +187,17 @@ maybe_t<int> builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t
         }
     }
 
+    const rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : L"");
+    if (bgcolor && bg.is_none()) {
+        streams.err.append_format(_(L"%ls: Unknown color '%ls'\n"), argv[0], bgcolor);
+        return STATUS_INVALID_ARGS;
+    }
+
+    if (print) {
+        print_colors(streams, bold, underline, italics, dim, reverse, bg);
+        return STATUS_CMD_OK;
+    }
+
     // Remaining arguments are foreground color.
     std::vector<rgb_color_t> fgcolors;
     for (; w.woptind < argc; w.woptind++) {
@@ -165,12 +214,6 @@ maybe_t<int> builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t
     const rgb_color_t fg = best_color(fgcolors, output_get_color_support());
     assert(fgcolors.empty() || !fg.is_none());
 
-    const rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : L"");
-    if (bgcolor && bg.is_none()) {
-        streams.err.append_format(_(L"%ls: Unknown color '%ls'\n"), argv[0], bgcolor);
-        return STATUS_INVALID_ARGS;
-    }
-
     // Test if we have at least basic support for setting fonts, colors and related bits - otherwise
     // just give up...
     if (cur_term == nullptr || !exit_attribute_mode) {
@@ -178,28 +221,7 @@ maybe_t<int> builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t
     }
     outputter_t outp;
 
-    if (bold && enter_bold_mode) {
-        // These casts are needed to work with different curses implementations.
-        writembs_nofail(outp, tparm(const_cast<char *>(enter_bold_mode)));
-    }
-
-    if (underline && enter_underline_mode) {
-        writembs_nofail(outp, enter_underline_mode);
-    }
-
-    if (italics && enter_italics_mode) {
-        writembs_nofail(outp, enter_italics_mode);
-    }
-
-    if (dim && enter_dim_mode) {
-        writembs_nofail(outp, enter_dim_mode);
-    }
-
-    if (reverse && enter_reverse_mode) {
-        writembs_nofail(outp, enter_reverse_mode);
-    } else if (reverse && enter_standout_mode) {
-        writembs_nofail(outp, enter_standout_mode);
-    }
+    print_modifiers(outp, bold, underline, italics, dim, reverse, bg);
 
     if (bgcolor != nullptr && bg.is_normal()) {
         writembs_nofail(outp, tparm(const_cast<char *>(exit_attribute_mode)));
diff --git a/tests/pexpects/set_color.py b/tests/pexpects/set_color.py
new file mode 100644
index 000000000..0d8d091b4
--- /dev/null
+++ b/tests/pexpects/set_color.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python3
+from pexpect_helper import SpawnedProc
+import subprocess
+import sys
+import time
+import os
+
+env = os.environ.copy()
+env["TERM"] = "xterm"
+
+sp = SpawnedProc(env=env)
+send, sendline, sleep, expect_prompt, expect_re, expect_str = (
+    sp.send,
+    sp.sendline,
+    sp.sleep,
+    sp.expect_prompt,
+    sp.expect_re,
+    sp.expect_str,
+)
+expect_prompt()
+
+# See that --print-colors prints the colors colored.
+# Note that we don't check *all* of them, just a few.
+sendline("set_color --print-colors")
+expect_str("black")
+expect_str("blue")
+expect_str("brblack")
+expect_str("brblue")
+expect_str("brcyan")
+expect_str("brgreen")
+expect_str("brmagenta")
+expect_str("brred")
+expect_str("brwhite")
+expect_str("bryellow")
+expect_str("cyan")
+expect_str("green")
+expect_str("magenta")
+expect_str("\x1b[31mred")
+expect_str("\x1b[37mwhite")
+expect_str("\x1b[33myellow")
+expect_str("normal")
+expect_prompt()
+
+sendline ("set_color --background blue --print-colors")
+expect_str("black")
+expect_str("blue")
+expect_str("brblack")
+expect_str("brblue")
+expect_str("brcyan")
+expect_str("brgreen")
+expect_str("brmagenta")
+expect_str("brred")
+expect_str("brwhite")
+expect_str("bryellow")
+expect_str("cyan")
+expect_str("green")
+expect_str("magenta")
+expect_str("\x1b[31m\x1b[44mred")
+expect_str("white")
+expect_str("yellow")
+expect_str("normal")
+expect_prompt()
+