2007-07-20 09:53:57 -04:00
|
|
|
import grp, method, mode2, os.path, pwd, re
|
2007-07-19 14:28:21 -04:00
|
|
|
from lex3 import Grammar, PatternRule, RegionRule, PatternGroupRule
|
|
|
|
from point2 import Point
|
2007-07-19 22:36:36 -04:00
|
|
|
from method import Method, Argument
|
2007-07-19 14:28:21 -04:00
|
|
|
|
|
|
|
class PermGrammar(Grammar):
|
|
|
|
rules = [
|
2007-07-19 17:51:20 -04:00
|
|
|
PatternRule(r'sticky', r'[tT]'),
|
|
|
|
PatternRule(r'setid', r'[sS]'),
|
2007-07-19 14:28:21 -04:00
|
|
|
PatternRule(r'read', r'r'),
|
|
|
|
PatternRule(r'write', r'w'),
|
|
|
|
PatternRule(r'exec', r'x'),
|
|
|
|
]
|
|
|
|
|
|
|
|
class PathGrammar(Grammar):
|
|
|
|
rules = [
|
|
|
|
RegionRule(r'perm', r'(?<=^.)', PermGrammar, r' '),
|
|
|
|
PatternGroupRule(r'fields', r'owner', r'[^ ]+ +', r'group', r'[^ ]+ +',
|
|
|
|
r'size', r'[^ ]+ +',
|
|
|
|
r'mtime', r'[A-Za-z]{3} [ 0-9]{2} [0-9]{2}:[0-9]{2} +',
|
|
|
|
r'name', r'[^\n]*'),
|
|
|
|
]
|
|
|
|
|
|
|
|
class DirGrammar(Grammar):
|
|
|
|
rules = [
|
|
|
|
RegionRule(r'file', r'^-', PathGrammar, r'\n'),
|
|
|
|
RegionRule(r'blk', r'^b', PathGrammar, r'\n'),
|
|
|
|
RegionRule(r'chr', r'^c', PathGrammar, r'\n'),
|
|
|
|
RegionRule(r'dir', r'^d', PathGrammar, r'\n'),
|
|
|
|
RegionRule(r'lnk', r'^l', PathGrammar, r'\n'),
|
|
|
|
RegionRule(r'fifo', r'^p', PathGrammar, r'\n'),
|
|
|
|
RegionRule(r'sock', r'^s', PathGrammar, r'\n'),
|
|
|
|
RegionRule(r'unk', r'^\?', PathGrammar, r'\n'),
|
|
|
|
]
|
|
|
|
|
|
|
|
class Dir(mode2.Fundamental):
|
|
|
|
grammar = DirGrammar()
|
|
|
|
colors = {
|
|
|
|
'blk.start': ('cyan', 'default'),
|
|
|
|
'blk.name': ('cyan', 'default'),
|
|
|
|
'chr.start': ('yellow', 'default'),
|
|
|
|
'chr.name': ('yellow', 'default'),
|
|
|
|
'dir.start': ('blue', 'default'),
|
|
|
|
'dir.name': ('blue', 'default'),
|
|
|
|
'lnk.start': ('green', 'default'),
|
|
|
|
'lnk.name': ('green', 'default'),
|
|
|
|
'fifo.start': ('red', 'default'),
|
|
|
|
'fifo.name': ('red', 'default'),
|
|
|
|
'sock.start': ('red', 'default'),
|
|
|
|
'sock.name': ('red', 'default'),
|
|
|
|
'unk.start': ('magenta', 'default'),
|
|
|
|
'unk.name': ('magenta', 'default'),
|
|
|
|
|
2007-07-19 17:51:20 -04:00
|
|
|
'perm.setid': ('yellow', 'default'),
|
|
|
|
'perm.sticky': ('yellow', 'default'),
|
|
|
|
'perm.read': ('magenta', 'default'),
|
|
|
|
'perm.write': ('magenta', 'default'),
|
|
|
|
'perm.exec': ('magenta', 'default'),
|
2007-07-19 14:28:21 -04:00
|
|
|
|
2007-07-19 17:51:20 -04:00
|
|
|
'owner': ('cyan', 'default'),
|
2007-07-19 14:28:21 -04:00
|
|
|
'group': ('cyan', 'default'),
|
|
|
|
'size': ('yellow', 'default'),
|
|
|
|
'mtime': ('green', 'default'),
|
|
|
|
}
|
|
|
|
def __init__(self, w):
|
|
|
|
mode2.Fundamental.__init__(self, w)
|
|
|
|
self.add_action(Chmod())
|
|
|
|
self.add_action(Chown())
|
|
|
|
self.add_action(Chgrp())
|
2007-07-19 22:36:36 -04:00
|
|
|
|
|
|
|
self.add_action(TouchPath())
|
|
|
|
self.add_action(RefreshView())
|
2007-07-19 14:28:21 -04:00
|
|
|
self.add_action_and_bindings(OpenPath(), ('RETURN',))
|
2007-07-19 17:51:20 -04:00
|
|
|
self.add_action_and_bindings(RemovePath(), ('DELETE', 'BACKSPACE', 'C-d'))
|
2007-07-19 14:28:21 -04:00
|
|
|
def name(self):
|
|
|
|
return "Dir"
|
|
|
|
|
2007-07-19 17:51:20 -04:00
|
|
|
def _resolve_token(w):
|
|
|
|
c = w.logical_cursor()
|
|
|
|
p = Point(0, c.y)
|
|
|
|
return w.get_next_token_by_type(p, 'name')
|
2007-07-20 09:53:57 -04:00
|
|
|
def _resolve_name(w):
|
2007-07-19 17:51:20 -04:00
|
|
|
t = _resolve_token(w)
|
2007-07-20 09:53:57 -04:00
|
|
|
return t.string
|
|
|
|
def _resolve_path(w):
|
|
|
|
name = _resolve_name(w)
|
|
|
|
path = os.path.join(w.buffer.path, name)
|
2007-07-19 17:51:20 -04:00
|
|
|
return path
|
|
|
|
|
2007-07-20 09:53:57 -04:00
|
|
|
def _find_name(w, s):
|
|
|
|
found = False
|
|
|
|
w.goto(Point(0, 0))
|
|
|
|
c = w.logical_cursor()
|
|
|
|
while not found and c.y < len(w.buffer.lines):
|
|
|
|
t = _resolve_token(w)
|
|
|
|
if t.string == s:
|
|
|
|
found = True
|
|
|
|
break
|
|
|
|
w.goto(Point(c.x, c.y + 1))
|
|
|
|
c = w.logical_cursor()
|
|
|
|
if not found:
|
|
|
|
w.goto(Point(0, 0))
|
|
|
|
|
|
|
|
class RefreshView(Method):
|
|
|
|
def _execute(self, w, **vargs):
|
|
|
|
t = _resolve_token(w)
|
|
|
|
s = t.string
|
|
|
|
w.buffer.reload()
|
|
|
|
_find_name(w, s)
|
|
|
|
class OpenPath(Method):
|
|
|
|
def _execute(self, w, **vargs):
|
|
|
|
path = _resolve_path(w)
|
|
|
|
w.set_error("opening %r" % path)
|
|
|
|
w.application.methods['open-file'].execute(w, filename=path)
|
|
|
|
|
2007-07-19 22:36:36 -04:00
|
|
|
class Chmod(Method):
|
2007-07-20 09:53:57 -04:00
|
|
|
args = [Argument('mode', type=type(''), prompt="New Mode: ")]
|
|
|
|
octal_re = re.compile('^[0-7]{1,4}$')
|
|
|
|
symbolic_re = re.compile('(?:[ugoa]*(?:[-+=](?:[rwxXst]*|[ugo]))+ *,?)+')
|
2007-07-19 14:28:21 -04:00
|
|
|
def _execute(self, w, **vargs):
|
2007-07-20 09:53:57 -04:00
|
|
|
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'])
|
|
|
|
basename = _resolve_name(w)
|
|
|
|
path = os.path.join(w.buffer.path, basename)
|
|
|
|
retval = os.system('chmod %r %r' % (vargs['mode'], path))
|
|
|
|
w.application.methods['refresh-view'].execute(w, filename=path)
|
|
|
|
_find_name(w, basename)
|
|
|
|
if retval != 0:
|
|
|
|
w.set_error("chmod %r failed (exit %d)" % (vargs['mode'], retval))
|
2007-07-19 22:36:36 -04:00
|
|
|
class Chown(Method):
|
2007-07-20 09:53:57 -04:00
|
|
|
args = [Argument('owner', type=type(''), prompt="New Owner: ")]
|
2007-07-19 14:28:21 -04:00
|
|
|
def _execute(self, w, **vargs):
|
2007-07-20 09:53:57 -04:00
|
|
|
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 owner.isdigit():
|
|
|
|
try:
|
|
|
|
pwd.getpwnam(owner)
|
|
|
|
except:
|
|
|
|
w.set_error("User %r does not exist" % owner)
|
|
|
|
return
|
|
|
|
if group is not None and not group.isdigit():
|
|
|
|
try:
|
|
|
|
grp.getgrnam(group)
|
|
|
|
except:
|
|
|
|
w.set_error("Group %r does not exist" % group)
|
|
|
|
return
|
|
|
|
|
|
|
|
basename = _resolve_name(w)
|
|
|
|
path = os.path.join(w.buffer.path, basename)
|
|
|
|
retval = os.system('chown %r %r' % (vargs['owner'], path))
|
|
|
|
w.application.methods['refresh-view'].execute(w, filename=path)
|
|
|
|
_find_name(w, basename)
|
|
|
|
if retval != 0:
|
|
|
|
w.set_error("chown %r failed (exit %d)" % (vargs['mode'], retval))
|
2007-07-19 22:36:36 -04:00
|
|
|
class Chgrp(Method):
|
2007-07-20 09:53:57 -04:00
|
|
|
args = [Argument('group', type=type(''), prompt="New Group: ")]
|
2007-07-19 14:28:21 -04:00
|
|
|
def _execute(self, w, **vargs):
|
|
|
|
w.set_error('chgrp not implemented')
|
|
|
|
|
2007-07-19 22:36:36 -04:00
|
|
|
class TouchPath(Method):
|
|
|
|
args = [Argument('filename', datatype="path", prompt="Touch File: ")]
|
|
|
|
def _execute(self, w, **vargs):
|
2007-07-20 09:53:57 -04:00
|
|
|
basename = vargs['filename']
|
|
|
|
path = os.path.join(w.buffer.path, basename)
|
2007-07-19 22:36:36 -04:00
|
|
|
retval = os.system('touch %r' % path)
|
|
|
|
w.application.methods['refresh-view'].execute(w, filename=path)
|
2007-07-20 09:53:57 -04:00
|
|
|
_find_name(w, basename)
|
2007-07-19 22:36:36 -04:00
|
|
|
if retval != 0:
|
2007-07-20 09:53:57 -04:00
|
|
|
w.set_error("touch %r failed (exit %d)" % (path, retval))
|
2007-07-19 22:36:36 -04:00
|
|
|
class RemovePath(Method):
|
2007-07-19 14:28:21 -04:00
|
|
|
def _execute(self, w, **vargs):
|
2007-07-20 09:53:57 -04:00
|
|
|
self._old_window = w
|
|
|
|
self._old_path = _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
|
2007-07-19 17:51:20 -04:00
|
|
|
try:
|
2007-07-20 09:53:57 -04:00
|
|
|
w.application.methods['previous-line'].execute(w)
|
2007-07-19 17:51:20 -04:00
|
|
|
os.remove(path)
|
|
|
|
w.set_error("deleted %r " % path)
|
2007-07-19 22:36:36 -04:00
|
|
|
w.application.methods['refresh-view'].execute(w, filename=path)
|
2007-07-19 17:51:20 -04:00
|
|
|
except:
|
|
|
|
w.set_error("failed to delete %r" % path)
|