diff --git a/IDEAS b/IDEAS index e6837b2..cfac716 100644 --- a/IDEAS +++ b/IDEAS @@ -1,3 +1,8 @@ +2008/03/18: + +tie cvs/svn comands into method/shell.py for code reuse +finish arg documentation and review method documentation + 2008/03/16: pdb/gdb/perldb buffer integration diff --git a/application.py b/application.py index 494a152..2a8de69 100755 --- a/application.py +++ b/application.py @@ -185,6 +185,7 @@ class Application(object): method.DATATYPES['command'] = completer.CommandCompleter() method.DATATYPES['shell'] = completer.ShellCompleter() method.DATATYPES['method'] = completer.MethodCompleter() + method.DATATYPES['register'] = completer.RegisterCompleter() method.DATATYPES['mode'] = completer.ModeCompleter() method.DATATYPES['perlfunction'] = completer.PerlFunctionCompleter() diff --git a/completer.py b/completer.py index b850fb5..1a8d682 100644 --- a/completer.py +++ b/completer.py @@ -94,6 +94,10 @@ class MethodCompleter(Completer): def get_candidates(self, s, w=None): return [n for n in w.application.methods if n.startswith(s)] +class RegisterCompleter(Completer): + def get_candidates(self, s, w=None): + return [n for n in w.application.registers if n.startswith(s)] + class ModeCompleter(Completer): def get_candidates(self, s, w=None): return [n for n in w.application.modes if n.startswith(s)] diff --git a/dirutil.py b/dirutil.py index 2b239c7..585cca5 100644 --- a/dirutil.py +++ b/dirutil.py @@ -6,9 +6,10 @@ def resolve_token(w, y=None): p = Point(0, w.logical_cursor().y) else: p = Point(0, y) - return w.get_next_token_by_type(p, 'name') + return w.get_next_token_by_type(p, 'dir_name') def resolve_name(w, y=None): t = resolve_token(w, y) + assert t is not None return t.string def resolve_path(w, y=None): name = resolve_name(w) diff --git a/method/__init__.py b/method/__init__.py index e10eb69..e2f83ba 100644 --- a/method/__init__.py +++ b/method/__init__.py @@ -8,6 +8,7 @@ DATATYPES = { "path": None, "buffer": None, "method": None, + "register": None, "command": None, "shell": None, "shellcommand": None, @@ -16,8 +17,12 @@ DATATYPES = { class MethodError(Exception): pass +def arg(n, t=type(''), dt=None, p=None, h='', dv=default.none, ld=False): + '''convenience function for arguments''' + return Argument(n, type=t, datatype=dt, prompt=p, help=h, default=dv, + load_default=ld) class Argument(object): - def __init__(self, name, type=type(""), datatype=None, prompt=None, help="", + def __init__(self, name, type=type(""), datatype=None, prompt=None, help='', default=default.none, load_default=False): self.name = name self.type = type @@ -72,7 +77,8 @@ class Method(object): help = "" def __init__(self): self.name = self._name() - self.help = self.__doc__ + if self.__doc__: + self.help = self.__doc__ def _name(cls): s = cls.__name__ @@ -308,7 +314,7 @@ class DeleteRightSpace(Method): class MetaX(Method): '''Invoke commands by name''' - args = [Argument('method', datatype="method", prompt="M-x ")] + args = [arg('method', dt="method", p="M-x ", h='Method to execute')] def _execute(self, w, **vargs): name = vargs['method'] if name in w.application.methods: @@ -704,7 +710,8 @@ class IndentBlock(Method): class FileDiff(Method): '''diff the buffer's contents with the given file''' - args = [Argument("path", type=type(""), prompt="Filename: ", datatype='path')] + args = [arg("path", t=type(""), p="Filename: ", dt='path', + h="path to diff against current buffer's contents")] def _execute(self, w, **vargs): cmd = ("/usr/bin/diff", '-u', '-', vargs['path']) pipe = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) @@ -729,7 +736,7 @@ class FileDiff(Method): class SetMode(Method): '''Set the mode of the current buffer''' - args = [Argument('mode', datatype='mode', prompt="Enter new mode: ")] + args = [arg('mode', dt='mode', p="Enter new mode: ")] def _execute(self, w, **vargs): mode_name = vargs['mode'] m = w.application.modes[mode_name](w) @@ -820,10 +827,11 @@ class CloseBracket(CloseTag): mytag = ']' class RegisterSave(Method): - MAX_TXT = 30 - MAX_REG = 20 '''Save the top item of the kill stack into the named register''' - args = [Argument('name', datatype="str", prompt="Register name: ")] + MAX_TXT = 30 + MAX_REG = 18 + args = [arg('name', dt="register", p="Register name: ", + h="Name of the register to use")] def _pre_execute(self, w, **vargs): if not w.has_kill(): raise MethodError, "No text on the kill stack" @@ -838,19 +846,21 @@ class RegisterSave(Method): w.set_error('Saved %r into register %r' % (text, name)) class RegisterRestore(Method): + '''Push the value saved in the named register onto the kill stack''' MAX_TXT = 30 MAX_REG = 18 - '''Push the value saved in the named register onto the kill stack''' - args = [Argument('name', datatype="str", prompt="Register name: ")] + args = [arg('name', dt="register", p="Register name: ", + h="Name of the register to use")] def _execute(self, w, **vargs): name = vargs['name'] if name not in w.application.registers: w.set_error('Register %r does not exist' % name) return + app = w.application text = app.registers[name] w.push_kill(text) if len(text) > self.MAX_TXT: text = text[0:self.MAX_TXT] + '...' if len(name) > self.MAX_REG: name = name[0:self.MAX_REG] + '...' - w.set_error('Restored %r from register %r' % (text2, name2)) + w.set_error('Restored %r from register %r' % (text, name)) diff --git a/method/buffers.py b/method/buffers.py index 980e1e1..cb6f498 100644 --- a/method/buffers.py +++ b/method/buffers.py @@ -3,20 +3,21 @@ from subprocess import Popen, PIPE, STDOUT import buffer, default, dirutil, regex, util, window from point import Point - -from method import DATATYPES, Method, Argument +from method import DATATYPES, Method, Argument, arg class OpenFile(Method): '''Open file in a new buffer, or go to file's open buffer''' - args = [Argument('filename', datatype="path", prompt="Open File: ", - default=default.path_dirname, load_default=True)] + args = [arg('filename', dt="path", p="Open File: ", dv=default.path_dirname, + ld=True, h="file to open")] def _execute(self, w, **vargs): b = w.application.open_path(vargs['filename']) SwitchBuffer().execute(w, buffername=b.name()) class OpenAesFile(Method): '''Open AES encrypted file in a new buffer, or go to file's open buffer''' - args = [Argument('filename', datatype="path", prompt="Open AES File: "), - Argument('password', prompt="Use AES Password: ")] + args = [arg('filename', dt="path", p="Open AES File: ", + dv=default.path_dirname, h="file to open"), + arg('password', p="Use AES Password: ", + h="the AES password the file was encrypted with")] def _execute(self, w, **vargs): b = w.application.open_path(vargs['filename'], 'aes', vargs['password']) SwitchBuffer().execute(w, buffername=b.name()) @@ -35,8 +36,8 @@ class ViewBufferParent(Method): class SwitchBuffer(Method): '''Switch to a different''' - args = [Argument('buffername', datatype="buffer", prompt="Switch To Buffer: ", - default=default.last_buffer)] + args = [arg('buffername', dt="buffer", p="Switch To Buffer: ", + dv=default.last_buffer, h="name of the buffer to switch to")] def _pre_execute(self, w, **vargs): a = w.application if len(a.bufferlist.buffers) < 1: @@ -51,9 +52,9 @@ class SwitchBuffer(Method): w.set_error("buffer %r was not found" % name) class KillBuffer(Method): '''Close the current buffer''' - force=False - args = [Argument('buffername', datatype="buffer", prompt="Kill Buffer: ", - default=default.current_buffer)] + force = False + args = [arg('buffername', dt="buffer", p="Kill Buffer: ", + dv=default.current_buffer, h="name of the buffer to kill")] def _execute(self, w, **vargs): name = vargs['buffername'] a = w.application @@ -85,9 +86,9 @@ class KillBuffer(Method): a.set_error('Please type "yes" or "no"') class ForceKillBuffer(KillBuffer): + '''Close the current buffer, automatically discarding any changes''' force=True - args = [Argument('buffername', datatype="buffer", prompt="Force Kill Buffer: ", - default=default.current_buffer)] + class ListBuffers(Method): '''List all open buffers in a new buffer''' def _execute(self, w, **vargs): @@ -98,8 +99,8 @@ class ListBuffers(Method): w.application.data_buffer("*Buffers*", data, switch_to=True) class SaveBufferAs(Method): '''Save the contents of a buffer to the specified path''' - args = [Argument('path', datatype="path", prompt="Write file: ", - default=default.current_working_dir, load_default=True)] + args = [arg('path', dt="path", p="Write file: ", ld=True, + dv=default.current_working_dir, h="new path to use")] def _execute(self, w, **vargs): curr_buffer = w.buffer curr_buffer_name = curr_buffer.name() diff --git a/method/cvs.py b/method/cvs.py index 9dc085f..6cb30b4 100644 --- a/method/cvs.py +++ b/method/cvs.py @@ -4,11 +4,12 @@ from subprocess import Popen, PIPE, STDOUT import buffer, default, dirutil, regex, util, window from point import Point -from method import DATATYPES, Method, Argument +from method import DATATYPES, Method, Argument, arg class CvsCommit(Method): '''diff the current file with the version in CVS''' - args = [Argument("msg", type=type(""), prompt="Commit Message: ")] + args = [arg("msg", t=type(""), p="Commit Message: ", + h="commit message to send to CVS")] regex = re.compile('^new revision: ([0-9.]+); previous revision: ([0-9.]+)$') def _execute(self, w, **vargs): if not hasattr(w.buffer, 'path'): @@ -119,9 +120,10 @@ class CvsDiff(Method): w.application.data_buffer("*Diff*", data, switch_to=True, modename='diff') w.set_error("Differences were found") class CvsDiff2(Method): - '''diff the current file with the version in CVS''' + '''diff the current file's contents with a version in CVS''' rev_regex = re.compile('^[0-9]+\.[0-9]+$') - args = [Argument("revision", type=type(""), prompt="Old Revision: ")] + args = [arg("revision", t=type(""), p="Old Revision: ", + h="revision number")] def _execute(self, w, **vargs): if not hasattr(w.buffer, 'path'): w.set_error("Buffer has no corresponding file") @@ -149,8 +151,8 @@ class CvsDiff2(Method): class CvsDiff3(Method): '''diff the current file with the version in CVS''' rev_regex = re.compile('^[0-9]+\.[0-9]+$') - args = [Argument("revision1", type=type(""), prompt="Old Revision: "), - Argument("revision2", type=type(""), prompt="New Revision: ")] + args = [arg("revision1", t=type(""), p="Old Revision: ", h='old revision number'), + arg("revision2", t=type(""), p="New Revision: ", h='new revision number')] def _execute(self, w, **vargs): if not hasattr(w.buffer, 'path'): w.set_error("Buffer has no corresponding file") diff --git a/method/move.py b/method/move.py index 239143d..2f1b01e 100644 --- a/method/move.py +++ b/method/move.py @@ -111,7 +111,7 @@ class GotoLine(Method): w.goto_line(n) class ForwardLines(Method): - '''Move forward the specified number of characters''' + '''Move forward the specified number of lines''' args = [Argument("lineno", type=type(0), prompt="Forward lines: ")] def _execute(self, w, **vargs): w.forward_lines(vargs["lineno"]) diff --git a/method/shell.py b/method/shell.py index 59ea13c..bcdeab6 100644 --- a/method/shell.py +++ b/method/shell.py @@ -16,9 +16,13 @@ class Exec(Method): except: pass (status, output) = commands.getstatusoutput(cmd) + self._display(w, output, status, cmd) + + def _display(self, w, data, status, cmd): bufname = '*%s*' % self.name.title() - w.application.data_buffer(bufname, output, switch_to=True) + w.application.data_buffer(bufname, data, switch_to=True) w.set_error("Shell exited with %d" % status) + def _execute(self, w, **vargs): if w.buffer.btype == 'dir': name = dirutil.resolve_name(w) @@ -42,7 +46,12 @@ class Pipe(Method): return (prog, vargs['cmd'], True) else: return (None, None, False) - + + def _display(self, w, data, status, prog, cmd, shell): + bufname = '*%s*' % self.name.title() + w.application.data_buffer(bufname, data, switch_to=True) + w.set_error("%s exited with status %d" % (prog, status)) + def _execute(self, w, **vargs): (prog, cmd, shell) = self._parse(w, **vargs) if prog is None or not cmd: @@ -56,11 +65,9 @@ class Pipe(Method): pipe.stdin.close() outdata = pipe.stdout.read() - status = pipe.wait() >> 8 + status = pipe.wait() >> 8 - bufname = '*%s*' % self.name.title() - w.application.data_buffer(bufname, outdata, switch_to=True) - w.set_error("%s exited with status %d" % (prog, status)) + self._display(w, outdata, status, prog, cmd, shell) class Grep(Pipe): '''Grep the buffer's contents for instances of a pattern, and display them in a new buffer'''