From f747b063182c0eb32e1bc24620a7ee4e1cf2b6f4 Mon Sep 17 00:00:00 2001 From: Erik Osheim Date: Thu, 9 Jul 2009 16:23:13 -0400 Subject: [PATCH] initial archive browsing support --HG-- branch : pmacs2 --- application.py | 19 +++++++++++-------- buffer/fs.py | 40 ++++++++++++++++++++++++++++++++++++---- mode/dir.py | 35 ++++++++++++++++++++++++++++++----- 3 files changed, 77 insertions(+), 17 deletions(-) diff --git a/application.py b/application.py index 321003b..d1b5cb1 100755 --- a/application.py +++ b/application.py @@ -347,19 +347,22 @@ class Application(object): def close_buffer_by_name(self, name): if self.has_buffer_name(name): self.close_buffer(self.get_buffer_by_name(name)) + + def make_name(self, name): + if self.has_buffer_name(name): + i = 1 + auxname = '%s/%d' % (name, i) + while self.has_buffer_name(auxname): + i += 1 + auxname = '%s/%d' % (name, i) + name = auxname + return name def open_path(self, path, binary=False, cipher=None, password=None): path = os.path.abspath(os.path.realpath(util.expand_tilde(path))) b = self.get_buffer_by_path(path) if b is None: - name = os.path.basename(path) - if self.has_buffer_name(name): - i = 1 - auxname = '%s/%d' % (name, i) - while self.has_buffer_name(auxname): - i += 1 - auxname = '%s/%d' % (name, i) - name = auxname + name = self.make_name(os.path.basename(path)) mode_name = None if cipher is None: diff --git a/buffer/fs.py b/buffer/fs.py index 22dd9c9..3a5589b 100644 --- a/buffer/fs.py +++ b/buffer/fs.py @@ -1,5 +1,9 @@ import fnmatch -import dirutil, os +import os +import shutil +import tempfile + +import dirutil from buffer import Buffer ignore = ['*.o', '*.lo', '*.la', '#*#', '*.rej', '*~', '.#*', '.DS_Store', @@ -25,7 +29,7 @@ class DirBuffer(Buffer): def path_exists(self): return os.path.exists(self.path) - def _get_names(self): + def get_names(self): if not self.path_exists(): raise Exception, "directory %r does not exists" % self.path names = os.listdir(self.path) @@ -36,7 +40,7 @@ class DirBuffer(Buffer): def _make_path(self, name): return os.path.join(self.path, name) def _get_lines(self): - names = self._get_names() + names = self.get_names() fieldlines = [] maxlens = [0] * 5 @@ -82,6 +86,34 @@ class DirBuffer(Buffer): def save_as(self, path): raise Exception, "can't save a directory buffer" +class ArchiveBuffer(DirBuffer): + btype = 'archive' + types = [ + ['.tar', 'tar xf %(archive)r -C %(dir)r'], + ['.tgz', 'tar xfz %(archive)r -C %(dir)r'], + ['.tar.gz', 'tar xfz %(archive)r -C %(dir)r'], + ['.tar.bz2', 'tar xfj %(archive)r -C %(dir)r'], + #['.gz', 'gunzip %(archive)r'], + #['.bz2', 'bunzip2 %(archive)r'], + #['.zip', 'unzip %(archive)r'], + #['.jar', 'unzip %(archive)r'], + ] + def __init__(self, path, name=None): + self.archive = os.path.realpath(path) + for suffix, cmd in self.types: + if self.archive.endswith(suffix): + path = tempfile.mkdtemp() + cwd = os.getcwd() + os.chdir(path) + s = cmd % {'archive': self.archive, 'dir': path} + os.chdir(cwd) + retval = os.system(s) + if retval != 0: raise Exception("%r failed" % s) + DirBuffer.__init__(self, path, name) + + def close(self): + shutil.rmtree(self.path) + class PathListBuffer(DirBuffer): btype = 'pathlist' def __init__(self, name, paths): @@ -93,7 +125,7 @@ class PathListBuffer(DirBuffer): self.settings['type-sort'] = False def path_exists(self): raise Exception - def _get_names(self): + def get_names(self): cwd = os.getcwd() return [x.replace(cwd, '.', 1) for x in self.paths] def _make_path(self, name): diff --git a/mode/dir.py b/mode/dir.py index 85885b4..f64142f 100644 --- a/mode/dir.py +++ b/mode/dir.py @@ -4,7 +4,7 @@ import buffer, buffer.fs from window import Window from lex import Grammar, PatternRule, RegionRule, PatternMatchRule from point import Point -from method import Method, Argument +from method import Method, Argument, arg class PermGrammar(Grammar): rules = [ @@ -59,12 +59,36 @@ class SortName(FsSettingBase): msg = "Sorting files by name, type" def _doit(self, w, **vargs): w.buffer.settings['type-sort'] = False +class OpenArchive(Method): + args = [arg('path', dt="path", p="Open Archive: ", h="archive to open")] + def _execute(self, w, **vargs): + path = vargs['path'] + a = w.application + b = a.get_buffer_by_path(path) + if not b: + name = a.make_name(os.path.basename(path)) + b = buffer.fs.ArchiveBuffer(path, name) + b.open() + Window(b, a, height=0, width=0, mode_name='dir') + a.add_buffer(b) + a.methods['switch-buffer'].execute(w, buffername=b.name()) + if b.btype != 'archive': + return + names = [x for x in b.get_names() if x != '.' and x != '..'] + if len(names) == 1: + path2 = os.path.join(b.path, names[0]) + a.methods['open-file'].execute(w, filename=path2) + class DirRefresh(Method): def _execute(self, w, **vargs): - t = dirutil.resolve_token(w) - s = t.string + t = None + try: + t = dirutil.resolve_token(w) + s = t.string + except: + pass w.buffer.reload() - dirutil.find_name(w, s) + if t: dirutil.find_name(w, s) class DirOpen(Method): def _execute(self, w, **vargs): path = dirutil.resolve_path(w) @@ -219,7 +243,8 @@ class Dir(mode.Fundamental): } actions = [DirRefresh, DirOpen, DirGrep, DirChmod, DirChown, DirChgrp, DirTouch, DirRemove, HideDotFiles, ShowDotFiles, SortName, - SortType] + SortType, + OpenArchive] def __init__(self, w): mode.Fundamental.__init__(self, w) self.add_bindings('dir-refresh', ('C-c r',))