160 lines
5.4 KiB
Python
160 lines
5.4 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 mode.perl import PerlGrammar
|
|
from point import Point
|
|
|
|
PAD = ' '
|
|
LIMIT = 79
|
|
|
|
class IperlExec(method.Method):
|
|
def _execute(self, w, **vargs):
|
|
if w.application.completion_window_is_open():
|
|
w.application.close_completion_buffer()
|
|
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
|
|
b = w.mode._get_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)
|
|
|
|
b.pipe.stdin.write("ENTER:%s\n" % s)
|
|
b.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()
|
|
b = w.mode._get_iperl()
|
|
|
|
x2 = w.logical_cursor().x
|
|
if not s or s[:x2].isspace():
|
|
w.insert_string_at_cursor(' ' * w.mode.tabwidth)
|
|
return
|
|
|
|
r = re.compile('^[a-zA-Z0-9_:$@*&%]$')
|
|
line = s
|
|
x1 = x2
|
|
while x1 > 0 and r.match(s[x1 - 1]):
|
|
x1 -= 1
|
|
word = line[x1:x2]
|
|
|
|
b.pipe.stdin.write("COMPLETE:%d:%d:%s\n" % (x1, x2, s))
|
|
b.pipe.stdin.flush()
|
|
(typ_, value) = w.mode._readline()
|
|
assert typ_ == 'COMPLETIONS', '%r %r' % (typ_, value)
|
|
|
|
candidates = [x for x in value.split('|') if x]
|
|
w.mode._read()
|
|
|
|
if candidates:
|
|
s = completer.find_common_string(candidates)
|
|
w.buffer.delete(Point(x1, 0), Point(x2, 0), force=True)
|
|
w.insert_string_at_cursor(s)
|
|
mode.mini.use_completion_window(a, s, candidates)
|
|
|
|
class IperlPathStart(method.Method):
|
|
'''Interactively run perl statements in the context of a buffer'''
|
|
def _start(self, w, parent):
|
|
a = w.application
|
|
if w.buffer.btype == 'iperl':
|
|
b = w.buffer
|
|
else:
|
|
name = buffer.IperlBuffer.create_name(parent)
|
|
if not a.has_buffer_name(name):
|
|
b = buffer.IperlBuffer(parent, a)
|
|
a.add_buffer(b)
|
|
window.Window(b, a)
|
|
else:
|
|
b = a.get_buffer_by_name(name)
|
|
self.main_buffer = b
|
|
if a.window().buffer is not b:
|
|
a.switch_buffer(b)
|
|
f = lambda x: None
|
|
w.application.open_mini_buffer('*** ', f, self, None, 'iperlmini')
|
|
def execute(self, w, **vargs):
|
|
self._start(w, w.buffer)
|
|
|
|
class IperlStart(IperlPathStart):
|
|
'''Interactively run perl statements'''
|
|
def execute(self, w, **vargs):
|
|
self._start(w, None)
|
|
|
|
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, IperlPathStart,
|
|
IperlPageUp, IperlPageDown, IperlGotoBeginning, IperlGotoEnd]
|
|
readre = re.compile('^([A-Z]+):(.*)\n$')
|
|
def _readline(self):
|
|
b = self._get_iperl()
|
|
line = b.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):
|
|
b = self._get_iperl()
|
|
output = []
|
|
while True:
|
|
(type_, value) = self._readline()
|
|
if type_ == 'PROMPT':
|
|
b.prompt = value.strip() + ' '
|
|
self.window.application.set_mini_buffer_prompt(b.prompt)
|
|
break
|
|
value.rstrip()
|
|
if value:
|
|
output.append(value)
|
|
if output:
|
|
return '\n'.join(output) + '\n'
|
|
else:
|
|
return ''
|
|
|
|
def _get_iperl(self):
|
|
a = self.window.application
|
|
if not a.has_buffer_name('*IPerl*'):
|
|
b = buffer.IperlBuffer(None)
|
|
a.add_buffer(b)
|
|
window.Window(b, a)
|
|
else:
|
|
b = a.bufferlist.get_buffer_by_name('*IPerl*')
|
|
return b
|
|
|
|
def __init__(self, w):
|
|
mode.Fundamental.__init__(self, w)
|
|
self.history = ['']
|
|
self.hindex = 0
|
|
b = self._get_iperl()
|
|
w.application.set_mini_buffer_prompt(b.prompt)
|
|
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', 'UP'))
|
|
self.add_bindings('console-history-next', ('C-n', 'DOWN'))
|
|
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
|