mode documentation improvements; better diff; ideas

--HG--
branch : pmacs2
This commit is contained in:
moculus 2009-03-28 03:40:09 +00:00
parent abaaef7c83
commit a971586fed
5 changed files with 69 additions and 32 deletions

12
IDEAS
View File

@ -1,3 +1,15 @@
2009/03/27:
1. Create a Method attribute meaning should-appear-in-help-buffers. Use this to
hide actions that only make sense when the mini-buffer is open, as well as weird
actions like "text-insert-space"
2. Create a way to figure out what actions are legal in the various mini-buffer
modes (search, replace, whatever).
3. Maybe write a per-mode "how to use this mode" document that can be accessed
in a uniform way. This way, various non-discoverable features can be documented.
2009/02/15:
Remove $MODE.lib in favor of $MODE.libs[]

View File

@ -341,6 +341,7 @@ class UppercaseWord(Method):
w.insert_string(p1, word.upper())
class MetaX(Method):
'''Call pmacs functions by name (with or without arguments)'''
args = [arg('method', dt="method", p="M-x ", h='Method to execute')]
name_re = re.compile(r'[a-z0-9_-]+')
@ -572,6 +573,7 @@ class UncommentRegion(Method):
# wrapping/justifying/etc
class WrapLine(Method):
'''Wrap a line of text based on a predefined margin'''
limit = 80
space_re = re.compile(' +')
def _token_len(self, tokens):
@ -636,6 +638,7 @@ class WrapLine(Method):
w.goto(Point(x, y))
class WrapParagraph(Method):
'''Wrap contiguous lines of text based on a predefined margin'''
limit = 80
valid_re = re.compile('^( *)([^ ].*)$')
empty_re = regex.whitespace
@ -854,31 +857,40 @@ class IndentBlock(Method):
w.buffer.delete(Point(0, p1.y), Point(0, p2.y))
w.buffer.insert_string(Point(0, p1.y), '\n'.join(lines) + '\n')
class FileDiff(Method):
class Diff(Method):
'''diff the buffer's contents with the given file'''
args = [arg("path", t=type(""), p="Filename: ", dt='path',
h="path to diff against current buffer's contents")]
args = [arg("path1", t=type(""), p="Filename: ", dt='path', h="left path to diff"),
arg("path2", t=type(""), p="Filename: ", dt='path', h="right path to diff")]
def _get_cmd(self, w, **vargs):
return ("/usr/bin/diff", '-u', vargs['path1'], vargs['path2'])
def _pipe_write(self, pipe, w, **vargs):
pass
def _execute(self, w, **vargs):
cmd = ("/usr/bin/diff", '-u', '-', vargs['path'])
cmd = self._get_cmd(w, **vargs)
pipe = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
pid = pipe.pid
indata = w.buffer.make_string()
pipe.stdin.write(indata)
pipe.stdin.close()
self._pipe_write(pipe, w, **vargs)
outdata = pipe.stdout.read()
errdata = pipe.stderr.read()
status = pipe.wait() >> 8
status = pipe.wait()
if status == 0:
w.set_error("No difference found")
w.set_error("No difference found" + str(status))
elif status == 1:
w.application.data_buffer("*Diff*", outdata, switch_to=True, modename='diff')
w.set_error("Differences were found")
else:
w.application.data_buffer("*Diff*", errdata, switch_to=True)
w.set_error("There was an error: %d exited with status %s" % (pid, status))
w.set_error("There was an error: %d exited with status %s" % (pipe.pid, status))
class FileDiff(Diff):
'''diff the buffer's contents with the given file'''
args = [arg("path", t=type(""), p="Filename: ", dt='path',
h="path to diff against current buffer's contents")]
def _get_cmd(self, w, **vargs):
return ("/usr/bin/diff", '-u', '-', vargs['path'])
def _pipe_write(self, pipe, w, **vargs):
indata = w.buffer.make_string()
pipe.stdin.write(indata)
pipe.stdin.close()
class SetMode(Method):
'''Set the mode of the current buffer'''
@ -915,7 +927,8 @@ class UnsplitWindow(Method):
w.application.single_slot()
w.set_error('Window has been unsplit back to one window!')
class CloseTag(Method):
class CloseParen(Method):
'''Insert ), matching if applicable'''
mytag = ')'
def _execute(self, w, **vargs):
# first, de-reference some variables and actually do the insertion
@ -968,13 +981,10 @@ class CloseTag(Method):
y -= 1
i = len(tokens[y]) - 1
class CloseParen(CloseTag):
'''Insert ), matching if applicable'''
mytag = ')'
class CloseBrace(CloseTag):
class CloseBrace(CloseParen):
'''Insert }, matching if applicable'''
mytag = '}'
class CloseBracket(CloseTag):
class CloseBracket(CloseParen):
'''Insert ], matching if applicable'''
mytag = ']'
@ -982,8 +992,7 @@ class RegisterSave(Method):
'''Save the top item of the kill stack into the named register'''
MAX_TXT = 30
MAX_REG = 18
args = [arg('name', dt="register", p="Register name: ",
h="Name of the register to use")]
args = [arg('name', dt="register", p="Register name: ", h="Register name to use")]
def _pre_execute(self, w, **vargs):
if not w.has_kill():
raise MethodError("No text on the kill stack")
@ -998,11 +1007,10 @@ 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'''
'''Push the value of the named register onto the kill stack'''
MAX_TXT = 30
MAX_REG = 18
args = [arg('name', dt="register", p="Register name: ",
h="Name of the register to use")]
args = [arg('name', dt="register", p="Register name: ", h="Register name to use")]
def _execute(self, w, **vargs):
name = vargs['name']
if name not in w.application.registers:
@ -1018,8 +1026,8 @@ class RegisterRestore(Method):
w.set_error('Restored %r from register %r' % (text, name))
class GetConfigVariable(Method):
args = [arg('name', dt='config', p="Variable name: ",
h='Name of the configuration parameter')]
'''View the value of a particular config variables'''
args = [arg('name', dt='config', p="Config variable: ", h='Config variable name')]
def _execute(self, w, **vargs):
name = vargs['name']
if name in w.application.config:
@ -1029,6 +1037,7 @@ class GetConfigVariable(Method):
w.set_error("param %r is not set" % (name,))
class ViewConfigVariables(Method):
'''View the value of all config variables'''
def _execute(self, w, **vargs):
lines = ["APPLICATION CONFIGURATION VARIABLES\n"]
for name in w.application.config:
@ -1037,10 +1046,9 @@ class ViewConfigVariables(Method):
w.application.data_buffer('*Config*', data, switch_to=True)
class SetConfigVariable(Method):
args = [arg('name', dt='config', p="Variable name: ",
h='Name of the configuration parameter'),
arg('value', t=type(''), p="Variable value: ",
h='Configuration parameter value to use')]
'''Set a particular config variable to a value'''
args = [arg('name', dt='config', p="Variable name: ", h='Config variable name'),
arg('value', t=type(''), p="Variable value: ", h='Config variable value')]
def _execute(self, w, **vargs):
name = vargs['name']
found = name in w.application.config
@ -1055,6 +1063,7 @@ class SetConfigVariable(Method):
w.set_error("previously unset param %r set to %r" % (name, value))
class ToggleHeader(Method):
'''Toggle the visibility of the buffer header'''
def _execute(self, w, **vargs):
if w.mode.showing_header():
w.mode.disable_header()
@ -1063,7 +1072,9 @@ class ToggleHeader(Method):
w.mode.enable_header()
w.set_error('Header visible')
# TODO: rename to left-margin
class ToggleLineNumbers(Method):
'''Toggle the visibility of the left margin'''
def _execute(self, w, **vargs):
if w.mode.showing_line_numbers():
w.mode.disable_line_numbers()
@ -1073,12 +1084,14 @@ class ToggleLineNumbers(Method):
w.set_error('Line numbers visible')
class SetTabWidth(Method):
'''Set the tab-width for the current buffer'''
args = [arg('width', t=type(0), p="Tab Width: ", h='New tab width for buffer')]
def _execute(self, w, **vargs):
w.mode.tabwidth = vargs['width']
w.set_error('Tab width set to %d' % w.mode.tabwidth)
class SetModeTabWidth(Method):
'''Set the default tab-width for the current mode'''
args = [arg('mode', dt='mode', p="Mode: ", h=''),
arg('width', t=type(0), p="Default Tab Width: ", h='New default tab width for mode')]
def _execute(self, w, **vargs):

View File

@ -66,6 +66,7 @@ class AwkTabber(StackTabber2):
return t.name in ('spaces', 'eol', 'comment')
class AwkFilterFile(Exec):
'''Filter a file through the current buffer's AWK program'''
show_success = True
args = [arg('path', dt="path", p="Filter File: ", dv=default.path_dirname, ld=True, h="file to open")]
def _execute(self, w, **vargs):
@ -87,6 +88,7 @@ class AwkFilterFile(Exec):
w.set_error("awk exited with status %d" % status)
class AwkFilterBuffer(Pipe):
'''Filter a buffer through the current buffer's AWK program'''
args = [arg('name', dt="buffer", p="Filter Buffer: ", h="name of the buffer to switch to")]
def _execute(self, w, **vargs):
if not hasattr(w.buffer, 'path'):
@ -111,6 +113,7 @@ class AwkFilterBuffer(Pipe):
w.set_error("awk exited with status %d" % status)
class AwkFilterInput(Method):
'''Filter input through the current buffer's AWK program'''
args = [arg('input', p="Data To Filter: ", h="data to filter")]
def _execute(self, w, **vargs):
if not hasattr(w.buffer, 'path'):

