168 lines
6.3 KiB
Python
168 lines
6.3 KiB
Python
import code, re, string, StringIO, sys, traceback
|
|
import buffer, color, completer, lex, method, mode, mode.mini, mode.consolemini, window
|
|
from subprocess import Popen, PIPE, STDOUT
|
|
#from lex import Grammar, PatternRule
|
|
from mode.perl import PerlGrammar
|
|
from point import Point
|
|
|
|
PAD = ' '
|
|
LIMIT = 79
|
|
|
|
class IperlExec(method.Method):
|
|
def _execute(self, w, **vargs):
|
|
s = w.buffer.make_string()
|
|
w.mode.history[-1] = s
|
|
w.mode.history.append('')
|
|
w.buffer.set_data('')
|
|
w.mode.hindex = len(w.mode.history) - 1
|
|
|
|
a = w.application
|
|
if not a.has_buffer_name('*IPerl*'):
|
|
raise Exception, "No iperl found!"
|
|
b = a.bufferlist.get_buffer_by_name('*IPerl*')
|
|
if a.window().buffer is not b:
|
|
a.switch_buffer(b)
|
|
p = a.get_mini_buffer_prompt()
|
|
b.insert_string(b.get_buffer_end(), p + s + '\n', force=True)
|
|
|
|
w.mode.pipe.stdin.write("ENTER:%s\n" % s)
|
|
w.mode.pipe.stdin.flush()
|
|
output = w.mode._read()
|
|
b.insert_string(b.get_buffer_end(), output, force=True)
|
|
|
|
class IperlTab(method.Method):
|
|
def execute(self, w, **vargs):
|
|
a = w.application
|
|
s = w.buffer.make_string()
|
|
|
|
x = w.logical_cursor().x
|
|
if not s or s[:x].isspace():
|
|
w.insert_string_at_cursor(' ' * w.mode.tabwidth)
|
|
return
|
|
|
|
l = lex.Lexer(w.mode, PerlGrammar)
|
|
tokens = list(l.lex([s]))
|
|
|
|
t = None
|
|
for t2 in tokens:
|
|
if t2.x < x and t2.end_x() >= x:
|
|
t = t2
|
|
break
|
|
if t is None:
|
|
return
|
|
|
|
s = t.string
|
|
w.mode.pipe.stdin.write("COMPLETE:%s\n" % s)
|
|
w.mode.pipe.stdin.flush()
|
|
(typ_, value) = w.mode._readline()
|
|
assert typ_ == 'COMPLETIONS'
|
|
|
|
candidates = [x for x in value.split('|') if x]
|
|
w.mode._read()
|
|
|
|
if candidates:
|
|
s = completer.find_common_string(candidates)
|
|
w.buffer.delete(Point(t.x, 0), Point(t.end_x(), 0), force=True)
|
|
w.insert_string_at_cursor(s)
|
|
mode.mini.use_completion_window(a, s, candidates)
|
|
|
|
class IperlStart(method.Method):
|
|
'''Evaluate python expressions (for advanced use and debugging only)'''
|
|
def execute(self, w, **vargs):
|
|
a = w.application
|
|
if not a.has_buffer_name('*IPerl*'):
|
|
b = buffer.IperlBuffer()
|
|
a.add_buffer(b)
|
|
window.Window(b, a)
|
|
b = a.bufferlist.get_buffer_by_name('*IPerl*')
|
|
if a.window().buffer is not b:
|
|
a.switch_buffer(b)
|
|
f = lambda x: None
|
|
w.application.open_mini_buffer('*** ', f, self, None, 'iperlmini')
|
|
|
|
class IperlPageUp(mode.consolemini.ConsolePageUp):
|
|
subbuf = '*IPerl*'
|
|
class IperlPageDown(mode.consolemini.ConsolePageDown):
|
|
subbuf = '*IPerl*'
|
|
class IperlGotoBeginning(mode.consolemini.ConsoleGotoBeginning):
|
|
subbuf = '*IPerl*'
|
|
class IperlGotoEnd(mode.consolemini.ConsoleGotoEnd):
|
|
subbuf = '*IPerl*'
|
|
|
|
class IperlMini(mode.Fundamental):
|
|
modename = 'IperlMini'
|
|
actions = [IperlExec, IperlTab, IperlStart,
|
|
IperlPageUp, IperlPageDown, IperlGotoBeginning, IperlGotoEnd]
|
|
readre = re.compile('^([A-Z]+):(.*)\n$')
|
|
def _readline(self):
|
|
line = self.pipe.stdout.readline()
|
|
m = self.readre.match(line)
|
|
if m:
|
|
return (m.group(1), m.group(2))
|
|
else:
|
|
return ('RAW', line.rstrip())
|
|
def _read(self):
|
|
output = []
|
|
while True:
|
|
(type_, value) = self._readline()
|
|
if type_ == 'PROMPT':
|
|
self.window.application.set_mini_buffer_prompt(value + ' ')
|
|
break
|
|
elif type_ in ('ERROR', 'RESULT'):
|
|
output.append(value.replace('\\n', '\n').replace('\\\\', '\\'))
|
|
elif type_ == 'RAW':
|
|
output.append(value)
|
|
return '\n'.join(output) + '\n'
|
|
|
|
def __init__(self, w):
|
|
mode.Fundamental.__init__(self, w)
|
|
self.bindings = {}
|
|
self.history = ['']
|
|
self.hindex = 0
|
|
|
|
cmd = ('iperl', '-p')
|
|
self.pipe = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
|
|
(type_, value) = self._readline()
|
|
assert type_ == 'PROMPT', type_
|
|
w.application.set_mini_buffer_prompt('%s ' % value.strip())
|
|
|
|
self.add_bindings('start-of-line', ('C-a', 'HOME',))
|
|
self.add_bindings('end-of-line', ('C-e', 'END',))
|
|
self.add_bindings('backward', ('C-b', 'L_ARROW',))
|
|
self.add_bindings('forward', ('C-f', 'R_ARROW',))
|
|
self.add_bindings('delete-left', ('DELETE', 'BACKSPACE',))
|
|
self.add_bindings('delete-left-word', ('M-DELETE', 'M-BACKSPACE',))
|
|
self.add_bindings('delete-right', ('C-d',))
|
|
self.add_bindings('delete-right-word', ('M-d',))
|
|
self.add_bindings('kill-region', ('C-w',))
|
|
self.add_bindings('copy-region', ('M-w',))
|
|
self.add_bindings('kill', ('C-k',))
|
|
self.add_bindings('copy', ('M-k',))
|
|
self.add_bindings('yank', ('C-y',))
|
|
self.add_bindings('pop-kill', ('M-y',))
|
|
self.add_bindings('right-word', ('M-f',))
|
|
self.add_bindings('left-word', ('M-b',))
|
|
self.add_bindings('set-mark', ('C-@',))
|
|
self.add_bindings('switch-mark', ('C-x C-x',))
|
|
self.add_bindings('undo', ('C-/', 'C-x u',))
|
|
self.add_bindings('redo', ('M-/', 'M-_', 'C-x r',))
|
|
self.add_bindings('toggle-margins', ('M-m',))
|
|
self.add_bindings('transpose-words', ('M-t',))
|
|
self.add_bindings('delete-left-whitespace', ('C-c DELETE', 'C-c BACKSPACE',))
|
|
self.add_bindings('delete-right-whitespace', ('C-c d',))
|
|
self.add_bindings('insert-space', ('SPACE',))
|
|
self.add_bindings('iperl-exec', ('RETURN',))
|
|
self.add_bindings('console-clear', ('C-l',))
|
|
self.add_bindings('console-cancel', ('C-]',))
|
|
self.add_bindings('console-history-prev', ('C-p',))
|
|
self.add_bindings('console-history-next', ('C-n',))
|
|
self.add_bindings('iperl-tab', ('TAB',))
|
|
self.add_bindings('iperl-page-up', ('M-v',))
|
|
self.add_bindings('iperl-page-down', ('C-v',))
|
|
self.add_bindings('iperl-goto-beginning', ('M-<',))
|
|
self.add_bindings('iperl-goto-end', ('M->',))
|
|
for c in string.letters + string.digits + string.punctuation:
|
|
self.add_binding('insert-string-%s' % c, c)
|
|
|
|
install = IperlMini.install
|