method bugfixes, doc updates, other improvements

--HG--
branch : pmacs2
This commit is contained in:
moculus 2008-03-18 14:51:47 +00:00
parent efadf61be5
commit 3cf80e026b
9 changed files with 71 additions and 40 deletions

5
IDEAS
View File

@ -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

View File

@ -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()

View File

@ -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)]

View File

@ -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)

View File

@ -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))

View File

@ -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()

View File

@ -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")

View File

@ -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"])

View File

@ -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)
@ -43,6 +47,11 @@ class Pipe(Method):
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'''