parent
79f120d089
commit
93ca1881bf
|
@ -3,7 +3,8 @@ import curses, curses.ascii, getpass, os, re, string, sys, termios, time
|
||||||
import traceback
|
import traceback
|
||||||
from subprocess import Popen, PIPE, STDOUT
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
|
|
||||||
import buffer, bufferlist, color, completer, keyinput, method, minibuffer, mode
|
import buffer, buffer.about, buffer.color
|
||||||
|
import bufferlist, color, completer, keyinput, method, minibuffer, mode
|
||||||
import util, window
|
import util, window
|
||||||
from point import Point
|
from point import Point
|
||||||
|
|
||||||
|
@ -134,7 +135,7 @@ class Application(object):
|
||||||
'latex', 'insertmini', 'conf', 'haskell', 'erlang',
|
'latex', 'insertmini', 'conf', 'haskell', 'erlang',
|
||||||
'iperl', 'iperlmini', 'ipython', 'ipythonmini', 'awk',
|
'iperl', 'iperlmini', 'ipython', 'ipythonmini', 'awk',
|
||||||
'bds', #XYZ
|
'bds', #XYZ
|
||||||
'shell', 'shellmini', 'fstab', 'yacc',
|
'shell', 'shellmini', 'fstab', 'yacc', 'pipe',
|
||||||
)
|
)
|
||||||
for name in names:
|
for name in names:
|
||||||
exec("import mode.%s; mode.%s.install(self)" % (name, name))
|
exec("import mode.%s; mode.%s.install(self)" % (name, name))
|
||||||
|
@ -161,8 +162,7 @@ class Application(object):
|
||||||
|
|
||||||
# initialize our buffers
|
# initialize our buffers
|
||||||
# note that the first buffer in buffers will be initially visible
|
# note that the first buffer in buffers will be initially visible
|
||||||
buffers.append(buffer.AboutBuffer())
|
buffers.append(buffer.about.AboutBuffer())
|
||||||
buffers.append(buffer.ScratchBuffer())
|
|
||||||
buffers.append(buffer.ConsoleBuffer())
|
buffers.append(buffer.ConsoleBuffer())
|
||||||
|
|
||||||
if self.rcerror:
|
if self.rcerror:
|
||||||
|
@ -478,7 +478,7 @@ class Application(object):
|
||||||
if self.has_buffer_name(name):
|
if self.has_buffer_name(name):
|
||||||
b = self.bufferlist.buffer_names[name]
|
b = self.bufferlist.buffer_names[name]
|
||||||
self.remove_buffer(b)
|
self.remove_buffer(b)
|
||||||
b = buffer.ColorDataBuffer(name, data)
|
b = buffer.color.ColorDataBuffer(name, data)
|
||||||
if modename is not None:
|
if modename is not None:
|
||||||
b.modename = modename
|
b.modename = modename
|
||||||
window.Window(b, self, height=0, width=0)
|
window.Window(b, self, height=0, width=0)
|
||||||
|
|
|
@ -354,21 +354,6 @@ class Buffer(object):
|
||||||
# should not happen
|
# should not happen
|
||||||
raise Exception, "iiiijjjj"
|
raise Exception, "iiiijjjj"
|
||||||
|
|
||||||
# scratch is a singleton
|
|
||||||
scratch = None
|
|
||||||
class ScratchBuffer(Buffer):
|
|
||||||
btype = 'scratch'
|
|
||||||
def __new__(cls, *args, **kwargs):
|
|
||||||
global scratch
|
|
||||||
if scratch is None:
|
|
||||||
scratch = object.__new__(ScratchBuffer, *args, **kwargs)
|
|
||||||
return scratch
|
|
||||||
def name(self):
|
|
||||||
return "*Scratch*"
|
|
||||||
def close(self):
|
|
||||||
global scratch
|
|
||||||
scratch = None
|
|
||||||
|
|
||||||
class DataBuffer(Buffer):
|
class DataBuffer(Buffer):
|
||||||
btype = 'data'
|
btype = 'data'
|
||||||
def __init__(self, name, data):
|
def __init__(self, name, data):
|
||||||
|
@ -533,122 +518,6 @@ class IpythonBuffer(InterpreterBuffer):
|
||||||
class BinaryDataException(Exception):
|
class BinaryDataException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class PipeBuffer(Buffer):
|
|
||||||
btype = 'pipe'
|
|
||||||
terms = {
|
|
||||||
'dumb': term.Dumb,
|
|
||||||
'xterm': term.XTerm,
|
|
||||||
}
|
|
||||||
modename = 'colortext'
|
|
||||||
def __init__(self, cmd, args, name=None, term='dumb'):
|
|
||||||
Buffer.__init__(self)
|
|
||||||
self.cmd = cmd
|
|
||||||
if name:
|
|
||||||
self._name = name
|
|
||||||
else:
|
|
||||||
self._name = '*Pipe*'
|
|
||||||
|
|
||||||
self.term = self.terms[term]()
|
|
||||||
self._pid, self._pty = pty.fork()
|
|
||||||
if self._pid == 0:
|
|
||||||
os.execve(cmd, [cmd] + args, {'TERM': self.term.name})
|
|
||||||
|
|
||||||
self._lock = threading.Lock()
|
|
||||||
self._towrite = ''
|
|
||||||
self._done = False
|
|
||||||
self._set_nonblock(self._pty)
|
|
||||||
self._thread = threading.Thread(target=self.pipe_read)
|
|
||||||
self._thread.setDaemon(True)
|
|
||||||
self._thread.start()
|
|
||||||
|
|
||||||
def _set_nonblock(self, fd):
|
|
||||||
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
|
|
||||||
fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NDELAY)
|
|
||||||
|
|
||||||
def _filter_output(self, output):
|
|
||||||
output2 = []
|
|
||||||
i = 0
|
|
||||||
escaped = []
|
|
||||||
for c in output:
|
|
||||||
if escaped:
|
|
||||||
escaped.append(c)
|
|
||||||
if c == 'm':
|
|
||||||
escaped = []
|
|
||||||
elif c == '\x1b':
|
|
||||||
escaped.append(c)
|
|
||||||
elif c == '\n':
|
|
||||||
output2.append(c)
|
|
||||||
i = 0
|
|
||||||
elif c == '\t':
|
|
||||||
j = i % 8
|
|
||||||
output2.append(' ' * (8 - j))
|
|
||||||
i += 8 - j
|
|
||||||
elif c == '\a':
|
|
||||||
pass
|
|
||||||
elif c == '\b':
|
|
||||||
if i > 0:
|
|
||||||
output2.pop(-1)
|
|
||||||
i -= 1
|
|
||||||
else:
|
|
||||||
output2.append(c)
|
|
||||||
i += 1
|
|
||||||
return ''.join(output2)
|
|
||||||
|
|
||||||
def pipe_read(self):
|
|
||||||
fd = self._pty
|
|
||||||
while not self._done:
|
|
||||||
if self._towrite:
|
|
||||||
ifd, ofd, efd = select.select([fd], [fd], [fd], 0.1)
|
|
||||||
else:
|
|
||||||
ifd, ofd, efd = select.select([fd], [], [fd], 0.1)
|
|
||||||
if ifd:
|
|
||||||
data = os.read(ifd[0], 1024)
|
|
||||||
end = self.get_buffer_end()
|
|
||||||
data = self.term.filter(data)
|
|
||||||
self.insert_string(end, data, force=True, act=ACT_NONE)
|
|
||||||
if ofd:
|
|
||||||
self._lock.acquire()
|
|
||||||
n = os.write(ofd[0], self._towrite)
|
|
||||||
self._towrite = self._towrite[n:]
|
|
||||||
self._lock.release()
|
|
||||||
if efd:
|
|
||||||
raise Exception, "exception is ready: %s" % repr(efd)
|
|
||||||
os.close(fd)
|
|
||||||
|
|
||||||
def pipe_write(self, s):
|
|
||||||
self._lock.acquire()
|
|
||||||
self._towrite += s
|
|
||||||
self._lock.release()
|
|
||||||
|
|
||||||
def insert_string(self, p, s, act=ACT_NORM, force=False):
|
|
||||||
lines = s.split("\n")
|
|
||||||
self.insert_lines(p, lines, act, force)
|
|
||||||
|
|
||||||
def insert_lines(self, p, lines, act=ACT_NORM, force=False):
|
|
||||||
llen = len(lines)
|
|
||||||
assert llen > 0
|
|
||||||
if not force and self.readonly():
|
|
||||||
raise ReadOnlyError("buffer is read-only")
|
|
||||||
p2 = p.vadd(len(lines[-1]), llen - 1)
|
|
||||||
if llen > 1:
|
|
||||||
self.lines.insert(p.y + 1, [])
|
|
||||||
self.lines[p.y + 1] = lines[-1] + self.lines[p.y][p.x:]
|
|
||||||
self.lines[p.y] = self.lines[p.y][:p.x] + lines[0]
|
|
||||||
for i in range(1, llen - 1):
|
|
||||||
self.lines.insert(p.y + i, lines[i])
|
|
||||||
else:
|
|
||||||
self.lines[p.y] = self.lines[p.y][:p.x] + lines[-1] + self.lines[p.y][p.x:]
|
|
||||||
self._region_add(p, p2, lines, act)
|
|
||||||
self.modified = True
|
|
||||||
|
|
||||||
def name(self): return self._name
|
|
||||||
def changed(self): return False
|
|
||||||
def readonly(self): return True
|
|
||||||
def undo(self, move, act): raise Exception, "invalid"
|
|
||||||
def redo(self, move, act): raise Exception, "invalid"
|
|
||||||
def reload(self): raise Exception, "invalid"
|
|
||||||
def close(self): raise Exception, "invalid"
|
|
||||||
|
|
||||||
class FileBuffer(Buffer):
|
class FileBuffer(Buffer):
|
||||||
btype = 'file'
|
btype = 'file'
|
||||||
def __init__(self, path, name=None):
|
def __init__(self, path, name=None):
|
||||||
|
@ -946,120 +815,3 @@ class PathListBuffer(DirBuffer):
|
||||||
return name
|
return name
|
||||||
def name(self):
|
def name(self):
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
# NOTE: this highlighter will not reprocess the data given. it is intended to
|
|
||||||
# be used with read-only buffers like DataBuffer and ColorBuffer
|
|
||||||
class ColorHighlighter(highlight.Highlighter):
|
|
||||||
color_re = re.compile(r'\[([a-zA-Z0-9\*:]+)\]')
|
|
||||||
color_map = {
|
|
||||||
'B': 'black',
|
|
||||||
'r': 'red',
|
|
||||||
'g': 'green',
|
|
||||||
'y': 'yellow',
|
|
||||||
'b': 'blue',
|
|
||||||
'm': 'magenta',
|
|
||||||
'c': 'cyan',
|
|
||||||
'w': 'white',
|
|
||||||
'd': 'default',
|
|
||||||
'*': 'bold',
|
|
||||||
}
|
|
||||||
def __init__(self):
|
|
||||||
self.tokens = []
|
|
||||||
def append_token(self, y, x, s, color):
|
|
||||||
s2 = s.replace('\\[', '[')
|
|
||||||
s2 = s2.replace('\\]', ']')
|
|
||||||
s2 = s2.replace('\\\\', '\\')
|
|
||||||
t = lex.Token('color_data', None, y, x, s2, color)
|
|
||||||
self.tokens[y].append(t)
|
|
||||||
return len(s) - len(s2)
|
|
||||||
def delete_token(self, y, i):
|
|
||||||
pass
|
|
||||||
def relex(self, lines, y1, x1, y2, x2, token=None):
|
|
||||||
pass
|
|
||||||
def relex_del(self, lines, y1, x1, y2, x2):
|
|
||||||
pass
|
|
||||||
def highlight(self, lines):
|
|
||||||
if self.tokens:
|
|
||||||
return
|
|
||||||
self.tokens = [[] for l in lines]
|
|
||||||
#self.tokens = [None] * len(lines)
|
|
||||||
for y in range(0, len(lines)):
|
|
||||||
self.tokens[y] = []
|
|
||||||
line = lines[y]
|
|
||||||
c = ['default', 'default']
|
|
||||||
i = 0
|
|
||||||
offset = 0
|
|
||||||
while i < len(line):
|
|
||||||
m = self.color_re.search(line, i)
|
|
||||||
if m:
|
|
||||||
(j, k) = (m.start(), m.end())
|
|
||||||
if j > i:
|
|
||||||
offset += self.append_token(y, i - offset, line[i:j], c)
|
|
||||||
fields = m.group(1).split(':')
|
|
||||||
c = [self.color_map.get(x, x) for x in fields]
|
|
||||||
offset += k - j
|
|
||||||
i = k
|
|
||||||
else:
|
|
||||||
offset += self.append_token(y, i - offset, line[i:], c)
|
|
||||||
break
|
|
||||||
|
|
||||||
class ColorDataBuffer(DataBuffer):
|
|
||||||
btype = 'colordata'
|
|
||||||
modename = 'colortext'
|
|
||||||
color_re = re.compile(r'\[([a-z:]+)\]')
|
|
||||||
def _highlight(self, data):
|
|
||||||
data2 = ColorHighlighter.color_re.sub('', data)
|
|
||||||
data2 = data2.replace('\\[', '[')
|
|
||||||
data2 = data2.replace('\\]', ']')
|
|
||||||
data2 = data2.replace('\\\\', '\\')
|
|
||||||
Buffer.set_data(self, data2, force=True)
|
|
||||||
lines = data.split(self.nl)
|
|
||||||
self.highlights = {'Colortext': ColorHighlighter()}
|
|
||||||
self.highlights['Colortext'].highlight(lines)
|
|
||||||
self.modified = False
|
|
||||||
def __init__(self, name, data):
|
|
||||||
DataBuffer.__init__(self, name, '')
|
|
||||||
self._highlight(data)
|
|
||||||
def set_data(self, data, force=True):
|
|
||||||
self._highlight(data)
|
|
||||||
|
|
||||||
ABOUT_DATA = '''
|
|
||||||
[r:d:*]===============================================================================
|
|
||||||
|
|
||||||
[y:d:*]************ ********** ****** ****** **** ******** *********
|
|
||||||
[y:d:*]************** ****************** ************* ********** ***********
|
|
||||||
[y:d:*]******* ***** ****** ***** **** **** ****** **** **** ***** ***
|
|
||||||
[y:d:*] *** *** *** *** *** **** **** **** *******
|
|
||||||
[y:d:*] *** *** *** *** *** **** **** **** ******
|
|
||||||
[y:d:*] ***** ***** ***** ***** **** **** ****** **** **** **** ****
|
|
||||||
[y:d:*] ************ ***** ***** **** ************* ********** **********
|
|
||||||
[y:d:*] ********** ***** ***** **** ****** **** ******** ********
|
|
||||||
[y:d:*] ***
|
|
||||||
[y:d:*] *** [c:d:*]pmacs[d:d:*] is a python-based text editor by [c:d:*]Erik Osheim[d:d:*], [b:d:*](c) 2005-2008
|
|
||||||
[y:d:*] *** [c:d:*]pmacs[d:d:*] is available to you under the [c:d:*]GNU General Public License v2
|
|
||||||
[y:d:*]*****
|
|
||||||
[y:d:*]***** [d:d:*]to view available commands use [c:d:*]C-c M-h [b:d:*](show-bindings-buffer)
|
|
||||||
[y:d:*]***** [d:d:*]open files with [c:d:*]C-x C-f[d:d:*]; save with [c:d:*]C-x C-s[d:d:*]; quit with [c:d:*]C-x C-c
|
|
||||||
|
|
||||||
[r:d:*]===============================================================================
|
|
||||||
'''
|
|
||||||
class AboutBuffer(ColorDataBuffer):
|
|
||||||
def __init__(self):
|
|
||||||
ColorDataBuffer.__init__(self, '*About*', ABOUT_DATA)
|
|
||||||
|
|
||||||
class ShellBuffer(Buffer):
|
|
||||||
btype = 'shell'
|
|
||||||
modename = 'shell'
|
|
||||||
def __init__(self):
|
|
||||||
Buffer.__init__(self)
|
|
||||||
self.clear()
|
|
||||||
def clear(self):
|
|
||||||
lines = ['=== Shell Console\n',
|
|
||||||
"=== Bash your brains out!\n"]
|
|
||||||
self.set_data(''.join(lines), force=True)
|
|
||||||
def name(self):
|
|
||||||
return '*Shell*'
|
|
||||||
def changed(self):
|
|
||||||
return False
|
|
||||||
def readonly(self):
|
|
||||||
return True
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
from buffer.color import ColorDataBuffer
|
||||||
|
|
||||||
|
_data = '''
|
||||||
|
[r:d:*]===============================================================================
|
||||||
|
|
||||||
|
[y:d:*]************ ********** ****** ****** **** ******** *********
|
||||||
|
[y:d:*]************** ****************** ************* ********** ***********
|
||||||
|
[y:d:*]******* ***** ****** ***** **** **** ****** **** **** ***** ***
|
||||||
|
[y:d:*] *** *** *** *** *** **** **** **** *******
|
||||||
|
[y:d:*] *** *** *** *** *** **** **** **** ******
|
||||||
|
[y:d:*] ***** ***** ***** ***** **** **** ****** **** **** **** ****
|
||||||
|
[y:d:*] ************ ***** ***** **** ************* ********** **********
|
||||||
|
[y:d:*] ********** ***** ***** **** ****** **** ******** ********
|
||||||
|
[y:d:*] ***
|
||||||
|
[y:d:*] *** [c:d:*]pmacs[d:d:*] is a python-based text editor by [c:d:*]Erik Osheim[d:d:*], [b:d:*](c) 2005-2008
|
||||||
|
[y:d:*] *** [c:d:*]pmacs[d:d:*] is available to you under the [c:d:*]GNU General Public License v2
|
||||||
|
[y:d:*]*****
|
||||||
|
[y:d:*]***** [d:d:*]to view available commands use [c:d:*]C-c M-h [b:d:*](show-bindings-buffer)
|
||||||
|
[y:d:*]***** [d:d:*]open files with [c:d:*]C-x C-f[d:d:*]; save with [c:d:*]C-x C-s[d:d:*]; quit with [c:d:*]C-x C-c
|
||||||
|
|
||||||
|
[r:d:*]===============================================================================
|
||||||
|
'''
|
||||||
|
class AboutBuffer(ColorDataBuffer):
|
||||||
|
def __init__(self):
|
||||||
|
ColorDataBuffer.__init__(self, '*About*', _data)
|
|
@ -0,0 +1,80 @@
|
||||||
|
import re
|
||||||
|
import lex
|
||||||
|
from buffer import Buffer, DataBuffer
|
||||||
|
from highlight import Highlighter
|
||||||
|
|
||||||
|
# NOTE: this highlighter will not reprocess the data given. it is intended to
|
||||||
|
# be used with read-only buffers like DataBuffer and ColorBuffer
|
||||||
|
class ColorHighlighter(Highlighter):
|
||||||
|
color_re = re.compile(r'\[([a-zA-Z0-9\*:]+)\]')
|
||||||
|
color_map = {
|
||||||
|
'B': 'black',
|
||||||
|
'r': 'red',
|
||||||
|
'g': 'green',
|
||||||
|
'y': 'yellow',
|
||||||
|
'b': 'blue',
|
||||||
|
'm': 'magenta',
|
||||||
|
'c': 'cyan',
|
||||||
|
'w': 'white',
|
||||||
|
'd': 'default',
|
||||||
|
'*': 'bold',
|
||||||
|
}
|
||||||
|
def __init__(self):
|
||||||
|
self.tokens = []
|
||||||
|
def append_token(self, y, x, s, color):
|
||||||
|
s2 = s.replace('\\[', '[')
|
||||||
|
s2 = s2.replace('\\]', ']')
|
||||||
|
s2 = s2.replace('\\\\', '\\')
|
||||||
|
t = lex.Token('color_data', None, y, x, s2, color)
|
||||||
|
self.tokens[y].append(t)
|
||||||
|
return len(s) - len(s2)
|
||||||
|
def delete_token(self, y, i):
|
||||||
|
pass
|
||||||
|
def relex(self, lines, y1, x1, y2, x2, token=None):
|
||||||
|
pass
|
||||||
|
def relex_del(self, lines, y1, x1, y2, x2):
|
||||||
|
pass
|
||||||
|
def highlight(self, lines):
|
||||||
|
if self.tokens:
|
||||||
|
return
|
||||||
|
self.tokens = [[] for l in lines]
|
||||||
|
#self.tokens = [None] * len(lines)
|
||||||
|
for y in range(0, len(lines)):
|
||||||
|
self.tokens[y] = []
|
||||||
|
line = lines[y]
|
||||||
|
c = ['default', 'default']
|
||||||
|
i = 0
|
||||||
|
offset = 0
|
||||||
|
while i < len(line):
|
||||||
|
m = self.color_re.search(line, i)
|
||||||
|
if m:
|
||||||
|
(j, k) = (m.start(), m.end())
|
||||||
|
if j > i:
|
||||||
|
offset += self.append_token(y, i - offset, line[i:j], c)
|
||||||
|
fields = m.group(1).split(':')
|
||||||
|
c = [self.color_map.get(x, x) for x in fields]
|
||||||
|
offset += k - j
|
||||||
|
i = k
|
||||||
|
else:
|
||||||
|
offset += self.append_token(y, i - offset, line[i:], c)
|
||||||
|
break
|
||||||
|
|
||||||
|
class ColorDataBuffer(DataBuffer):
|
||||||
|
btype = 'colordata'
|
||||||
|
modename = 'colortext'
|
||||||
|
color_re = re.compile(r'\[([a-z:]+)\]')
|
||||||
|
def _highlight(self, data):
|
||||||
|
data2 = ColorHighlighter.color_re.sub('', data)
|
||||||
|
data2 = data2.replace('\\[', '[')
|
||||||
|
data2 = data2.replace('\\]', ']')
|
||||||
|
data2 = data2.replace('\\\\', '\\')
|
||||||
|
Buffer.set_data(self, data2, force=True)
|
||||||
|
lines = data.split(self.nl)
|
||||||
|
self.highlights = {'Colortext': ColorHighlighter()}
|
||||||
|
self.highlights['Colortext'].highlight(lines)
|
||||||
|
self.modified = False
|
||||||
|
def __init__(self, name, data):
|
||||||
|
DataBuffer.__init__(self, name, '')
|
||||||
|
self._highlight(data)
|
||||||
|
def set_data(self, data, force=True):
|
||||||
|
self._highlight(data)
|
|
@ -0,0 +1,123 @@
|
||||||
|
import fcntl, os, select, pty, threading
|
||||||
|
|
||||||
|
from buffer import Buffer, ACT_NORM, ACT_NONE
|
||||||
|
import term
|
||||||
|
|
||||||
|
class PipeBuffer(Buffer):
|
||||||
|
btype = 'pipe'
|
||||||
|
terms = {
|
||||||
|
'dumb': term.Dumb,
|
||||||
|
'xterm': term.XTerm,
|
||||||
|
}
|
||||||
|
modename = 'pipe'
|
||||||
|
def __init__(self, cmd, args, name=None, term='dumb'):
|
||||||
|
Buffer.__init__(self)
|
||||||
|
self.cmd = cmd
|
||||||
|
if name:
|
||||||
|
self._name = name
|
||||||
|
else:
|
||||||
|
self._name = '*Pipe*'
|
||||||
|
|
||||||
|
self.term = self.terms[term]()
|
||||||
|
self._pid, self._pty = pty.fork()
|
||||||
|
if self._pid == 0:
|
||||||
|
os.execve(cmd, [cmd] + args, {'TERM': self.term.name})
|
||||||
|
|
||||||
|
self._lock = threading.Lock()
|
||||||
|
self._towrite = ''
|
||||||
|
self._done = False
|
||||||
|
self._set_nonblock(self._pty)
|
||||||
|
self._thread = threading.Thread(target=self.pipe_read)
|
||||||
|
self._thread.setDaemon(True)
|
||||||
|
self._thread.start()
|
||||||
|
|
||||||
|
def _set_nonblock(self, fd):
|
||||||
|
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
|
||||||
|
fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NDELAY)
|
||||||
|
|
||||||
|
def _filter_output(self, output):
|
||||||
|
output2 = []
|
||||||
|
i = 0
|
||||||
|
escaped = []
|
||||||
|
for c in output:
|
||||||
|
if escaped:
|
||||||
|
escaped.append(c)
|
||||||
|
if c == 'm':
|
||||||
|
escaped = []
|
||||||
|
elif c == '\x1b':
|
||||||
|
escaped.append(c)
|
||||||
|
elif c == '\n':
|
||||||
|
output2.append(c)
|
||||||
|
i = 0
|
||||||
|
elif c == '\t':
|
||||||
|
j = i % 8
|
||||||
|
output2.append(' ' * (8 - j))
|
||||||
|
i += 8 - j
|
||||||
|
elif c == '\a':
|
||||||
|
pass
|
||||||
|
elif c == '\b':
|
||||||
|
if i > 0:
|
||||||
|
output2.pop(-1)
|
||||||
|
i -= 1
|
||||||
|
else:
|
||||||
|
output2.append(c)
|
||||||
|
i += 1
|
||||||
|
return ''.join(output2)
|
||||||
|
|
||||||
|
def pipe_read(self):
|
||||||
|
fd = self._pty
|
||||||
|
try:
|
||||||
|
while not self._done:
|
||||||
|
if self._towrite:
|
||||||
|
ifd, ofd, efd = select.select([fd], [fd], [fd], 0.1)
|
||||||
|
else:
|
||||||
|
ifd, ofd, efd = select.select([fd], [], [fd], 0.1)
|
||||||
|
if ifd:
|
||||||
|
data = os.read(ifd[0], 1024)
|
||||||
|
end = self.get_buffer_end()
|
||||||
|
data = self.term.filter(data)
|
||||||
|
self.insert_string(end, data, force=True, act=ACT_NONE)
|
||||||
|
if ofd:
|
||||||
|
self._lock.acquire()
|
||||||
|
n = os.write(ofd[0], self._towrite)
|
||||||
|
self._towrite = self._towrite[n:]
|
||||||
|
self._lock.release()
|
||||||
|
if efd:
|
||||||
|
raise Exception, "exception is ready: %s" % repr(efd)
|
||||||
|
except OSError, e:
|
||||||
|
# read error means we're done
|
||||||
|
pass
|
||||||
|
os.close(fd)
|
||||||
|
|
||||||
|
def pipe_write(self, s):
|
||||||
|
self._lock.acquire()
|
||||||
|
self._towrite += s
|
||||||
|
self._lock.release()
|
||||||
|
|
||||||
|
def insert_string(self, p, s, act=ACT_NORM, force=False):
|
||||||
|
lines = s.split("\n")
|
||||||
|
self.insert_lines(p, lines, act, force)
|
||||||
|
|
||||||
|
def insert_lines(self, p, lines, act=ACT_NORM, force=False):
|
||||||
|
llen = len(lines)
|
||||||
|
assert llen > 0
|
||||||
|
if not force and self.readonly():
|
||||||
|
raise ReadOnlyError("buffer is read-only")
|
||||||
|
p2 = p.vadd(len(lines[-1]), llen - 1)
|
||||||
|
if llen > 1:
|
||||||
|
self.lines.insert(p.y + 1, [])
|
||||||
|
self.lines[p.y + 1] = lines[-1] + self.lines[p.y][p.x:]
|
||||||
|
self.lines[p.y] = self.lines[p.y][:p.x] + lines[0]
|
||||||
|
for i in range(1, llen - 1):
|
||||||
|
self.lines.insert(p.y + i, lines[i])
|
||||||
|
else:
|
||||||
|
self.lines[p.y] = self.lines[p.y][:p.x] + lines[-1] + self.lines[p.y][p.x:]
|
||||||
|
self._region_add(p, p2, lines, act)
|
||||||
|
self.modified = True
|
||||||
|
|
||||||
|
def name(self): return self._name
|
||||||
|
def changed(self): return False
|
||||||
|
def readonly(self): return True
|
||||||
|
def undo(self, move, act): raise Exception, "invalid"
|
||||||
|
def redo(self, move, act): raise Exception, "invalid"
|
||||||
|
def reload(self): raise Exception, "invalid"
|
|
@ -1,7 +1,8 @@
|
||||||
import os, commands, re, sets, tempfile
|
import os, commands, re, sets, tempfile
|
||||||
from subprocess import Popen, PIPE, STDOUT
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
|
|
||||||
import buffer, default, dirutil, regex, util, window
|
import buffer, buffer.about
|
||||||
|
import 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
|
||||||
|
@ -147,7 +148,7 @@ class AboutPmacs(Method):
|
||||||
def _execute(self, w, **vargs):
|
def _execute(self, w, **vargs):
|
||||||
a = w.application
|
a = w.application
|
||||||
if not a.has_buffer_name('*About*'):
|
if not a.has_buffer_name('*About*'):
|
||||||
b = buffer.AboutBuffer()
|
b = buffer.about.AboutBuffer()
|
||||||
a.add_buffer(b)
|
a.add_buffer(b)
|
||||||
window.Window(b, a)
|
window.Window(b, a)
|
||||||
b = a.bufferlist.get_buffer_by_name('*About*')
|
b = a.bufferlist.get_buffer_by_name('*About*')
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import keyinput
|
||||||
|
from mode import Fundamental
|
||||||
|
from method import Method
|
||||||
|
|
||||||
|
class PipeInsertChr(Method):
|
||||||
|
_is_method = False
|
||||||
|
def __init__(self, i):
|
||||||
|
self.name = "pipe-insert-chr-%s" % i
|
||||||
|
self.args = []
|
||||||
|
self.help = "Insert chr(%d) into the current pipe-buffer." % i
|
||||||
|
self.string = chr(i)
|
||||||
|
def _execute(self, w, **vargs):
|
||||||
|
w.buffer.pipe_write(self.string)
|
||||||
|
|
||||||
|
class Pipe(Fundamental):
|
||||||
|
modename = 'pipe'
|
||||||
|
def __init__(self, w):
|
||||||
|
Fundamental.__init__(self, w)
|
||||||
|
_codes = [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14] + \
|
||||||
|
[16, 18, 20, 23, 25] + list(range(32, 128))
|
||||||
|
for i in _codes:
|
||||||
|
sym = keyinput.MAP.get(i, chr(i))
|
||||||
|
obj = PipeInsertChr(i)
|
||||||
|
w.application.methods[obj.name] = obj
|
||||||
|
self.add_binding(obj.name, sym)
|
||||||
|
|
||||||
|
install = Pipe.install
|
|
@ -1,5 +1,6 @@
|
||||||
import code, os, re, string, StringIO, sys, traceback
|
import code, os, re, string, StringIO, sys, traceback
|
||||||
import buffer, color, completer, lex, method, mode, window
|
import buffer, buffer.pipe
|
||||||
|
import color, completer, lex, method, mode, window
|
||||||
from lex import Grammar, PatternRule, RegionRule
|
from lex import Grammar, PatternRule, RegionRule
|
||||||
from point import Point
|
from point import Point
|
||||||
from method import Method
|
from method import Method
|
||||||
|
@ -124,7 +125,7 @@ class OpenShell(Method):
|
||||||
def execute(self, w, **vargs):
|
def execute(self, w, **vargs):
|
||||||
a = w.application
|
a = w.application
|
||||||
if not a.has_buffer_name('*Shell*'):
|
if not a.has_buffer_name('*Shell*'):
|
||||||
b = buffer.PipeBuffer('/bin/bash', [], name="*Shell*", term='xterm')
|
b = buffer.pipe.PipeBuffer('/bin/bash', [], name="*Shell*", term='xterm')
|
||||||
a.add_buffer(b)
|
a.add_buffer(b)
|
||||||
window.Window(b, a)
|
window.Window(b, a)
|
||||||
b = a.bufferlist.get_buffer_by_name('*Shell*')
|
b = a.bufferlist.get_buffer_by_name('*Shell*')
|
||||||
|
|
Loading…
Reference in New Issue