Add file_scheme segment

Fixes #207
This commit is contained in:
ZyX 2014-08-03 23:58:34 +04:00
parent e89832be14
commit 74a3c9a0ca
5 changed files with 84 additions and 15 deletions

View File

@ -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",

View File

@ -40,6 +40,10 @@
"draw_soft_divider": false,
"after": " "
},
{
"name": "file_scheme",
"priority": 20
},
{
"name": "file_directory",
"priority": 40,

View File

@ -3,6 +3,7 @@
from __future__ import unicode_literals, absolute_import, division
import os
import re
try:
import vim
except ImportError:
@ -153,22 +154,65 @@ 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
<http://tools.ietf.org/html/rfc3986#section-3.1>`_ 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
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
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:

View File

@ -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()

View File

@ -525,6 +525,9 @@ class _Buffer(object):
import os
if type(name) is not bytes:
name = name.encode('utf-8')
if ':/' in name:
self._name = name
else:
self._name = os.path.abspath(name)
def __getitem__(self, line):