Open htzh opened 8 years ago
I think I understand part of the reason for the behavior. The Editor
instance initializes the default style for the underlying Application
. If I call use_colorscheme
it generates a new current_style
which can be detected and trigger an update of the final styles dict. However if I merely update editor.current_style.styles
this update is not triggered. As shown in the following interactive session in ptpython, where e
is an Editor
instance:
>>> e.application.style.get_token_to_attributes_dict()[Token.Toolbar.Status]
Attrs(color='ffffff', bgcolor='444444', bold=False, underline=False, reverse=False)
>>> e.current_style.styles.update({Token.Toolbar.Status : '#ffffff bg:#222222'})
>>> e.application.style.get_token_to_attributes_dict()[Token.Toolbar.Status]
Attrs(color='ffffff', bgcolor='444444', bold=False, underline=False, reverse=False)
However use_colorscheme
does change the dynamic style attributes by overwriting the current_style
attribute:
>>> e.application.style.get_token_to_attributes_dict()[Token.Name.Entity]
Attrs(color='999999', bgcolor=None, bold=True, underline=False, reverse=False)
>>> e.use_colorscheme('colorful')
>>> e.application.style.get_token_to_attributes_dict()[Token.Name.Entity]
Attrs(color='880000', bgcolor=None, bold=True, underline=False, reverse=False)
So it seems for now I need to either modify styles.py
directly or if I want to overload the behavior I need to emulate the use_colorscheme
method and overwrite current_style
.
The overloading and indirection are kind of confusing here.
>>> ms = get_editor_style_by_name('friendly')
>>> ms.styles[Token.Toolbar.Status]
'#ffffff bg:#444444'
>>> ms.styles.update({Token.Toolbar.Status : '#ffffff bg:#222222'})
>>> e.current_style = ms
>>> e.application.style.get_token_to_attributes_dict()[Token.Name.Entity]
Attrs(color='d55537', bgcolor=None, bold=True, underline=False, reverse=False)
>>> e.application.style.get_token_to_attributes_dict()[Token.Toolbar.Status]
Attrs(color='ffffff', bgcolor='444444', bold=False, underline=False, reverse=False)
>>> ms.styles[Token.Toolbar.Status]
'#ffffff bg:#222222'
>>> ms.styles[Token.Name.Entity]
'bold #d55537'
How does the dict know to update certain property (Token.Name.Entity
) but not others (Token.Toolbar.Status
)?
The following works for me but I still don't fully understand the magic:
# Apply colorscheme. (:colorscheme emacs)
my_style_extensions = {
# Toolbar colors.
Token.Toolbar.Status: '#ffffff bg:#222222',
Token.Toolbar.Status.CursorPosition: '#ffffff bg:#222222',
Token.Toolbar.Status.Percentage: '#ffbbbb bg:#222222',
}
pyvim.style.style_extensions.update(my_style_extensions)
editor.use_colorscheme('emacs')
Okay this is my understanding. The base class is pygments.Style
@add_metaclass(StyleMeta)
class Style(object):
The StyleMeta
metaclass overloads __new__
and during the construction of the Style class creates a cached dict _styles
from the class attribute styles
. But apparently (related to the implementation of the add_metaclass decorator?) according to Python semantics the statements in the scope of our class EditorStyle
and the base class Style
get executed first before the metaclass __new__
is called so the updates done in the body of the class definition show up in the cached object _styles
. However after the class is constructed any new updates to styles
has no effect on _styles
which explains the weirdness I was seeing.
This (i.e., the execution order of the class scope statements and the metaclass __new__
method) seems to me to border on undefined behavior voodoo territory but then I am not a Python programmer worthy of anything.
Hi @htzh,
Thanks for taking the time to troubleshoot the issue!
I should admit that I didn't create an API to install new color schemes. Probably, just like ptpython, we would need an install_ui_colorscheme
function: https://github.com/jonathanslenders/ptpython/blob/master/examples/ptpython_config/config.py#L102
In ptpython, it's possible to choose the color of the Python source code and the UI decorations independently. This is what I want in Pyvim.
Styles are immutable classes. Well, actually they are mutable, but as you experienced, it's not a good idea to alter an existing style, because not all the changes are propagated through the application. There are also caching layers in between. And I think there is one style class that acts as a proxy to the text highlighting style and the ui style.
So, what we need is an install_ui_colorscheme
function and a use_ui_colorscheme
function. I take this issue as a feature request to do that. It's possible that you find a workaround, but that's not a clean way.
Cheers, Jonathan
In my ConEmu terminal the cursor position is pale green over grey with very low contrast and is barely readable. I cycled through the themes offered by ConEmu and even the best contrast is still hard to read. I tried to customize through
.pyvimrc
by adding the following:I am trying to darken the toolbar background but it seems to have no effect on the mode line. I must not be understanding something correctly however there is no documentation on how these colors are used. I.e. I am merely guess that toolbar style controls the mode line but it is not clear that is indeed the case.
On a more basic level I noticed that terminal color themes do seem to change font colors as well, sometimes a little but sometimes dramatically. Is there any pointer on how these pygment styles are translated to terminal colors as the terminal supposedly only supports 256 colors?