gpt4 book ai didi

python - 在嵌入式 Python 解释器中启用代码完成

转载 作者:太空狗 更新时间:2023-10-29 21:37:51 24 4
gpt4 key购买 nike

我有一个 PyQT 小部件解释器在工作,代码来自 here如下:

import os
import re
import sys
import code

from PyQt4.QtGui import *
from PyQt4.QtCore import *

class MyInterpreter(QWidget):

def __init__(self, parent):

super(MyInterpreter, self).__init__(parent)
hBox = QHBoxLayout()

self.setLayout(hBox)
self.textEdit = PyInterp(self)

# this is how you pass in locals to the interpreter
self.textEdit.initInterpreter(locals())

self.resize(650, 300)
self.centerOnScreen()

hBox.addWidget(self.textEdit)
hBox.setMargin(0)
hBox.setSpacing(0)

def centerOnScreen(self):
# center the widget on the screen
resolution = QDesktopWidget().screenGeometry()
self.move((resolution.width() / 2) - (self.frameSize().width() / 2),
(resolution.height() / 2) - (self.frameSize().height() / 2))

class PyInterp(QTextEdit):

class InteractiveInterpreter(code.InteractiveInterpreter):

def __init__(self, locals):
code.InteractiveInterpreter.__init__(self, locals)

def runIt(self, command):
code.InteractiveInterpreter.runsource(self, command)


def __init__(self, parent):
super(PyInterp, self).__init__(parent)

sys.stdout = self
sys.stderr = self
self.refreshMarker = False # to change back to >>> from ...
self.multiLine = False # code spans more than one line
self.command = '' # command to be ran
self.printBanner() # print sys info
self.marker() # make the >>> or ... marker
self.history = [] # list of commands entered
self.historyIndex = -1
self.interpreterLocals = {}

# setting the color for bg and text
palette = QPalette()
palette.setColor(QPalette.Base, QColor(0, 0, 0))
palette.setColor(QPalette.Text, QColor(0, 255, 0))
self.setPalette(palette)
self.setFont(QFont('Courier', 12))

# initilize interpreter with self locals
self.initInterpreter(locals())


def printBanner(self):
self.write(sys.version)
self.write(' on ' + sys.platform + '\n')
self.write('PyQt4 ' + PYQT_VERSION_STR + '\n')
msg = 'Type !hist for a history view and !hist(n) history index recall'
self.write(msg + '\n')


def marker(self):
if self.multiLine:
self.insertPlainText('... ')
else:
self.insertPlainText('>>> ')

def initInterpreter(self, interpreterLocals=None):
if interpreterLocals:
# when we pass in locals, we don't want it to be named "self"
# so we rename it with the name of the class that did the passing
# and reinsert the locals back into the interpreter dictionary
selfName = interpreterLocals['self'].__class__.__name__
interpreterLocalVars = interpreterLocals.pop('self')
self.interpreterLocals[selfName] = interpreterLocalVars
else:
self.interpreterLocals = interpreterLocals
self.interpreter = self.InteractiveInterpreter(self.interpreterLocals)

def updateInterpreterLocals(self, newLocals):
className = newLocals.__class__.__name__
self.interpreterLocals[className] = newLocals

def write(self, line):
self.insertPlainText(line)
self.ensureCursorVisible()

def clearCurrentBlock(self):
# block being current row
length = len(self.document().lastBlock().text()[4:])
if length == 0:
return None
else:
# should have a better way of doing this but I can't find it
[self.textCursor().deletePreviousChar() for x in xrange(length)]
return True

def recallHistory(self):
# used when using the arrow keys to scroll through history
self.clearCurrentBlock()
if self.historyIndex <> -1:
self.insertPlainText(self.history[self.historyIndex])
return True

def customCommands(self, command):

if command == '!hist': # display history
self.append('') # move down one line
# vars that are in the command are prefixed with ____CC and deleted
# once the command is done so they don't show up in dir()
backup = self.interpreterLocals.copy()
history = self.history[:]
history.reverse()
for i, x in enumerate(history):
iSize = len(str(i))
delta = len(str(len(history))) - iSize
line = line = ' ' * delta + '%i: %s' % (i, x) + '\n'
self.write(line)
self.updateInterpreterLocals(backup)
self.marker()
return True

