def reportChangedClone(self, child_v, b, h, gnx): trace = (False or g.app.debug) and not g.unitTesting c = self.c fileName = c.cacheListFileName old, new = child_v.b, b same = ( old == new or new.endswith('\n') and old == new[: -1] or old.endswith('\n') and new == old[: -1]) # if trace and not same: if trace and (not same or h == 'writeException'): g.trace('same %s old %s new %s %s %s' % ( same, len(old), len(new), h, fileName)) # This would make it impossible to clear nodes! # if not new: return same if same: return c.nodeConflictList.append(g.bunch( tag='(cached)', fileName=fileName, gnx=gnx, b_old=child_v.b, h_old=child_v.h, b_new=b, h_new=h, )) # Always issue the warning. g.error("cached read node changed:", child_v.h) child_v.h, child_v.b = h, b child_v.setDirty() c.changed = True # Tell getLeoFile to propegate dirty nodes.
def reportIfNodeChanged(self, child_tuple, child_v, fileName, parent_v): ''' Schedule a recovered node if child_v is substantially different from an earlier version. Issue a (rare) warning if two different files are involved. ''' trace = (False or g.app.debug) and not g.unitTesting always_warn = True # True always warn about changed nodes. c = self.c h, b, gnx, grandChildren = child_tuple old_b, new_b = child_v.b, b old_h, new_h = child_v.h, h # Leo 5.6: test headlines. same_head = old_h == new_h same_body = ( old_b == new_b or new_b.endswith('\n') and old_b == new_b[: -1] or old_b.endswith('\n') and new_b == old_b[: -1] ) if same_head and same_body: return old_roots = list(getattr(child_v, 'tempRoots', set())) same_file = ( len(old_roots) == 0 or len(old_roots) == 1 and old_roots[0] == fileName ) must_warn = not same_file if not hasattr(child_v, 'tempRoots'): child_v.tempRoots = set() child_v.tempRoots.add(fileName) if trace: # g.trace('same h: %s, same b: %s same fn: %s' % ( # same_head, same_body, same_file)) g.trace('fileName', fileName) g.trace('tempRoots', old_roots) if must_warn: # This is the so-called "rare" case: # The node differs in two different external files. self.warning('out-of-sync node: %s' % h) g.es_print('using node in %s' % fileName) if always_warn or must_warn: if c.make_node_conflicts_node: g.es_print('creating recovered node:', h) c.nodeConflictList.append(g.bunch( tag='(cached)', fileName=fileName, gnx=gnx, b_old=child_v.b, h_old=child_v.h, b_new=b, h_new=h, root_v=parent_v, )) # Always update the node. child_v.h, child_v.b = h, b child_v.setDirty() c.changed = True # Tell getLeoFile to propegate dirty nodes.
def state_handler(self, event=None): '''Handle keys while in the "screencast" input state.''' trace = False and not g.unitTesting m = self c = m.c k = c.k state = k.getState(m.state_name) char = event and event.char or '' if trace: g.trace('char: %s k.state.kind: %s m.k_state: %s' % (repr(char), repr(k.state.kind), m.k_state and repr(m.k_state.kind) or '<none>')) if m.ignore_keys: return if state == 0: # Init the minibuffer as in k.fullCommand. if trace: g.trace('======= state 0 =====') assert m.p1 and m.p1 == m.p k.mb_event = event k.mb_prefix = k.getLabel() k.mb_prompt = 'Screencast: ' k.mb_tabList = [] k.setLabel(k.mb_prompt) k.setState(m.state_name, 1, m.state_handler) m.next() # Only exit on Ctrl-g. # Because of menu handling, it's convenient to have escape go to the next slide. # That way an "extra" escape while dismissing menus will be handled well. elif char == 'Escape': # m.quit() m.next() elif char == 'Right': m.next() elif char == 'Left': m.prev() elif m.k_state.kind != m.state_name: # We are simulating another state. # Pass the character to *that* state, # making *sure* to save/restore all state. kind, n, handler = k.state.kind, k.state.n, k.state.handler m_state_copy = g.bunch(kind=m.k_state.kind, n=m.k_state.n, handler=m.k_state.handler) m.single_key(char) k.setState(kind, n, handler) m.set_state(m_state_copy) elif trace: g.trace('ignore %s' % (repr(char)))
def state_handler (self,event=None): '''Handle keys while in the "screencast" input state.''' trace = False and not g.unitTesting m = self ; c = m.c ; k = c.k state = k.getState(m.state_name) char = event and event.char or '' if trace: g.trace('char: %s k.state.kind: %s m.k_state: %s' % ( repr(char),repr(k.state.kind), m.k_state and repr(m.k_state.kind) or '<none>')) if m.ignore_keys: return if state == 0: # Init the minibuffer as in k.fullCommand. if trace: g.trace('======= state 0 =====') assert m.p1 and m.p1 == m.p k.mb_event = event k.mb_prefix = k.getLabel() k.mb_prompt = 'Screencast: ' k.mb_tabList = [] k.setLabel(k.mb_prompt) k.setState(m.state_name,1,m.state_handler) m.next() # Only exit on Ctrl-g. # Because of menu handling, it's convenient to have escape go to the next slide. # That way an "extra" escape while dismissing menus will be handled well. elif char == 'Escape': # m.quit() m.next() elif char == 'Right': m.next() elif char == 'Left': m.prev() elif m.k_state.kind != m.state_name: # We are simulating another state. # Pass the character to *that* state, # making *sure* to save/restore all state. kind,n,handler = k.state.kind,k.state.n,k.state.handler m_state_copy = g.bunch(kind=m.k_state.kind, n=m.k_state.n,handler=m.k_state.handler) m.single_key(char) k.setState(kind,n,handler) m.set_state(m_state_copy) elif trace: g.trace('ignore %s' % (repr(char)))
def collectChangedNodes(self, root_v, aList, fileName): '''Populates c.nodeConflictList with data about nodes that are going to change during recreation of outline from cached list.''' c = self.c #@+others #@+node:vitalije.20180507113809.1: *5* vnodes helper iterator gnxDict = c.fileCommands.gnxDict def vnodes(_vlist): h, b, gnx, c_vlist = _vlist v = gnxDict.get(gnx) if v: yield v, h, b, gnx for x in c_vlist: for y in vnodes(x): yield y #@-others for v, h, b, gnx in vnodes(aList): if v is root_v and not (v.b or v.children): # # no children and an empty body of root node most probably means # we are reading external file for the first time. In this case # there is no point in counting this as nodeConflict continue same_h = v.h == h same_b = (v.b == b or (v.b[-1:] == '\n' and v.b[:-1] == b) or (b[-1:] == '\n' and v.b == b[:-1])) if same_h and same_b: continue c.nodeConflictList.append( g.bunch( tag='(cached)', fileName=fileName, gnx=gnx, b_old=v.b, h_old=v.h, b_new=b, h_new=h, root_v=root_v, ))
def __init__(self, c): self.c = c self.log_color = 'black' self.log_focus = True # True: writing to log sets focus to log. self.ignore_keys = False # True: ignore keys in state_handler. self.quit_flag = False # True if m.quit has been called. self.k_state = g.bunch(kind=None, n=None, handler=None) # Saved k.state. self.key_w = None # Saved widget for passed-along key handling. self.n1 = 0.02 # default minimal typing delay. self.n2 = 0.175 # default maximum typing delay. self.p1 = None # The first slide of the show. self.p = None # The present slide of the show. self.speed = 1.0 # Amount to multiply wait times. self.state_name = 'screencast' # The state name to enable m.state_handler. self.node_stack = [] # For m.prev and m.undo. self.text_flag = False # True: m.next shows body text instead of executing it. self.user_dict = {} # For use by scripts. self.widgets = [] # List of (popup) widgets created by this class. # inject c.screenCastController c.screenCastController = self
class ConfigShim(config_base): def __init__(self): config_base.__init__(self) g.pr('\n===== ConfigShim: new_config: %s\n' % new_config) self.setObjectName('ConfigShim') if new_config: #@+<< define bunch settings >> #@+node:ekr.20190331082353.1: *3* << define bunch settings >> # '(\w+)': With: \1 = advanced = g.Bunch( autoCompDelay=200, fileExtensionsToLoadFromDir='py,pyw,pyx,txt,bat', find_autoHide_timeout=10, homeAndEndWorkOnDisplayedLine=0, shellMaxLines=10000, titleText='{fileName} ({fullPath}) - Interactive Editor for Python', ) settings = g.Bunch( allowFloatingShell=0, autoCallTip=1, autoClose_Brackets=1, autoClose_Quotes=1, autoComplete=1, autoComplete_acceptKeys='Tab', autoComplete_caseSensitive=0, autoComplete_fillups='\n', autoComplete_keywords=1, autoIndent=1, changeDirOnFileExec=0, defaultIndentUsingSpaces=1, defaultIndentWidth=4, defaultLineEndings='CRLF', defaultStyle='python', justificationWidth=70, language='English (US)', removeTrailingWhitespaceWhenSaving=0, ) shellConfigs2 = [ g.Bunch( argv='', environ='', exe='c:\\anaconda3\\python.exe', gui='auto', ipython='yes', name='Python', projectPath='', pythonPath='', scriptFile='', startDir='', startupScript='', ) ] shortcuts2 = g.bunch( #@+<< define bunch shortcuts2 >> #@+node:ekr.20190331082549.1: *4* << define bunch shortcuts2 >> edit__comment='Ctrl+R,', edit__copy='Ctrl+C,Ctrl+Insert', edit__cut='Ctrl+X,Shift+Delete', edit__dedent='Shift+Tab,', edit__delete_line='Ctrl+D,', edit__duplicate_line='Ctrl+Shift+D,', edit__find_next='Ctrl+G,F3', edit__find_or_replace='Ctrl+F,', edit__find_previous='Ctrl+Shift+G,Shift+F3', edit__find_selection='Ctrl+F3,', edit__find_selection_backward='Ctrl+Shift+F3,', edit__indent='Tab,', edit__justify_commentdocstring='Ctrl+J,', edit__paste='Ctrl+V,Shift+Insert', edit__paste_and_select='Ctrl+Shift+V', edit__redo='Ctrl+Y,', edit__select_all='Ctrl+A,', edit__toggle_breakpoint='Ctrl+B,', edit__uncomment='Ctrl+T,', edit__undo='Ctrl+Z,', file__close='Ctrl+W,', file__new='Ctrl+N,', file__open='Ctrl+O,', file__save='Ctrl+S,', run__execute_cell='Ctrl+Return,Ctrl+Enter', run__execute_cell_and_advance='Ctrl+Shift+Return,Ctrl+Shift+Enter', run__execute_file='Ctrl+E,F5', run__execute_main_file='Ctrl+M,F6', run__execute_selection='Alt+Return,F9', run__execute_selection_and_advance='Shift+F9,Shift+Alt+Return', run__run_file_as_script='Ctrl+Shift+E,Ctrl+F5', run__run_main_file_as_script='Ctrl+Shift+M,Ctrl+F6', shell__clear_screen='Ctrl+L,', shell__close='Alt+K,', shell__create_shell_1_='Ctrl+1,', shell__create_shell_2_='Ctrl+2,', shell__create_shell_3_='Ctrl+3,', shell__create_shell_4_='Ctrl+4,', shell__create_shell_5_='Ctrl+5,', shell__create_shell_6_='Ctrl+6,', shell__create_shell_7_='Ctrl+7,', shell__create_shell_8_='Ctrl+8,', shell__interrupt='Ctrl+I,Meta+C', shell__postmortem_debug_from_last_traceback='Ctrl+P,', shell__restart='Ctrl+K,', shell__terminate='Ctrl+Shift+K,', view__select_editor='Ctrl+9,F2', view__select_previous_file='Ctrl+Tab,', view__select_shell='Ctrl+0,F1', view__zooming__zoom_in='Ctrl+=,Ctrl++', view__zooming__zoom_out='Ctrl+-,', view__zooming__zoom_reset='Ctrl+\\,' #@-<< define bunch shortcuts2 >> ) state = g.Bunch( editorState2=[ #@+<< define editorState2 >> #@+node:ekr.20190331082353.2: *4* << define editorState2 >> [ 'C:\\apps\\pyzo\\source\\pyzo\\codeeditor\\highlighter.py', 3279, 96 ], [ 'C:\\apps\\pyzo\\source\\pyzo\\core\\editorTabs.py', 22913, 693 ], [ 'C:\\apps\\pyzo\\source\\pyzo\\codeeditor\\highlighter.py', 'hist' ], ['C:\\apps\\pyzo\\source\\pyzo\\core\\editorTabs.py', 'hist'] #@-<< define editorState2 >> ], find_autoHide=1, find_matchCase=0, find_regExp=0, find_show=0, find_wholeWord=1, loadedTools=[ 'pyzofilebrowser', 'pyzologger', 'pyzosourcestructure' ], newUser=1, windowGeometry= 'AdnQywACAAAAAAGjAAAA2AAABv0AAANWAAABqwAAAPcAAAb1AAADTgAAAAAAAAAAB4A=\n', windowState= ('AAAA/wAAAAD9AAAAAgAAAAAAAACeAAACRPwCAAAAAfwAAAAUAAACRAAAAYgA/////AIAAAAC+wAA\n' 'AB4AcAB5AHoAbwBmAGkAbABlAGIAcgBvAHcAcwBlAHIBAAAAFAAAAWEAAAEIAP////sAAAAmAHAA\n' 'eQB6AG8AcwBvAHUAcgBjAGUAcwB0AHIAdQBjAHQAdQByAGUBAAABewAAAN0AAAB6AP///wAAAAEA\n' 'AAGEAAACRPwCAAAABvsAAAAMAHMAaABlAGwAbABzAQAAABQAAAD/AAAAcwD////7AAAAFABwAHkA\n' 'egBvAGwAbwBnAGcAZQByAQAAARkAAAE/AAAAWQD////7AAAAGgBwAHkAegBvAHcAbwByAGsAcwBw\n' 'AGEAYwBlAAAAAT4AAAEaAAAAAAAAAAD7AAAAJgBwAHkAegBvAGkAbgB0AGUAcgBhAGMAdABpAHYA\n' 'ZQBoAGUAbABwAAAAAnkAAAB6AAAAAAAAAAD7AAAAIgBwAHkAegBvAGgAaQBzAHQAbwByAHkAdgBp\n' 'AGUAdwBlAHIAAAACGgAAAVsAAAAAAAAAAPsAAAAcAHAAeQB6AG8AdwBlAGIAYgByAG8AdwBzAGUA\n' 'cgAAAAKwAAAAxQAAAAAAAAAAAAADHQAAAkQAAAAEAAAABAAAAAgAAAAI/AAAAAA=\n' )) tools = g.Bunch(pyzofilebrowser=g.Bunch(), pyzofilebrowser2=g.Bunch( expandedDirs=['c:\\apps\\pyzo\\source\\pyzo'], nameFilter='!*.pyc', path='c:\\apps\\pyzo\\source\\pyzo', searchMatchCase=0, searchRegExp=0, searchSubDirs=1, starredDirs=[ g.Bunch( addToPythonpath=0, name='Pyzo sources', path='c:\\apps\\pyzo\\source', ) ]), pyzohistoryviewer=g.Bunch(), pyzointeractivehelp=g.Bunch(fontSize=14, noNewlines=1, smartNewlines=1), pyzologger=g.Bunch(), pyzosourcestructure=g.Bunch( level=1, showTypes=['class', 'def', 'cell', 'todo'], ), pyzowebbrowser=g.Bunch( bookMarks=[ 'docs.python.org', 'scipy.org', 'doc.qt.nokia.com/4.5/', 'pyzo.org', ], zoomFactor=1.0, ), pyzoworkspace=g.Bunch( hideTypes=[], typeTranslation=g.Bunch( builtin_function_or_method='function', method='function'))) view = g.Bunch(autoComplete_popupSize=[300, 100], codeFolding=0, doBraceMatch=1, edgeColumn=80, fontname='DejaVu Sans Mono', highlightCurrentLine=1, highlightMatchingBracket=1, qtstyle='fusion', showIndentationGuides=1, showLineEndings=0, showStatusbar=0, showWhitespace=0, showWrapSymbols=0, tabWidth=4, wrap=1, zoom=2) #@-<< define bunch settings >> #@+<< new config methods >> #@+node:ekr.20190331052308.1: *3* << new config methods >> #@+others #@+node:ekr.20190331052308.2: *4* ConfigShim.__repr__ def __repr__(self): return 'ConfigShim' # return g.obj2string(self) # Can't do this: it calls repr! #@+node:ekr.20190331052308.3: *4* ConfigShim.__getattribute__ def __getattribute__(self, key): '''The usual shinanigans...''' ### return object.__getattribute__(self, key) try: val = object.__getattribute__(self, key) except AttributeError: if key in self: val = self[key] else: raise if key not in config_shim_seen: config_shim_seen[key] = True g.pr('\n===== ConfigShim.__getattribute__', key, val) return val #@+node:ekr.20190331052308.4: *4* ConfigShim.__setattr__ (not used) # def __setattr__(self, key, val): # if key in Dict.__reserved_names__: # # Either let OrderedDict do its work, or disallow # if key not in Dict.__pure_names__: # return _dict.__setattr__(self, key, val) # else: # raise AttributeError('Reserved name, this key can only ' + # 'be set via ``d[%r] = X``' % key) # else: # # if isinstance(val, dict): val = Dict(val) -> no, makes a copy! # self[key] = val #@-others #@-<< new config methods >> else: #@+<< old config methods >> #@+node:ekr.20190331052251.1: *3* << old config methods >> #@+others #@+node:ekr.20190317082751.2: *4* ConfigShim.__repr__ def __repr__(self): from pyzo.util.zon import isidentifier # Changed import. identifier_items = [] nonidentifier_items = [] for key, val in self.items(): if isidentifier(key): identifier_items.append('%s=%r' % (key, val)) else: nonidentifier_items.append('(%r, %r)' % (key, val)) if nonidentifier_items: return 'Dict([%s], %s)' % (', '.join(nonidentifier_items), ', '.join(identifier_items)) else: return 'Dict(%s)' % (', '.join(identifier_items)) #@+node:ekr.20190317082751.3: *4* ConfigShim.__getattribute__ def __getattribute__(self, key): try: ### return object.__getattribute__(self, key) val = object.__getattribute__(self, key) if False and key not in ('advanced', 'shortcuts2', 'settings'): # g.pr('===== LeoPyzoConfig 1: %r: %r' % (key, val)) g.pr('===== LeoPyzoConfig 1: %r' % key) return val except AttributeError: if key in self: if False and key not in ('advanced', 'shortcuts2', 'settings'): # g.pr('===== LeoPyzoConfig 1: %r: %r' % (key, g.truncate(self[key], 50))) g.pr('===== LeoPyzoConfig 2: %r' % key) return self[key] else: raise #@+node:ekr.20190317082751.4: *4* ConfigShim.__setattr__ def __setattr__(self, key, val): if key in Dict.__reserved_names__: # Either let OrderedDict do its work, or disallow if key not in Dict.__pure_names__: return _dict.__setattr__(self, key, val) else: raise AttributeError('Reserved name, this key can only ' + 'be set via ``d[%r] = X``' % key) else: # if isinstance(val, dict): val = Dict(val) -> no, makes a copy! self[key] = val