mirror of
https://github.com/powerline/powerline.git
synced 2025-07-26 23:35:04 +02:00
Add ability to override configuration options
Related changes: - Moved all non-ASCII symbols into `segment_data` - Added --config_path, replaced nargs='*' with better action='append' - Added g:powerline_config_path vim option - Added ipython overrides (via additional arguments to setup() or c.Powerline) TODO: support for non-string scalars in vim overrides. Fixes #231
This commit is contained in:
parent
c86b047ed4
commit
f211bb6c74
@ -132,8 +132,8 @@ Common configuration is a subdictionary that is a value of ``common`` key in
|
|||||||
|
|
||||||
``paths``
|
``paths``
|
||||||
Defines additional paths which will be searched for modules when using
|
Defines additional paths which will be searched for modules when using
|
||||||
:ref:`module segment option <config-themes-seg-module>`. Paths defined
|
:ref:`module segment option <config-themes-seg-module>`. Paths defined here
|
||||||
here have priority when searching for modules.
|
have priority when searching for modules.
|
||||||
|
|
||||||
Extension-specific configuration
|
Extension-specific configuration
|
||||||
--------------------------------
|
--------------------------------
|
||||||
@ -236,7 +236,8 @@ Themes
|
|||||||
using :ref:`local themes <config-ext-local_themes>` values of these keys are
|
using :ref:`local themes <config-ext-local_themes>` values of these keys are
|
||||||
first searched in the segment description, then in ``segment_data`` key of
|
first searched in the segment description, then in ``segment_data`` key of
|
||||||
a local theme, then in ``segment_data`` key of a :ref:`default theme
|
a local theme, then in ``segment_data`` key of a :ref:`default theme
|
||||||
<config-ext-theme>`.
|
<config-ext-theme>`. For the :ref:`default theme <config-ext-theme>` itself
|
||||||
|
step 2 is obviously avoided.
|
||||||
|
|
||||||
``segments``
|
``segments``
|
||||||
A dict with a ``left`` and a ``right`` list, consisting of segment
|
A dict with a ``left`` and a ``right`` list, consisting of segment
|
||||||
@ -354,3 +355,74 @@ A segment function must return one of the following values:
|
|||||||
* A list of dicts consisting of a ``contents`` string, and
|
* A list of dicts consisting of a ``contents`` string, and
|
||||||
a ``highlight_group`` list. This is useful for providing a particular
|
a ``highlight_group`` list. This is useful for providing a particular
|
||||||
highlighting group depending on the segment contents.
|
highlighting group depending on the segment contents.
|
||||||
|
|
||||||
|
Local configuration
|
||||||
|
===================
|
||||||
|
|
||||||
|
Depending on the application used it is possible to override configuration. Here
|
||||||
|
is the list:
|
||||||
|
|
||||||
|
Vim overrides
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Vim configuration can be overridden using the following options:
|
||||||
|
|
||||||
|
``g:powerline_config_overrides``
|
||||||
|
Dictionary, recursively merged with contents of
|
||||||
|
:file:`powerline/config.json`.
|
||||||
|
|
||||||
|
``g:powerline_theme_overrides__{theme_name}``
|
||||||
|
Dictionary, recursively merged with contents of
|
||||||
|
:file:`powerline/themes/vim/{theme_name}.json`. Note that this way you can’t
|
||||||
|
redefine some value (e.g. segment) in list, only the whole list itself: only
|
||||||
|
dictionaries are merged recursively.
|
||||||
|
|
||||||
|
``g:powerline_config_path``
|
||||||
|
Path (must be expanded, ``~`` shortcut is not supported). Points to the
|
||||||
|
directory which will be searched for configuration. When this option is
|
||||||
|
present, none of the other locations are searched.
|
||||||
|
|
||||||
|
Powerline script overrides
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Powerline script has a number of options controlling powerline behavior. Here
|
||||||
|
``VALUE`` always means “some JSON object”.
|
||||||
|
|
||||||
|
``-c KEY.NESTED_KEY=VALUE`` or ``--config=KEY.NESTED_KEY=VALUE``
|
||||||
|
Overrides options from :file:`powerline/config.json`.
|
||||||
|
``KEY.KEY2.KEY3=VALUE`` is a shortcut for ``KEY={"KEY2": {"KEY3": VALUE}}``.
|
||||||
|
Multiple options (i.e. ``-c K1=V1 -c K2=V2``) are allowed, result (in the
|
||||||
|
example: ``{"K1": V1, "K2": V2}``) is recursively merged with the contents
|
||||||
|
of the file.
|
||||||
|
|
||||||
|
``-t THEME_NAME.KEY.NESTED_KEY=VALUE`` or ``--theme_option=THEME_NAME.KEY.NESTED_KEY=VALUE``
|
||||||
|
Overrides options from :file:`powerline/themes/{ext}/{THEME_NAME}.json`.
|
||||||
|
``KEY.NESTED_KEY=VALUE`` is processed like described above, ``{ext}`` is the
|
||||||
|
first argument to powerline script. May be passed multiple times.
|
||||||
|
|
||||||
|
``-p PATH`` or ``--config_path=PATH``
|
||||||
|
Sets directory where configuration should be read from. If present, no
|
||||||
|
default locations are searched for configuration. No expansions are
|
||||||
|
performed by powerline script itself, but ``-p ~/.powerline`` will likely be
|
||||||
|
expanded by the shell to something like ``-p /home/user/.powerline``.
|
||||||
|
|
||||||
|
Ipython overrides
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Ipython overrides depend on ipython version. Before ipython-0.11 you should pass
|
||||||
|
additional keyword arguments to setup() function. After ipython-0.11 you should
|
||||||
|
use ``c.Powerline.KEY``. Supported ``KEY`` strings or keyword argument names:
|
||||||
|
|
||||||
|
``config_overrides``
|
||||||
|
Overrides options from :file:`powerline/config.json`. Should be a dictionary
|
||||||
|
that will be recursively merged with the contents of the file.
|
||||||
|
|
||||||
|
``theme_overrides``
|
||||||
|
Overrides options from :file:`powerline/themes/ipython/*.json`. Should be
|
||||||
|
a dictionary where keys are theme names and values are dictionaries which
|
||||||
|
will be recursively merged with the contents of the given theme.
|
||||||
|
|
||||||
|
``path``
|
||||||
|
Sets directory where configuration should be read from. If present, no
|
||||||
|
default locations are searched for configuration. No expansions are
|
||||||
|
performed thus you cannot use paths starting with ``~/``.
|
||||||
|
@ -0,0 +1,81 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import importlib
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from powerline.colorscheme import Colorscheme
|
||||||
|
from powerline.lib import underscore_to_camelcase
|
||||||
|
|
||||||
|
|
||||||
|
def load_json_config(search_paths, config_file):
|
||||||
|
config_file += '.json'
|
||||||
|
for path in search_paths:
|
||||||
|
config_file_path = os.path.join(path, config_file)
|
||||||
|
if os.path.isfile(config_file_path):
|
||||||
|
with open(config_file_path, 'r') as config_file_fp:
|
||||||
|
return json.load(config_file_fp)
|
||||||
|
raise IOError('Config file not found in search path: {0}'.format(config_file))
|
||||||
|
|
||||||
|
|
||||||
|
class Powerline(object):
|
||||||
|
def __init__(self, ext, renderer_module=None):
|
||||||
|
self.config_paths = self.get_config_paths()
|
||||||
|
|
||||||
|
# Load main config file
|
||||||
|
config = self.load_main_config()
|
||||||
|
common_config = config['common']
|
||||||
|
ext_config = config['ext'][ext]
|
||||||
|
self.ext = ext
|
||||||
|
|
||||||
|
# Load and initialize colorscheme
|
||||||
|
colorscheme_config = self.load_colorscheme_config(ext_config['colorscheme'])
|
||||||
|
colorscheme = Colorscheme(colorscheme_config)
|
||||||
|
|
||||||
|
# Load and initialize extension theme
|
||||||
|
theme_config = self.load_theme_config(ext_config.get('theme', 'default'))
|
||||||
|
common_config['paths'] = [os.path.expanduser(path) for path in common_config.get('paths', [])]
|
||||||
|
self.import_paths = common_config['paths']
|
||||||
|
theme_kwargs = {
|
||||||
|
'ext': ext,
|
||||||
|
'colorscheme': colorscheme,
|
||||||
|
'common_config': common_config,
|
||||||
|
'segment_info': self.get_segment_info(),
|
||||||
|
}
|
||||||
|
local_themes = self.get_local_themes(ext_config.get('local_themes', {}))
|
||||||
|
|
||||||
|
# Load and initialize extension renderer
|
||||||
|
renderer_module_name = renderer_module or ext
|
||||||
|
renderer_module_import = 'powerline.renderers.{0}'.format(renderer_module_name)
|
||||||
|
renderer_class_name = '{0}Renderer'.format(underscore_to_camelcase(renderer_module_name))
|
||||||
|
try:
|
||||||
|
Renderer = getattr(importlib.import_module(renderer_module_import), renderer_class_name)
|
||||||
|
except ImportError as e:
|
||||||
|
sys.stderr.write('Error while importing renderer module: {0}\n'.format(e))
|
||||||
|
sys.exit(1)
|
||||||
|
options = {'term_truecolor': common_config.get('term_24bit_colors', False)}
|
||||||
|
self.renderer = Renderer(theme_config, local_themes, theme_kwargs, **options)
|
||||||
|
|
||||||
|
def get_config_paths(self):
|
||||||
|
config_home = os.environ.get('XDG_CONFIG_HOME', os.path.join(os.path.expanduser('~'), '.config'))
|
||||||
|
config_path = os.path.join(config_home, 'powerline')
|
||||||
|
plugin_path = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'config_files')
|
||||||
|
return [config_path, plugin_path]
|
||||||
|
|
||||||
|
def load_theme_config(self, name):
|
||||||
|
return load_json_config(self.config_paths, os.path.join('themes', self.ext, name))
|
||||||
|
|
||||||
|
def load_main_config(self):
|
||||||
|
return load_json_config(self.config_paths, 'config')
|
||||||
|
|
||||||
|
def load_colorscheme_config(self, name):
|
||||||
|
return load_json_config(self.config_paths, os.path.join('colorschemes', self.ext, name))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_local_themes(local_themes):
|
||||||
|
return {}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_segment_info():
|
||||||
|
return None
|
@ -1,4 +1,4 @@
|
|||||||
from powerline.core import Powerline
|
from powerline.ipython import IpythonPowerline
|
||||||
|
|
||||||
from IPython.core.prompts import PromptManager
|
from IPython.core.prompts import PromptManager
|
||||||
|
|
||||||
@ -19,8 +19,23 @@ class PowerlinePromptManager(PromptManager):
|
|||||||
return res if color else res_nocolor
|
return res if color else res_nocolor
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigurableIpythonPowerline(IpythonPowerline):
|
||||||
|
def __init__(self, ip):
|
||||||
|
config = ip.config.Powerline
|
||||||
|
self.config_overrides = config.get('config_overrides')
|
||||||
|
self.theme_overrides = config.get('theme_overrides', {})
|
||||||
|
self.path = config.get('path')
|
||||||
|
super(ConfigurableIpythonPowerline, self).__init__()
|
||||||
|
|
||||||
|
|
||||||
def load_ipython_extension(ip):
|
def load_ipython_extension(ip):
|
||||||
powerline = Powerline('ipython')
|
global old_prompt_manager
|
||||||
|
|
||||||
|
old_prompt_manager = ip.prompt_manager
|
||||||
|
powerline = ConfigurableIpythonPowerline(ip)
|
||||||
|
|
||||||
ip.prompt_manager = PowerlinePromptManager(powerline=powerline,
|
ip.prompt_manager = PowerlinePromptManager(powerline=powerline,
|
||||||
shell=ip.prompt_manager.shell, config=ip.prompt_manager.config)
|
shell=ip.prompt_manager.shell, config=ip.prompt_manager.config)
|
||||||
|
|
||||||
|
def unload_ipython_extension(ip):
|
||||||
|
ip.prompt_manager = old_prompt_manager
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from powerline.core import Powerline
|
from powerline.ipython import IpythonPowerline
|
||||||
from IPython.Prompts import BasePrompt
|
from IPython.Prompts import BasePrompt
|
||||||
from IPython.ipapi import get as get_ipython
|
from IPython.ipapi import get as get_ipython
|
||||||
|
|
||||||
@ -18,10 +18,18 @@ class PowerlinePrompt(BasePrompt):
|
|||||||
return '%s>%s' % ('-' * self.prompt_text_len, ' ' * self.nrspaces)
|
return '%s>%s' % ('-' * self.prompt_text_len, ' ' * self.nrspaces)
|
||||||
|
|
||||||
|
|
||||||
def setup(prompt='1'):
|
class ConfigurableIpythonPowerline(IpythonPowerline):
|
||||||
|
def __init__(self, config_overrides=None, theme_overrides={}, path=None):
|
||||||
|
self.config_overrides = config_overrides
|
||||||
|
self.theme_overrides = theme_overrides
|
||||||
|
self.path = path
|
||||||
|
super(ConfigurableIpythonPowerline, self).__init__()
|
||||||
|
|
||||||
|
|
||||||
|
def setup(prompt='1', **kwargs):
|
||||||
ip = get_ipython()
|
ip = get_ipython()
|
||||||
|
|
||||||
powerline = Powerline('ipython')
|
powerline = ConfigurableIpythonPowerline(**kwargs)
|
||||||
|
|
||||||
attr = 'prompt' + prompt
|
attr = 'prompt' + prompt
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
from libqtile import bar
|
from libqtile import bar
|
||||||
from libqtile.widget import base
|
from libqtile.widget import base
|
||||||
|
|
||||||
from powerline.core import Powerline as PowerlineCore
|
from powerline import Powerline as PowerlineCore
|
||||||
|
|
||||||
|
|
||||||
class Powerline(base._TextBox):
|
class Powerline(base._TextBox):
|
||||||
|
@ -18,15 +18,16 @@ endif
|
|||||||
let s:powerline_pycmd = substitute(get(g:, 'powerline_pycmd', 'py'), '\v^(py)%[thon](3?)$', '\1\2', '')
|
let s:powerline_pycmd = substitute(get(g:, 'powerline_pycmd', 'py'), '\v^(py)%[thon](3?)$', '\1\2', '')
|
||||||
let s:powerline_pyeval = get(g:, 'powerline_pyeval', s:powerline_pycmd.'eval')
|
let s:powerline_pyeval = get(g:, 'powerline_pyeval', s:powerline_pycmd.'eval')
|
||||||
|
|
||||||
|
let s:import_cmd = 'from powerline.vim import VimPowerline'
|
||||||
try
|
try
|
||||||
exec s:powerline_pycmd 'from powerline.core import Powerline'
|
exec s:powerline_pycmd s:import_cmd
|
||||||
catch
|
catch
|
||||||
" An error occured while importing the module, it could be installed
|
" An error occured while importing the module, it could be installed
|
||||||
" outside of Python's module search paths. Update sys.path and try again.
|
" outside of Python's module search paths. Update sys.path and try again.
|
||||||
exec s:powerline_pycmd 'import sys, vim'
|
exec s:powerline_pycmd 'import sys, vim'
|
||||||
exec s:powerline_pycmd 'sys.path.append(vim.eval(''expand("<sfile>:h:h:h:h:h")''))'
|
exec s:powerline_pycmd 'sys.path.append(vim.eval(''expand("<sfile>:h:h:h:h:h")''))'
|
||||||
try
|
try
|
||||||
exec s:powerline_pycmd 'from powerline.core import Powerline'
|
exec s:powerline_pycmd s:import_cmd
|
||||||
catch
|
catch
|
||||||
call s:CriticalError('An error occured while importing the Powerline package.
|
call s:CriticalError('An error occured while importing the Powerline package.
|
||||||
\ This could be caused by an invalid sys.path setting, or by an incompatible
|
\ This could be caused by an invalid sys.path setting, or by an incompatible
|
||||||
@ -35,7 +36,8 @@ catch
|
|||||||
finish
|
finish
|
||||||
endtry
|
endtry
|
||||||
endtry
|
endtry
|
||||||
exec s:powerline_pycmd 'powerline = Powerline("vim", segment_info={})'
|
exec s:powerline_pycmd 'powerline = VimPowerline()'
|
||||||
|
exec s:powerline_pycmd 'del VimPowerline'
|
||||||
|
|
||||||
if !get(g:, 'powerline_debugging_pyeval') && exists('*'. s:powerline_pyeval)
|
if !get(g:, 'powerline_debugging_pyeval') && exists('*'. s:powerline_pyeval)
|
||||||
let s:pyeval = function(s:powerline_pyeval)
|
let s:pyeval = function(s:powerline_pyeval)
|
||||||
|
@ -1,8 +1,18 @@
|
|||||||
import zsh
|
import zsh
|
||||||
from powerline.core import Powerline
|
from powerline.shell import ShellPowerline
|
||||||
|
|
||||||
|
|
||||||
|
def get_var_config(var):
|
||||||
|
try:
|
||||||
|
return dict(((k, json.loads(v)) for k, v in zsh.getvalue(var).items()))
|
||||||
|
except:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class Args(object):
|
class Args(object):
|
||||||
|
ext = ['shell']
|
||||||
|
renderer_module = 'zsh_prompt'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def last_exit_code(self):
|
def last_exit_code(self):
|
||||||
return zsh.last_exit_code()
|
return zsh.last_exit_code()
|
||||||
@ -11,6 +21,14 @@ class Args(object):
|
|||||||
def last_pipe_status(self):
|
def last_pipe_status(self):
|
||||||
return zsh.pipestatus()
|
return zsh.pipestatus()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def config(self):
|
||||||
|
return get_var_config('POWERLINE_CONFIG')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def theme_option(self):
|
||||||
|
return get_var_config('POWERLINE_THEME_CONFIG')
|
||||||
|
|
||||||
|
|
||||||
class Prompt(object):
|
class Prompt(object):
|
||||||
__slots__ = ('render', 'side', 'savedpsvar', 'savedps')
|
__slots__ = ('render', 'side', 'savedpsvar', 'savedps')
|
||||||
@ -38,6 +56,6 @@ def set_prompt(powerline, psvar, side):
|
|||||||
|
|
||||||
|
|
||||||
def setup():
|
def setup():
|
||||||
powerline = Powerline(ext='shell', renderer_module='zsh_prompt', segment_info=Args())
|
powerline = ShellPowerline(Args())
|
||||||
set_prompt(powerline, 'PS1', 'left')
|
set_prompt(powerline, 'PS1', 'left')
|
||||||
set_prompt(powerline, 'RPS1', 'right')
|
set_prompt(powerline, 'RPS1', 'right')
|
||||||
|
@ -1,20 +1,29 @@
|
|||||||
{
|
{
|
||||||
"default_module": "powerline.segments.common",
|
"default_module": "powerline.segments.common",
|
||||||
|
"segment_data": {
|
||||||
|
"hostname": {
|
||||||
|
"before": " ",
|
||||||
|
"args": {
|
||||||
|
"only_if_ssh": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"virtualenv": {
|
||||||
|
"before": "ⓔ "
|
||||||
|
},
|
||||||
|
"branch": {
|
||||||
|
"before": " "
|
||||||
|
}
|
||||||
|
},
|
||||||
"segments": {
|
"segments": {
|
||||||
"left": [
|
"left": [
|
||||||
{
|
{
|
||||||
"name": "hostname",
|
"name": "hostname"
|
||||||
"before": " ",
|
|
||||||
"args": {
|
|
||||||
"only_if_ssh": true
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "user"
|
"name": "user"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "virtualenv",
|
"name": "virtualenv"
|
||||||
"before": "ⓔ "
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "cwd",
|
"name": "cwd",
|
||||||
@ -31,8 +40,7 @@
|
|||||||
"highlight_group": "exit_fail"
|
"highlight_group": "exit_fail"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "branch",
|
"name": "branch"
|
||||||
"before": " "
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,32 @@
|
|||||||
{
|
{
|
||||||
"default_module": "powerline.segments.common",
|
"default_module": "powerline.segments.common",
|
||||||
|
"segment_data": {
|
||||||
|
"hostname": {
|
||||||
|
"before": " ",
|
||||||
|
"args": {
|
||||||
|
"only_if_ssh": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"virtualenv": {
|
||||||
|
"before": "ⓔ "
|
||||||
|
},
|
||||||
|
"branch": {
|
||||||
|
"before": " "
|
||||||
|
}
|
||||||
|
},
|
||||||
"segments": {
|
"segments": {
|
||||||
"left": [
|
"left": [
|
||||||
{
|
{
|
||||||
"name": "hostname",
|
"name": "hostname"
|
||||||
"before": " "
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "user"
|
"name": "user"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "virtualenv",
|
"name": "virtualenv"
|
||||||
"before": "ⓔ "
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "branch",
|
"name": "branch"
|
||||||
"before": " "
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "cwd",
|
"name": "cwd",
|
||||||
|
@ -1,16 +1,32 @@
|
|||||||
{
|
{
|
||||||
"default_module": "powerline.segments.common",
|
"default_module": "powerline.segments.common",
|
||||||
|
"segment_data": {
|
||||||
|
"uptime": {
|
||||||
|
"before": "⇑ "
|
||||||
|
},
|
||||||
|
"external_ip": {
|
||||||
|
"before": "ⓦ "
|
||||||
|
},
|
||||||
|
"date": {
|
||||||
|
"before": "⌚ "
|
||||||
|
},
|
||||||
|
"email_imap_alert": {
|
||||||
|
"before": "✉ ",
|
||||||
|
"args": {
|
||||||
|
"username": "",
|
||||||
|
"password": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"segments": {
|
"segments": {
|
||||||
"right": [
|
"right": [
|
||||||
{
|
{
|
||||||
"name": "uptime",
|
"name": "uptime",
|
||||||
"before": "⇑ ",
|
|
||||||
"priority": 50,
|
"priority": 50,
|
||||||
"divider_highlight_group": "background:divider"
|
"divider_highlight_group": "background:divider"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "external_ip",
|
"name": "external_ip",
|
||||||
"before": "ⓦ ",
|
|
||||||
"priority": 50,
|
"priority": 50,
|
||||||
"divider_highlight_group": "background:divider"
|
"divider_highlight_group": "background:divider"
|
||||||
},
|
},
|
||||||
@ -35,18 +51,12 @@
|
|||||||
{
|
{
|
||||||
"name": "date",
|
"name": "date",
|
||||||
"args": {"format": "%H:%M"},
|
"args": {"format": "%H:%M"},
|
||||||
"before": "⌚ ",
|
|
||||||
"highlight_group": ["time", "date"],
|
"highlight_group": ["time", "date"],
|
||||||
"divider_highlight_group": "time:divider"
|
"divider_highlight_group": "time:divider"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "email_imap_alert",
|
"name": "email_imap_alert",
|
||||||
"before": "✉ ",
|
|
||||||
"priority": 10,
|
"priority": 10,
|
||||||
"args": {
|
|
||||||
"username": "",
|
|
||||||
"password": ""
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "hostname"
|
"name": "hostname"
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import importlib
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from powerline.colorscheme import Colorscheme
|
|
||||||
from powerline.matcher import Matcher
|
|
||||||
from powerline.lib import underscore_to_camelcase
|
|
||||||
|
|
||||||
|
|
||||||
class Powerline(object):
|
|
||||||
def __init__(self, ext, renderer_module=None, segment_info=None, renderer_options={}):
|
|
||||||
config_home = os.environ.get('XDG_CONFIG_HOME', os.path.expanduser('~/.config'))
|
|
||||||
config_path = os.path.join(config_home, 'powerline')
|
|
||||||
plugin_path = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'config_files')
|
|
||||||
self.search_paths = [config_path, plugin_path]
|
|
||||||
sys.path[:0] = self.search_paths
|
|
||||||
|
|
||||||
# Load main config file
|
|
||||||
config = self._load_json_config('config')
|
|
||||||
self.config = config['common']
|
|
||||||
self.config_ext = config['ext'][ext]
|
|
||||||
|
|
||||||
# Load and initialize colorscheme
|
|
||||||
colorscheme_config = self._load_json_config(os.path.join('colorschemes', ext, self.config_ext['colorscheme']))
|
|
||||||
colorscheme = Colorscheme(colorscheme_config)
|
|
||||||
|
|
||||||
# Load and initialize extension theme
|
|
||||||
theme_config = self._load_theme_config(ext, self.config_ext.get('theme', 'default'))
|
|
||||||
self.config['paths'] = [os.path.expanduser(path) for path in self.config.get('paths', [])]
|
|
||||||
self.get_matcher = Matcher(ext, self.config['paths']).get
|
|
||||||
theme_kwargs = {
|
|
||||||
'ext': ext,
|
|
||||||
'colorscheme': colorscheme,
|
|
||||||
'common_config': self.config,
|
|
||||||
'segment_info': segment_info,
|
|
||||||
}
|
|
||||||
local_themes = {}
|
|
||||||
for key, local_theme_name in self.config_ext.get('local_themes', {}).items():
|
|
||||||
key = self.get_matcher(key)
|
|
||||||
local_themes[key] = {'config': self._load_theme_config(ext, local_theme_name)}
|
|
||||||
|
|
||||||
# Load and initialize extension renderer
|
|
||||||
renderer_module_name = renderer_module or ext
|
|
||||||
renderer_module_import = 'powerline.renderers.{0}'.format(renderer_module_name)
|
|
||||||
renderer_class_name = '{0}Renderer'.format(underscore_to_camelcase(renderer_module_name))
|
|
||||||
try:
|
|
||||||
Renderer = getattr(importlib.import_module(renderer_module_import), renderer_class_name)
|
|
||||||
except ImportError as e:
|
|
||||||
sys.stderr.write('Error while importing renderer module: {0}\n'.format(e))
|
|
||||||
sys.exit(1)
|
|
||||||
options = {'term_truecolor': self.config.get('term_24bit_colors', False)}
|
|
||||||
options.update(renderer_options)
|
|
||||||
self.renderer = Renderer(theme_config, local_themes, theme_kwargs, **options)
|
|
||||||
|
|
||||||
def add_local_theme(self, key, config):
|
|
||||||
'''Add local themes at runtime (e.g. during vim session).
|
|
||||||
|
|
||||||
Accepts key as first argument (same as keys in config.json:
|
|
||||||
ext/*/local_themes) and configuration dictionary as the second (has
|
|
||||||
format identical to themes/*/*.json)
|
|
||||||
|
|
||||||
Returns True if theme was added successfully and False if theme with
|
|
||||||
the same matcher already exists
|
|
||||||
'''
|
|
||||||
key = self.get_matcher(key)
|
|
||||||
try:
|
|
||||||
self.renderer.add_local_theme(key, {'config': config})
|
|
||||||
except KeyError:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _load_theme_config(self, ext, name):
|
|
||||||
return self._load_json_config(os.path.join('themes', ext, name))
|
|
||||||
|
|
||||||
def _load_json_config(self, config_file):
|
|
||||||
config_file += '.json'
|
|
||||||
for path in self.search_paths:
|
|
||||||
config_file_path = os.path.join(path, config_file)
|
|
||||||
if os.path.isfile(config_file_path):
|
|
||||||
with open(config_file_path, 'r') as config_file_fp:
|
|
||||||
return json.load(config_file_fp)
|
|
||||||
raise IOError('Config file not found in search path: {0}'.format(config_file))
|
|
27
powerline/ipython.py
Normal file
27
powerline/ipython.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from powerline import Powerline
|
||||||
|
from powerline.lib import mergedicts
|
||||||
|
|
||||||
|
|
||||||
|
class IpythonPowerline(Powerline):
|
||||||
|
def __init__(self):
|
||||||
|
super(IpythonPowerline, self).__init__('ipython')
|
||||||
|
|
||||||
|
def get_config_paths(self):
|
||||||
|
if self.path:
|
||||||
|
return [self.path]
|
||||||
|
else:
|
||||||
|
return super(IpythonPowerline, self).get_config_paths()
|
||||||
|
|
||||||
|
def load_main_config(self):
|
||||||
|
r = super(IpythonPowerline, self).load_main_config()
|
||||||
|
if self.config_overrides:
|
||||||
|
mergedicts(r, self.config_overrides)
|
||||||
|
return r
|
||||||
|
|
||||||
|
def load_theme_config(self, name):
|
||||||
|
r = super(IpythonPowerline, self).load_theme_config(name)
|
||||||
|
if name in self.theme_overrides:
|
||||||
|
mergedicts(r, self.theme_overrides[name])
|
||||||
|
return r
|
@ -6,3 +6,12 @@ from powerline.lib.url import urllib_read, urllib_urlencode # NOQA
|
|||||||
def underscore_to_camelcase(string):
|
def underscore_to_camelcase(string):
|
||||||
'''Return a underscore_separated_string as CamelCase.'''
|
'''Return a underscore_separated_string as CamelCase.'''
|
||||||
return ''.join(word.capitalize() or '_' for word in string.split('_'))
|
return ''.join(word.capitalize() or '_' for word in string.split('_'))
|
||||||
|
|
||||||
|
def mergedicts(d1, d2):
|
||||||
|
'''Recursively merge two dictionaries. First dictionary is modified in-place.
|
||||||
|
'''
|
||||||
|
for k in d2:
|
||||||
|
if k in d1 and type(d1[k]) is dict and type(d2[k]) is dict:
|
||||||
|
mergedicts(d1[k], d2[k])
|
||||||
|
else:
|
||||||
|
d1[k] = d2[k]
|
||||||
|
@ -4,19 +4,16 @@ from importlib import import_module
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
class Matcher(object):
|
def gen_matcher_getter(ext, import_paths):
|
||||||
def __init__(self, ext, path):
|
def get(match_name):
|
||||||
self.ext = ext
|
|
||||||
self.path = path
|
|
||||||
|
|
||||||
def get(self, match_name):
|
|
||||||
match_module, separator, match_function = match_name.rpartition('.')
|
match_module, separator, match_function = match_name.rpartition('.')
|
||||||
if not separator:
|
if not separator:
|
||||||
match_module = 'powerline.matchers.{0}'.format(self.ext)
|
match_module = 'powerline.matchers.{0}'.format(ext)
|
||||||
match_function = match_name
|
match_function = match_name
|
||||||
oldpath = sys.path
|
oldpath = sys.path
|
||||||
sys.path = self.path + sys.path
|
sys.path = import_paths + sys.path
|
||||||
try:
|
try:
|
||||||
return getattr(import_module(match_module), match_function)
|
return getattr(import_module(match_module), match_function)
|
||||||
finally:
|
finally:
|
||||||
sys.path = oldpath
|
sys.path = oldpath
|
||||||
|
return get
|
||||||
|
42
powerline/shell.py
Normal file
42
powerline/shell.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from powerline import Powerline
|
||||||
|
from powerline.lib import mergedicts
|
||||||
|
|
||||||
|
|
||||||
|
def mergeargs(argvalue):
|
||||||
|
if not argvalue:
|
||||||
|
return None
|
||||||
|
l = argvalue
|
||||||
|
r = dict([argvalue[0]])
|
||||||
|
for subval in argvalue[1:]:
|
||||||
|
mergedicts(r, dict([subval]))
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
class ShellPowerline(Powerline):
|
||||||
|
def __init__(self, args):
|
||||||
|
self.args = args
|
||||||
|
self.theme_option = mergeargs(args.theme_option) or {}
|
||||||
|
super(ShellPowerline, self).__init__(args.ext[0], args.renderer_module)
|
||||||
|
|
||||||
|
def get_segment_info(self):
|
||||||
|
return self.args
|
||||||
|
|
||||||
|
def load_main_config(self):
|
||||||
|
r = super(ShellPowerline, self).load_main_config()
|
||||||
|
if self.args.config:
|
||||||
|
mergedicts(r, mergeargs(self.args.config))
|
||||||
|
return r
|
||||||
|
|
||||||
|
def load_theme_config(self, name):
|
||||||
|
r = super(ShellPowerline, self).load_theme_config(name)
|
||||||
|
if name in self.theme_option:
|
||||||
|
mergedicts(r, self.theme_option[name])
|
||||||
|
return r
|
||||||
|
|
||||||
|
def get_config_paths(self):
|
||||||
|
if self.args.config_path:
|
||||||
|
return [self.args.config_path]
|
||||||
|
else:
|
||||||
|
return super(ShellPowerline, self).get_config_paths()
|
72
powerline/vim.py
Normal file
72
powerline/vim.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
from powerline.bindings.vim import vim_get_func
|
||||||
|
from powerline import Powerline
|
||||||
|
from powerline.lib import mergedicts
|
||||||
|
from powerline.matcher import gen_matcher_getter
|
||||||
|
import vim
|
||||||
|
|
||||||
|
|
||||||
|
vim_exists = vim_get_func('exists', rettype=int)
|
||||||
|
|
||||||
|
def _override_from(config, override_varname):
|
||||||
|
if vim_exists(override_varname):
|
||||||
|
# FIXME vim.eval has problem with numeric types, vim.bindeval may be
|
||||||
|
# absent (and requires converting values to python built-in types),
|
||||||
|
# vim.eval with typed call like the one I implemented in frawor is slow.
|
||||||
|
# Maybe eval(vime.eval('string({0})'.format(override_varname)))?
|
||||||
|
overrides = vim.eval(override_varname)
|
||||||
|
mergedicts(config, overrides)
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
class VimPowerline(Powerline):
|
||||||
|
def __init__(self):
|
||||||
|
super(VimPowerline, self).__init__('vim')
|
||||||
|
|
||||||
|
def add_local_theme(self, key, config):
|
||||||
|
'''Add local themes at runtime (during vim session).
|
||||||
|
|
||||||
|
Accepts key as first argument (same as keys in config.json:
|
||||||
|
ext/*/local_themes) and configuration dictionary as the second (has
|
||||||
|
format identical to themes/*/*.json)
|
||||||
|
|
||||||
|
Returns True if theme was added successfully and False if theme with
|
||||||
|
the same matcher already exists
|
||||||
|
'''
|
||||||
|
key = self.get_matcher(key)
|
||||||
|
try:
|
||||||
|
self.renderer.add_local_theme(key, {'config': config})
|
||||||
|
except KeyError:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def load_main_config(self):
|
||||||
|
return _override_from(super(VimPowerline, self).load_main_config(), 'g:powerline_config_overrides')
|
||||||
|
|
||||||
|
def load_theme_config(self, name):
|
||||||
|
# Note: themes with non-[a-zA-Z0-9_] names are impossible to override
|
||||||
|
# (though as far as I know exists() won’t throw). Won’t fix, use proper
|
||||||
|
# theme names.
|
||||||
|
return _override_from(super(VimPowerline, self).load_theme_config(name), 'g:powerline_theme_overrides__'+name)
|
||||||
|
|
||||||
|
def get_local_themes(self, local_themes):
|
||||||
|
self.get_matcher = gen_matcher_getter(self.ext, self.import_paths)
|
||||||
|
r = {}
|
||||||
|
for key, local_theme_name in local_themes.items():
|
||||||
|
key = self.get_matcher(key)
|
||||||
|
r[key] = {'config': self.load_theme_config(local_theme_name)}
|
||||||
|
return r
|
||||||
|
|
||||||
|
def get_config_paths(self):
|
||||||
|
if vim_exists('g:powerline_config_path'):
|
||||||
|
return [vim.eval('g:powerline_config_path')]
|
||||||
|
else:
|
||||||
|
return super(VimPowerline, self).get_config_paths()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_segment_info():
|
||||||
|
return {}
|
@ -6,11 +6,11 @@ import sys
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from powerline.core import Powerline
|
from powerline.shell import ShellPowerline
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import os
|
import os
|
||||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
from powerline.core import Powerline # NOQA
|
from powerline.shell import ShellPowerline # NOQA
|
||||||
|
|
||||||
def oval(s):
|
def oval(s):
|
||||||
if '=' not in s:
|
if '=' not in s:
|
||||||
@ -22,6 +22,20 @@ def oval(s):
|
|||||||
val = json.loads(s[idx+1:])
|
val = json.loads(s[idx+1:])
|
||||||
return (o, val)
|
return (o, val)
|
||||||
|
|
||||||
|
def odotval(s):
|
||||||
|
o, val = oval(s)
|
||||||
|
keys = o.split('.')
|
||||||
|
if len(keys) > 1:
|
||||||
|
r = (keys[0], {})
|
||||||
|
rcur = r[1]
|
||||||
|
for key in keys[1:-1]:
|
||||||
|
rcur[key] = {}
|
||||||
|
rcur = rcur[key]
|
||||||
|
rcur[keys[-1]] = val
|
||||||
|
return r
|
||||||
|
else:
|
||||||
|
return (o, val)
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description=__doc__)
|
parser = argparse.ArgumentParser(description=__doc__)
|
||||||
parser.add_argument('ext', nargs=1)
|
parser.add_argument('ext', nargs=1)
|
||||||
parser.add_argument('side', nargs='?', choices=('left', 'right'))
|
parser.add_argument('side', nargs='?', choices=('left', 'right'))
|
||||||
@ -29,11 +43,13 @@ parser.add_argument('-r', '--renderer_module', metavar='MODULE', type=str)
|
|||||||
parser.add_argument('-w', '--width', type=int)
|
parser.add_argument('-w', '--width', type=int)
|
||||||
parser.add_argument('--last_exit_code', metavar='INT', type=int)
|
parser.add_argument('--last_exit_code', metavar='INT', type=int)
|
||||||
parser.add_argument('--last_pipe_status', metavar='LIST', default='', type=lambda s: [int(status) for status in s.split()])
|
parser.add_argument('--last_pipe_status', metavar='LIST', default='', type=lambda s: [int(status) for status in s.split()])
|
||||||
parser.add_argument('-o', '--renderer_option', nargs='*', metavar='OPTION=VALUE', type=oval)
|
parser.add_argument('-c', '--config', metavar='KEY.KEY=VALUE', type=odotval, action='append')
|
||||||
|
parser.add_argument('-t', '--theme_option', metavar='THEME.KEY.KEY=VALUE', type=odotval, action='append')
|
||||||
|
parser.add_argument('-p', '--config_path', metavar='PATH')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
powerline = Powerline(ext=args.ext[0], renderer_module=args.renderer_module, segment_info=args, renderer_options=dict(args.renderer_option or {}))
|
powerline = ShellPowerline(args)
|
||||||
rendered = powerline.renderer.render(width=args.width, side=args.side)
|
rendered = powerline.renderer.render(width=args.width, side=args.side)
|
||||||
try:
|
try:
|
||||||
sys.stdout.write(rendered)
|
sys.stdout.write(rendered)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user