file browsing ahoy

--HG--
branch : pmacs2
This commit is contained in:
moculus 2007-07-19 18:28:21 +00:00
parent 5a59f28525
commit 3bb9e6b7a6
5 changed files with 188 additions and 10 deletions

View File

@ -11,7 +11,7 @@ import mode2
import mode_mini, mode_search, mode_replace, mode_which import mode_mini, mode_search, mode_replace, mode_which
import mode_console, mode_consolemini import mode_console, mode_consolemini
import mode_c, mode_python, mode_perl, mode_nasm, mode_sh, mode_sql import mode_c, mode_python, mode_perl, mode_nasm, mode_sh, mode_sql
import mode_blame, mode_diff import mode_blame, mode_diff, mode_dir
import mode_xml, mode_tt, mode_css, mode_javascript, mode_html import mode_xml, mode_tt, mode_css, mode_javascript, mode_html
import mode_text, mode_mutt import mode_text, mode_mutt
import mode_bds, mode_life import mode_bds, mode_life
@ -84,6 +84,7 @@ class Application(object):
'console': mode_console.Console, 'console': mode_console.Console,
'consolemini': mode_consolemini.Console, 'consolemini': mode_consolemini.Console,
'diff': mode_diff.Diff, 'diff': mode_diff.Diff,
'dir': mode_dir.Dir,
'fundamental': mode2.Fundamental, 'fundamental': mode2.Fundamental,
'mini': mode_mini.Mini, 'mini': mode_mini.Mini,
'nasm': mode_nasm.Nasm, 'nasm': mode_nasm.Nasm,
@ -253,7 +254,7 @@ class Application(object):
b = buffer2.FileBuffer(path, name=name) b = buffer2.FileBuffer(path, name=name)
elif os.path.isdir(path): elif os.path.isdir(path):
b = buffer2.DirBuffer(path, name=name) b = buffer2.DirBuffer(path, name=name)
mode_name = 'fundamental' mode_name = 'dir'
else: else:
raise Exception, "not a file or dir: %r" % path raise Exception, "not a file or dir: %r" % path
elif cipher == 'aes': elif cipher == 'aes':

View File

@ -1,4 +1,4 @@
import md5, os, sets, shutil import datetime, md5, os, pwd, re, sets, shutil, stat
import aes, regex, highlight2 import aes, regex, highlight2
from point2 import Point from point2 import Point
@ -475,6 +475,14 @@ class AesBuffer(FileBuffer):
def write_filter(self, data): def write_filter(self, data):
return aes.encrypt_data(data, self.password) 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): class DirBuffer(Buffer):
btype = 'dir' btype = 'dir'
def __init__(self, path, nl='\n', name=None): def __init__(self, path, nl='\n', name=None):
@ -490,14 +498,93 @@ class DirBuffer(Buffer):
return self._name return self._name
def path_exists(self): def path_exists(self):
return os.path.exists(self.path) return os.path.exists(self.path)
def open(self): def open(self):
if not self.path_exists(): if not self.path_exists():
raise Exception, "directory %r does not exists" % self.path raise Exception, "directory %r does not exists" % self.path
self.lines = []
names = os.listdir(self.path)
if self.path != '/': if self.path != '/':
self.lines.append('..') names.insert(0, '..')
for name in os.listdir(self.path): names.insert(0, '.')
self.lines.append(name)
lines = []
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
perms = ''.join(perm)
try:
usr = pwd.getpwuid(info.st_uid)[0]
except:
usr = str(info.st_uid)
try:
grp = pwd.getpwuid(info.st_gid)[0]
except:
grp = 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, usr, grp, size, mtime, name)
for i in range(0, 5):
try:
maxlens[i] = max(maxlens[i], len(fields[i]))
except:
raise Exception, '%d %r' % (i, fields[i])
lines.append(fields)
lines.sort(cmp=_path_sort)
fmt = '%%%ds %%-%ds %%-%ds %%%ds %%%ds %%s' % tuple(maxlens)
self.lines = []
for fields in lines:
s = fmt % fields
self.lines.append(s)
def reload(self): def reload(self):
self.open() self.open()
def save(self, force=False): def save(self, force=False):

View File

@ -137,7 +137,7 @@ class PatternGroupRule(PatternRule):
pairs = [] pairs = []
while i < len(args): while i < len(args):
tokname, pattern = args[i], args[i+1] tokname, pattern = args[i], args[i+1]
pairs.append((name, re.compile(pattern, self.reflags))) pairs.append((tokname, re.compile(pattern, self.reflags)))
i += 2 i += 2
Rule.__init__(self, name) Rule.__init__(self, name)
self.pairs = tuple(pairs) self.pairs = tuple(pairs)

89
mode_dir.py Normal file
View File

@ -0,0 +1,89 @@
import method, mode2, os.path
from lex3 import Grammar, PatternRule, RegionRule, PatternGroupRule
from point2 import Point
class PermGrammar(Grammar):
rules = [
PatternRule(r'set', r's'),
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'),
'perm.set': ('red', 'default'),
'perm.read': ('magenta', 'default'),
'perm.write': ('magenta', 'default'),
'perm.exec': ('magenta', 'default'),
'owner': ('blue', 'default'),
'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())
self.add_action_and_bindings(OpenPath(), ('RETURN',))
def name(self):
return "Dir"
class Chmod(method.Method):
def _execute(self, w, **vargs):
w.set_error('chmod not implemented')
class Chown(method.Method):
def _execute(self, w, **vargs):
w.set_error('chown not implemented')
class Chgrp(method.Method):
def _execute(self, w, **vargs):
w.set_error('chgrp not implemented')
class OpenPath(method.Method):
def _execute(self, w, **vargs):
assert w.buffer.btype == 'dir'
c = w.logical_cursor()
p = Point(0, c.y)
t = w.get_next_token_by_type(p, 'name')
path = os.path.join(w.buffer.path, t.string)
w.set_error("opening %r" % path)
w.application.methods['open-file'].execute(w, filename=path)

View File

@ -577,10 +577,11 @@ class Window(object):
return token return token
return None return None
def get_next_token_by_lambda(self, p, f): def get_next_token_by_lambda(self, p, f):
for token in self.get_highlighter().tokens[p.y]: tokens = self.get_highlighter().tokens[p.y]
for token in tokens:
if token.x < p.x: if token.x < p.x:
continue continue
if f(token.name): if f(token):
return token return token
return None return None
def get_next_token_by_type(self, p, name): def get_next_token_by_type(self, p, name):