diff --git a/buffer2.py b/buffer2.py index eb2aab7..2b7ba58 100644 --- a/buffer2.py +++ b/buffer2.py @@ -1,5 +1,5 @@ import datetime, grp, md5, os, pwd, re, sets, shutil, stat -import aes, regex, highlight2 +import aes, dirutil, regex, highlight2 from point2 import Point # undo/redo stack constants @@ -478,14 +478,6 @@ class AesBuffer(FileBuffer): def write_filter(self, data): return aes.encrypt_data(data, self.password) -def _path_sort(a, b): - try: - x = cmp(a[0][0], b[0][0]) - if x != 0: - return -x - return cmp(a[5], b[5]) - except: - raise Exception, repr(a) + ' ' + repr(b) class DirBuffer(Buffer): btype = 'dir' def __init__(self, path, nl='\n', name=None): @@ -500,94 +492,24 @@ class DirBuffer(Buffer): def path_exists(self): return os.path.exists(self.path) - def _get_lines(self): + def _get_names(self): if not self.path_exists(): raise Exception, "directory %r does not exists" % self.path - names = os.listdir(self.path) if self.path != '/': names.insert(0, '..') names.insert(0, '.') + return names + def _make_path(self, name): + return os.path.join(self.path, name) + def _get_lines(self): + names = self._get_names() fieldlines = [] maxlens = [0] * 5 for name in names: - # let's escape some troublesome characters - name = re.sub(r'([\a\b\n\r\t\v])', r'\\\1', name) - - path = os.path.join(self.path, name) - info = os.stat(path) - - # - regular, b block, c character, d directory, l symlink, p fifo - # s socket, ? unknown - perm = [' '] * 10 - if stat.S_ISREG(info.st_mode): - perm[0] = '-' - elif stat.S_ISBLK(info.st_mode): - perm[0] = 'b' - elif stat.S_ISCHR(info.st_mode): - perm[0] = 'c' - elif stat.S_ISDIR(info.st_mode): - perm[0] = 'd' - elif stat.S_ISLNK(info.st_mode): - perm[0] = 'l' - elif stat.S_ISFIFO(info.st_mode): - perm[0] = 'p' - elif stat.S_ISSOCK(info.st_mode): - perm[0] = 's' - else: - perm[0] = '?' - - i = 1 - symbols = ('r', 'w', 'x') - for bundle in ((stat.S_IRUSR, stat.S_IWUSR, stat.S_IXUSR), - (stat.S_IRGRP, stat.S_IWGRP, stat.S_IXGRP), - (stat.S_IROTH, stat.S_IWOTH, stat.S_IXOTH)): - for j in range(0, 3): - if info.st_mode & bundle[j]: - perm[i] = symbols[j] - else: - perm[i] = '-' - i += 1 - - if info.st_mode & stat.S_ISUID: - if perm[3] == 'x': - perm[3] = 's' - else: - perm[3] = 'S' - if info.st_mode & stat.S_ISGID: - if perm[6] == 'x': - perm[6] = 's' - else: - perm[6] = 'S' - if info.st_mode & stat.S_ISVTX: - if perm[9] == 'x': - perm[9] = 't' - else: - perm[9] = 'T' - - perms = ''.join(perm) - - try: - user = pwd.getpwuid(info.st_uid)[0] - except: - user = str(info.st_uid) - try: - group = grp.getgrgid(info.st_gid)[0] - except: - group = str(info.st_gid) - - size = info.st_size - unit = 0 - units = ('B', 'K', 'M', 'G',) - while unit < 3 and size > 1024: - size = size / 1024 - unit += 1 - size = '%d%s' % (size, units[unit]) - - mtime = datetime.datetime.fromtimestamp(info.st_mtime).strftime('%b %d %H:%M') - - fields = (perms, user, group, size, mtime, name) + path = self._make_path(name) + fields = dirutil.path_fields(path, name) for i in range(0, 5): try: maxlens[i] = max(maxlens[i], len(fields[i])) @@ -595,7 +517,7 @@ class DirBuffer(Buffer): raise Exception, '%d %r' % (i, fields[i]) fieldlines.append(fields) - fieldlines.sort(cmp=_path_sort) + fieldlines.sort(cmp=dirutil.path_sort) fmt = '%%%ds %%-%ds %%-%ds %%%ds %%%ds %%s' % tuple(maxlens) lines = [] @@ -612,3 +534,22 @@ class DirBuffer(Buffer): raise Exception, "can't save a directory buffer" def save_as(self, path): raise Exception, "can't save a directory buffer" + +class PathListBuffer(DirBuffer): + btype = 'pathlist' + def __init__(self, name, paths, nl='\n'): + Buffer.__init__(self, nl) + self.paths = paths + self._name = name + def path_exists(self): + raise Exception + def _get_names(self): + cwd = os.getcwd() + return [x.replace(cwd, '.', 1) for x in self.paths] + def _make_path(self, name): + if name.startswith('.'): + return name.replace('.', os.getcwd(), 1) + else: + return name + def name(self): + return self._name diff --git a/dirutil.py b/dirutil.py index b845630..17ba4b9 100644 --- a/dirutil.py +++ b/dirutil.py @@ -1,4 +1,4 @@ -import grp, os, pwd +import datetime, grp, os, pwd, re, stat from point2 import Point def resolve_token(w): @@ -48,3 +48,88 @@ def valid_group(group): except: return False +def path_sort(a, b): + try: + x = cmp(a[0][0], b[0][0]) + if x != 0: + return -x + return cmp(a[5], b[5]) + except: + raise Exception, repr(a) + ' ' + repr(b) + +def path_fields(path, name): + # let's escape some troublesome characters + name = re.sub(r'([\a\b\n\r\t\v])', r'\\\1', name) + info = os.stat(path) + + # - regular, b block, c character, d directory, l symlink, p fifo + # s socket, ? unknown + perm = [' '] * 10 + if stat.S_ISREG(info.st_mode): + perm[0] = '-' + elif stat.S_ISBLK(info.st_mode): + perm[0] = 'b' + elif stat.S_ISCHR(info.st_mode): + perm[0] = 'c' + elif stat.S_ISDIR(info.st_mode): + perm[0] = 'd' + elif stat.S_ISLNK(info.st_mode): + perm[0] = 'l' + elif stat.S_ISFIFO(info.st_mode): + perm[0] = 'p' + elif stat.S_ISSOCK(info.st_mode): + perm[0] = 's' + else: + perm[0] = '?' + + i = 1 + symbols = ('r', 'w', 'x') + for bundle in ((stat.S_IRUSR, stat.S_IWUSR, stat.S_IXUSR), + (stat.S_IRGRP, stat.S_IWGRP, stat.S_IXGRP), + (stat.S_IROTH, stat.S_IWOTH, stat.S_IXOTH)): + for j in range(0, 3): + if info.st_mode & bundle[j]: + perm[i] = symbols[j] + else: + perm[i] = '-' + i += 1 + + if info.st_mode & stat.S_ISUID: + if perm[3] == 'x': + perm[3] = 's' + else: + perm[3] = 'S' + if info.st_mode & stat.S_ISGID: + if perm[6] == 'x': + perm[6] = 's' + else: + perm[6] = 'S' + if info.st_mode & stat.S_ISVTX: + if perm[9] == 'x': + perm[9] = 't' + else: + perm[9] = 'T' + + perms = ''.join(perm) + + try: + user = pwd.getpwuid(info.st_uid)[0] + except: + user = str(info.st_uid) + try: + group = grp.getgrgid(info.st_gid)[0] + except: + group = str(info.st_gid) + + size = info.st_size + unit = 0 + units = ('B', 'K', 'M', 'G',) + while unit < 3 and size > 1024: + size = size / 1024 + unit += 1 + size = '%d%s' % (size, units[unit]) + + mtime = datetime.datetime.fromtimestamp(info.st_mtime).strftime('%b %d %H:%M') + + fields = (perms, user, group, size, mtime, name) + return fields diff --git a/method.py b/method.py index 467377b..ebc8968 100644 --- a/method.py +++ b/method.py @@ -1435,7 +1435,7 @@ class RegisterRestore(Method): w.set_error('Restored %r from register %r' % (text2, name2)) class Pipe(Method): - '''Pipe the buffer's contents through the given command, and display the output in a new buffer''' + '''Pipe the buffer's contents through the command, and display the output in a new buffer''' args = [Argument('cmd', datatype="str", prompt="Command: ")] def _parse(self, w, **vargs): m = regex.shell_command.match(vargs['cmd']) diff --git a/mode/dir.py b/mode/dir.py index 6d1e9da..8e3f446 100644 --- a/mode/dir.py +++ b/mode/dir.py @@ -1,4 +1,5 @@ import commands, dirutil, grp, method, mode2, os.path, pwd, re +import buffer2, window2 from lex3 import Grammar, PatternRule, RegionRule, PatternGroupRule from point2 import Point from method import Method, Argument @@ -66,6 +67,7 @@ class Dir(mode2.Fundamental): mode2.Fundamental.__init__(self, w) self.add_action_and_bindings(RefreshView(), ('C-c r',)) self.add_action_and_bindings(OpenPath(), ('RETURN',)) + self.add_action_and_bindings(DirGrep(), ('C-c G',)) self.add_action_and_bindings(Chmod(), ('C-c m',)) self.add_action_and_bindings(Chown(), ('C-c o',)) self.add_action_and_bindings(Chgrp(), ('C-c g',)) @@ -85,6 +87,20 @@ class OpenPath(Method): path = dirutil.resolve_path(w) w.set_error("opening %r" % path) w.application.methods['open-file'].execute(w, filename=path) +class DirGrep(Method): + args = [Argument('pattern', datatype="str", prompt="Pattern: ")] + def _execute(self, w, **vargs): + cmd = 'grep -rEl %r %r' % (vargs['pattern'], w.buffer.path) + (status, output) = commands.getstatusoutput(cmd) + paths = output.split('\n') + bufname = '*%s*' % self.name.title() + b = buffer2.PathListBuffer(bufname, paths) + b.modename = 'dir' + b.open() + window2.Window(b, w.application, height=0, width=0) + w.application.add_buffer(b) + w.application.switch_buffer(b) + w.set_error("grep exited with %d" % status) class DirCmd(Method): def _make_cmd(self, w, path, **vargs):