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: 2008/03/16:
pdb/gdb/perldb buffer integration pdb/gdb/perldb buffer integration

View File

@ -185,6 +185,7 @@ class Application(object):
method.DATATYPES['command'] = completer.CommandCompleter() method.DATATYPES['command'] = completer.CommandCompleter()
method.DATATYPES['shell'] = completer.ShellCompleter() method.DATATYPES['shell'] = completer.ShellCompleter()
method.DATATYPES['method'] = completer.MethodCompleter() method.DATATYPES['method'] = completer.MethodCompleter()
method.DATATYPES['register'] = completer.RegisterCompleter()
method.DATATYPES['mode'] = completer.ModeCompleter() method.DATATYPES['mode'] = completer.ModeCompleter()
method.DATATYPES['perlfunction'] = completer.PerlFunctionCompleter() method.DATATYPES['perlfunction'] = completer.PerlFunctionCompleter()

View File

@ -94,6 +94,10 @@ class MethodCompleter(Completer):
def get_candidates(self, s, w=None): def get_candidates(self, s, w=None):
return [n for n in w.application.methods if n.startswith(s)] 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): class ModeCompleter(Completer):
def get_candidates(self, s, w=None): def get_candidates(self, s, w=None):
return [n for n in w.application.modes if n.startswith(s)] 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) p = Point(0, w.logical_cursor().y)
else: else:
p = Point(0, y) 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): def resolve_name(w, y=None):
t = resolve_token(w, y) t = resolve_token(w, y)
assert t is not None
return t.string return t.string
def resolve_path(w, y=None): def resolve_path(w, y=None):
name = resolve_name(w) name = resolve_name(w)

View File

