Skip to content

Commit

Permalink
Merge pull request #608 from jsbautista/HighlightTracebacks
Browse files Browse the repository at this point in the history
Use selected syntax style for tracebacks and improve ANSI color codes support
  • Loading branch information
dalthviz authored Aug 12, 2024
2 parents 564dcf9 + 7de610f commit f79480d
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 6 deletions.
31 changes: 26 additions & 5 deletions qtconsole/ansi_code_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,31 @@ def _replace_special(self, match):
self.actions.append(ScrollAction('scroll', 'down', 'page', 1))
return ''

def _parse_ansi_color(self, color, intensity):
"""
Map an ANSI color code to color name or a RGB tuple.
Based on: https://gist.github.com/MightyPork/1d9bd3a3fd4eb1a661011560f6921b5b
"""
parsed_color = None
if color < 16:
# Adjust for intensity, if possible.
if intensity > 0 and color < 8:
color += 8
parsed_color = self.color_map.get(color, None)
elif (color > 231):
s = int((color - 232) * 10 + 8)
parsed_color = (s, s, s)
else:
n = color - 16
b = n % 6
g = (n - b) / 6 % 6
r = (n - b - g * 6) / 36 % 6
r = int(r * 40 + 55) if r else 0
g = int(g * 40 + 55) if g else 0
b = int(b * 40 + 55) if b else 0
parsed_color = (r, g, b)
return parsed_color


class QtAnsiCodeProcessor(AnsiCodeProcessor):
""" Translates ANSI escape codes into QTextCharFormats.
Expand Down Expand Up @@ -323,12 +348,8 @@ def get_color(self, color, intensity=0):
""" Returns a QColor for a given color code or rgb list, or None if one
cannot be constructed.
"""

if isinstance(color, int):
# Adjust for intensity, if possible.
if color < 8 and intensity > 0:
color += 8
constructor = self.color_map.get(color, None)
constructor = self._parse_ansi_color(color, intensity)
elif isinstance(color, (tuple, list)):
constructor = color
else:
Expand Down
14 changes: 13 additions & 1 deletion qtconsole/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,7 @@ def set_syntax_style(self, syntax_style):
colors='nocolor'
elif styles.dark_style(syntax_style):
colors='linux'

else:
colors='lightbg'
self.active_frontend.syntax_style = syntax_style
Expand All @@ -809,7 +810,18 @@ def set_syntax_style(self, syntax_style):
self.active_frontend._syntax_style_changed()
self.active_frontend._style_sheet_changed()
self.active_frontend.reset(clear=True)
self.active_frontend._execute("%colors linux", True)
self.active_frontend._execute(
f"""
from IPython.core.ultratb import VerboseTB
if getattr(VerboseTB, 'tb_highlight_style', None) is not None:
VerboseTB.tb_highlight_style = '{syntax_style}'
elif getattr(VerboseTB, '_tb_highlight_style', None) is not None:
VerboseTB._tb_highlight_style = '{syntax_style}'
else:
get_ipython().run_line_magic('colors', '{colors}')
""",
True)


def close_active_frontend(self):
self.close_tab(self.active_frontend)
Expand Down
6 changes: 6 additions & 0 deletions qtconsole/tests/test_jupyter_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,15 @@ def test_stylesheet_changed(self):
# By default, the background is light. White text is rendered as black
self.assertEqual(w._ansi_processor.get_color(15).name(), '#000000')

# Color code 40
self.assertEqual(w._ansi_processor.get_color(40).name(), '#00d700')

# Change to a dark colorscheme. White text is rendered as white
w.syntax_style = 'monokai'
self.assertEqual(w._ansi_processor.get_color(15).name(), '#ffffff')

# Color code 40 with monokai
self.assertEqual(w._ansi_processor.get_color(40).name(), '#00d700')

@pytest.mark.skipif(not sys.platform.startswith('linux'),
reason="Works only on Linux")
Expand Down

0 comments on commit f79480d

Please sign in to comment.