autocomplete - rlcompleter2 code completion in an embedded Python Interpreter? -
i took this code starting point, , auto complete rlcompleter2, there 2 problems in following code,
import xxx yyyauto complete on yyy doesn't work- the locals() not copied interactiveinterpreter, tried use code in autodesk maya, eg, run
x=3in maya script editor, , runxin pyqt interpreter, saysnameerror: name 'x' not defined. if not use maya, error can reproduced external python interpreter well, first define variable, launch ui, variable not copied interpreter in ui.
import os import re import sys import code pyqt4.qtgui import * pyqt4.qtcore import * class myinterpreter(qwidget): def __init__(self, parent): super(myinterpreter, self).__init__(parent) hbox = qhboxlayout() self.setlayout(hbox) self.textedit = pyinterp(self) # how pass in locals interpreter self.textedit.initinterpreter(locals()) self.resize(850, 400) # self.centeronscreen() hbox.addwidget(self.textedit) hbox.setmargin(0) hbox.setspacing(0) def centeronscreen(self): # center widget on 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 # change >>> ... self.multiline = false # code spans more 1 line self.command = '' # command ran self.printbanner() # print sys info self.marker() # make >>> or ... marker self.history = [] # list of commands entered self.historyindex = -1 self.interpreterlocals = {} # setting color bg , 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', 10)) # initilize interpreter self locals self.initinterpreter(locals()) rlcompleter2 import completer self.completer = completer() def printbanner(self): self.write(sys.version) self.write(' on ' + sys.platform + '\n') self.write('pyqt4 ' + pyqt_version_str + '\n') # msg = 'type !hist history view , !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 pass in locals, don't want named "self" # rename name of class did passing # , reinsert locals 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 better way of doing can't find [self.textcursor().deletepreviouschar() x in xrange(length)] return true def recallhistory(self): # used when using arrow keys 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 1 line # vars in command prefixed ____cc , deleted # once command done don't show in dir() backup = self.interpreterlocals.copy() history = self.history[:] history.reverse() 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 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_tab: line = str(self.document().lastblock().text())[4:] self.completer.construct(line) if len(self.completer.rl_matches) == 1: self.clearcurrentblock() self.insertplaintext(self.completer.rl_matches[0]) else: print 'repeat:', self.completer.repeated mod = self.completer.repeated % len(self.completer.completions) if mod == 0: # print '\n'.join(self.completer.rl_matches) col_print(self.completer.rl_matches) else: print ' ' print '\n'.join(self.completer.rl_matches) # print self.completer.rl_matches self.marker() self.insertplaintext(line) return 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 position 4 in current block. 4 because that's # 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 qt version < 4.7, have use position() - block().position() if self.textcursor().positioninblock() == 4: return none if event.key() in [qt.key_return, qt.key_enter]: # set cursor end of line 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 , self.multiline: # multi line command self.command += line + '\n' # + command , line self.append('') # move down 1 line self.marker() # handle marker style return none if self.haveline , not self.multiline: # 1 line command self.command = line # line command self.append('') # move down 1 line self.interpreter.runit(self.command) self.command = '' # clear command self.marker() # handle marker style return none if self.multiline , not self.haveline: # multi line done self.append('') # move down 1 line self.interpreter.runit(self.command) self.command = '' # clear command self.multiline = false # single line self.marker() # handle marker style return none if not self.haveline , not self.multiline: # enter self.append('') self.marker() return none return none # allow other key events super(pyinterp, self).keypressevent(event) # https://stackoverflow.com/a/30861871/2052889 def col_print(lines, term_width=90, indent=0, pad=2): n_lines = len(lines) if n_lines == 0: return col_width = max(len(line) line in lines) n_cols = int((term_width + pad - indent)/(col_width + pad)) n_cols = min(n_lines, max(1, n_cols)) col_len = int(n_lines/n_cols) + (0 if n_lines % n_cols == 0 else 1) if (n_cols - 1) * col_len >= n_lines: n_cols -= 1 cols = [lines[i*col_len: i*col_len + col_len] in range(n_cols)] rows = list(zip(*cols)) rows_missed = zip(*[col[len(rows):] col in cols[:-1]]) rows.extend(rows_missed) row in rows: print(" "*indent + (" "*pad).join(line.ljust(col_width) line in row)) def main(): app = qapplication(sys.argv) win = myinterpreter(none) win.show() sys.exit(app.exec_()) if __name__ == "__main__": main() desired effect: https://gfycat.com/distantscrawnycivet 
current effect: https://gfycat.com/deafeningheavyboto 
Comments
Post a Comment