if re.match('!hist\(\d+\)', command): # recall command from history
backup = self.interpreterLocals.copy()
history = self.history[:]
history.reverse()
index = int(command[6:-1])
self.clearCurrentBlock()
command = history[index]
if command[-1] == ':':
self.multiLine = True
self.write(command)
self.updateInterpreterLocals(backup)
return True

return False

def keyPressEvent(self, event):

if event.key() == Qt.Key_Escape:
# proper exit
self.interpreter.runIt('exit()')

if event.key() == Qt.Key_Down:
if self.historyIndex == len(self.history):
self.historyIndex -= 1
try:
if self.historyIndex > -1:
self.historyIndex -= 1
self.recallHistory()
else:
self.clearCurrentBlock()
except:
pass
return None

if event.key() == Qt.Key_Up:
try:
if len(self.history) - 1 > self.historyIndex:
self.historyIndex += 1
self.recallHistory()
else:
self.historyIndex = len(self.history)
except:
pass
return None

if event.key() == Qt.Key_Home:
# set cursor to position 4 in current block. 4 because that's where
# the marker stops
blockLength = len(self.document().lastBlock().text()[4:])
lineLength = len(self.document().toPlainText())
position = lineLength - blockLength
textCursor = self.textCursor()
textCursor.setPosition(position)
self.setTextCursor(textCursor)
return None

if event.key() in [Qt.Key_Left, Qt.Key_Backspace]:
# don't allow deletion of marker
if self.textCursor().positionInBlock() == 4:
return None

if event.key() in [Qt.Key_Return, Qt.Key_Enter]:
# set cursor to end of line to avoid line splitting
textCursor = self.textCursor()
position = len(self.document().toPlainText())
textCursor.setPosition(position)
self.setTextCursor(textCursor)

line = str(self.document().lastBlock().text())[4:] # remove marker
line.rstrip()
self.historyIndex = -1

if self.customCommands(line):
return None
else:
try:
line[-1]
self.haveLine = True
if line[-1] == ':':
self.multiLine = True
self.history.insert(0, line)
except:
self.haveLine = False

if self.haveLine and self.multiLine: # multi line command
self.command += line + '\n' # + command and line
self.append('') # move down one line
self.marker() # handle marker style
return None

if self.haveLine and not self.multiLine: # one line command
self.command = line # line is the command
self.append('') # move down one line
self.interpreter.runIt(self.command)
self.command = '' # clear command
self.marker() # handle marker style
return None

if self.multiLine and not self.haveLine: # multi line done
self.append('') # move down one line
self.interpreter.runIt(self.command)
self.command = '' # clear command
self.multiLine = False # back to single line
self.marker() # handle marker style
return None

if not self.haveLine and not self.multiLine: # just enter
self.append('')
self.marker()
return None
return None

# allow all other key events
super(PyInterp, self).keyPressEvent(event)

if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyInterpreter(None)
win.show()
sys.exit(app.exec_())

有没有一种简单的方法可以让一些制表符补全只针对本地符号?

最佳答案

我想你指的是 rlcompleter的完成者对象。

你可以这样使用它:

from rlcompleter import Completer

line = str(...)

completer = Completer(self.interpreter.locals)
suggestion = completer.complete(line, 0)
self.insertPlainText(suggestion)

数字参数表示第 n 个建议,您可以对其进行迭代,直到它返回 None

例如,假设我们有

>>> my_data = '012345'

然后

>>> completer.complete('my_', 0)
'my_data'
>>> completer.complete('my_data.s', 0)
'my_data.split('
>>> completer.complete('my_data.s', 1)
'my_data.splitlines('

请注意,虽然上面的代码使用了 interpreter.locals,但您可以应用更广泛的搜索(但一定要提供字典)。

关于python - 在嵌入式 Python 解释器中启用代码完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12431555/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com