pmacs3/mode/dir.py

209 lines
8.2 KiB
Python
Raw Normal View History

2007-10-21 20:55:29 -04:00
import commands, dirutil, grp, method, mode, os.path, pwd, re
2008-10-29 10:58:06 -04:00
import buffer, buffer.fs
import window
2007-10-21 20:52:48 -04:00
from lex import Grammar, PatternRule, RegionRule, PatternGroupRule
from point import Point
2007-07-21 11:40:53 -04:00
from method import Method, Argument
class PermGrammar(Grammar):
rules = [
2008-03-16 11:39:17 -04:00
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'),
2007-07-21 11:40:53 -04:00
]
class PathGrammar(Grammar):
rules = [
2008-03-16 11:39:17 -04:00
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]*',
),
2007-07-21 11:40:53 -04:00
]
class DirGrammar(Grammar):
rules = [
2008-03-16 11:39:17 -04:00
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'),
2007-07-21 11:40:53 -04:00
]
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)
2007-07-22 13:53:32 -04:00
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)
2008-04-01 19:14:58 -04:00
paths = [x for x in output.split('\n') if x]
2007-07-22 13:53:32 -04:00
bufname = '*%s*' % self.name.title()
2008-10-29 10:58:06 -04:00
b = buffer.fs.PathListBuffer(bufname, paths)
2007-07-22 13:53:32 -04:00
b.modename = 'dir'
b.open()
2007-10-21 20:55:29 -04:00
window.Window(b, w.application, height=0, width=0)
2007-07-22 13:53:32 -04:00
w.application.add_buffer(b)
w.application.switch_buffer(b)
w.set_error("grep exited with %d" % status)
2007-07-21 11:40:53 -04:00
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))
2007-07-23 10:50:07 -04:00
#w.application.methods['refresh-view'].execute(w, filename=path)
2007-07-21 11:40:53 -04:00
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)
2007-10-19 02:41:33 -04:00
2008-04-18 23:32:08 -04:00
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'),
2008-04-18 23:32:08 -04:00
'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'),
2008-04-18 23:32:08 -04:00
'dir_owner': ('cyan', 'default', 'bold'),
'dir_group': ('cyan', 'default', 'bold'),
'dir_size': ('yellow', 'default', 'bold'),
'dir_mtime': ('green', 'default', 'bold'),
2008-04-18 23:32:08 -04:00
}
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'))
2007-10-19 02:41:33 -04:00
install = Dir.install