View File

@ -6,6 +6,7 @@ from point import Point
subgroup_re = re.compile(r'((?:\\\\)*)\\(0|[1-9][0-9]*)')
class ReplaceOne(method.Method):
'In a replace command, replace the next occurance'
def execute(self, w, **vargs):
m = w.buffer.method
_replace(m)
@ -13,6 +14,7 @@ class ReplaceOne(method.Method):
_finish(m, w)
class ReplaceDone(method.Method):
'In a replace command, replace the next occurance and exit'
def execute(self, w, **vargs):
m = w.buffer.method
_replace(m)
@ -20,12 +22,14 @@ class ReplaceDone(method.Method):
w.set_error("Replace done")
class SkipReplace(method.Method):
'In a replace command, skip the next occurance'
def execute(self, w, **vargs):
m = w.buffer.method
_find_next(m, True)
_finish(m, w)
class ReplaceAll(method.Method):
'In a replace command, replace all remaining occurances'
def execute(self, w, **vargs):
m = w.buffer.method
while m.p1 is not None:
@ -35,6 +39,7 @@ class ReplaceAll(method.Method):
w.set_error("Replace ended")
class CancelReplace(method.Method):
'Cancel a currently running replace command'
def execute(self, w, **vargs):
_end(w)
w.set_error("Replace cancelled")

View File

@ -20,6 +20,7 @@ def _make_regex(w, s):
raise searchutil.IllegalPatternError("failed to compile: %r" % s)
class SearchNext(method.Method):
'In a search command, move to the next occurance'
def execute(self, w, **vargs):
w.buffer.method.direction = 'next'
s = w.buffer.make_string()
@ -34,6 +35,7 @@ class SearchNext(method.Method):
action.execute(w)
class SearchPrevious(method.Method):
'In a search command, move to the previous occurance'
def execute(self, w, **vargs):
w.buffer.method.direction = 'previous'
if not w.buffer.make_string():
@ -48,6 +50,7 @@ class SearchPrevious(method.Method):
w.application.clear_highlighted_ranges('search')
class EndSearch(method.Method):
'End the current search command, leaving the cursor in place'
def execute(self, w, **vargs):
old_w = w.buffer.method.old_window
old_c = w.buffer.method.old_cursor
@ -56,6 +59,7 @@ class EndSearch(method.Method):
w.set_error("Mark set to search start")
class CancelSearch(method.Method):
'End the current search command, restoring the cursor to the search start'
def execute(self, w, **vargs):
w.buffer.method.old_window.goto(w.buffer.method.old_cursor)
_end(w)