Skip to content

Commit

Permalink
Backport PR #521 on branch 3.x (PR: Add logic to handle traceback col…
Browse files Browse the repository at this point in the history
…or configuration) (#523)
  • Loading branch information
meeseeksmachine authored Nov 26, 2024
1 parent b1871e8 commit 07c44d1
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 15 deletions.
35 changes: 28 additions & 7 deletions spyder_kernels/console/kernel.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
from spyder_kernels.utils.mpl import automatic_backend, MPL_BACKENDS_TO_SPYDER
from spyder_kernels.utils.nsview import (
get_remote_data, make_remote_view, get_size)
from spyder_kernels.utils.style import create_style_class
from spyder_kernels.console.shell import SpyderShell
from spyder_kernels.comms.utils import WriteContext

Expand Down Expand Up @@ -639,6 +640,8 @@ def set_configuration(self, conf):
ret["special_kernel_error"] = value
elif key == "color scheme":
self.set_color_scheme(value)
elif key == "traceback_highlight_style":
self.set_traceback_syntax_highlighting(value)
elif key == "jedi_completer":
self.set_jedi_completer(value)
elif key == "greedy_completer":
Expand All @@ -657,13 +660,31 @@ def set_configuration(self, conf):
return ret

def set_color_scheme(self, color_scheme):
if color_scheme == "dark":
# Needed to change the colors of tracebacks
self.shell.run_line_magic("colors", "linux")
self.set_sympy_forecolor(background_color='dark')
elif color_scheme == "light":
self.shell.run_line_magic("colors", "lightbg")
self.set_sympy_forecolor(background_color='light')
self.shell.set_spyder_theme(color_scheme)
self.set_sympy_forecolor(background_color=color_scheme)
self.set_traceback_highlighting(color_scheme)

def set_traceback_highlighting(self, color_scheme):
"""Set the traceback highlighting color."""
color = 'bg:ansired' if color_scheme == 'dark' else 'bg:ansiyellow'
from IPython.core.ultratb import VerboseTB

if getattr(VerboseTB, 'tb_highlight', None) is not None:
VerboseTB.tb_highlight = color
elif getattr(VerboseTB, '_tb_highlight', None) is not None:
VerboseTB._tb_highlight = color

def set_traceback_syntax_highlighting(self, syntax_style):
"""Set the traceback syntax highlighting style."""
import IPython.core.ultratb
from IPython.core.ultratb import VerboseTB

IPython.core.ultratb.get_style_by_name = create_style_class

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

def get_cwd(self):
"""Get current working directory."""
Expand Down
14 changes: 14 additions & 0 deletions spyder_kernels/console/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def __init__(self, *args, **kwargs):
self._allow_kbdint = False
self.register_debugger_sigint()
self.update_gui_frontend = False
self._spyder_theme = 'dark'

# register post_execute
self.events.register('post_execute', self.do_post_execute)
Expand Down Expand Up @@ -84,6 +85,19 @@ def _showtraceback(self, etype, evalue, stb):
stb = ['']
super(SpyderShell, self)._showtraceback(etype, evalue, stb)

def set_spyder_theme(self, theme):
"""Set the theme for the console."""
self._spyder_theme = theme
if theme == "dark":
# Needed to change the colors of tracebacks
self.run_line_magic("colors", "linux")
elif theme == "light":
self.run_line_magic("colors", "lightbg")

def get_spyder_theme(self):
"""Get the theme for the console."""
return self._spyder_theme

def enable_matplotlib(self, gui=None):
"""Enable matplotlib."""
if gui is None or gui.lower() == "auto":
Expand Down
3 changes: 0 additions & 3 deletions spyder_kernels/console/start.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ def kernel_config():
# Don't load nor save history in our IPython consoles.
spy_cfg.HistoryAccessor.enabled = False

# Until we implement Issue 1052
spy_cfg.InteractiveShell.xmode = 'Plain'

# Jedi completer.
jedi_o = os.environ.get('SPY_JEDI_O') == 'True'
spy_cfg.IPCompleter.use_jedi = jedi_o
Expand Down
6 changes: 4 additions & 2 deletions spyder_kernels/customize/code_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,14 @@ class SpyderCodeRunner(Magics):
Functions and magics related to code execution, debugging, profiling, etc.
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

self.show_global_msg = True
self.show_invalid_syntax_msg = True
self.umr = UserModuleReloader(
namelist=os.environ.get("SPY_UMR_NAMELIST", None)
namelist=os.environ.get("SPY_UMR_NAMELIST", None),
shell=self.shell,
)
super().__init__(*args, **kwargs)

@runfile_arguments
@needs_local_scope
Expand Down
11 changes: 8 additions & 3 deletions spyder_kernels/customize/umr.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class UserModuleReloader:
namelist [list]: blacklist in terms of module name
"""

def __init__(self, namelist=None, pathlist=None):
def __init__(self, namelist=None, pathlist=None, shell=None):
if namelist is None:
namelist = []
else:
Expand All @@ -45,6 +45,7 @@ def __init__(self, namelist=None, pathlist=None):
self.namelist = namelist + spy_modules + mpl_modules + other_modules

self.pathlist = pathlist
self._shell = shell

# List of previously loaded modules
self.previous_modules = list(sys.modules.keys())
Expand Down Expand Up @@ -92,7 +93,11 @@ def run(self):
# Report reloaded modules
if self.verbose and modnames_to_reload:
modnames = modnames_to_reload
print("\x1b[4;33m%s\x1b[24m%s\x1b[0m"
% ("Reloaded modules", ": "+", ".join(modnames)))
colors = {"dark": "33", "light": "31"}
color = colors["dark"]
if self._shell:
color = colors[self._shell.get_spyder_theme()]
content = ": "+", ".join(modnames)
print(f"\x1b[4;{color}mReloaded modules\x1b[24m{content}\x1b[0m")

return modnames_to_reload
138 changes: 138 additions & 0 deletions spyder_kernels/utils/style.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright (c) 2009- Spyder Kernels Contributors
#
# Licensed under the terms of the MIT License
# (see spyder_kernels/__init__.py for details)
# -----------------------------------------------------------------------------

"""
Style for IPython Console
"""

# Third party imports
from pygments.style import Style
from pygments.token import (
Name,
Keyword,
Comment,
String,
Number,
Punctuation,
Operator,
)


def create_pygments_dict(color_scheme_dict):
"""
Create a dictionary that saves the given color scheme as a
Pygments style.
"""

def give_font_weight(is_bold):
if is_bold:
return "bold"
else:
return ""

def give_font_style(is_italic):
if is_italic:
return "italic"
else:
return ""

color_scheme = color_scheme_dict

fon_c, fon_fw, fon_fs = color_scheme["normal"]
font_color = fon_c
font_font_weight = give_font_weight(fon_fw)
font_font_style = give_font_style(fon_fs)

key_c, key_fw, key_fs = color_scheme["keyword"]
keyword_color = key_c
keyword_font_weight = give_font_weight(key_fw)
keyword_font_style = give_font_style(key_fs)

bui_c, bui_fw, bui_fs = color_scheme["builtin"]
builtin_color = bui_c
builtin_font_weight = give_font_weight(bui_fw)
builtin_font_style = give_font_style(bui_fs)

str_c, str_fw, str_fs = color_scheme["string"]
string_color = str_c
string_font_weight = give_font_weight(str_fw)
string_font_style = give_font_style(str_fs)

num_c, num_fw, num_fs = color_scheme["number"]
number_color = num_c
number_font_weight = give_font_weight(num_fw)
number_font_style = give_font_style(num_fs)

com_c, com_fw, com_fs = color_scheme["comment"]
comment_color = com_c
comment_font_weight = give_font_weight(com_fw)
comment_font_style = give_font_style(com_fs)

def_c, def_fw, def_fs = color_scheme["definition"]
definition_color = def_c
definition_font_weight = give_font_weight(def_fw)
definition_font_style = give_font_style(def_fs)

ins_c, ins_fw, ins_fs = color_scheme["instance"]
instance_color = ins_c
instance_font_weight = give_font_weight(ins_fw)
instance_font_style = give_font_style(ins_fs)

font_token = font_font_style + " " + font_font_weight + " " + font_color
definition_token = (
definition_font_style
+ " "
+ definition_font_weight
+ " "
+ definition_color
)
builtin_token = (
builtin_font_style + " " + builtin_font_weight + " " + builtin_color
)
instance_token = (
instance_font_style + " " + instance_font_weight + " " + instance_color
)
keyword_token = (
keyword_font_style + " " + keyword_font_weight + " " + keyword_color
)
comment_token = (
comment_font_style + " " + comment_font_weight + " " + comment_color
)
string_token = (
string_font_style + " " + string_font_weight + " " + string_color
)
number_token = (
number_font_style + " " + number_font_weight + " " + number_color
)

syntax_style_dic = {
Name: font_token.strip(),
Name.Class: definition_token.strip(),
Name.Function: definition_token.strip(),
Name.Builtin: builtin_token.strip(),
Name.Builtin.Pseudo: instance_token.strip(),
Keyword: keyword_token.strip(),
Keyword.Type: builtin_token.strip(),
Comment: comment_token.strip(),
String: string_token.strip(),
Number: number_token.strip(),
Punctuation: font_token.strip(),
Operator.Word: keyword_token.strip(),
}

return syntax_style_dic


def create_style_class(color_scheme_dict):
"""Create a Pygments Style class with the given color scheme."""

class StyleClass(Style):
default_style = ""
styles = create_pygments_dict(color_scheme_dict)

return StyleClass

0 comments on commit 07c44d1

Please sign in to comment.