Skip to content

Commit 08c9e5b

Browse files
Fix colors in Windows. (When the foreground/background have modified colors).
1 parent e2170df commit 08c9e5b

File tree

1 file changed

+30
-24
lines changed

1 file changed

+30
-24
lines changed

prompt_toolkit/terminal/win32_output.py

+30-24
Original file line numberDiff line numberDiff line change
@@ -206,17 +206,24 @@ def reset_attributes(self):
206206
def set_attributes(self, attrs):
207207
fgcolor, bgcolor, bold, underline, italic, blink, reverse = attrs
208208

209-
if reverse:
210-
fgcolor, bgcolor = bgcolor, fgcolor
209+
# Start from the default attributes.
210+
attrs = self.default_attrs
211+
212+
# Override the last four bits: foreground color.
213+
if fgcolor is not None:
214+
attrs = attrs & ~0xf
215+
attrs |= self.color_lookup_table.lookup_fg_color(fgcolor)
216+
217+
# Override the next four bits: background color.
218+
if bgcolor is not None:
219+
attrs = attrs & ~0xf0
220+
attrs |= self.color_lookup_table.lookup_bg_color(bgcolor)
211221

212-
# Make sure to reverse, even when no values were specified.
213-
if fgcolor is None:
214-
fgcolor = '000000'
215-
if bgcolor is None:
216-
bgcolor = 'ffffff'
222+
# Reverse: swap these four bits groups.
223+
if reverse:
224+
attrs = (attrs & ~0xff) | ((attrs & 0xf) << 4) | ((attrs & 0xf0) >> 4)
217225

218-
i = self.color_lookup_table.lookup_color(fgcolor, bgcolor)
219-
self._winapi(windll.kernel32.SetConsoleTextAttribute, self.hconsole, i)
226+
self._winapi(windll.kernel32.SetConsoleTextAttribute, self.hconsole, attrs)
220227

221228
def disable_autowrap(self):
222229
# Not supported by Windows.
@@ -497,29 +504,28 @@ def _color_indexes(self, color):
497504
self.best_match[color] = indexes
498505
return indexes
499506

500-
def lookup_color(self, fg_color, bg_color):
507+
def lookup_fg_color(self, fg_color):
501508
"""
502509
Return the color for use in the
503510
`windll.kernel32.SetConsoleTextAttribute` API call.
504511
505512
:param fg_color: Foreground as text. E.g. 'ffffff' or 'red'
506-
:param bg_color: Background as text. E.g. 'ffffff' or 'red'
507513
"""
508-
# Set the default foreground color. (Otherwise, many things will be
509-
# invisible.) Note that gray is the default on Windows, not GRAY|INTENSITY!
510-
if fg_color is None:
511-
fg_index = FOREGROUND_COLOR.GRAY
514+
# Foreground.
515+
if fg_color in FG_ANSI_COLORS:
516+
return FG_ANSI_COLORS[fg_color]
512517
else:
513-
# Foreground.
514-
if fg_color in FG_ANSI_COLORS:
515-
fg_index = FG_ANSI_COLORS[fg_color]
516-
else:
517-
fg_index = self._color_indexes(fg_color)[0]
518+
return self._color_indexes(fg_color)[0]
519+
520+
def lookup_bg_color(self, bg_color):
521+
"""
522+
Return the color for use in the
523+
`windll.kernel32.SetConsoleTextAttribute` API call.
518524
525+
:param bg_color: Background as text. E.g. 'ffffff' or 'red'
526+
"""
519527
# Background.
520528
if bg_color in BG_ANSI_COLORS:
521-
bg_index = BG_ANSI_COLORS[bg_color]
529+
return BG_ANSI_COLORS[bg_color]
522530
else:
523-
bg_index = self._color_indexes(bg_color)[1]
524-
525-
return fg_index | bg_index
531+
return self._color_indexes(bg_color)[1]

0 commit comments

Comments
 (0)