📄 reader.py
字号:
screeninfo.append((0, l2[wrapcount*w - lp:]+[1]))
self.screeninfo = screeninfo
self.cxy = self.pos2xy(self.pos)
return screen
def bow(self, p=None):
"""Return the 0-based index of the word break preceding p most
immediately.
p defaults to self.pos; word boundaries are determined using
self.syntax_table."""
if p is None:
p = self.pos
st = self.syntax_table
b = self.buffer
p -= 1
while p >= 0 and st.get(b[p], SYNTAX_WORD) <> SYNTAX_WORD:
p -= 1
while p >= 0 and st.get(b[p], SYNTAX_WORD) == SYNTAX_WORD:
p -= 1
return p + 1
def eow(self, p=None):
"""Return the 0-based index of the word break following p most
immediately.
p defaults to self.pos; word boundaries are determined using
self.syntax_table."""
if p is None:
p = self.pos
st = self.syntax_table
b = self.buffer
while p < len(b) and st.get(b[p], SYNTAX_WORD) <> SYNTAX_WORD:
p += 1
while p < len(b) and st.get(b[p], SYNTAX_WORD) == SYNTAX_WORD:
p += 1
return p
def bol(self, p=None):
"""Return the 0-based index of the line break preceding p most
immediately.
p defaults to self.pos."""
# XXX there are problems here.
if p is None:
p = self.pos
b = self.buffer
p -= 1
while p >= 0 and b[p] <> '\n':
p -= 1
return p + 1
def eol(self, p=None):
"""Return the 0-based index of the line break following p most
immediately.
p defaults to self.pos."""
if p is None:
p = self.pos
b = self.buffer
while p < len(b) and b[p] <> '\n':
p += 1
return p
def get_arg(self, default=1):
"""Return any prefix argument that the user has supplied,
returning `default' if there is None. `default' defaults
(groan) to 1."""
if self.arg is None:
return default
else:
return self.arg
def get_prompt(self, lineno, cursor_on_line):
"""Return what should be in the left-hand margin for line
`lineno'."""
if self.arg is not None and cursor_on_line:
return "(arg: %s) "%self.arg
if "\n" in self.buffer:
if lineno == 0:
return self._ps2
elif lineno == self.buffer.count("\n"):
return self._ps4
else:
return self._ps3
else:
return self._ps1
def push_input_trans(self, itrans):
self.input_trans_stack.append(self.input_trans)
self.input_trans = itrans
def pop_input_trans(self):
self.input_trans = self.input_trans_stack.pop()
def pos2xy(self, pos):
"""Return the x, y coordinates of position 'pos'."""
# this *is* incomprehensible, yes.
y = 0
assert 0 <= pos <= len(self.buffer)
if pos == len(self.buffer):
y = len(self.screeninfo) - 1
p, l2 = self.screeninfo[y]
return p + len(l2) - 1, y
else:
for p, l2 in self.screeninfo:
l = l2.count(1)
if l > pos:
break
else:
pos -= l
y += 1
c = 0
i = 0
while c < pos:
c += l2[i]
i += 1
while l2[i] == 0:
i += 1
return p + i, y
def insert(self, text):
"""Insert 'text' at the insertion point."""
self.buffer[self.pos:self.pos] = list(text)
self.pos += len(text)
self.dirty = 1
def update_cursor(self):
"""Move the cursor to reflect changes in self.pos"""
self.cxy = self.pos2xy(self.pos)
self.console.move_cursor(*self.cxy)
def after_command(self, cmd):
"""This function is called to allow post command cleanup."""
if getattr(cmd, "kills_digit_arg", 1):
if self.arg is not None:
self.dirty = 1
self.arg = None
def prepare(self):
"""Get ready to run. Call restore when finished. You must not
write to the console in between the calls to prepare and
restore."""
try:
self.console.prepare()
self.arg = None
self.screeninfo = []
self.finished = 0
del self.buffer[:]
self.pos = 0
self.dirty = 1
self.last_command = None
self._ps1, self._ps2, self._ps3, self._ps4 = \
map(str, [self.ps1, self.ps2, self.ps3, self.ps4])
except:
self.restore()
raise
def last_command_is(self, klass):
if not self.last_command:
return 0
return issubclass(klass, self.last_command)
def restore(self):
"""Clean up after a run."""
self.console.restore()
def finish(self):
"""Called when a command signals that we're finished."""
pass
def message(self, msg="none"):
self.msg = "[ "+msg+" ] "
self.dirty = 1
def error(self, msg="none"):
self.msg = "! " + msg + " "
self.dirty = 1
self.console.beep()
def refresh(self):
"""Recalculate and refresh the screen."""
if self.console.isbusy():
return
# this call sets up self.cxy, so call it first.
screen = self.calc_screen()
self.console.refresh(screen, self.cxy)
self.dirty = 0 # forgot this for a while (blush)
def do_cmd(self, cmd):
if isinstance(cmd[0], str):
cmd = self.commands.get(cmd[0],
commands.invalid_command)(self, cmd)
elif isinstance(cmd[0], type):
cmd = cmd[0](self, cmd)
else:
cmd=cmd[0]
cmd.do()
self.after_command(cmd)
if self.dirty:
self.refresh()
else:
self.update_cursor()
if not isinstance(cmd, commands.digit_arg):
self.last_command = cmd.__class__
self.finished = cmd.finish
if self.finished:
self.console.finish()
self.finish()
def handle1(self, block=1):
"""Handle a single event. Wait as long as it takes if block
is true (the default), otherwise return None if no event is
pending."""
if self.msg:
self.msg = ''
self.dirty = 1
while 1:
event = self.console.get_event(block)
if not event: # can only happen if we're not blocking
return None
if event.evt == 'key':
self.input_trans.push(event)
elif event.evt == 'scroll':
self.refresh()
elif event.evt == 'resize':
self.refresh()
else:
pass
cmd = self.input_trans.get()
if cmd is None:
if block:
continue
else:
return None
self.do_cmd(cmd)
return 1
def readline(self):
"""Read a line. The implementation of this method also shows
how to drive Reader if you want more control over the event
loop."""
self.prepare()
try:
self.refresh()
while not self.finished:
self.handle1()
return self.get_buffer()
finally:
self.restore()
def bind(self, spec, command):
self.keymap = self.keymap + ((spec, command),)
self.input_trans = input.KeymapTranslator(
self.keymap,
invalid_cls='invalid-key',
character_cls='self-insert')
def get_buffer(self, encoding=None):
if encoding is None:
encoding = self.console.encoding
return u''.join(self.buffer).encode(self.console.encoding)
def get_unicode(self):
"""Return the current buffer as a unicode string."""
return u''.join(self.buffer)
def test():
from pyrepl.unix_console import UnixConsole
reader = Reader(UnixConsole())
reader.ps1 = "**> "
reader.ps2 = "/*> "
reader.ps3 = "|*> "
reader.ps4 = "\*> "
while reader.readline():
pass
if __name__=='__main__':
test()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -