From 3f2aabb77bf9c7e79eace61c3da048271c97b17a Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 26 Sep 2014 00:20:58 +0400 Subject: [PATCH 1/2] Refactor Vim and common branch segments to share code --- powerline/segments/common/vcs.py | 57 ++++++++++++++++++------------ powerline/segments/vim/__init__.py | 43 +++++++++++----------- tests/test_segments.py | 50 ++++++++++++++++---------- 3 files changed, 86 insertions(+), 64 deletions(-) diff --git a/powerline/segments/common/vcs.py b/powerline/segments/common/vcs.py index a6311bc5..9daddf1e 100644 --- a/powerline/segments/common/vcs.py +++ b/powerline/segments/common/vcs.py @@ -2,32 +2,45 @@ from __future__ import (unicode_literals, division, absolute_import, print_function) from powerline.lib.vcs import guess, tree_status +from powerline.segments import Segment, with_docstring from powerline.theme import requires_segment_info, requires_filesystem_watcher @requires_filesystem_watcher @requires_segment_info -def branch(pl, segment_info, create_watcher, status_colors=False): - '''Return the current VCS branch. +class BranchSegment(Segment): + divider_highlight_group = None - :param bool status_colors: - determines whether repository status will be used to determine highlighting. Default: False. + @staticmethod + def get_directory(segment_info): + return segment_info['getcwd']() - Highlight groups used: ``branch_clean``, ``branch_dirty``, ``branch``. - ''' - name = segment_info['getcwd']() - repo = guess(path=name, create_watcher=create_watcher) - if repo is not None: - branch = repo.branch() - scol = ['branch'] - if status_colors: - try: - status = tree_status(repo, pl) - except Exception as e: - pl.exception('Failed to compute tree status: {0}', str(e)) - status = '?' - scol.insert(0, 'branch_dirty' if status and status.strip() else 'branch_clean') - return [{ - 'contents': branch, - 'highlight_group': scol, - }] + def __call__(self, pl, segment_info, create_watcher, status_colors=False): + name = self.get_directory(segment_info) + if name: + repo = guess(path=name, create_watcher=create_watcher) + if repo is not None: + branch = repo.branch() + scol = ['branch'] + if status_colors: + try: + status = tree_status(repo, pl) + except Exception as e: + pl.exception('Failed to compute tree status: {0}', str(e)) + status = '?' + scol.insert(0, 'branch_dirty' if status and status.strip() else 'branch_clean') + return [{ + 'contents': branch, + 'highlight_group': scol, + 'divider_highlight_group': self.divider_highlight_group, + }] + + +branch = with_docstring(BranchSegment(), +'''Return the current VCS branch. + +:param bool status_colors: + determines whether repository status will be used to determine highlighting. Default: False. + +Highlight groups used: ``branch_clean``, ``branch_dirty``, ``branch``. +''') diff --git a/powerline/segments/vim/__init__.py b/powerline/segments/vim/__init__.py index 6467890d..31f3557e 100644 --- a/powerline/segments/vim/__init__.py +++ b/powerline/segments/vim/__init__.py @@ -17,9 +17,11 @@ from powerline.bindings.vim import (vim_get_func, getbufvar, vim_getbufoption, list_tabpage_buffers_segment_info) from powerline.theme import requires_segment_info, requires_filesystem_watcher from powerline.lib import add_divider_highlight_group -from powerline.lib.vcs import guess, tree_status +from powerline.lib.vcs import guess from powerline.lib.humanize_bytes import humanize_bytes from powerline.lib import wraps_saveargs as wraps +from powerline.segments.common.vcs import BranchSegment +from powerline.segments import with_docstring try: from __builtin__ import xrange as range @@ -480,31 +482,26 @@ def modified_buffers(pl, text='+ ', join_str=','): @requires_filesystem_watcher @requires_segment_info -def branch(pl, segment_info, create_watcher, status_colors=False): - '''Return the current working branch. +class VimBranchSegment(BranchSegment): + divider_highlight_group = 'branch:divider' - :param bool status_colors: - determines whether repository status will be used to determine highlighting. Default: False. + @staticmethod + def get_directory(segment_info): + if vim_getbufoption(segment_info, 'buftype'): + return None + return buffer_name(segment_info) - Highlight groups used: ``branch_clean``, ``branch_dirty``, ``branch``. - Divider highlight group used: ``branch:divider``. - ''' - name = buffer_name(segment_info) - skip = not (name and (not vim_getbufoption(segment_info, 'buftype'))) - if not skip: - repo = guess(path=name, create_watcher=create_watcher) - if repo is not None: - branch = repo.branch() - scol = ['branch'] - if status_colors: - status = tree_status(repo, pl) - scol.insert(0, 'branch_dirty' if status and status.strip() else 'branch_clean') - return [{ - 'contents': branch, - 'highlight_group': scol, - 'divider_highlight_group': 'branch:divider', - }] +branch = with_docstring(VimBranchSegment(), +'''Return the current working branch. + +:param bool status_colors: + determines whether repository status will be used to determine highlighting. Default: False. + +Highlight groups used: ``branch_clean``, ``branch_dirty``, ``branch``. + +Divider highlight group used: ``branch:divider``. +''') @requires_filesystem_watcher diff --git a/tests/test_segments.py b/tests/test_segments.py index 57f23abb..62db1288 100644 --- a/tests/test_segments.py +++ b/tests/test_segments.py @@ -600,23 +600,33 @@ class TestVcs(TestCommon): branch = partial(common.branch, pl=pl, create_watcher=create_watcher) with replace_attr(self.module, 'guess', get_dummy_guess(status=lambda: None, directory='/tmp/tests')): with replace_attr(self.module, 'tree_status', lambda repo, pl: None): - self.assertEqual(branch(segment_info=segment_info, status_colors=False), [ - {'highlight_group': ['branch'], 'contents': 'tests'} - ]) - self.assertEqual(branch(segment_info=segment_info, status_colors=True), [ - {'contents': 'tests', 'highlight_group': ['branch_clean', 'branch']} - ]) + self.assertEqual(branch(segment_info=segment_info, status_colors=False), [{ + 'highlight_group': ['branch'], + 'contents': 'tests', + 'divider_highlight_group': None + }]) + self.assertEqual(branch(segment_info=segment_info, status_colors=True), [{ + 'contents': 'tests', + 'highlight_group': ['branch_clean', 'branch'], + 'divider_highlight_group': None + }]) with replace_attr(self.module, 'guess', get_dummy_guess(status=lambda: 'D ', directory='/tmp/tests')): with replace_attr(self.module, 'tree_status', lambda repo, pl: 'D '): - self.assertEqual(branch(segment_info=segment_info, status_colors=False), [ - {'highlight_group': ['branch'], 'contents': 'tests'} - ]) - self.assertEqual(branch(segment_info=segment_info, status_colors=True), [ - {'contents': 'tests', 'highlight_group': ['branch_dirty', 'branch']} - ]) - self.assertEqual(branch(segment_info=segment_info, status_colors=False), [ - {'highlight_group': ['branch'], 'contents': 'tests'} - ]) + self.assertEqual(branch(segment_info=segment_info, status_colors=False), [{ + 'highlight_group': ['branch'], + 'contents': 'tests', + 'divider_highlight_group': None + }]) + self.assertEqual(branch(segment_info=segment_info, status_colors=True), [{ + 'contents': 'tests', + 'highlight_group': ['branch_dirty', 'branch'], + 'divider_highlight_group': None + }]) + self.assertEqual(branch(segment_info=segment_info, status_colors=False), [{ + 'highlight_group': ['branch'], + 'contents': 'tests', + 'divider_highlight_group': None + }]) with replace_attr(self.module, 'guess', lambda path, create_watcher: None): self.assertEqual(branch(segment_info=segment_info, status_colors=False), None) @@ -1057,16 +1067,16 @@ class TestVim(TestCase): create_watcher = get_fallback_create_watcher() branch = partial(self.vim.branch, pl=pl, create_watcher=create_watcher) with vim_module._with('buffer', '/foo') as segment_info: - with replace_attr(self.vim, 'guess', get_dummy_guess(status=lambda: None)): - with replace_attr(self.vim, 'tree_status', lambda repo, pl: None): + with replace_attr(self.vcs, 'guess', get_dummy_guess(status=lambda: None)): + with replace_attr(self.vcs, 'tree_status', lambda repo, pl: None): self.assertEqual(branch(segment_info=segment_info, status_colors=False), [ {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch'], 'contents': 'foo'} ]) self.assertEqual(branch(segment_info=segment_info, status_colors=True), [ {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_clean', 'branch'], 'contents': 'foo'} ]) - with replace_attr(self.vim, 'guess', get_dummy_guess(status=lambda: 'DU')): - with replace_attr(self.vim, 'tree_status', lambda repo, pl: 'DU'): + with replace_attr(self.vcs, 'guess', get_dummy_guess(status=lambda: 'DU')): + with replace_attr(self.vcs, 'tree_status', lambda repo, pl: 'DU'): self.assertEqual(branch(segment_info=segment_info, status_colors=False), [ {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch'], 'contents': 'foo'} ]) @@ -1155,6 +1165,8 @@ class TestVim(TestCase): sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), 'path'))) from powerline.segments import vim cls.vim = vim + from powerline.segments.common import vcs + cls.vcs = vcs @classmethod def tearDownClass(cls): From 8b1a502f0d71b52304543d07a24eb12b890a8d9d Mon Sep 17 00:00:00 2001 From: ZyX Date: Fri, 26 Sep 2014 00:34:32 +0400 Subject: [PATCH 2/2] Add ignore_statuses option to branch segments Closes #1080 --- powerline/segments/common/vcs.py | 18 ++++++++++++--- powerline/segments/vim/__init__.py | 10 ++++++++- tests/test_segments.py | 36 ++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/powerline/segments/common/vcs.py b/powerline/segments/common/vcs.py index 9daddf1e..401741b2 100644 --- a/powerline/segments/common/vcs.py +++ b/powerline/segments/common/vcs.py @@ -15,7 +15,7 @@ class BranchSegment(Segment): def get_directory(segment_info): return segment_info['getcwd']() - def __call__(self, pl, segment_info, create_watcher, status_colors=False): + def __call__(self, pl, segment_info, create_watcher, status_colors=False, ignore_statuses=()): name = self.get_directory(segment_info) if name: repo = guess(path=name, create_watcher=create_watcher) @@ -28,7 +28,11 @@ class BranchSegment(Segment): except Exception as e: pl.exception('Failed to compute tree status: {0}', str(e)) status = '?' - scol.insert(0, 'branch_dirty' if status and status.strip() else 'branch_clean') + else: + status = status and status.strip() + if status in ignore_statuses: + status = None + scol.insert(0, 'branch_dirty' if status else 'branch_clean') return [{ 'contents': branch, 'highlight_group': scol, @@ -40,7 +44,15 @@ branch = with_docstring(BranchSegment(), '''Return the current VCS branch. :param bool status_colors: - determines whether repository status will be used to determine highlighting. Default: False. + Determines whether repository status will be used to determine highlighting. + Default: False. +:param bool ignore_statuses: + List of statuses which will not result in repo being marked as dirty. Most + useful is setting this option to ``["U"]``: this will ignore repository + which has just untracked files (i.e. repository with modified, deleted or + removed files will be marked as dirty, while just untracked files will make + segment show clean repository). Only applicable if ``status_colors`` option + is True. Highlight groups used: ``branch_clean``, ``branch_dirty``, ``branch``. ''') diff --git a/powerline/segments/vim/__init__.py b/powerline/segments/vim/__init__.py index 31f3557e..86260e6b 100644 --- a/powerline/segments/vim/__init__.py +++ b/powerline/segments/vim/__init__.py @@ -496,7 +496,15 @@ branch = with_docstring(VimBranchSegment(), '''Return the current working branch. :param bool status_colors: - determines whether repository status will be used to determine highlighting. Default: False. + Determines whether repository status will be used to determine highlighting. + Default: False. +:param bool ignore_statuses: + List of statuses which will not result in repo being marked as dirty. Most + useful is setting this option to ``["U"]``: this will ignore repository + which has just untracked files (i.e. repository with modified, deleted or + removed files will be marked as dirty, while just untracked files will make + segment show clean repository). Only applicable if ``status_colors`` option + is True. Highlight groups used: ``branch_clean``, ``branch_dirty``, ``branch``. diff --git a/tests/test_segments.py b/tests/test_segments.py index 62db1288..8070f44d 100644 --- a/tests/test_segments.py +++ b/tests/test_segments.py @@ -629,6 +629,28 @@ class TestVcs(TestCommon): }]) with replace_attr(self.module, 'guess', lambda path, create_watcher: None): self.assertEqual(branch(segment_info=segment_info, status_colors=False), None) + with replace_attr(self.module, 'guess', get_dummy_guess(status=lambda: 'U')): + with replace_attr(self.module, 'tree_status', lambda repo, pl: 'U'): + self.assertEqual(branch(segment_info=segment_info, status_colors=False, ignore_statuses=['U']), [{ + 'highlight_group': ['branch'], + 'contents': 'tests', + 'divider_highlight_group': None + }]) + self.assertEqual(branch(segment_info=segment_info, status_colors=True, ignore_statuses=['DU']), [{ + 'highlight_group': ['branch_dirty', 'branch'], + 'contents': 'tests', + 'divider_highlight_group': None + }]) + self.assertEqual(branch(segment_info=segment_info, status_colors=True), [{ + 'highlight_group': ['branch_dirty', 'branch'], + 'contents': 'tests', + 'divider_highlight_group': None + }]) + self.assertEqual(branch(segment_info=segment_info, status_colors=True, ignore_statuses=['U']), [{ + 'highlight_group': ['branch_clean', 'branch'], + 'contents': 'tests', + 'divider_highlight_group': None + }]) class TestTime(TestCommon): @@ -1083,6 +1105,20 @@ class TestVim(TestCase): self.assertEqual(branch(segment_info=segment_info, status_colors=True), [ {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_dirty', 'branch'], 'contents': 'foo'} ]) + with replace_attr(self.vcs, 'guess', get_dummy_guess(status=lambda: 'U')): + with replace_attr(self.vcs, 'tree_status', lambda repo, pl: 'U'): + self.assertEqual(branch(segment_info=segment_info, status_colors=False, ignore_statuses=['U']), [ + {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch'], 'contents': 'foo'} + ]) + self.assertEqual(branch(segment_info=segment_info, status_colors=True, ignore_statuses=['DU']), [ + {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_dirty', 'branch'], 'contents': 'foo'} + ]) + self.assertEqual(branch(segment_info=segment_info, status_colors=True), [ + {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_dirty', 'branch'], 'contents': 'foo'} + ]) + self.assertEqual(branch(segment_info=segment_info, status_colors=True, ignore_statuses=['U']), [ + {'divider_highlight_group': 'branch:divider', 'highlight_group': ['branch_clean', 'branch'], 'contents': 'foo'} + ]) def test_file_vcs_status(self): pl = Pl()