def __init__ (self,c,char,event,shortcut,w,x,y,x_root,y_root): trace = False and not g.unitTesting if g.isStroke(shortcut): g.trace('***** (leoKeyEvent) oops: already a stroke',shortcut,g.callers()) stroke = shortcut else: stroke = g.KeyStroke(shortcut) if shortcut else None assert g.isStrokeOrNone(stroke),'(leoKeyEvent) %s %s' % ( repr(stroke),g.callers()) if trace: g.trace('(leoKeyEvent) stroke',stroke) self.c = c self.char = char or '' self.event = event # New in Leo 4.11. self.stroke = stroke self.w = self.widget = w # Optional ivars self.x = x self.y = y # Support for fastGotoNode plugin self.x_root = x_root self.y_root = y_root
def __init__(self, c, char, event, binding, w, x=None, y=None, x_root=None, y_root=None ): '''Ctor for LeoKeyEvent class.''' if g.isStroke(binding): g.trace('***** (LeoKeyEvent) oops: already a stroke', binding, g.callers()) stroke = binding else: stroke = g.KeyStroke(binding) if binding else None assert g.isStrokeOrNone(stroke), '(LeoKeyEvent) %s %s' % ( repr(stroke), g.callers()) if 'keys' in g.app.debug: print('LeoKeyEvent: binding: %s, stroke: %s, char: %r' % ( binding, stroke, char)) self.c = c self.char = char or '' self.event = event # New in Leo 4.11. self.stroke = stroke self.w = self.widget = w # Optional ivars self.x = x self.y = y # Support for fastGotoNode plugin self.x_root = x_root self.y_root = y_root
def full_redraw (self,p=None,scroll=True,forceDraw=False): '''Redraw all visible nodes of the tree. Preserve the vertical scrolling unless scroll is True.''' trace = False and not g.app.unitTesting verbose = False c = self.c if g.app.disable_redraw: if trace: g.trace('*** disabled',g.callers()) return if self.busy(): return g.trace('*** full_redraw: busy!',g.callers()) if p is None: p = c.currentPosition() elif c.hoistStack and len(c.hoistStack) == 1 and p.h.startswith('@chapter') and p.hasChildren(): # Make sure the current position is visible. # Part of fix of bug 875323: Hoist an @chapter node leaves a non-visible node selected. p = p.firstChild() if trace: g.trace('selecting',p.h) c.frame.tree.select(p) c.setCurrentPosition(p) else: c.setCurrentPosition(p) self.redrawCount += 1 if trace: t1 = g.getTime() self.initData() self.nodeDrawCount = 0 try: self.redrawing = True self.drawTopTree(p) finally: self.redrawing = False self.setItemForCurrentPosition(scroll=scroll) c.requestRedrawFlag= False if trace: theTime = g.timeSince(t1) g.trace('*** %s: scroll %5s drew %3s nodes in %s' % ( self.redrawCount,scroll,self.nodeDrawCount,theTime),g.callers()) return p # Return the position, which may have changed.
def redraw(self): "redraw after menu used" g.trace(g.callers()) # IMPORTANT ASSUMPTION: called only after menu used # read updates from menu choice # Tk seems to use menu label when '' is used as value? # note, keys not present if coming via clear_all if self.pickles.has_key('node'): if self.pickles['node'].get() == 'CLEO_BLANK': self.pickles['node'].set('') if self.pickles.has_key('archetype'): if self.pickles['archetype'].get() == 'CLEO_BLANK': self.pickles['archetype'].set('') for ky, vl in self.pickles.iteritems(): self.setat(self.pickleV, ky, vl.get()) self.loadIcons(self.pickleP) self.clear_marks(self.c.frame.tree.canvas) self.update_project(self.pickleP) c = self.c c.setChanged(True) c.redraw_now()
def makeCommand(self, chapterName, binding=None): '''Make chapter-select-<chapterName> command.''' trace = False and not g.unitTesting trace_redef = True c, cc = self.c, self commandName = 'chapter-select-%s' % chapterName inverseBindingsDict = c.k.computeInverseBindingDict() if commandName in c.commandsDict: if trace and trace_redef: g.trace('===== already defined', commandName) g.trace('inverse', inverseBindingsDict.get(commandName)) return if trace: g.trace('===== defining', commandName, binding, g.callers(1)) g.trace('inverse', inverseBindingsDict.get(commandName)) def select_chapter_callback(event,cc=cc,name=chapterName): chapter = cc.chaptersDict.get(name) if chapter: try: cc.selectChapterLockout = True cc.selectChapterByNameHelper(chapter,collapse=True) c.redraw(chapter.p) # 2016/04/20. finally: cc.selectChapterLockout = False else: # Possible, but not likely. cc.note('no such chapter: %s' % name) # Always bind the command without a shortcut. # This will create the command bound to any existing settings. bindings = (None, binding) if binding else (None,) for shortcut in bindings: c.k.registerCommand(commandName, select_chapter_callback, shortcut=shortcut)
def hide(self, tag, kwargs, force=False): '''Hide all wikiview tags. Now done in the colorizer.''' trace = False and not g.unitTesting trace_parts = True trace_pats = False c = self.c if not (self.active or force) or kwargs['c'] != c: return w = c.frame.body.widget cursor = w.textCursor() s = w.toPlainText() if trace: g.trace('=====', g.callers()) g.printList(g.splitLines(s)) for urlpat in self.urlpats: if trace and trace_pats: g.trace(repr(urlpat)) for m in urlpat.finditer(s): if trace: g.trace('FOUND', urlpat.pattern, m.start(0), repr(m.group(0))) for group_n, group in enumerate(m.groups()): if group is None: continue if trace and trace_parts: g.trace( m.start(group_n+1), m.end(group_n+1), repr(m.group(group_n+1))) cursor.setPosition(m.start(group_n+1)) cursor.setPosition(m.end(group_n+1), cursor.KeepAnchor) cfmt = cursor.charFormat() cfmt.setFontPointSize(self.pts) cfmt.setFontLetterSpacing(self.pct) # cfmt._is_hidden = True # gets lost cursor.setCharFormat(cfmt)
def doHandlersForTag (self,tag,keywords): """Execute all handlers for a given tag, in alphabetical order. All exceptions are caught by the caller, doHook.""" trace = False and not g.unitTesting traceIdle = False if g.app.killed: return None if trace and (traceIdle or tag != 'idle'): g.trace(tag,g.callers(6)) if tag in self.handlers: bunches = self.handlers.get(tag) # Execute hooks in some random order. # Return if one of them returns a non-None result. for bunch in bunches: val = self.callTagHandler(bunch,tag,keywords) if val is not None: return val if 'all' in self.handlers: bunches = self.handlers.get('all') for bunch in bunches: self.callTagHandler(bunch,tag,keywords) return None
def skipCodeBlock (self,s,i,kind): '''Skip the code block in a function or class definition.''' trace = False start = i if kind == 'class': i = self.skipInterface(s,i) else: i = self.skipBlock(s,i,delim1=None,delim2=None) if self.sigFailTokens: i = g.skip_ws(s,i) for z in self.sigFailTokens: if g.match(s,i,z): if trace: g.trace('failtoken',z) return start,False if i > start: i = self.skipNewline(s,i,kind) if trace: g.trace(g.callers()) g.trace('returns...\n',g.listToString(g.splitLines(s[start:i]))) return i,True
def endGen(self, s): """Remember the underlining characters in the root's uA.""" trace = False and not g.unitTesting p = self.root if p: tag = "rst-import" d = p.v.u.get(tag, {}) underlines1 = "".join([str(z) for z in self.underlines1]) underlines2 = "".join([str(z) for z in self.underlines2]) d["underlines1"] = underlines1 d["underlines2"] = underlines2 self.underlines1 = underlines1 self.underlines2 = underlines2 if trace: g.trace(repr(underlines1), repr(underlines2), g.callers(4)) p.v.u[tag] = d # Append a warning to the root node. warningLines = ( "Warning: this node is ignored when writing this file.", "However, @ @rst-options are recognized in this node.", ) lines = [".. %s" % (z) for z in warningLines] warning = "\n%s\n" % "\n".join(lines) self.root.b = self.root.b + warning
def finishCreate (self): '''Find or make the @chapters and @chapter trash nodes.''' trace = (False or g.trace_startup) and not g.unitTesting if trace: print('cc.finishCreate',g.callers()) cc,c = self,self.c if cc.findChaptersNode(): if hasattr(c.frame.iconBar,'createChaptersIcon'): if not cc.tt: cc.tt = c.frame.iconBar.createChaptersIcon() # Create the main chapter cc.chaptersDict['main'] = Chapter(c,cc,'main') tag = '@chapter' for p in c.all_unique_positions(): h = p.h # if h.startswith(tag) and not h.startswith('@chapters'): if g.match_word(h,0,tag): tabName = h[len(tag):].strip() if tabName and tabName not in ('main',): if cc.chaptersDict.get(tabName): self.error('duplicate chapter name: %s' % tabName) else: cc.chaptersDict[tabName] = Chapter(c,cc,tabName) # Fix bug: https://github.com/leo-editor/leo-editor/issues/31 cc.initing = False # Always select the main chapter. # It can be alarming to open a small chapter in a large .leo file. cc.selectChapterByName('main',collapse=False)
def endGen (self,s): '''Remember the underlining characters in the root's uA.''' trace = False and not g.unitTesting p = self.root if p: tag = 'rst-import' d = p.v.u.get(tag,{}) underlines1 = ''.join([str(z) for z in self.underlines1]) underlines2 = ''.join([str(z) for z in self.underlines2]) d ['underlines1'] = underlines1 d ['underlines2'] = underlines2 self.underlines1 = underlines1 self.underlines2 = underlines2 if trace: g.trace(repr(underlines1),repr(underlines2),g.callers(4)) p.v.u [tag] = d # Append a warning to the root node. warningLines = ( 'Warning: this node is ignored when writing this file.', 'However, @ @rst-options are recognized in this node.', ) lines = ['.. %s' % (z) for z in warningLines] warning = '\n%s\n' % '\n'.join(lines) self.root.b = self.root.b + warning
def selectChapterByName (self,name,collapse=True,create=True): '''Select a chapter. Return True if a redraw is needed.''' trace = False and not g.unitTesting cc,c = self,self.c if type(name) == type(9): return cc.note('PyQt5 chapaters not supported') chapter = cc.chaptersDict.get(name) if chapter: cc.selectChapterByNameHelper(chapter,collapse=collapse) elif create: # There is an @chapter node, but no actual chapter. if trace: g.trace('*** creating',name) cc.createChapterByName(name,p=c.p,undoType='Create Chapter') else: # create is False if called from the minibuffer. # do nothing if the user mis-types. cc.note('no such chapter: %s' % name) chapter = cc.chaptersDict.get('main') if chapter: self.selectChapterByNameHelper(chapter,collapse=collapse) else: g.trace(g.callers()) cc.error('no main chapter!')
def fail (self,msg=None): """Mark a unit test as having failed.""" import leo.core.leoGlobals as g g.app.unitTestDict["fail"] = g.callers()
def listen(self,name): g.trace(name,g.callers()) self.srv.listen(name) print("lproto.py: listen on",self.srv.fullServerName())
def next_place(self, s, offset=0): """ Given string s containing a placeholder like <| block |>, return (s2,start,end) where s2 is s without the <| and |>, and start, end are the positions of the beginning and end of block. """ trace = False c = self.c new_pos = s.find(c.abbrev_place_start, offset) new_end = s.find(c.abbrev_place_end, offset) if (new_pos < 0 or new_end < 0) and offset: new_pos = s.find(c.abbrev_place_start) new_end = s.find(c.abbrev_place_end) if not (new_pos < 0 or new_end < 0): g.es("Found placeholder earlier in body") if new_pos < 0 or new_end < 0: if trace: g.trace('new_pos', new_pos, 'new_end', new_end) return s, None, None start = new_pos place_holder_delim = s[new_pos: new_end + len(c.abbrev_place_end)] place_holder = place_holder_delim[ len(c.abbrev_place_start): -len(c.abbrev_place_end)] s2 = s[: start] + place_holder + s[start + len(place_holder_delim):] end = start + len(place_holder) if trace: g.trace(start, end, g.callers()) return s2, start, end
def note(self, s, killUnitTest=False): if g.unitTesting: if 0: # To trace cause of failed unit test. g.trace('=====',s, g.callers()) if killUnitTest: assert False, s else: g.note('Note: %s' % (s))
def cmd_LoadRecursive(event): """Recursive update, with expansions.""" g.trace(event,g.callers()) c = event.get('c') for s in run_recursive(c): path = getPath(c, s) if path: sync_node_to_folder(c,s,path,updateOnly=True,recurse=True)
def __getattr__(self, name): aList = self.d.get(name, []) callers = g.callers(4) if callers not in aList: aList.append(callers) self.d[name] = aList g.trace('%30s' % ('TemplateMenu.' + name), callers) return g.NullObject()
def oops(self): """Default do-nothing method for NullGui class. It is NOT an error to use this method.""" # It is not usually an error to call methods of this class. # However, this message is useful when writing gui plugins. if 1: g.trace("NullGui", g.callers(4))
def __set_c(self,c): '''Designate the commander to be returned by the getter.''' self.update() if c in self.commanders_list: self.commander = c else: g.trace(g.callers()) raise ValueError(c)
def insert_ignore_directive(self, parent): c = self.c parent.v.b = parent.v.b.rstrip() + '\n@ignore\n' # Do *not* update the screen by setting p.b. if g.unitTesting: g.app.unitTestDict['fail'] = g.callers() elif parent.isAnyAtFileNode() and not parent.isAtAutoNode(): g.warning('inserting @ignore') c.import_error_nodes.append(parent.h)
def ch_level(self, ch): '''Return the underlining level associated with ch.''' assert ch in underlines, (repr(ch), g.callers()) d = self.rst_seen if ch in d: return d.get(ch) else: self.rst_level += 1 d[ch] = self.rst_level return self.rst_level
def selectChapterForPosition(self, p, chapter=None): ''' Select a chapter containing position p. New in Leo 4.11: prefer the given chapter if possible. Do nothing if p if p does not exist or is in the presently selected chapter. Note: this code calls c.redraw() if the chapter changes. ''' trace = False and not g.unitTesting c, cc = self.c, self # New in Leo 4.11 if cc.selectChapterLockout: return selChapter = cc.getSelectedChapter() if trace: g.trace('***', p.h, chapter.name if chapter else 'main', selChapter.name if selChapter else 'main', g.callers(2)) if not chapter and not selChapter: if trace: g.trace('*** selecting main chapter') return if not p: if trace: g.trace('no p') return if not c.positionExists(p): if trace: g.trace('does not exist', p.h) return # New in Leo 4.11: prefer the given chapter if possible. theChapter = chapter or selChapter if not theChapter: return # First, try the presently selected chapter. firstName = theChapter.name # g.trace('===== firstName', firstName) if firstName == 'main': if trace: g.trace('no search: main chapter:', p.h) return if theChapter.positionIsInChapter(p): if trace: g.trace('position found in chapter:', theChapter.name, p.h) cc.selectChapterByName(theChapter.name) return for name in cc.chaptersDict: if name not in (firstName, 'main'): theChapter = cc.chaptersDict.get(name) if theChapter.positionIsInChapter(p): if trace: g.trace('select:', theChapter.name) cc.selectChapterByName(name) break else: if trace: g.trace('select main') cc.selectChapterByName('main') # Fix bug 869385: Chapters make the nav_qt.py plugin useless assert not self.selectChapterLockout # New in Leo 5.6: don't call c.redraw immediately. c.redraw_later()
def update(self, clear=True): """ How should object display itself on the screen. Define here, but do not actually refresh the curses display, since this should be done as little as possible. This base widget puts nothing on screen. """ trace = False and not g.unitTesting if trace: g.trace('===== Widget', g.callers()) if self.hidden: self.clear() return True
def unselect(self): '''Remember chapter info when a chapter is about to be unselected.''' trace = False and not g.unitTesting c = self.c if self.name != 'main' and c.hoistStack: try: c.hoistStack.pop() except Exception: g.trace('c.hoistStack underflow', g.callers()) self.p = c.p if trace: g.trace('*** %s, p: %s' % (self.name, self.p.h))
def skipInterface(self, s, i): """Skip from the opening delim to *past* the matching closing delim. If no matching is found i is set to len(s)""" trace = False start = i delim2 = "end." level = 0 start = i startIndent = self.startSigIndent if trace: g.trace("***", "startIndent", startIndent, g.callers()) while i < len(s): progress = i if g.is_nl(s, i): backslashNewline = i > 0 and g.match(s, i - 1, "\\\n") i = g.skip_nl(s, i) if not backslashNewline and not g.is_nl(s, i): j, indent = g.skip_leading_ws_with_indent(s, i, self.tab_width) line = g.get_line(s, j) if trace: g.trace("indent", indent, line) if indent < startIndent and line.strip(): # An non-empty underindented line. # Issue an error unless it contains just the closing bracket. if level == 1 and g.match(s, j, delim2): pass else: if j not in self.errorLines: # No error yet given. self.errorLines.append(j) self.underindentedLine(line) elif s[i] in (" ", "\t"): i += 1 # speed up the scan. elif self.startsComment(s, i): i = self.skipComment(s, i) elif self.startsString(s, i): i = self.skipString(s, i) elif g.match(s, i, delim2): i += len(delim2) if trace: g.trace("returns\n", repr(s[start:i])) return i else: i += 1 assert progress < i self.error("no interface") if 1: g.pr("** no interface **") i, j = g.getLine(s, start) g.trace(i, s[i:j]) else: if trace: g.trace("** no interface") return start
def computeBody (self,s,start,sigStart,codeEnd): '''Return the body of a section.''' trace = False and not g.unitTesting # Never indent any text; discard the entire signature. body1 = '' body2 = s[self.sigEnd:codeEnd] body2 = g.removeLeadingBlankLines(body2) # Don't warn about missing tail newlines: they will be added. if trace: # g.trace(s[start:sigStart]) g.trace('body: %s' % repr(body1 + body2),'\n',g.callers()) return body1,body2
def display(self): """Do an update of the object AND refresh the screen""" trace = False and not g.unitTesting if trace: name = self.__class__.__name__ if name.startswith('Leo'): g.trace('(Widget)', name, g.callers()) if self.hidden: self.clear() self.parent.refresh() else: self.update() self.parent.refresh()
def propagate_changes(self, old_public_file, old_private_file): ''' Propagate the changes from the public file (without_sentinels) to the private file (with_sentinels) ''' trace, verbose = False and not g.unitTesting, False import leo.core.leoAtFile as leoAtFile x = self ; at = self.c.atFileCommands at.errors = 0 if trace: g.trace('*** header scanned: encoding:',at.encoding) self.encoding = at.encoding s = at.readFileToUnicode(old_private_file) # Sets at.encoding and inits at.readLines. old_private_lines = g.splitLines(s) s = at.readFileToUnicode(old_public_file) if at.encoding != self.encoding: g.trace('can not happen: encoding mismatch: %s %s' % ( at.encoding,self.encoding)) at.encoding = self.encoding old_public_lines = g.splitLines(s) if 0: g.trace('\nprivate lines...%s' % old_private_file) for s in old_private_lines: g.trace(type(s),g.isUnicode(s),repr(s)) g.trace('\npublic lines...%s' % old_public_file) for s in old_public_lines: g.trace(type(s),g.isUnicode(s),repr(s)) marker = x.markerFromFileLines(old_private_lines,old_private_file) if trace and verbose: g.trace( 'marker',marker, '\npublic_file',old_public_file, '\npublic lines...\n%s' %( g.listToString(old_public_lines,toRepr=True)), '\nprivate_file',old_private_file, '\nprivate lines...\n%s\n' %( g.listToString(old_private_lines,toRepr=True))) new_private_lines = x.propagate_changed_lines( old_public_lines,old_private_lines,marker) # Important bug fix: Never create the private file here! fn = old_private_file exists = g.os_path_exists(fn) different = new_private_lines != old_private_lines copy = exists and different if trace: g.trace('\nexists',exists,fn,'different',different,'errors',x.errors,at.errors) # 2010/01/07: check at.errors also. if copy and x.errors == 0 and at.errors == 0: s = ''.join(new_private_lines) ok = x.replaceFileWithString(fn,s) if trace: g.trace('ok',ok,'writing private file',fn,g.callers()) return copy
def check(self, unused_s, parent): '''True if perfect import checks pass.''' if g.app.suppressImportChecks: g.app.suppressImportChecks = False return True c = self.c sfn = g.shortFileName(self.root.h) s1 = g.toUnicode(self.file_s, self.encoding) s2 = self.trial_write() lines1, lines2 = g.splitLines(s1), g.splitLines(s2) if 0: # An excellent trace for debugging. g.trace(c.shortFileName()) g.printObj(lines1, tag='lines1') g.printObj(lines2, tag='lines2') if self.strict: # Ignore blank lines only. # Adding nodes may add blank lines. lines1 = self.strip_blank_lines(lines1) lines2 = self.strip_blank_lines(lines2) else: # Ignore blank lines and leading whitespace. # Importing may regularize whitespace, and that's good. lines1 = self.strip_all(lines1) lines2 = self.strip_all(lines2) # Forgive trailing whitespace problems in the last line. # This is not the same as clean_last_lines. if lines1 and lines2 and lines1 != lines2: lines1[-1] = lines1[-1].rstrip()+'\n' lines2[-1] = lines2[-1].rstrip()+'\n' # self.trace_lines(lines1, lines2, parent) ok = lines1 == lines2 if not ok and not self.strict: # Issue an error only if something *other than* lws is amiss. lines1, lines2 = self.strip_lws(lines1), self.strip_lws(lines2) ok = lines1 == lines2 if ok and not g.unitTesting: print('warning: leading whitespace changed in:', self.root.h) if not ok: self.show_failure(lines1, lines2, sfn) # self.trace_lines(lines1, lines2, parent) # Ensure that the unit tests fail when they should. # Unit tests do not generate errors unless the mismatch line does not match. if g.app.unitTesting: d = g.app.unitTestDict d['result'] = ok if not ok: d['fail'] = g.callers() # Used in a unit test. c.importCommands.errors += 1 return ok
def oops(self): """Return a "must be overridden" message""" g.pr("BaseEditCommandsClass oops:", g.callers(), "must be overridden in subclass")
def fail(self, msg=None): """Mark a unit test as having failed.""" import leo.core.leoGlobals as g g.app.unitTestDict["fail"] = g.callers()
def message (self, func): ''' Send a message to the framework. ''' g.trace('=====', func, g.callers())
def trace_status(self, line, new_state, prev_state, stack, top): """Do-nothing override of Import.trace_status.""" assert False, g.callers()
def oops(self) -> None: g.trace("NullGui", g.callers(4))
def oops(self): g.trace("StringGui", g.callers(4))
def runMainLoop(self): g.trace(g.callers()) sys.exit(0)
def oops(self): g.pr("LeoMenu oops:", g.callers(4), "should be overridden in subclass")
tips = [ UserTip(n=629, tags=['Scripting'], title="Use a universal shortcut for your scripts", text="""\ You can have a personal shortcut to run script while developing it. For example: put `@key=Alt-4` in headline. If your script grows to several subnodes, you won't have to select top node every time you wish to run script. It would be enough to just press your universal shortcut. """), UserTip(n=628, tags=['Scripting'], title="Clearing the Log window", text="""\ When developing scripts that use Log window to display results, it is sometimes useful to clear Log window by inserting the following two lines at the beginning of your script: c.frame.log.selectTab('Log') c.frame.log.clearLog() """), UserTip(n=626, tags=[], title="Use section references sparingly", text="""\ Within scripts, use section references only when code must be placed exactly. Here is a common pattern for @file nodes for python files: @first # -*- coding: utf-8 -*- %s %s """ % (g.angleBrackets('imports'), '@others')), UserTip(n=625, tags=['Markdown', 'Documentation'], title="The @button make-md-toc script in LeoDocs.leo", text="""\ The @button make-md-toc script in LeoDocs.leo writes a markdown table of contents to the console. You can then copy the text from the console to your document. The selected outline node should be an `@auto-md` node. """), UserTip(n=624, tags=['Settings', 'Scripting'], title="The pyflakes command", text="""\ pyflakes is a superb programming tool. It checks python files almost instantly. These settings cause Leo to run pyflakes whenever saving a .py file and to raise a dialog if any errors are found: @bool run-pyflakes-on-write = True @bool syntax-error-popup = True See https://pypi.python.org/pypi/pyflakes. """), UserTip(n=623, tags=['Commands', 'Scripting'], title="The beautify command & @nobeautify directive", text="""\ The @nobeautify directive suppresses beautification of the node in which it appears. """), UserTip(n=622, tags=['Command', 'Testing'], title="The pylint command", text="""\ Leo's pylint command runs pylint on all `@<file>` nodes in the selected trees. Pylint runs in the background, so you can continue to use Leo while pylint runs. See: https://www.pylint.org/. """), UserTip(n=621, tags=['Tutorial', 'Commands'], title="The rst3 command", text="""\ The rst3 command converts an @rst tree to a document file. See http://leoeditor.com/tutorial-rst3.html. """), UserTip(n=620, tags=['PIM', 'Tutorial'], title="Use abbreviations", text="""\ Leo's abbreviations can correct spelling mistakes, expand to multiple lines or even trees of nodes. Abbreviations can execute scripts and can prompt for values to be substituted within the abbreviation. See http://leoeditor.com/tutorial-pim.html#using-abbreviations-and-templates. """), UserTip(n=619, tags=['Tutorial', 'Testing', 'Scripting'], title="Use @test nodes", text="""\ @test nodes create unit tests. They automatically convert the body to a subclass of unittest.TestCase. Leo's run-* commands execute unit tests. See http://leoeditor.com/tutorial-basics.html#test-nodes. """), UserTip(n=618, tags=['Scripting', 'Tutorial'], title="Use @button nodes", text="""\ @button nodes create commands. For example, `@button my-command` creates the `my-command` button and the `my-command` command. Within `@button` scripts, c.p is the presently selected outline node. As a result, @button nodes bring scripts to data. """), UserTip(n=617, tags=['Plugins'], title="Leo's most important plugins", text="""\ Become familiar with Leo's most important plugins: - bookmarks.py manages bookmarks. - contextmenu.py shows a menu when when righ-clicking. - mod_scripting.py supports @button and @command nodes. - quicksearch.py adds a Nav tab for searching. - todo.py handles to-do lists and is a project manager. - valuespace.py creates an outline-oriented spreadsheet. - viewrendered.py renders content in the rendering pane. """), UserTip(n=616, tags=[ 'Settings', ], title="Put personal settings myLeoSettings.leo", text="""\ Put your personal settings in myLeoSettings.leo, not leoSettings.leo. - The leo-settings-leo command opens leoSettings.leo. - The my-leo-settings-leo command opens myLeoSettings.leo. - Copy the desired settings nodes from leoSettings.leo to myLeoSettings.leo. """), UserTip(n=615, tags=[ 'Tutorial', ], title="Learn to use clones", text=""" Clones are "live" copies of the node itself and all its descendants. See http://leoeditor.com/tutorial-pim.html#clones. """), UserTip(n=614, tags=['Command', 'Tutorial'], title="You don't have to remember command names", text=""" To execute a command, type `Alt-X` followed by the first few characters of command name, followed by `Tab`. The list of commands matching what you have typed appears. """), UserTip(n=612, tags=['Commands', 'Power user', 'Scripting', 'Study'], title="Use cff to gather nodes matching a pattern", text=""" The cff command (aka clone-find-flattened) prompts for a search pattern, then clones all matching nodes so they are the children of a new last top-level node. This is a great way to study code. """), UserTip(n=611, tags=['Command', 'Power-User'], title="Use cffm to gather outline nodes", text=""" The cff command (aka clone-find-flattened-marked) clones all marked nodes as a children of a new node, created as the last top-level node. Use this to gather nodes throughout an outline. """), UserTip(n=610, tags=['Scripting', 'Debugging', 'Beginner'], title="g.callers() returns a list of callers", text=""" g.callers() returns the last n callers (default 4) callers of a function or method. The verbose option shows each caller on a separate line. For example: g.trace(g.callers()) You must [launch Leo from a console for this to work. See http://leoeditor.com/running.html#running-leo-from-a-console-window. """), UserTip(n=609, tags=['Scripting', 'Debugging', 'Beginner'], title="Use g.trace to debug scripts", text=""" The g.trace function prints all its arguments to the console. It's great for seeing patterns in running code. You must [launch Leo from a console for this to work. See http://leoeditor.com/running.html#running-leo-from-a-console-window. """), UserTip(n=608, tags=['Scripting', 'Debugging'], title="Use g.pdb from the console", text=""" g.pdb launches Python's pdb debugger, adapted for Leo. See https://docs.python.org/3/library/pdb.html. You must [launch Leo from a console for this to work. See http://leoeditor.com/running.html#running-leo-from-a-console-window. """), UserTip(n=607, tags=['Commands', 'Find'], title="The find-quick-selected command", text=""" The find-quick-selected (Ctrl-Shift-F) command finds all nodes containing the selected text. """), UserTip(n=606, tags=['Commands', 'Scripting'], title="The parse-body command", text=""" The parse-body command parses p.b (the body text of the selected node) into separate nodes. """), UserTip(n=605, tags=[ 'Commands', ], title="The sort-siblings command", text=""" The sort-siblings (Alt-A) command sorts all the child nodes of their parent, or all top-level nodes. """), UserTip(n=0, tags=[ 'Settings', ], title="Search for settings in leoSettings.leo", text=""" leoSettings.leo contains the defaults for all of Leo's settings, with documentation for each. Searching leoSettings.leo is thus a good way to find settings. """), UserTip(n=0, tags=[ 'Commands', 'Power User', ], title='Use Alt-N (goto-next-clone) to find "primary" clone', text=""" Use Alt-N to cycle through the clones of the present cloned node. This is a fast way of finding the clone whose ancestor is an @<file> node. """), UserTip(n=0, tags=[ 'Power User', ], title='Move clones to the last top-level node', text=""" Focus your attention of the task at hand by cloning nodes, including @file nodes, then moving those clones so they are the last top-level nodes in the outline. This allows you to work on nodes scattered throughout an outline without altering the structure of @file nodes. """), UserTip(n=0, tags=[ 'Beginner', ], title='Search LeoDocs.leo', text=""" The easiest way to find information on a topic is to search LeoDocs.leo. """), ]
def oops(self): g.pr("textGui oops", g.callers(), "should be implemented")
n=611, tags=['Command', 'Power-User'], title="Use cffm to gather outline nodes", text=""" The cff command (aka clone-find-flattened-marked) clones all marked nodes as a children of a new node, created as the last top-level node. Use this to gather nodes throughout an outline. """), UserTip( n=610, tags=['Scripting', 'Debugging', 'Beginner'], title="g.callers() returns a list of callers", text=""" g.callers() returns the last n callers (default 4) callers of a function or method. The verbose option shows each caller on a separate line. For example: g.trace(g.callers()) You must [launch Leo from a console for this to work. See http://leoeditor.com/running.html#running-leo-from-a-console-window. """), UserTip( n=609, tags=['Scripting', 'Debugging', 'Beginner'], title="Use g.trace to debug scripts", text="""
def oops(self) -> Any: # It is not usually an error to call methods of this class. # However, this message is useful when writing gui plugins. if 1: g.pr("LeoGui oops", g.callers(4), "should be overridden in subclass")
def fail(self, msg=None): '''Mark an AtShadowTestCase as having failed.''' import leo.core.leoGlobals as g g.app.unitTestDict["fail"] = g.callers()
def fail(self, msg=None): """Mark an AtShadowTestCase as having failed.""" g.app.unitTestDict["fail"] = g.callers()
tips = [ #@+<< define tips >> #@+node:ekr.20180121053422.1: ** << define tips >> #@@wrap #@+others #@+node:ekr.20180324073355.1: *3* Misc. tips #@+node:ekr.20180324065653.2: *4* Most important plugins UserTip(n=617, tags=['Plugins'], title="Leo's most important plugins", text="""\ Become familiar with Leo's most important plugins: - bookmarks.py manages bookmarks. - contextmenu.py shows a menu when when righ-clicking. - mod_scripting.py supports @button and @command nodes. The eval* command support persistent evaluation. - quicksearch.py adds a Nav tab for searching. - todo.py handles to-do lists and is a project manager. - viewrendered.py renders content in the rendering pane. """), #@+node:ekr.20180324072923.1: *4* Move clones to last top-level node UserTip(n=0, tags=[ 'Power User', ], title='Move clones to the last top-level node', text=""" Focus your attention of the task at hand by cloning nodes, including @file nodes, then moving those clones so they are the last top-level nodes in the outline. This allows you to work on nodes scattered throughout an outline without altering the structure of @file nodes. """), #@+node:ekr.20180324065653.3: *4* myLeoSettings.leo UserTip(n=616, tags=[ 'Settings', ], title="Put personal settings myLeoSettings.leo", text="""\ Put your personal settings in myLeoSettings.leo, not leoSettings.leo. - The leo-settings-leo command opens leoSettings.leo. - The my-leo-settings-leo command opens myLeoSettings.leo. - Copy the desired settings nodes from leoSettings.leo to myLeoSettings.leo. """), #@+node:ekr.20180324065152.3: *4* Re @button make-md-toc UserTip(n=625, tags=['Markdown', 'Documentation'], title="The @button make-md-toc script in LeoDocs.leo", text="""\ The @button make-md-toc script in LeoDocs.leo writes a markdown table of contents to the console. You can then copy the text from the console to your document. The selected outline node should be an `@auto-md` node. """), #@+node:ekr.20180324073053.1: *3* Tips re Commands #@+node:ekr.20180324065153.1: *4* beautify command & @nobeautify UserTip(n=623, tags=['Commands', 'Scripting'], title="The beautify command & @nobeautify directive", text="""\ The @nobeautify directive suppresses beautification of the node in which it appears. """), #@+node:ekr.20180324072156.1: *4* cff command UserTip(n=612, tags=['Commands', 'Power user', 'Scripting', 'Study'], title="Use cff to gather nodes matching a pattern", text=""" The cff command (aka clone-find-flattened) prompts for a search pattern, then clones all matching nodes so they are the children of a new last top-level node. This is a great way to study code. """), #@+node:ekr.20180324072433.1: *4* cffm command UserTip(n=611, tags=['Command', 'Power-User'], title="Use cffm to gather outline nodes", text=""" The cff command (aka clone-find-flattened-marked) clones all marked nodes as a children of a new node, created as the last top-level node. Use this to gather nodes throughout an outline. """), #@+node:ekr.20180324072541.1: *4* find-quick-selected command UserTip(n=607, tags=['Commands', 'Find'], title="The find-quick-selected command", text=""" The find-quick-selected (Ctrl-Shift-F) command finds all nodes containing the selected text. """), #@+node:ekr.20180324072904.1: *4* goto-next-clone command UserTip(n=0, tags=[ 'Commands', 'Power User', ], title='Use Alt-N (goto-next-clone) to find "primary" clone', text=""" Use Alt-N to cycle through the clones of the present cloned node. This is a fast way of finding the clone whose ancestor is an @<file> node. """), #@+node:ekr.20180324065153.6: *4* leo-* commands UserTip(n=0, tags=[ 'Commands', ], title='Use leo-* commands to open common .leo files', text=""" You can open files such as CheatSheet.leo, quickstart.leo, leoSettings.leo, myLeoSettings.leo and scripts.leo with commands starting with 'leo-'. <Alt-X>leo-<tab> shows the complete list. """), #@+node:ekr.20180324072609.1: *4* parse-body command UserTip(n=606, tags=['Commands', 'Scripting'], title="The parse-body command", text=""" The parse-body command parses p.b (the body text of the selected node) into separate nodes. """), #@+node:ekr.20180324065153.2: *4* pylint command UserTip(n=622, tags=['Command', 'Testing'], title="The pylint command", text="""\ Leo's pylint command runs pylint on all `@<file>` nodes in the selected trees. Pylint runs in the background, so you can continue to use Leo while pylint runs. See: https://www.pylint.org/. """), #@+node:ekr.20180324073008.1: *4* repeat-complex-command UserTip(n=0, tags=[ 'Power User', ], title='Use Ctrl-P (repeat-complex-command) to avoid key bindings', text=""" Ctrl-P re-executes the last command made from the minibuffer. You can use this to avoid having to define key bindings. For example, instead of pressing an @button button, execute its command from the minibuffer. Now you can re-execute the button using Ctrl-P. """), #@+node:ekr.20180324065153.3: *4* rst3 command UserTip(n=621, tags=['Tutorial', 'Commands'], title="The rst3 command", text="""\ The rst3 command converts an @rst tree to a document file. See http://leoeditor.com/tutorial-rst3.html. """), #@+node:ekr.20180324072625.1: *4* sort-siblings command UserTip(n=605, tags=[ 'Commands', ], title="The sort-siblings command", text=""" The sort-siblings (Alt-A) command sorts all the child nodes of their parent, or all top-level nodes. """), #@+node:ekr.20180324073210.1: *3* Tips re Scripting #@+node:ekr.20180324065152.1: *4* Clearing the log window UserTip(n=628, tags=['Scripting'], title="Clearing the Log window", text="""\ When developing scripts that use Log window to display results, it is sometimes useful to clear Log window by inserting the following two lines at the beginning of your script: c.frame.log.selectTab('Log') c.frame.log.clearLog() """), #@+node:ekr.20180324072452.1: *4* g.callers() UserTip(n=610, tags=['Scripting', 'Debugging', 'Beginner'], title="g.callers() returns a list of callers", text=""" g.callers() returns the last n callers (default 4) callers of a function or method. The verbose option shows each caller on a separate line. For example: g.trace(g.callers()) You must [launch Leo from a console for this to work. See http://leoeditor.com/running.html#running-leo-from-a-console-window. """), #@+node:ekr.20180324072527.1: *4* g.pdb UserTip(n=608, tags=['Scripting', 'Debugging'], title="Use g.pdb from the console", text=""" g.pdb launches Python's pdb debugger, adapted for Leo. See https://docs.python.org/3/library/pdb.html. You must [launch Leo from a console for this to work. See http://leoeditor.com/running.html#running-leo-from-a-console-window. """), #@+node:ekr.20180324072513.1: *4* g.trace UserTip(n=609, tags=['Scripting', 'Debugging', 'Beginner'], title="Use g.trace to debug scripts", text=""" The g.trace function prints all its arguments to the console. It's great for seeing patterns in running code. You must [launch Leo from a console for this to work. See http://leoeditor.com/running.html#running-leo-from-a-console-window. """), #@+node:ekr.20180324065152.4: *4* Pyflakes UserTip(n=624, tags=['Settings', 'Scripting'], title="The pyflakes command", text="""\ pyflakes is a superb programming tool. It checks python files almost instantly. These settings cause Leo to run pyflakes whenever saving a .py file and to raise a dialog if any errors are found: @bool run-pyflakes-on-write = True @bool syntax-error-popup = True See https://pypi.python.org/pypi/pyflakes. """), #@+node:ekr.20180324065653.1: *4* Re @button UserTip(n=618, tags=['Scripting', 'Tutorial'], title="Use @button nodes", text="""\ @button nodes create commands. For example, `@button my-command` creates the `my-command` button and the `my-command` command. Within `@button` scripts, c.p is the presently selected outline node. As a result, @button nodes bring scripts to data. """), #@+node:ekr.20180324065153.5: *4* Re @test UserTip(n=619, tags=['Tutorial', 'Testing', 'Scripting'], title="Use @test nodes", text="""\ @test nodes create unit tests. They automatically convert the body to a subclass of unittest.TestCase. Leo's run-* commands execute unit tests. See http://leoeditor.com/tutorial-basics.html#test-nodes. """), #@+node:ekr.20180324065152.2: *4* Section refs vs @others UserTip(n=626, tags=[], title="Use section references sparingly", text="""\ Within scripts, use section references only when code must be placed exactly. Here is a common pattern for @file nodes for python files: @first # -*- coding: utf-8 -*- %s %s """ % (g.angleBrackets('imports'), '@others')), #@+node:ekr.20180324085629.1: *4* Use section refs to avoid "one @others per node" rule UserTip(n=0, tags=[ 'Scripting', ], title='Use section refs to avoid one @others per node rule', text="""\ Nodes can have at most one @others directive. You can work around this restriction as follows: %(at)sfile myFile.py %(at)sothers %(start)s organizer %(end)s where the body of the %(start)s organizer %(end)s node contains just @others.""" % { 'at': "@", 'end': ">>", 'start': "<<", }), #@+node:ekr.20180324073458.1: *3* Tips re Work flow #@+node:ekr.20180324065153.4: *4* Abbreviations UserTip(n=620, tags=['PIM', 'Tutorial'], title="Use abbreviations", text="""\ Leo's abbreviations can correct spelling mistakes, expand to multiple lines or even trees of nodes. Abbreviations can execute scripts and can prompt for values to be substituted within the abbreviation. See http://leoeditor.com/tutorial-pim.html#using-abbreviations-and-templates. """), #@+node:ekr.20180324072110.1: *4* Clones UserTip(n=615, tags=[ 'Tutorial', ], title="Learn to use clones", text=""" Clones are "live" copies of the node itself and all its descendants. See http://leoeditor.com/tutorial-pim.html#clones. """), #@+node:ekr.20180324072812.1: *4* Search for settings UserTip(n=0, tags=[ 'Settings', ], title="Search for settings in leoSettings.leo", text=""" leoSettings.leo contains the defaults for all of Leo's settings, with documentation for each. Searching leoSettings.leo is thus a good way to find settings. """), #@+node:ekr.20180324072951.1: *4* Search LeoDocs.leo UserTip(n=0, tags=[ 'Beginner', ], title='Search LeoDocs.leo', text=""" The easiest way to find information on a topic is to search LeoDocs.leo. """), #@+node:ekr.20180324072128.1: *4* Typing completion UserTip(n=614, tags=['Command', 'Tutorial'], title="You don't have to remember command names", text=""" To execute a command, type `Alt-X` followed by the first few characters of command name, followed by `Tab`. The list of commands matching what you have typed appears. """), #@+node:ekr.20180324065145.1: *4* Use a universal shortcut UserTip(n=629, tags=['Scripting'], title="Use a universal shortcut for your scripts", text="""\ You can have a personal shortcut to run script while developing it. For example: put `@key=Alt-4` in headline. If your script grows to several subnodes, you won't have to select top node every time you wish to run script. It would be enough to just press your universal shortcut. """), #@+node:ekr.20180312101254.1: *4* How to find your @command nodes UserTip(n=0, tags=['Settings'], title="How to find all your @command nodes", text="""\ myLeoSettings.leo can define *common* @command nodes that apply to all outlines. Such nodes reside in the @commands subtree of the @settings tree in myLeoSettings.leo. <alt-x>@c<tab> shows all the @command nodes in effect for the present outline, no matter where defined. """), #@-others #@-<< define tips >> ]
def verbatim_error(self): x = self x.error('file syntax error: nothing follows verbatim sentinel') g.trace(g.callers())
def create_child_node(self, parent, line, headline): """Create a child node of parent.""" assert False, g.callers()
def cut_stack(self, new_state, stack): """Cut back the stack until stack[-1] matches new_state.""" assert False, g.callers()