diff --git a/docs/source/develop/segments.rst b/docs/source/develop/segments.rst index f69a600c..66003a72 100644 --- a/docs/source/develop/segments.rst +++ b/docs/source/develop/segments.rst @@ -29,6 +29,24 @@ object it should receive the following arguments: And also any other argument(s) specified by user in :ref:`args key ` (no additional arguments by default). +.. note:: + For powerline-lint to work properly the following things may be needed: + + #. If your segment is a :py:class:`powerline.segments.Segment` and used + arguments are scattered over multiple methods + :py:meth:`powerline.segments.Segment.argspecobjs` should be overridden in + subclass to tell powerline-lint which objects should be inspected for + arguments. + #. If your segment takes some arguments that are never listed, but accessed + via ``kwargs.get()`` or you cannot use previous function for whatever + reason :py:meth:`powerline.segments.Segment.additional_args` should be + overridden in subclass. + #. If you are expecting user to use one :ref:`name ` + for multiple segments which cannot be linked to the segment function + automatically by powerline-lint (e.g. because there are no instances of + the segments in question in the default configuration) you should use + :py:func:`powerline.lint.checks.register_common_name`. + Object representing segment may have the following attributes used by powerline: diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index 49cb511a..51c25860 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -19,7 +19,7 @@ from powerline.lint.checks import (check_matcher_func, check_ext, check_config, check_segment_module, check_exinclude_function, type_keys, check_segment_function, check_args, get_one_segment_function, check_highlight_groups, check_highlight_group, check_full_segment_data, - get_all_possible_functions, check_segment_data_key) + get_all_possible_functions, check_segment_data_key, register_common_name) from powerline.lint.spec import Spec from powerline.lint.context import Context @@ -289,6 +289,10 @@ theme_spec = common_theme_spec().update( ) +def register_common_names(): + register_common_name('player', 'powerline.segments.common.players', '_player') + + def check(paths=None, debug=False, echoerr=echoerr, require_ext=None): '''Check configuration sanity @@ -308,6 +312,7 @@ def check(paths=None, debug=False, echoerr=echoerr, require_ext=None): ``False`` if user configuration seems to be completely sane and ``True`` if some problems were found. ''' + register_common_names() search_paths = paths or get_config_paths() find_config_files = generate_config_finder(lambda: search_paths) diff --git a/powerline/lint/checks.py b/powerline/lint/checks.py index a59d4440..52abdb78 100644 --- a/powerline/lint/checks.py +++ b/powerline/lint/checks.py @@ -5,6 +5,8 @@ import os import re import logging +from collections import defaultdict + from powerline.lib.threaded import ThreadedSegment from powerline.lib.unicode import unicode from powerline.lint.markedjson.markedvalue import MarkedUnicode @@ -673,6 +675,16 @@ def get_one_segment_function(data, context, echoerr): yield func +common_names = defaultdict(set) + + +def register_common_name(name, cmodule, cname): + s = cmodule + '.' + cname + cmodule_mark = Mark('', 1, 1, s, 1) + cname_mark = Mark('', 1, len(cmodule) + 1, s, len(cmodule) + 1) + common_names[name].add((MarkedUnicode(cmodule, cmodule_mark), MarkedUnicode(cname, cname_mark))) + + def get_all_possible_functions(data, context, echoerr): name = context[-2][0] module, name = name.rpartition('.')[::2] @@ -681,6 +693,11 @@ def get_all_possible_functions(data, context, echoerr): if func: yield func else: + if name in common_names: + for cmodule, cname in common_names[name]: + cfunc = import_segment(cname, data, context, echoerr, module=MarkedUnicode(cmodule, None)) + if cfunc: + yield cfunc for ext, theme_config in list_themes(data, context): for segments in theme_config.get('segments', {}).values(): for segment in segments: diff --git a/powerline/segments/common/players.py b/powerline/segments/common/players.py index 45568728..838ff1c7 100644 --- a/powerline/segments/common/players.py +++ b/powerline/segments/common/players.py @@ -53,6 +53,9 @@ class PlayerSegment(Segment): 'highlight_group': ['now_playing', 'player_' + (stats['state'] or 'fallback'), 'player'], }] + def get_player_status(self, pl): + pass + def argspecobjs(self): for ret in super(PlayerSegment, self).argspecobjs(): yield ret @@ -112,6 +115,9 @@ Highlight groups used: ``player_fallback`` or ``player``, ``player_play`` or ``p ''' +_player = with_docstring(PlayerSegment(), _common_args.format('_player')) + + class CmusPlayerSegment(PlayerSegment): def get_player_status(self, pl): '''Return cmus player information. @@ -459,5 +465,16 @@ class NowPlayingSegment(Segment): assert(isinstance(player_segment, PlayerSegment)) return player_segment(**kwargs) + def argspecobjs(self): + for ret in super(NowPlayingSegment, self).argspecobjs(): + yield ret + yield '__call__', PlayerSegment.__call__ + for k, v in globals().items(): + if isinstance(v, type) and issubclass(v, PlayerSegment) and v is not DbusPlayerSegment: + yield 'get_player_status', v.get_player_status + + def omitted_args(self, name, method): + return (0,) + now_playing = NowPlayingSegment()