@ -8,6 +8,7 @@ DATATYPES = {
"path": None, "path": None,
"buffer": None, "buffer": None,
"method": None, "method": None,
"register": None,
"command": None, "command": None,
"shell": None, "shell": None,
"shellcommand": None, "shellcommand": None,
@ -16,8 +17,12 @@ DATATYPES = {
class MethodError(Exception): class MethodError(Exception):
pass 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): 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): default=default.none, load_default=False):
self.name = name self.name = name
self.type = type self.type = type
@ -72,7 +77,8 @@ class Method(object):
help = "" help = ""
def __init__(self): def __init__(self):
self.name = self._name() self.name = self._name()
self.help = self.__doc__ if self.__doc__:
self.help = self.__doc__
def _name(cls): def _name(cls):
s = cls.__name__ s = cls.__name__
@ -308,7 +314,7 @@ class DeleteRightSpace(Method):
class MetaX(Method): class MetaX(Method):
'''Invoke commands by name''' '''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): def _execute(self, w, **vargs):
name = vargs['method'] name = vargs['method']
if name in w.application.methods: if name in w.application.methods:
@ -704,7 +710,8 @@ class IndentBlock(Method):
class FileDiff(Method): class FileDiff(Method):
'''diff the buffer's contents with the given file''' '''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): def _execute(self, w, **vargs):
cmd = ("/usr/bin/diff", '-u', '-', vargs['path']) cmd = ("/usr/bin/diff", '-u', '-', vargs['path'])
pipe = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) pipe = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
@ -729,7 +736,7 @@ class FileDiff(Method):
class SetMode(Method): class SetMode(Method):
'''Set the mode of the current buffer''' '''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): def _execute(self, w, **vargs):
mode_name = vargs['mode'] mode_name = vargs['mode']
m = w.application.modes[mode_name](w) m = w.application.modes[mode_name](w)
@ -820,10 +827,11 @@ class CloseBracket(CloseTag):
mytag = ']' mytag = ']'
class RegisterSave(Method): class RegisterSave(Method):
MAX_TXT = 30
MAX_REG = 20
'''Save the top item of the kill stack into the named register''' '''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): def _pre_execute(self, w, **vargs):
if not w.has_kill(): if not w.has_kill():
raise MethodError, "No text on the kill stack" 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)) w.set_error('Saved %r into register %r' % (text, name))
class RegisterRestore(Method): class RegisterRestore(Method):
'''Push the value saved in the named register onto the kill stack'''
MAX_TXT = 30 MAX_TXT = 30
MAX_REG = 18 MAX_REG = 18
'''Push the value saved in the named register onto the kill stack''' args = [arg('name', dt="register", p="Register name: ",
args = [Argument('name', datatype="str", prompt="Register name: ")] h="Name of the register to use")]
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
name = vargs['name'] name = vargs['name']
if name not in w.application.registers: if name not in w.application.registers:
w.set_error('Register %r does not exist' % name) w.set_error('Register %r does not exist' % name)
return return
app = w.application
text = app.registers[name] text = app.registers[name]
w.push_kill(text) w.push_kill(text)
if len(text) > self.MAX_TXT: if len(text) > self.MAX_TXT:
text = text[0:self.MAX_TXT] + '...' text = text[0:self.MAX_TXT] + '...'
if len(name) > self.MAX_REG: if len(name) > self.MAX_REG:
name = name[0: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 import buffer, default, dirutil, regex, util, window
from point import Point from point import Point
from method import DATATYPES, Method, Argument, arg
from method import DATATYPES, Method, Argument
class OpenFile(Method): class OpenFile(Method):
'''Open file in a new buffer, or go to file's open buffer''' '''Open file in a new buffer, or go to file's open buffer'''
args = [Argument('filename', datatype="path", prompt="Open File: ", args = [arg('filename', dt="path", p="Open File: ", dv=default.path_dirname,
default=default.path_dirname, load_default=True)] ld=True, h="file to open")]
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
b = w.application.open_path(vargs['filename']) b = w.application.open_path(vargs['filename'])
SwitchBuffer().execute(w, buffername=b.name()) SwitchBuffer().execute(w, buffername=b.name())
class OpenAesFile(Method): class OpenAesFile(Method):
'''Open AES encrypted file in a new buffer, or go to file's open buffer''' '''Open AES encrypted file in a new buffer, or go to file's open buffer'''
args = [Argument('filename', datatype="path", prompt="Open AES File: "), args = [arg('filename', dt="path", p="Open AES File: ",
Argument('password', prompt="Use AES Password: ")] 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): def _execute(self, w, **vargs):
b = w.application.open_path(vargs['filename'], 'aes', vargs['password']) b = w.application.open_path(vargs['filename'], 'aes', vargs['password'])
SwitchBuffer().execute(w, buffername=b.name()) SwitchBuffer().execute(w, buffername=b.name())
@ -35,8 +36,8 @@ class ViewBufferParent(Method):
class SwitchBuffer(Method): class SwitchBuffer(Method):
'''Switch to a different''' '''Switch to a different'''
args = [Argument('buffername', datatype="buffer", prompt="Switch To Buffer: ", args = [arg('buffername', dt="buffer", p="Switch To Buffer: ",
default=default.last_buffer)] dv=default.last_buffer, h="name of the buffer to switch to")]
def _pre_execute(self, w, **vargs): def _pre_execute(self, w, **vargs):
a = w.application a = w.application
if len(a.bufferlist.buffers) < 1: if len(a.bufferlist.buffers) < 1:
@ -51,9 +52,9 @@ class SwitchBuffer(Method):
w.set_error("buffer %r was not found" % name) w.set_error("buffer %r was not found" % name)
class KillBuffer(Method): class KillBuffer(Method):
'''Close the current buffer''' '''Close the current buffer'''
force=False force = False
args = [Argument('buffername', datatype="buffer", prompt="Kill Buffer: ", args = [arg('buffername', dt="buffer", p="Kill Buffer: ",
default=default.current_buffer)] dv=default.current_buffer, h="name of the buffer to kill")]
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
name = vargs['buffername'] name = vargs['buffername']
a = w.application a = w.application
@ -85,9 +86,9 @@ class KillBuffer(Method):
a.set_error('Please type "yes" or "no"') a.set_error('Please type "yes" or "no"')
class ForceKillBuffer(KillBuffer): class ForceKillBuffer(KillBuffer):
'''Close the current buffer, automatically discarding any changes'''
force=True force=True
args = [Argument('buffername', datatype="buffer", prompt="Force Kill Buffer: ",
default=default.current_buffer)]
class ListBuffers(Method): class ListBuffers(Method):
'''List all open buffers in a new buffer''' '''List all open buffers in a new buffer'''
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
@ -98,8 +99,8 @@ class ListBuffers(Method):
w.application.data_buffer("*Buffers*", data, switch_to=True) w.application.data_buffer("*Buffers*", data, switch_to=True)
class SaveBufferAs(Method): class SaveBufferAs(Method):
'''Save the contents of a buffer to the specified path''' '''Save the contents of a buffer to the specified path'''
args = [Argument('path', datatype="path", prompt="Write file: ", args = [arg('path', dt="path", p="Write file: ", ld=True,
default=default.current_working_dir, load_default=True)] dv=default.current_working_dir, h="new path to use")]
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
curr_buffer = w.buffer curr_buffer = w.buffer
curr_buffer_name = curr_buffer.name() 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 import buffer, default, dirutil, regex, util, window
from point import Point from point import Point
from method import DATATYPES, Method, Argument from method import DATATYPES, Method, Argument, arg
class CvsCommit(Method): class CvsCommit(Method):
'''diff the current file with the version in CVS''' '''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.]+)$') regex = re.compile('^new revision: ([0-9.]+); previous revision: ([0-9.]+)$')
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
if not hasattr(w.buffer, 'path'): 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.application.data_buffer("*Diff*", data, switch_to=True, modename='diff')
w.set_error("Differences were found") w.set_error("Differences were found")
class CvsDiff2(Method): 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]+$') 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): def _execute(self, w, **vargs):
if not hasattr(w.buffer, 'path'): if not hasattr(w.buffer, 'path'):
w.set_error("Buffer has no corresponding file") w.set_error("Buffer has no corresponding file")
@ -149,8 +151,8 @@ class CvsDiff2(Method):
class CvsDiff3(Method): class CvsDiff3(Method):
'''diff the current file with the version in CVS''' '''diff the current file with the version in CVS'''
rev_regex = re.compile('^[0-9]+\.[0-9]+$') rev_regex = re.compile('^[0-9]+\.[0-9]+$')
args = [Argument("revision1", type=type(""), prompt="Old Revision: "), args = [arg("revision1", t=type(""), p="Old Revision: ", h='old revision number'),
Argument("revision2", type=type(""), prompt="New Revision: ")] arg("revision2", t=type(""), p="New Revision: ", h='new revision number')]
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
if not hasattr(w.buffer, 'path'): if not hasattr(w.buffer, 'path'):
w.set_error("Buffer has no corresponding file") w.set_error("Buffer has no corresponding file")

View File

@ -111,7 +111,7 @@ class GotoLine(Method):
w.goto_line(n) w.goto_line(n)
class ForwardLines(Method): 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: ")] args = [Argument("lineno", type=type(0), prompt="Forward lines: ")]
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
w.forward_lines(vargs["lineno"]) w.forward_lines(vargs["lineno"])

View File

@ -16,9 +16,13 @@ class Exec(Method):
except: except:
pass pass
(status, output) = commands.getstatusoutput(cmd) (status, output) = commands.getstatusoutput(cmd)
self._display(w, output, status, cmd)
def _display(self, w, data, status, cmd):
bufname = '*%s*' % self.name.title() 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) w.set_error("Shell exited with %d" % status)
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
if w.buffer.btype == 'dir': if w.buffer.btype == 'dir':
name = dirutil.resolve_name(w) name = dirutil.resolve_name(w)
@ -43,6 +47,11 @@ class Pipe(Method):
else: else:
return (None, None, False) 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): def _execute(self, w, **vargs):
(prog, cmd, shell) = self._parse(w, **vargs) (prog, cmd, shell) = self._parse(w, **vargs)
if prog is None or not cmd: if prog is None or not cmd:
@ -56,11 +65,9 @@ class Pipe(Method):
pipe.stdin.close() pipe.stdin.close()
outdata = pipe.stdout.read() outdata = pipe.stdout.read()
status = pipe.wait() >> 8 status = pipe.wait() >> 8
bufname = '*%s*' % self.name.title() self._display(w, outdata, status, prog, cmd, shell)
w.application.data_buffer(bufname, outdata, switch_to=True)
w.set_error("%s exited with status %d" % (prog, status))
class Grep(Pipe): class Grep(Pipe):
'''Grep the buffer's contents for instances of a pattern, and display them in a new buffer''' '''Grep the buffer's contents for instances of a pattern, and display them in a new buffer'''