Open AdrienLemaire opened 4 years ago
I have never tried to customize IPython
or ipdb
colors myself.
I am sorry I cannot help and hope you'll report here if you succeeds.
I can modify the prompt text in IPython/core/debugger.py
prompt = 'ipdb> '
I can modify the prompt color in IPython/terminal/interactiveshell.py
class TerminalInteractiveShell(InteractiveShell):
def _make_style_from_name_or_cls(self, name_or_cls):
if name_or_cls == 'legacy':
else :
if isinstance(name_or_cls, str):
style_cls = get_style_by_name(name_or_cls)
else:
style_cls = name_or_cls
style_overrides = {
Token.Prompt: '#009900', # <-- OUR GREEN
Token.PromptNum: '#ansibrightgreen bold',
Token.OutPrompt: '#990000',
Token.OutPromptNum: '#ansibrightred bold',
}
style_overrides.update(self.highlighting_style_overrides)
style = merge_styles([
style_from_pygments_cls(style_cls),
style_from_pygments_dict(style_overrides),
])
Looks like we can update this from ipython_config.py
from pygments.token import Token
c.TerminalInteractiveShell.highlighting_style_overrides = {
Token.Prompt: '#cc6666',
}
in prompt_toolkit/styles/style.py
, I set __import__('pprint').pprint([vars(s) for s in styles])
in merge_styles to record the difference between ipdb and ipython terminal shells:
Looks like in ipdb's case, a style is added twice.
It's being called from Application._create_merged_style
in prompt_toolkit/application/application.py
, itself only called during initialization of Application.
Thus we're re-initializing Application late in the process and nuking all the style setting done previously.
Application seems to get initialized from PromptSession initialization in prompt_toolkit/shortcuts/prompt.py
Calling ipython
in a shell will only call TerminalInteractiveShell, but ipdb will call TerminalInteractiveShell followed by TerminalPdb.
IPython/terminal/interactiveshell.py
class TerminalInteractiveShell(InteractiveShell):
@property
def debugger_cls(self):
return Pdb if self.simple_prompt else TerminalPdb
ipdb/main.py
debugger_cls = shell.debugger_cls
The shell.debugger_cls had been called and set up with ipapp.initialize()
TerminalInteractiveShell inherits Interactiveshell
IPython/core/ultratb.py
class VerboseTB(TBTools):
def __init__(self, color_scheme='Linux', call_pdb=False, ostream=None,
tb_offset=0, long_header=False, include_vars=True,
check_cache=None, debugger_cls = None,
parent=None, config=None):
self.debugger_cls = debugger_cls or debugger.Pdb
def debugger(self, force=False):
if force or self.call_pdb:
if self.pdb is None:
self.pdb = self.debugger_cls()
IPython/core/crashhandler.py
class CrashHandler(object):
def __call__(self, etype, evalue, etb):
TBhandler = ultratb.VerboseTB(
color_scheme=color_scheme,
long_header=1,
call_pdb=self.call_pdb,
)
IPython/terminal/ipapp.py
class IPAppCrashHandler(CrashHandler):
...
class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp):
crash_handler_class = IPAppCrashHandler
Realizing that althought IPython uses TerminalInteractiveShell and calls debugger_cls, the TerminalPdb class is never instantiated!!!
Not sure how to debug this further, I do not understand how ipython colorizes text in the ipython shell
ipdb
is a lightweight wrapper around IPython
debugger. You might want to ask help to the IPython
community.
I went down this rabbit hole yesterday, and the solution does lie within IPython. IPython uses two different color schemes: one is Pygments, and the other one is changed through c.InteractiveShell.colors
in the config file. For the second one there are very limited options and they only use basic 8-bit colors, presumably for compatibility. Using different ANSI escape codes, you can get a lot of much nicer colors depending on what your terminal supports.
If you compare this to master, you can see all the files that need to be changed to add the theme. It's probably possible to do all of that through the config file, but I'm not sure how.
Since this is the first hit on the googz for change ipdb colors - In my case the blues were too dark against the black background. Here's how you change the theme:
pip install ipdb
ipython profile create
~/ipython/profile_default/ipython_config.py
c.InteractiveShell.colors =
(about line 442) to c.InteractiveShell.colors = 'Linux'
@camAtGitHub Thanks a lot for that walkthrough !
@gotcha Is there currently a way to tell ipdb to start a non-default ipython-profile?
my usecase:
I use startup-files of the default ipython-profile for interactive sessions,
but when debugging the application with pdb, i don't want that startup-code to be run.
as a quickfix, I'm currently wrapping my all code in startup-file in a condition like this:
import os
is_ipython = int(os.getenv("IS_IPYTHON", "0"))
if is_ipython:
print(f"\nRunning {__file__}")
.... actual startup-code ....
an ipdb-config setting to start ipdb initialised with an "ipdb-"ipython-profile would nice I think:
[ipdb]
profile=ipdb
I'll create a PR for this
Related: #50, #144, #57, #1
By searching around, I understand (probably incorrectly) that ipdb should use ipython's color scheme by default. And that ipython use pygments styles.
So I tried the following:
Within the same virtualenv, I get colors within ipython, but not within ipdb:
The prompt seems to be another matter, and I haven't figured out how to change its color yet.
Therefore, I have 2 related questions:
Thanks for your help in advance!