From 74a3c9a0ca90cd55ce4d8f5297838a575bdb6d52 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 3 Aug 2014 23:58:34 +0400 Subject: [PATCH 1/2] Add file_scheme segment Fixes #207 --- .../colorschemes/vim/__main__.json | 1 + .../config_files/themes/vim/default.json | 4 ++ powerline/segments/vim.py | 72 +++++++++++++++---- tests/test_segments.py | 17 +++++ tests/vim.py | 5 +- 5 files changed, 84 insertions(+), 15 deletions(-) diff --git a/powerline/config_files/colorschemes/vim/__main__.json b/powerline/config_files/colorschemes/vim/__main__.json index 0294a5bb..ea9ba29e 100644 --- a/powerline/config_files/colorschemes/vim/__main__.json +++ b/powerline/config_files/colorschemes/vim/__main__.json @@ -7,6 +7,7 @@ "file_encoding": "file_format", "file_type": "file_format", "branch": "information:additional", + "file_scheme": "file_name", "file_directory": "information:additional", "file_name_empty": "file_directory", "line_percent": "information:additional", diff --git a/powerline/config_files/themes/vim/default.json b/powerline/config_files/themes/vim/default.json index 05204943..d80010df 100644 --- a/powerline/config_files/themes/vim/default.json +++ b/powerline/config_files/themes/vim/default.json @@ -40,6 +40,10 @@ "draw_soft_divider": false, "after": " " }, + { + "name": "file_scheme", + "priority": 20 + }, { "name": "file_directory", "priority": 40, diff --git a/powerline/segments/vim.py b/powerline/segments/vim.py index ee69b782..d622a601 100644 --- a/powerline/segments/vim.py +++ b/powerline/segments/vim.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals, absolute_import, division import os +import re try: import vim except ImportError: @@ -153,28 +154,71 @@ def readonly_indicator(pl, segment_info, text=''): return text if int(vim_getbufoption(segment_info, 'readonly')) else None +SCHEME_RE = re.compile(b'^\\w[\\w\\d+\\-.]*(?=:)') + + @requires_segment_info -def file_directory(pl, segment_info, shorten_user=True, shorten_cwd=True, shorten_home=False): - '''Return file directory (head component of the file path). +def file_scheme(pl, segment_info): + '''Return the protocol part of the file. - :param bool shorten_user: - shorten ``$HOME`` directory to :file:`~/` + Protocol is the part of the full filename just before the colon which + starts with a latin letter and contains only latin letters, digits, plus, + period or hyphen (refer to `RFC3986 + `_ for the description of + URI scheme). If there is no such a thing ``None`` is returned, effectively + removing segment. - :param bool shorten_cwd: - shorten current directory to :file:`./` - - :param bool shorten_home: - shorten all directories in :file:`/home/` to :file:`~user/` instead of :file:`/home/user/`. + .. note:: + Segment will not check whether there is ``//`` just after the + colon or if there is at least one slash after the scheme. Reason: it is + not always present. E.g. when opening file inside a zip archive file + name will look like :file:`zipfile:/path/to/archive.zip::file.txt`. + ``file_scheme`` segment will catch ``zipfile`` part here. ''' name = buffer_name(segment_info['buffer']) if not name: return None - file_directory = vim_funcs['fnamemodify'](name, (':~' if shorten_user else '') - + (':.' if shorten_cwd else '') + ':h') - if not file_directory: + match = SCHEME_RE.match(name) + if match: + return unicode(match.group(0)) + + +@requires_segment_info +def file_directory(pl, segment_info, remove_scheme=True, shorten_user=True, shorten_cwd=True, shorten_home=False): + '''Return file directory (head component of the file path). + + :param bool remove_scheme: + Remove scheme part from the segment name, if present. See documentation + of file_scheme segment for the description of what scheme is. Also + removes the colon. + + :param bool shorten_user: + Shorten ``$HOME`` directory to :file:`~/`. Does not work for files with + scheme. + + :param bool shorten_cwd: + Shorten current directory to :file:`./`. Does not work for files with + scheme present. + + :param bool shorten_home: + Shorten all directories in :file:`/home/` to :file:`~user/` instead of + :file:`/home/user/`. Does not work for files with scheme present. + ''' + name = buffer_name(segment_info['buffer']) + if not name: return None - if shorten_home and file_directory.startswith('/home/'): - file_directory = b'~' + file_directory[6:] + match = SCHEME_RE.match(name) + if match: + if remove_scheme: + name = name[len(match.group(0)) + 1:] # Remove scheme and colon + file_directory = vim_funcs['fnamemodify'](name, ':h') + else: + file_directory = vim_funcs['fnamemodify'](name, (':~' if shorten_user else '') + + (':.' if shorten_cwd else '') + ':h') + if not file_directory: + return None + if shorten_home and file_directory.startswith('/home/'): + file_directory = b'~' + file_directory[6:] file_directory = file_directory.decode('utf-8', 'powerline_vim_strtrans_error') return file_directory + os.sep diff --git a/tests/test_segments.py b/tests/test_segments.py index 58b2a52e..fc729858 100644 --- a/tests/test_segments.py +++ b/tests/test_segments.py @@ -619,6 +619,15 @@ class TestVim(TestCase): self.assertEqual(vim.readonly_indicator(pl=pl, segment_info=segment_info), '') self.assertEqual(vim.readonly_indicator(pl=pl, segment_info=segment_info, text='L'), 'L') + def test_file_scheme(self): + pl = Pl() + segment_info = vim_module._get_segment_info() + self.assertEqual(vim.file_scheme(pl=pl, segment_info=segment_info), None) + with vim_module._with('buffer', '/tmp/’’/abc') as segment_info: + self.assertEqual(vim.file_scheme(pl=pl, segment_info=segment_info), None) + with vim_module._with('buffer', 'zipfile:/tmp/abc.zip::abc/abc.vim') as segment_info: + self.assertEqual(vim.file_scheme(pl=pl, segment_info=segment_info), 'zipfile') + def test_file_directory(self): pl = Pl() segment_info = vim_module._get_segment_info() @@ -632,6 +641,14 @@ class TestVim(TestCase): self.assertEqual(vim.file_directory(pl=pl, segment_info=segment_info), '/tmp/') os.environ['HOME'] = '/tmp' self.assertEqual(vim.file_directory(pl=pl, segment_info=segment_info), '~/') + with vim_module._with('buffer', 'zipfile:/tmp/abc.zip::abc/abc.vim') as segment_info: + self.assertEqual(vim.file_directory(pl=pl, segment_info=segment_info, remove_scheme=False), 'zipfile:/tmp/abc.zip::abc/') + self.assertEqual(vim.file_directory(pl=pl, segment_info=segment_info, remove_scheme=True), '/tmp/abc.zip::abc/') + self.assertEqual(vim.file_directory(pl=pl, segment_info=segment_info), '/tmp/abc.zip::abc/') + os.environ['HOME'] = '/tmp' + self.assertEqual(vim.file_directory(pl=pl, segment_info=segment_info, remove_scheme=False), 'zipfile:/tmp/abc.zip::abc/') + self.assertEqual(vim.file_directory(pl=pl, segment_info=segment_info, remove_scheme=True), '/tmp/abc.zip::abc/') + self.assertEqual(vim.file_directory(pl=pl, segment_info=segment_info), '/tmp/abc.zip::abc/') def test_file_name(self): pl = Pl() diff --git a/tests/vim.py b/tests/vim.py index a0db754a..77995cf7 100644 --- a/tests/vim.py +++ b/tests/vim.py @@ -525,7 +525,10 @@ class _Buffer(object): import os if type(name) is not bytes: name = name.encode('utf-8') - self._name = os.path.abspath(name) + if ':/' in name: + self._name = name + else: + self._name = os.path.abspath(name) def __getitem__(self, line): return self._buf_lines[line] From 50703f1cef37f49a37006fbfc347793dc76a13d2 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 4 Aug 2014 00:07:30 +0400 Subject: [PATCH 2/2] Fix unicode/bytes handling for python-3 --- powerline/segments/vim.py | 2 +- tests/vim.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/powerline/segments/vim.py b/powerline/segments/vim.py index d622a601..077bd67e 100644 --- a/powerline/segments/vim.py +++ b/powerline/segments/vim.py @@ -180,7 +180,7 @@ def file_scheme(pl, segment_info): return None match = SCHEME_RE.match(name) if match: - return unicode(match.group(0)) + return match.group(0).decode('ascii') @requires_segment_info diff --git a/tests/vim.py b/tests/vim.py index 77995cf7..c7db4230 100644 --- a/tests/vim.py +++ b/tests/vim.py @@ -525,7 +525,7 @@ class _Buffer(object): import os if type(name) is not bytes: name = name.encode('utf-8') - if ':/' in name: + if b':/' in name: self._name = name else: self._name = os.path.abspath(name)