Merge pull request #1039 from ZyX-I/function-key

Refactor function segments
This commit is contained in:
Nikolai Aleksandrovich Pavlov 2014-08-30 00:17:05 +04:00
commit c488b2da7b
41 changed files with 350 additions and 256 deletions

View File

@ -64,8 +64,9 @@ Common configuration is a subdictionary that is a value of ``common`` key in
``paths``
Defines additional paths which will be searched for modules when using
:ref:`module segment option <config-themes-seg-module>`. Paths defined here
have priority when searching for modules.
:ref:`function segment option <config-themes-seg-function>` or :ref:`Vim
local_themes option <config-ext-local_themes>`. Paths defined here have
priority when searching for modules.
.. _config-common-log:
@ -283,7 +284,8 @@ ascii Theme without any unicode characters at all
.. _config-themes-default_module:
``default_module``
Python module where segments will be looked by default.
Python module where segments will be looked by default. Defaults to
``powerline.segments.{ext}``.
``spaces``
Defines number of spaces just before the divider (on the right side) or just
@ -325,8 +327,8 @@ ascii Theme without any unicode characters at all
.. _config-themes-segment_data:
``segment_data``
A dict where keys are segment names or strings ``{module}.{name}``. Used to
specify default values for various keys:
A dict where keys are segment names or strings ``{module}.{function}``. Used
to specify default values for various keys:
:ref:`after <config-themes-seg-after>`,
:ref:`before <config-themes-seg-before>`,
:ref:`contents <config-themes-seg-contents>` (only for string segments
@ -335,8 +337,8 @@ ascii Theme without any unicode characters at all
Key :ref:`args <config-themes-seg-args>` (only for function and
segments_list segments) is handled specially: unlike other values it is
merged with all other values, except that a single ``{module}.{name}`` key
if found prevents merging all ``{name}`` values.
merged with all other values, except that a single ``{module}.{function}``
key if found prevents merging all ``{function}`` values.
When using :ref:`local themes <config-ext-local_themes>` values of these
keys are first searched in the segment description, then in ``segment_data``
@ -372,8 +374,8 @@ ascii Theme without any unicode characters at all
``filler`` or ``segments_list``:
``function``
The segment contents is the return value of the function defined
in the :ref:`name option <config-themes-seg-name>`.
The segment contents is the return value of the function defined in
the :ref:`function option <config-themes-seg-function>`.
``string``
A static string segment where the contents is defined in the
@ -382,22 +384,31 @@ ascii Theme without any unicode characters at all
option <config-themes-seg-highlight_group>`.
``segments_list``
Sub-list of segments. This list only allows :ref:`name
<config-themes-seg-name>`, :ref:`segments
Sub-list of segments. This list only allows :ref:`function
<config-themes-seg-function>`, :ref:`segments
<config-themes-seg-segments>` and :ref:`args
<config-themes-seg-args>` options.
.. _config-themes-seg-module:
``module``
Function module, only required for function segments. Defaults to
``powerline.segments.{extension}``. Default is overriden by
:ref:`default_module theme option <config-themes-default_module>`.
.. _config-themes-seg-name:
``name``
Function name, only required for function and list segments.
Segment name. If present allows referring to this segment in
:ref:`segment_data <config-themes-segment_data>` dictionary by this
name. If not ``string`` segments may not be referred there at all and
``function`` and ``segments_list`` segments may be referred there using
either ``{module}.{function_name}`` or ``{function_name}``, whichever
will be found first. Function name is taken from :ref:`function key
<config-themes-seg-function>`.
.. note::
If present prevents ``function`` key from acting as a segment name.
.. _config-themes-seg-function:
``function``
Function used to get segment contents, in format ``{module}.{function}``
or ``{function}``. If ``{module}`` is omitted :ref:`default_module
option <config-themes-default_module>` is used.
.. _config-themes-seg-highlight_group:

View File

@ -25,6 +25,10 @@
"contents": "LN "
},
"time": {
"before": ""
},
"powerline.segments.common.network_load": {
"args": {
"recv_format": "DL {value:>8}",
@ -50,9 +54,6 @@
"powerline.segments.common.uptime": {
"before": "UP "
},
"powerline.segments.common.date": {
"before": ""
},
"powerline.segments.common.email_imap_alert": {
"before": "MAIL "
},

View File

@ -3,7 +3,7 @@
"segments": {
"left": [
{
"name": "virtualenv",
"function": "virtualenv",
"priority": 10
},
{
@ -13,8 +13,7 @@
"highlight_group": ["prompt"]
},
{
"name": "prompt_count",
"module": "powerline.segments.ipython",
"function": "powerline.segments.ipython.prompt_count",
"draw_soft_divider": false
},
{

View File

@ -1,5 +1,5 @@
{
"default_module": "powerline.segments.common",
"default_module": "powerline.segments.ipython",
"segments": {
"left": [
{
@ -11,8 +11,7 @@
"highlight_group": ["prompt"]
},
{
"name": "prompt_count",
"module": "powerline.segments.ipython",
"function": "prompt_count",
"draw_soft_divider": false
},
{

View File

@ -1,4 +1,5 @@
{
"default_module": "powerline.segments.ipython",
"segments": {
"left": [
{
@ -9,8 +10,7 @@
"highlight_group": ["prompt"]
},
{
"name": "prompt_count",
"module": "powerline.segments.ipython",
"function": "prompt_count",
"draw_soft_divider": false
},
{

View File

@ -24,6 +24,10 @@
"contents": " "
},
"time": {
"before": "⌚ "
},
"powerline.segments.common.network_load": {
"args": {
"recv_format": "⬇ {value:>8}",
@ -49,9 +53,6 @@
"powerline.segments.common.uptime": {
"before": "⇑ "
},
"powerline.segments.common.date": {
"before": "⌚ "
},
"powerline.segments.common.email_imap_alert": {
"before": "✉ "
},

View File

@ -3,7 +3,7 @@
"segments": {
"left": [
{
"name": "continuation"
"function": "continuation"
}
],
"right": [

View File

@ -3,40 +3,36 @@
"segments": {
"left": [
{
"module": "powerline.segments.shell",
"name": "mode"
"function": "powerline.segments.shell.mode"
},
{
"name": "hostname",
"function": "hostname",
"priority": 10
},
{
"name": "user",
"function": "user",
"priority": 30
},
{
"name": "virtualenv",
"function": "virtualenv",
"priority": 50
},
{
"module": "powerline.segments.shell",
"name": "cwd",
"function": "powerline.segments.shell.cwd",
"priority": 10
},
{
"module": "powerline.segments.shell",
"name": "jobnum",
"function": "powerline.segments.shell.jobnum",
"priority": 20
}
],
"right": [
{
"module": "powerline.segments.shell",
"name": "last_pipe_status",
"function": "powerline.segments.shell.last_pipe_status",
"priority": 10
},
{
"name": "branch",
"function": "branch",
"priority": 40
}
]

View File

@ -3,34 +3,31 @@
"segments": {
"left": [
{
"name": "hostname",
"function": "hostname",
"priority": 10
},
{
"name": "user",
"function": "user",
"priority": 30
},
{
"name": "virtualenv",
"function": "virtualenv",
"priority": 50
},
{
"name": "branch",
"function": "branch",
"priority": 40
},
{
"module": "powerline.segments.shell",
"name": "cwd",
"function": "powerline.segments.shell.cwd",
"priority": 10
},
{
"module": "powerline.segments.shell",
"name": "jobnum",
"function": "powerline.segments.shell.jobnum",
"priority": 20
},
{
"module": "powerline.segments.shell",
"name": "last_status",
"function": "powerline.segments.shell.last_status",
"priority": 10
}
]

View File

@ -3,26 +3,26 @@
"segments": {
"right": [
{
"name": "uptime",
"function": "uptime",
"priority": 50
},
{
"name": "system_load",
"function": "system_load",
"priority": 50
},
{
"name": "date",
"before": ""
"function": "date"
},
{
"name": "date",
"function": "date",
"name": "time",
"args": {
"format": "%H:%M",
"istime": true
}
},
{
"name": "hostname"
"function": "hostname"
}
]
}

View File

@ -24,6 +24,10 @@
"contents": "␤ "
},
"time": {
"before": "⌚ "
},
"powerline.segments.common.network_load": {
"args": {
"recv_format": "⬇ {value:>8}",
@ -49,9 +53,6 @@
"powerline.segments.common.uptime": {
"before": "⇑ "
},
"powerline.segments.common.date": {
"before": "⌚ "
},
"powerline.segments.common.email_imap_alert": {
"before": "✉ "
},

View File

@ -24,6 +24,10 @@
"contents": "␤ "
},
"time": {
"before": ""
},
"powerline.segments.common.network_load": {
"args": {
"recv_format": "⇓ {value:>8}",
@ -49,9 +53,6 @@
"powerline.segments.common.uptime": {
"before": "↑ "
},
"powerline.segments.common.date": {
"before": ""
},
"powerline.segments.common.email_imap_alert": {
"before": "MAIL "
},

View File

@ -25,6 +25,10 @@
"contents": "␤"
},
"time": {
"before": ""
},
"powerline.segments.common.network_load": {
"args": {
"recv_format": "⇓{value:>8}",
@ -50,9 +54,6 @@
"powerline.segments.common.uptime": {
"before": "↑"
},
"powerline.segments.common.date": {
"before": ""
},
"powerline.segments.common.email_imap_alert": {
"before": "M "
},

View File

@ -2,67 +2,65 @@
"segments": {
"left": [
{
"name": "mode",
"function": "mode",
"exclude_modes": ["nc"]
},
{
"name": "visual_range",
"function": "visual_range",
"include_modes": ["v", "V", "^V", "s", "S", "^S"],
"priority": 10
},
{
"name": "paste_indicator",
"function": "paste_indicator",
"exclude_modes": ["nc"],
"priority": 10
},
{
"name": "branch",
"function": "branch",
"exclude_modes": ["nc"],
"priority": 30
},
{
"name": "readonly_indicator",
"function": "readonly_indicator",
"draw_soft_divider": false,
"after": " "
},
{
"name": "file_scheme",
"function": "file_scheme",
"priority": 20
},
{
"name": "file_directory",
"function": "file_directory",
"priority": 40,
"draw_soft_divider": false
},
{
"name": "file_name",
"function": "file_name",
"draw_soft_divider": false
},
{
"name": "file_vcs_status",
"function": "file_vcs_status",
"before": " ",
"draw_soft_divider": false
},
{
"name": "modified_indicator",
"function": "modified_indicator",
"before": " "
},
{
"exclude_modes": ["i", "R", "Rv"],
"name": "trailing_whitespace",
"function": "trailing_whitespace",
"display": false,
"priority": 60
},
{
"exclude_modes": ["nc"],
"module": "powerline.segments.vim.plugin.syntastic",
"name": "syntastic",
"function": "powerline.segments.vim.plugin.syntastic.syntastic",
"priority": 50
},
{
"exclude_modes": ["nc"],
"module": "powerline.segments.vim.plugin.tagbar",
"name": "current_tag",
"function": "powerline.segments.vim.plugin.tagbar.current_tag",
"draw_soft_divider": false,
"priority": 50
},
@ -76,23 +74,23 @@
],
"right": [
{
"name": "file_format",
"function": "file_format",
"draw_soft_divider": false,
"exclude_modes": ["nc"],
"priority": 60
},
{
"name": "file_encoding",
"function": "file_encoding",
"exclude_modes": ["nc"],
"priority": 60
},
{
"name": "file_type",
"function": "file_type",
"exclude_modes": ["nc"],
"priority": 60
},
{
"name": "line_percent",
"function": "line_percent",
"priority": 50,
"width": 4,
"align": "r"
@ -103,13 +101,13 @@
"highlight_group": ["line_current_symbol", "line_current"]
},
{
"name": "line_current",
"function": "line_current",
"draw_soft_divider": false,
"width": 3,
"align": "r"
},
{
"name": "virtcol_current",
"function": "virtcol_current",
"draw_soft_divider": false,
"priority": 20,
"before": ":",

View File

@ -2,7 +2,7 @@
"segments": {
"left": [
{
"name": "file_name",
"function": "file_name",
"draw_soft_divider": false
},
{
@ -15,7 +15,7 @@
],
"right": [
{
"name": "line_percent",
"function": "line_percent",
"priority": 30,
"width": 4,
"align": "r"
@ -26,7 +26,7 @@
"highlight_group": ["line_current_symbol", "line_current"]
},
{
"name": "line_current",
"function": "line_current",
"draw_soft_divider": false,
"width": 3,
"align": "r"

View File

@ -3,7 +3,7 @@
"segments": {
"left": [
{
"name": "ctrlp",
"function": "ctrlp",
"args": {
"side": "left"
}
@ -18,7 +18,7 @@
],
"right": [
{
"name": "ctrlp",
"function": "ctrlp",
"args": {
"side": "right"
}

View File

@ -3,7 +3,7 @@
"segments": {
"left": [
{
"name": "nerdtree"
"function": "nerdtree"
},
{
"type": "string",

View File

@ -12,7 +12,7 @@
"highlight_group": ["file_name"]
},
{
"name": "window_title",
"function": "window_title",
"draw_soft_divider": false
},
{
@ -30,7 +30,7 @@
"highlight_group": ["line_current_symbol", "line_current"]
},
{
"name": "line_current",
"function": "line_current",
"draw_soft_divider": false,
"width": 3,
"align": "r"

View File

@ -4,39 +4,38 @@
"left": [
{
"type": "segment_list",
"module": "powerline.listers.vim",
"name": "tabbuflister",
"function": "powerline.listers.vim.tabbuflister",
"segments": [
{
"name": "tabnr",
"function": "tabnr",
"after": " ",
"exclude_modes": ["tab", "buf", "buf_nc"],
"priority": 5
},
{
"name": "bufnr",
"function": "bufnr",
"after": " ",
"exclude_modes": ["tab", "buf", "tab_nc"],
"priority": 5
},
{
"name": "file_directory",
"function": "file_directory",
"priority": 40
},
{
"name": "file_name",
"function": "file_name",
"args": {
"display_no_file": true
},
"priority": 10
},
{
"name": "tab_modified_indicator",
"function": "tab_modified_indicator",
"exclude_modes": ["buf", "buf_nc"],
"priority": 5
},
{
"name": "modified_indicator",
"function": "modified_indicator",
"exclude_modes": ["tab", "tab_nc"],
"priority": 5
}
@ -52,7 +51,7 @@
],
"right": [
{
"name": "single_tab"
"function": "single_tab"
}
]
}

View File

@ -3,22 +3,22 @@
"segments": {
"right": [
{
"name": "weather",
"function": "weather",
"priority": 50
},
{
"name": "date",
"before": ""
"function": "date"
},
{
"name": "date",
"function": "date",
"name": "time",
"args": {
"format": "%H:%M",
"istime": true
}
},
{
"name": "email_imap_alert",
"function": "email_imap_alert",
"priority": 10,
"args": {
"username": "",

View File

@ -808,16 +808,16 @@ generic_keys = set((
'display'
))
type_keys = {
'function': set(('args', 'module', 'draw_inner_divider')),
'function': set(('function', 'args', 'draw_inner_divider')),
'string': set(('contents', 'type', 'highlight_group', 'divider_highlight_group')),
'filler': set(('type', 'highlight_group', 'divider_highlight_group')),
'segment_list': set(('segments', 'module', 'args', 'type')),
'segment_list': set(('function', 'segments', 'args', 'type')),
}
required_keys = {
'function': set(('name',)),
'function': set(('function',)),
'string': set(()),
'filler': set(),
'segment_list': set(('name', 'segments',)),
'segment_list': set(('function', 'segments',)),
}
highlight_keys = set(('highlight_group', 'name'))
@ -887,8 +887,17 @@ def check_segment_module(module, data, context, echoerr):
return True, False, False
def get_function_strings(function_name, context, ext):
if '.' in function_name:
module, function_name = function_name.rpartition('.')[::2]
else:
module = context[0][1].get(
'default_module', MarkedUnicode('powerline.segments.' + ext, None))
return module, function_name
def check_full_segment_data(segment, data, context, echoerr):
if 'name' not in segment:
if 'name' not in segment and 'function' not in segment:
return True, False, False
ext = data['ext']
@ -899,11 +908,17 @@ def check_full_segment_data(segment, data, context, echoerr):
else:
top_segment_data = data['ext_theme_configs'].get(main_theme_name, {}).get('segment_data', {})
names = [segment['name']]
if segment.get('type', 'function') == 'function':
module = segment.get('module', context[0][1].get('default_module', MarkedUnicode(
'powerline.segments.' + ext, None)))
names.insert(0, unicode(module) + '.' + unicode(names[0]))
function_name = segment.get('function')
if function_name:
module, function_name = get_function_strings(function_name, context, ext)
names = [module + '.' + function_name, function_name]
else:
names = []
elif segment.get('name'):
names = [segment['name']]
else:
return True, False, False
segment_copy = segment.copy()
@ -921,15 +936,9 @@ def check_full_segment_data(segment, data, context, echoerr):
return check_key_compatibility(segment_copy, data, context, echoerr)
def import_segment(name, data, context, echoerr, module=None):
def import_segment(name, data, context, echoerr, module):
context_has_marks(context)
havemarks(name)
if not module:
module = context[-2][1].get(
'module', context[0][1].get(
'default_module', MarkedUnicode(
'powerline.segments.' + data['ext'], None)))
havemarks(module)
havemarks(name, module)
with WithPath(data['import_paths']):
try:
@ -956,11 +965,12 @@ def import_segment(name, data, context, echoerr, module=None):
return func
def check_segment_name(name, data, context, echoerr):
havemarks(name)
def check_segment_function(function_name, data, context, echoerr):
havemarks(function_name)
ext = data['ext']
module, function_name = get_function_strings(function_name, context, ext)
if context[-2][1].get('type', 'function') == 'function':
func = import_segment(name, data, context, echoerr)
func = import_segment(function_name, data, context, echoerr, module=module)
if not func:
return True, False, True
@ -974,7 +984,7 @@ def check_segment_name(name, data, context, echoerr):
D_H_G_USED_STR = 'Divider highlight group used: '
LDHGUS = len(D_H_G_USED_STR)
pointer = 0
mark_name = '<{0} docstring>'.format(name)
mark_name = '<{0} docstring>'.format(function_name)
for i, line in enumerate(func.__doc__.split('\n')):
if H_G_USED_STR in line:
idx = line.index(H_G_USED_STR) + LHGUS
@ -1000,7 +1010,7 @@ def check_segment_name(name, data, context, echoerr):
'found highlight group {0} not defined in the following colorschemes: {1}\n'
'(Group name was obtained from function documentation.)'
).format(divider_hl_group, list_sep.join(r)),
problem_mark=name.mark
problem_mark=function_name.mark
)
hadproblem = True
@ -1039,7 +1049,7 @@ def check_segment_name(name, data, context, echoerr):
'found highlight groups list ({0}) with all groups not defined in some colorschemes\n'
'(Group names were taken from function documentation.)'
).format(list_sep.join((h[0] for h in required_pack))),
problem_mark=name.mark
problem_mark=function_name.mark
)
for r, h in zip(rs, required_pack):
echoerr(
@ -1049,7 +1059,7 @@ def check_segment_name(name, data, context, echoerr):
)
hadproblem = True
else:
r = hl_exists(name, data, context, echoerr, allow_gradients=True)
r = hl_exists(function_name, data, context, echoerr, allow_gradients=True)
if r:
echoerr(
context='Error while checking theme (key {key})'.format(key=context_key(context)),
@ -1058,27 +1068,27 @@ def check_segment_name(name, data, context, echoerr):
'(If not specified otherwise in documentation, '
'highlight group for function segments\n'
'is the same as the function name.)'
).format(name, list_sep.join(r)),
problem_mark=name.mark
).format(function_name, list_sep.join(r)),
problem_mark=function_name.mark
)
hadproblem = True
return True, False, hadproblem
elif context[-2][1].get('type') != 'segment_list':
if name not in context[0][1].get('segment_data', {}):
if function_name not in context[0][1].get('segment_data', {}):
main_theme_name = data['main_config'].get('ext', {}).get(ext, {}).get('theme', None)
if data['theme'] == main_theme_name:
main_theme = {}
else:
main_theme = data['ext_theme_configs'].get(main_theme_name, {})
if (
name not in main_theme.get('segment_data', {})
and name not in data['ext_theme_configs'].get('__main__', {}).get('segment_data', {})
and not any(((name in theme.get('segment_data', {})) for theme in data['top_themes'].values()))
function_name not in main_theme.get('segment_data', {})
and function_name not in data['ext_theme_configs'].get('__main__', {}).get('segment_data', {})
and not any(((function_name in theme.get('segment_data', {})) for theme in data['top_themes'].values()))
):
echoerr(context='Error while checking segments (key {key})'.format(key=context_key(context)),
problem='found useless use of name key (such name is not present in theme/segment_data)',
problem_mark=name.mark)
problem_mark=function_name.mark)
return True, False, False
@ -1192,16 +1202,22 @@ def check_segment_data_key(key, data, context, echoerr):
for segments in theme.get('segments', {}).values():
for segment in segments:
if 'name' in segment:
if has_module_name:
module = segment.get('module', theme.get('default_module', 'powerline.segments.' + ext))
full_name = unicode(module) + '.' + unicode(segment['name'])
if key == full_name:
found = True
break
else:
if key == segment['name']:
found = True
break
if key == segment['name']:
found = True
break
else:
function_name = segment.get('function')
if function_name:
module, function_name = get_function_strings(function_name, ((None, theme),), ext)
if has_module_name:
full_name = module + '.' + function_name
if key == full_name:
found = True
break
else:
if key == function_name:
found = True
break
if found:
break
if found:
@ -1288,9 +1304,11 @@ def check_args(get_functions, args, data, context, echoerr):
def get_one_segment_function(data, context, echoerr):
name = context[-2][1].get('name')
if name:
func = import_segment(name, data, context, echoerr)
ext = data['ext']
function_name = context[-2][1].get('function')
if function_name:
module, function_name = get_function_strings(function_name, context, ext)
func = import_segment(function_name, data, context, echoerr, module=module)
if func:
yield func
@ -1307,14 +1325,14 @@ def get_all_possible_functions(data, context, echoerr):
for segments in theme_config.get('segments', {}).values():
for segment in segments:
if segment.get('type', 'function') == 'function':
module = segment.get(
'module',
theme_config.get('default_module', MarkedUnicode(
'powerline.segments.' + data['ext'], None))
)
func = import_segment(name, data, context, echoerr, module=module)
if func:
yield func
function_name = segment.get('function')
current_name = segment.get('name')
if function_name:
module, function_name = get_function_strings(function_name, ((None, theme_config),), ext)
if current_name == name or function_name == name:
func = import_segment(function_name, data, context, echoerr, module=module)
if func:
yield func
args_spec = Spec(
@ -1326,7 +1344,8 @@ segment_module_spec = Spec().type(unicode).func(check_segment_module).optional()
sub_segments_spec = Spec()
segment_spec = Spec(
type=Spec().oneof(type_keys).optional(),
name=Spec().re('^[a-zA-Z_]\w*$').func(check_segment_name).optional(),
name=Spec().re('^[a-zA-Z_]\w*$').optional(),
function=Spec().re('^(\w+\.)*[a-zA-Z_]\w*$').func(check_segment_function).optional(),
exclude_modes=Spec().list(vim_mode_spec()).optional(),
include_modes=Spec().list(vim_mode_spec()).optional(),
draw_hard_divider=Spec().type(bool).optional(),

View File

@ -4,34 +4,35 @@ from __future__ import absolute_import, unicode_literals, division, print_functi
from powerline.lib.watcher import create_file_watcher
def list_segment_key_values(segment, theme_configs, segment_data, key, module=None, default=None):
def list_segment_key_values(segment, theme_configs, segment_data, key, function_name=None, name=None, module=None, default=None):
try:
yield segment[key]
except KeyError:
pass
try:
name = segment['name']
except KeyError:
pass
else:
found_module_key = False
for theme_config in theme_configs:
try:
segment_data = theme_config['segment_data']
except KeyError:
pass
else:
found_module_key = False
for theme_config in theme_configs:
try:
segment_data = theme_config['segment_data']
except KeyError:
pass
else:
if function_name and not name:
if module:
try:
yield segment_data[module + '.' + name][key]
yield segment_data[module + '.' + function_name][key]
found_module_key = True
except KeyError:
pass
if not found_module_key:
try:
yield segment_data[name][key]
yield segment_data[function_name][key]
except KeyError:
pass
if name:
try:
yield segment_data[name][key]
except KeyError:
pass
if segment_data is not None:
try:
yield segment_data[key]
@ -58,26 +59,31 @@ def get_segment_key(merge, *args, **kwargs):
def get_function(data, segment):
segment_module = str(segment.get('module', data['default_module']))
function = data['get_module_attr'](segment_module, segment['name'], prefix='segment_generator')
function_name = segment['function']
if '.' in function_name:
module, function_name = function_name.rpartition('.')[::2]
else:
module = data['default_module']
function = data['get_module_attr'](module, function_name, prefix='segment_generator')
if not function:
raise ImportError('Failed to obtain segment function')
return None, function, segment_module
return None, function, module, function_name, segment.get('name')
def get_string(data, segment):
return data['get_key'](False, segment, None, 'contents'), None, None
name = segment.get('name')
return data['get_key'](False, segment, None, None, name, 'contents'), None, None, None, name
def get_filler(data, segment):
return None, None, None
return None, None, None, None, None
segment_getters = {
"function": get_function,
"string": get_string,
"filler": get_filler,
"segment_list": get_function,
'function': get_function,
'string': get_string,
'filler': get_filler,
'segment_list': get_function,
}
@ -185,8 +191,8 @@ def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, ge
'segment_data': None,
}
def get_key(merge, segment, module, key, default=None):
return get_segment_key(merge, segment, theme_configs, data['segment_data'], key, module, default)
def get_key(merge, segment, module, function_name, name, key, default=None):
return get_segment_key(merge, segment, theme_configs, data['segment_data'], key, function_name, name, module, default)
data['get_key'] = get_key
def get(segment, side):
@ -197,12 +203,12 @@ def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, ge
raise TypeError('Unknown segment type: {0}'.format(segment_type))
try:
contents, _contents_func, module = get_segment_info(data, segment)
contents, _contents_func, module, function_name, name = get_segment_info(data, segment)
except Exception as e:
pl.exception('Failed to generate segment from {0!r}: {1}', segment, str(e), prefix='segment_generator')
return None
if not get_key(False, segment, module, 'display', True):
if not get_key(False, segment, module, function_name, name, 'display', True):
return None
segment_datas = getattr(_contents_func, 'powerline_segment_datas', None)
@ -213,12 +219,12 @@ def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, ge
pass
if segment_type == 'function':
highlight_group = [module + '.' + segment['name'], segment['name']]
highlight_group = [module + '.' + function_name, function_name]
else:
highlight_group = segment.get('highlight_group') or segment.get('name')
highlight_group = segment.get('highlight_group') or name
if segment_type in ('function', 'segment_list'):
args = dict(((str(k), v) for k, v in get_key(True, segment, module, 'args', {}).items()))
args = dict(((str(k), v) for k, v in get_key(True, segment, module, function_name, name, 'args', {}).items()))
if segment_type == 'segment_list':
# Handle startup and shutdown of _contents_func?
@ -227,7 +233,7 @@ def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, ge
for subsegment in segment['segments']
]
return {
'name': segment.get('name'),
'name': name or function_name,
'type': segment_type,
'highlight_group': None,
'divider_highlight_group': None,
@ -278,12 +284,12 @@ def gen_segment_getter(pl, ext, common_config, theme_configs, default_module, ge
contents_func = None
return {
'name': segment.get('name'),
'name': name or function_name,
'type': segment_type,
'highlight_group': highlight_group,
'divider_highlight_group': None,
'before': get_key(False, segment, module, 'before', ''),
'after': get_key(False, segment, module, 'after', ''),
'before': get_key(False, segment, module, function_name, name, 'before', ''),
'after': get_key(False, segment, module, function_name, name, 'after', ''),
'contents_func': contents_func,
'contents': contents,
'priority': segment.get('priority', None),

7
tests/run_lint_tests.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh
FAILED=0
if ! ${PYTHON} scripts/powerline-lint -p powerline/config_files ; then
echo "Failed powerline-lint"
FAILED=1
fi
exit $FAILED

9
tests/run_python_tests.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/sh
FAILED=0
for file in tests/test_*.py ; do
if ! ${PYTHON} $file --verbose --catch ; then
echo "Failed test(s) from $file"
FAILED=1
fi
done
exit $FAILED

9
tests/run_shell_tests.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/sh
FAILED=0
if ! sh tests/test_shells/test.sh --fast ; then
echo "Failed shells"
if ${PYTHON} -c 'import platform, sys; sys.exit(1 * (platform.python_implementation() == "PyPy"))' ; then
FAILED=1
fi
fi
exit $FAILED

11
tests/run_vim_tests.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/sh
FAILED=0
for script in tests/*.vim ; do
if ! vim -u NONE -S $script || test -f message.fail ; then
echo "Failed script $script" >&2
cat message.fail >&2
rm message.fail
FAILED=1
fi
done
exit $FAILED

View File

@ -1,29 +1,11 @@
#!/bin/sh
: ${PYTHON:=python}
FAILED=0
export PYTHON="${PYTHON:=python}"
export PYTHONPATH="${PYTHONPATH}:`realpath .`"
for file in tests/test_*.py ; do
if ! ${PYTHON} $file --verbose --catch ; then
echo "Failed test(s) from $file"
for script in tests/run_*_tests.sh ; do
if ! sh $script ; then
echo "Failed $script"
FAILED=1
fi
done
if ! ${PYTHON} scripts/powerline-lint -p powerline/config_files ; then
echo "Failed powerline-lint"
FAILED=1
fi
for script in tests/*.vim ; do
if ! vim -u NONE -S $script || test -f message.fail ; then
echo "Failed script $script" >&2
cat message.fail >&2
rm message.fail
FAILED=1
fi
done
if ! bash tests/test_shells/test.sh --fast ; then
echo "Failed shells"
if ${PYTHON} -c 'import platform, sys; sys.exit(1 * (platform.python_implementation() == "PyPy"))' ; then
FAILED=1
fi
fi
exit $FAILED

View File

@ -123,7 +123,7 @@ config = {
'segments': {
'left': [
{
'name': 'environment',
'function': 'environment',
'args': {
'variable': 'TEST',
},
@ -442,8 +442,7 @@ class TestSegmentAttributes(TestRender):
config['themes/test/default']['segments'] = {
'left': [
{
'name': 'm1',
'module': 'bar'
'function': 'bar.m1'
}
]
}
@ -469,14 +468,57 @@ class TestSegmentAttributes(TestRender):
config['themes/test/default']['segments'] = {
'left': [
{
'name': 'm1',
'module': 'bar'
'function': 'bar.m1'
}
]
}
self.assertRenderEqual(p, '{56} pl;{6-}>>{--}')
class TestSegmentData(TestRender):
@add_args
def test_segment_data(self, p, config):
def m1(**kwargs):
return 'S'
def m2(**kwargs):
return 'S'
sys.modules['bar'] = Args(m1=m1, m2=m2)
config['themes/powerline']['segment_data'] = {
'm1': {
'before': '1'
},
'bar.m2': {
'before': '2'
},
'n': {
'before': '3'
},
'm2': {
'before': '4'
},
}
config['themes/test/default']['segments'] = {
'left': [
{
'function': 'bar.m1'
},
{
'function': 'bar.m1',
'name': 'n'
},
{
'function': 'bar.m2',
'name': 'n'
},
{
'function': 'bar.m2'
}
]
}
self.assertRenderEqual(p, '{56} 1S{56}>{56}3S{610}>>{910}3S{910}>{910}2S{10-}>>{--}')
class TestVim(TestCase):
def test_environ_update(self):
# Regression test: test that segment obtains environment from vim, not

View File

@ -1,5 +1,6 @@
#!/usr/bin/vim -S
set encoding=utf-8
let g:powerline_config_path = expand('<sfile>:p:h:h') . '/powerline/config_files'
tabedit abc
tabedit def
try

View File

@ -138,10 +138,16 @@ class TestConfig(TestCase):
old_cwd = None
saved_get_config_paths = None
def setUpModule():
global old_cwd
global saved_get_config_paths
import powerline
saved_get_config_paths = powerline.get_config_paths
path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'powerline', 'config_files')
powerline.get_config_paths = lambda: [path]
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'path')))
old_cwd = os.getcwd()
from powerline.segments import vim
@ -150,6 +156,9 @@ def setUpModule():
def tearDownModule():
global old_cwd
global saved_get_config_paths
import powerline
powerline.get_config_paths = saved_get_config_paths
os.chdir(old_cwd)
old_cwd = None
sys.path.pop(0)

View File

@ -1,6 +1,5 @@
export VIRTUAL_ENV=
source powerline/bindings/bash/powerline.sh
POWERLINE_COMMAND="$POWERLINE_COMMAND -p $PWD/powerline/config_files"
POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
cd tests/shell/3rd

View File

@ -1,5 +1,4 @@
. powerline/bindings/shell/powerline.sh
POWERLINE_COMMAND="$POWERLINE_COMMAND -p $PWD/powerline/config_files"
POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
export VIRTUAL_ENV=

View File

@ -1,5 +1,4 @@
. powerline/bindings/shell/powerline.sh
POWERLINE_COMMAND="$POWERLINE_COMMAND -p $PWD/powerline/config_files"
POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
export VIRTUAL_ENV=

View File

@ -3,7 +3,6 @@ while jobs | grep fish_update_completions
sleep 1
end
powerline-setup
set POWERLINE_COMMAND "$POWERLINE_COMMAND -p $PWD/powerline/config_files"
set POWERLINE_COMMAND "$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
set POWERLINE_COMMAND "$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
setenv VIRTUAL_ENV

View File

@ -1,5 +1,4 @@
. powerline/bindings/shell/powerline.sh
POWERLINE_COMMAND="$POWERLINE_COMMAND -p $PWD/powerline/config_files"
POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
export VIRTUAL_ENV=

View File

@ -1,5 +1,5 @@
source powerline/bindings/tcsh/powerline.tcsh
set POWERLINE_COMMAND=$POWERLINE_COMMAND:q" -p "$PWD:q/powerline/config_files" -t default_leftonly.segment_data.hostname.args.only_if_ssh=false -c ext.shell.theme=default_leftonly"
set POWERLINE_COMMAND=$POWERLINE_COMMAND:q" -t default_leftonly.segment_data.hostname.args.only_if_ssh=false -c ext.shell.theme=default_leftonly"
unsetenv VIRTUAL_ENV
cd tests/shell/3rd
cd .git

View File

@ -5,9 +5,8 @@ setopt interactivecomments
# POWERLINE_CONFIG=( ext.shell.theme=default_leftonly )
POWERLINE_NO_ZSH_ZPYTHON=1 # TODO: make tests work with zsh/zpython
source powerline/bindings/zsh/powerline.zsh
POWERLINE_COMMAND=( $POWERLINE_COMMAND -p $PWD/powerline/config_files )
POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false )
POWERLINE_COMMAND=( $POWERLINE_COMMAND -c ext.shell.theme=default_leftonly )
POWERLINE_COMMAND="$POWERLINE_COMMAND -t default_leftonly.segment_data.hostname.args.only_if_ssh=false"
POWERLINE_COMMAND="$POWERLINE_COMMAND -c ext.shell.theme=default_leftonly"
export VIRTUAL_ENV=
cd tests/shell/3rd
cd .git
@ -26,13 +25,13 @@ cd ../'(echo)'
cd ../'$(echo)'
cd ../'`echo`'
cd ..
POWERLINE_COMMAND=( $POWERLINE_COMMAND[1,4] ${${POWERLINE_COMMAND[5]}/_leftonly} ) ; bindkey -v
POWERLINE_COMMAND="${POWERLINE_COMMAND//_leftonly}" ; bindkey -v

echo abc
false
POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.segment_data.hostname.display=false )
POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.segment_data.user.display=false )
POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.segment_data.hostname.display=false"
POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.segment_data.user.display=false"
select abc in def ghi jkl
do
echo $abc
@ -40,7 +39,7 @@ do
done
1
hash -d foo=$PWD:h ; cd .
POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.dividers.left.hard=\$ABC )
POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.dividers.left.hard=\$ABC"
true
true is the last line
exit

View File

@ -74,7 +74,7 @@ run() {
IPYTHONDIR="$PWD/tests/shell/ipython_home" \
POWERLINE_SHELL_CONTINUATION=$additional_prompts \
POWERLINE_SHELL_SELECT=$additional_prompts \
POWERLINE_COMMAND="${POWERLINE_COMMAND}" \
POWERLINE_COMMAND="${POWERLINE_COMMAND} -p $PWD/powerline/config_files" \
"$@"
}
@ -232,6 +232,9 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te
scripts/powerline-config shell command
for TEST_TYPE in "daemon" "nodaemon" ; do
if test "x$ONLY_TEST_TYPE" != "x" && test "x$ONLY_TEST_TYPE" != "x$TEST_TYPE" ; then
continue
fi
if test x$FAST = x1 ; then
if test $TEST_TYPE = daemon ; then
VARIANTS=3
@ -245,12 +248,9 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te
if test $TEST_TYPE = daemon ; then
sh -c '
echo $$ > tests/shell/daemon_pid
$PYTHON ./scripts/powerline-daemon -s$ADDRESS -f &>tests/shell/daemon_log
$PYTHON ./scripts/powerline-daemon -s$ADDRESS -f >tests/shell/daemon_log 2>&1
' &
fi
if test "x$ONLY_TEST_TYPE" != "x" && test "x$ONLY_TEST_TYPE" != "x$TEST_TYPE" ; then
continue
fi
echo "> Testing $TEST_TYPE"
I=-1
for POWERLINE_COMMAND in \
@ -332,7 +332,7 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te
done
fi
if ! $PYTHON scripts/powerline-daemon -s$ADDRESS &> tests/shell/daemon_log_2 ; then
if ! $PYTHON scripts/powerline-daemon -s$ADDRESS > tests/shell/daemon_log_2 2>&1 ; then
echo "Daemon exited with status $?"
FAILED=1
else

View File

@ -17,14 +17,14 @@
  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'
  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'
  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  `echo`  cd ..
  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND[1,4] ${${POWERLINE_COMMAND[5]}/_leftonly} ) ; bindkey -v
  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="${POWERLINE_COMMAND//_leftonly}" ; bindkey -v
 INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd   COMMND   HOSTNAME  USER  ⋯  tests  shell  3rd  
 INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  
 INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  echo abc
abc
 INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  false
 INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.segment_data.hostname.display=false )
 INSERT  USER  ⋯  tests  shell  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.segment_data.user.display=false )
 INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.segment_data.hostname.display=false"
 INSERT  USER  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.segment_data.user.display=false"
 INSERT  ⋯  tests  shell  3rd  select abc in def ghi jkl
 select                            do
 select                             echo $abc
@ -34,5 +34,5 @@ abc
                   Select variant  1
def
 INSERT  ⋯  tests  shell  3rd  hash -d foo=$PWD:h ; cd .
 INSERT  ~foo  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.dividers.left.hard=\$ABC )
 INSERT  ~foo  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.dividers.left.hard=\$ABC"
 INSERT $ABC~foo  3rd $ABCtrue

View File

@ -17,14 +17,14 @@
  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'
  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'
  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  `echo`  cd ..
  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND[1,4] ${${POWERLINE_COMMAND[5]}/_leftonly} ) ; bindkey -v
  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND="${POWERLINE_COMMAND//_leftonly}" ; bindkey -v
 INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd   COMMND   HOSTNAME  USER  ⋯  tests  shell  3rd  
 INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  
 INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  echo abc
abc
 INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  false
 INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.segment_data.hostname.display=false )
 INSERT  USER  ⋯  tests  shell  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.segment_data.user.display=false )
 INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.segment_data.hostname.display=false"
 INSERT  USER  ⋯  tests  shell  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.segment_data.user.display=false"
 INSERT  ⋯  tests  shell  3rd  select abc in def ghi jkl
 select  do
 select   echo $abc
@ -34,5 +34,5 @@ abc
 Select variant  1
def
 INSERT  ⋯  tests  shell  3rd  hash -d foo=$PWD:h ; cd .
 INSERT  ~foo  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND -t default.dividers.left.hard=\$ABC )
 INSERT  ~foo  3rd  POWERLINE_COMMAND="$POWERLINE_COMMAND -t default.dividers.left.hard=\$ABC"
 INSERT $ABC~foo  3rd $ABCtrue

View File

@ -1,5 +1,6 @@
#!/usr/bin/vim -S
set encoding=utf-8
let g:powerline_config_path = expand('<sfile>:p:h:h') . '/powerline/config_files'
source powerline/bindings/vim/plugin/powerline.vim
edit abc
tabedit def