2010-04-20 01:18:25 -04:00
|
|
|
import os
|
2010-04-20 01:38:23 -04:00
|
|
|
from method import Method, arg
|
2009-06-10 16:07:03 -04:00
|
|
|
import buffer.colors
|
2009-05-10 01:45:57 -04:00
|
|
|
import util
|
|
|
|
import lex
|
|
|
|
|
2009-05-10 02:01:09 -04:00
|
|
|
class VcException(Exception): pass
|
|
|
|
|
2010-10-15 11:44:34 -04:00
|
|
|
class VcBase(Method):
|
|
|
|
_is_method = False
|
|
|
|
def _get_path(self, w):
|
|
|
|
if not hasattr(w.buffer, 'path'):
|
|
|
|
raise VcException("buffer has no path")
|
|
|
|
cwd = os.getcwd() + os.path.sep
|
|
|
|
path = w.buffer.path
|
|
|
|
if path.startswith(cwd):
|
|
|
|
path = path[len(cwd):]
|
|
|
|
return path
|
|
|
|
|
2009-05-10 01:45:57 -04:00
|
|
|
class VcBlame(Method):
|
2009-05-10 22:45:16 -04:00
|
|
|
_is_method = False
|
|
|
|
line_re = None
|
|
|
|
prefix_fmt = None
|
|
|
|
pretest_err_msg = None
|
2009-05-14 23:59:13 -04:00
|
|
|
num_fields = 1
|
2009-05-10 22:45:16 -04:00
|
|
|
def _pretest(self):
|
|
|
|
return True
|
2009-05-10 01:45:57 -04:00
|
|
|
def _filter(self, line):
|
|
|
|
m = self.line_re.match(line)
|
|
|
|
if not m:
|
2009-05-10 02:01:09 -04:00
|
|
|
raise VcException("couldn't parse %r" % line)
|
2009-05-14 23:59:13 -04:00
|
|
|
groups = m.groups()
|
|
|
|
return {'fields': groups[:-1], 'content': groups[-1], 'tokens': []}
|
2009-05-10 01:45:57 -04:00
|
|
|
def _open_pipe(self, w, **vargs):
|
|
|
|
raise Exception('unimplemented')
|
2009-05-14 23:59:13 -04:00
|
|
|
def _build_groups(self, w, **vargs):
|
2009-05-10 01:45:57 -04:00
|
|
|
pipe = self._open_pipe(w, **vargs)
|
2009-05-14 23:59:13 -04:00
|
|
|
groups = []
|
|
|
|
gsizes = [0] * self.num_fields
|
2020-09-03 23:50:36 -04:00
|
|
|
for s in pipe.stdout:
|
|
|
|
line = s.decode('UTF-8')
|
2009-05-14 23:59:13 -04:00
|
|
|
d = self._filter(line)
|
2020-08-31 20:58:27 -04:00
|
|
|
for i in range(0, self.num_fields):
|
2009-05-14 23:59:13 -04:00
|
|
|
gsizes[i] = max(gsizes[i], len(d['fields'][i]))
|
|
|
|
groups.append(d)
|
2009-05-10 01:45:57 -04:00
|
|
|
status = pipe.wait() >> 8
|
2009-05-14 23:59:13 -04:00
|
|
|
if status != 0:
|
|
|
|
raise Exception("There was an error (%d)" % status)
|
|
|
|
return groups, gsizes
|
|
|
|
def _lex_groups(self, groups, w, **vargs):
|
2009-05-10 01:45:57 -04:00
|
|
|
if w.mode.grammar:
|
|
|
|
lexer = lex.Lexer(w.mode, w.mode.grammar)
|
2009-05-14 23:59:13 -04:00
|
|
|
for t in lexer.lex([d['content'] for d in groups]):
|
2009-05-10 01:45:57 -04:00
|
|
|
groups[t.y]['tokens'].append(t)
|
2009-05-14 23:59:13 -04:00
|
|
|
def _build_lines(self, groups, gsizes, w, **vargs):
|
|
|
|
self._lex_groups(groups, w, **vargs)
|
2009-05-10 01:45:57 -04:00
|
|
|
lines = []
|
|
|
|
for d in groups:
|
|
|
|
if d['tokens']:
|
|
|
|
suffix = ''
|
|
|
|
for t in d['tokens']:
|
2009-06-10 16:07:03 -04:00
|
|
|
code = buffer.colors.get_cbuf_code(*t.color)
|
2009-05-10 01:45:57 -04:00
|
|
|
suffix += code + util.cbuf_escape(t.string)
|
|
|
|
else:
|
|
|
|
suffix = d['content'] + '\n'
|
2009-05-14 23:59:13 -04:00
|
|
|
tpl = tuple(util.flatzip(gsizes, d['fields']))
|
|
|
|
lines.append(self.prefix_fmt % tpl + ' ' + suffix)
|
|
|
|
return lines
|
|
|
|
def _execute(self, w, **vargs):
|
|
|
|
if not self._pretest():
|
|
|
|
w.set_error(self.pretest_err_msg)
|
|
|
|
return
|
|
|
|
elif not hasattr(w.buffer, 'path'):
|
|
|
|
w.set_error("Buffer has no corresponding file")
|
|
|
|
return
|
|
|
|
|
|
|
|
try:
|
|
|
|
groups, gsizes = self._build_groups(w, **vargs)
|
2020-08-31 20:58:27 -04:00
|
|
|
except Exception as e:
|
2009-05-14 23:59:13 -04:00
|
|
|
w.set_error(str(e))
|
2010-10-15 11:44:34 -04:00
|
|
|
return
|
2009-05-10 01:45:57 -04:00
|
|
|
|
2009-05-14 23:59:13 -04:00
|
|
|
data = ''.join(self._build_lines(groups, gsizes, w, **vargs))
|
|
|
|
w.application.color_data_buffer("*Blame*", data, switch_to=True)
|
2010-04-20 01:18:25 -04:00
|
|
|
|
|
|
|
class VcRevView(Method):
|
|
|
|
'''show file contents at revision'''
|
|
|
|
_is_method = False
|
|
|
|
namebase = 'VC'
|
|
|
|
def _get_path(self, w, **vargs):
|
|
|
|
cwd = os.getcwd() + os.path.sep
|
|
|
|
path = w.buffer.path
|
|
|
|
if path.startswith(cwd):
|
|
|
|
path = path[len(cwd):]
|
|
|
|
return path
|
|
|
|
|
|
|
|
def _get_cmd(self, w, **vargs):
|
|
|
|
path = self._get_path(w, **vargs)
|
|
|
|
raise Exception("unimplemented")
|
|
|
|
|
|
|
|
def _get_name(self, w, **vargs):
|
|
|
|
return '*%s:%s-%s' % (self.namebase, w.buffer.name(), vargs['revision'])
|
|
|
|
|
|
|
|
def _execute(self, w, **vargs):
|
|
|
|
if not hasattr(w.buffer, 'path'):
|
|
|
|
w.set_error("Buffer has no corresponding file")
|
|
|
|
return
|
|
|
|
|
|
|
|
cmd = self._get_cmd(w, **vargs)
|
|
|
|
name = self._get_name(w, **vargs)
|
|
|
|
mname = w.mode.name.lower()
|
|
|
|
status, out, err = util.communicate(cmd)
|
|
|
|
|
|
|
|
w.application.data_buffer(name, out, switch_to=True, modename=mname)
|
|
|
|
|
|
|
|
class VcDateView(VcRevView):
|
|
|
|
'''show file contents at date'''
|
|
|
|
args = [arg("date", t=type(""), p="Date: ", h="date specifier")]
|
|
|
|
def _get_name(self, w, **vargs):
|
|
|
|
return '*%s:%s-%s' % (self.namebase, w.buffer.name(), vargs['date'])
|