import commands, dirutil, grp, method, mode, os.path, pwd, re import buffer, window from lex import Grammar, PatternRule, RegionRule, PatternGroupRule from point import Point from method import Method, Argument class PermGrammar(Grammar): rules = [ PatternRule(r'perm_sticky', r'[tT]'), PatternRule(r'perm_setid', r'[sS]'), PatternRule(r'perm_read', r'r'), PatternRule(r'perm_write', r'w'), PatternRule(r'perm_exec', r'x'), ] class PathGrammar(Grammar): rules = [ RegionRule(r'dir_perm', r'(?<=^.)', PermGrammar, r' '), PatternGroupRule( r'dir_fields', r'dir_owner', r'[^ ]+ +', r'dir_group', r'[^ ]+ +', r'dir_size', r'[^ ]+ +', r'dir_mtime', r'[A-Za-z]{3} [ 0-9]{2} [0-9]{2}:[0-9]{2} +', r'dir_name', r'[^\n]*', ), ] class DirGrammar(Grammar): rules = [ RegionRule(r'dir_file', r'^-', PathGrammar, r'\n'), RegionRule(r'dir_blk', r'^b', PathGrammar, r'\n'), RegionRule(r'dir_chr', r'^c', PathGrammar, r'\n'), RegionRule(r'dir_dir', r'^d', PathGrammar, r'\n'), RegionRule(r'dir_lnk', r'^l', PathGrammar, r'\n'), RegionRule(r'dir_fifo', r'^p', PathGrammar, r'\n'), RegionRule(r'dir_sock', r'^s', PathGrammar, r'\n'), RegionRule(r'dir_unk', r'^\?', PathGrammar, r'\n'), ] class RefreshView(Method): def _execute(self, w, **vargs): t = dirutil.resolve_token(w) s = t.string w.buffer.reload() dirutil.find_name(w, s) class OpenPath(Method): def _execute(self, w, **vargs): 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 = [x for x in output.split('\n') if x] bufname = '*%s*' % self.name.title() b = buffer.PathListBuffer(bufname, paths) b.modename = 'dir' b.open() window.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): return '' def _run(self, w, **vargs): basename = dirutil.resolve_name(w) path = os.path.join(w.buffer.path, basename) cmd = self._make_cmd(w, path, **vargs) (status, output) = commands.getstatusoutput(cmd) if status != 0: w.set_error("%s failed (exit %d)" % (self.name, status)) #w.application.methods['refresh-view'].execute(w, filename=path) dirutil.find_name(w, basename) class Chmod(DirCmd): args = [Argument('mode', type=type(''), prompt="New Mode: ")] octal_re = re.compile('^[0-7]{1,4}$') symbolic_re = re.compile('(?:[ugoa]*(?:[-+=](?:[rwxXst]*|[ugo]))+ *,?)+') def _make_cmd(self, w, path, **vargs): return 'chmod %r %r' % (vargs['mode'], path) def _execute(self, w, **vargs): if self.octal_re.match(vargs['mode']): pass elif self.symbolic_re.match(vargs['mode']): pass else: w.set_error("Not a valid mode: %r" % vargs['mode']) self._run(w, **vargs) class Chown(DirCmd): args = [Argument('owner', type=type(''), prompt="New Owner: ")] def _make_cmd(self, w, path, **vargs): return 'chown %r %r' % (vargs['owner'], path) def _execute(self, w, **vargs): fields = vargs['owner'].split(':') if len(fields) == 1: (owner, group) = (fields[0], None) elif len(fields) == 2: (owner, group) = fields else: w.set_error("Malformed 'owner' argument: %r" % vargs['owner']) return if not dirutil.valid_owner(owner): w.set_error('User %r does not exist' % owner) return if group is not None and not dirutil.valid_group(group): w.set_error('Group %r does not exist' % group) return self._run(w, **vargs) class Chgrp(DirCmd): args = [Argument('group', type=type(''), prompt="New Group: ")] def _make_cmd(self, w, path, **vargs): return 'chgrp %r %r' % (vargs['group'], path) def _execute(self, w, **vargs): if not dirutil.valid_group(vargs['group']): w.set_error('Group %r does not exist' % group) return self._run(w, **vargs) class TouchPath(Method): args = [Argument('filename', datatype="path", prompt="Touch File: ")] def _execute(self, w, **vargs): basename = vargs['filename'] path = os.path.join(w.buffer.path, basename) retval = os.system('touch %r' % path) w.application.methods['refresh-view'].execute(w, filename=path) dirutil.find_name(w, basename) if retval != 0: w.set_error("touch %r failed (exit %d)" % (path, retval)) class RemovePath(Method): def _execute(self, w, **vargs): self._old_window = w self._old_path = dirutil.resolve_path(w) basename = os.path.basename(self._old_path) self._prompt = "Do you want to delete %r? " % basename w.application.open_mini_buffer(self._prompt, self._callback) def _callback(self, v): a = self._old_window.application if v == 'yes': self._doit() a.close_mini_buffer() return if v == 'no': a.close_mini_buffer() return a.open_mini_buffer(self._prompt, self._callback) a.set_error('Please type "yes" or "no"') def _doit(self): w = self._old_window path = self._old_path try: w.application.methods['previous-line'].execute(w) os.remove(path) w.set_error("deleted %r " % path) w.application.methods['refresh-view'].execute(w, filename=path) except: w.set_error("failed to delete %r" % path) class Dir(mode.Fundamental): modename = 'Dir' grammar = DirGrammar() colors = { 'dir_blk.start': ('cyan', 'default', 'bold'), 'dir_blk.dir_name': ('cyan', 'default', 'bold'), 'dir_chr.start': ('yellow', 'default', 'bold'), 'dir_chr.dir_name': ('yellow', 'default', 'bold'), 'dir_dir.start': ('blue', 'default', 'bold'), 'dir_dir.dir_name': ('blue', 'default', 'bold'), 'dir_lnk.start': ('green', 'default', 'bold'), 'dir_lnk.dir_name': ('green', 'default', 'bold'), 'dir_fifo.start': ('red', 'default', 'bold'), 'dir_fifo.dir_name': ('red', 'default', 'bold'), 'dir_sock.start': ('red', 'default', 'bold'), 'dir_sock.dir_name': ('red', 'default', 'bold'), 'dir_unk.start': ('magenta', 'default', 'bold'), 'dir_unk.dir_name': ('magenta', 'default', 'bold'), 'dir_perm.perm_setid': ('yellow', 'default', 'bold'), 'dir_perm.perm_sticky': ('yellow', 'default', 'bold'), 'dir_perm.perm_read': ('magenta', 'default', 'bold'), 'dir_perm.perm_write': ('magenta', 'default', 'bold'), 'dir_perm.perm_exec': ('magenta', 'default', 'bold'), 'dir_owner': ('cyan', 'default', 'bold'), 'dir_group': ('cyan', 'default', 'bold'), 'dir_size': ('yellow', 'default', 'bold'), 'dir_mtime': ('green', 'default', 'bold'), } actions = [RefreshView, OpenPath, DirGrep, Chmod, Chown, Chgrp, TouchPath, RemovePath] def __init__(self, w): mode.Fundamental.__init__(self, w) self.add_bindings('refresh-view', ('C-c r',)) self.add_bindings('open-path', ('RETURN',)) self.add_bindings('dir-grep', ('C-c G',)) self.add_bindings('chmod', ('C-c m',)) self.add_bindings('chown', ('C-c o',)) self.add_bindings('chgrp', ('C-c g',)) self.add_bindings('touch-path', ('C-c t',)) self.add_bindings('remove-path', ('DELETE', 'BACKSPACE', 'C-d')) install = Dir.install