示例#1
0
    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
示例#2
0
 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
示例#3
0
    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.
示例#4
0
    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()
示例#5
0
    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)
示例#6
0
 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
示例#8
0
    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
示例#9
0
    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
示例#10
0
    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)
示例#11
0
    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
示例#12
0
    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!')
示例#13
0
        def fail (self,msg=None):

            """Mark a unit test as having failed."""

            import leo.core.leoGlobals as g

            g.app.unitTestDict["fail"] = g.callers()
示例#14
0
 def listen(self,name):
     
     g.trace(name,g.callers())
     
     self.srv.listen(name)
     
     print("lproto.py: listen on",self.srv.fullServerName())
示例#15
0
 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
示例#16
0
 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))
示例#17
0
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)
示例#18
0
 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()
示例#19
0
    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))
示例#20
0
 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)
示例#21
0
 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)
示例#22
0
 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
示例#23
0
    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()
示例#24
0
 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
示例#25
0
 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))
示例#26
0
    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
示例#27
0
 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
示例#28
0
 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()
示例#29
0
 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
示例#30
0
 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
示例#31
0
 def oops(self):
     """Return a "must be overridden" message"""
     g.pr("BaseEditCommandsClass oops:", g.callers(),
          "must be overridden in subclass")
示例#32
0
        def fail(self, msg=None):
            """Mark a unit test as having failed."""

            import leo.core.leoGlobals as g

            g.app.unitTestDict["fail"] = g.callers()
示例#33
0
 def message (self, func):
     '''
     Send a message to the framework.
     '''
     g.trace('=====', func, g.callers())
示例#34
0
 def trace_status(self, line, new_state, prev_state, stack, top):
     """Do-nothing override of Import.trace_status."""
     assert False, g.callers()
示例#35
0
 def oops(self) -> None:
     g.trace("NullGui", g.callers(4))
示例#36
0
    def oops(self):

        g.trace("StringGui", g.callers(4))
示例#37
0
 def runMainLoop(self):
     g.trace(g.callers())
     sys.exit(0)
示例#38
0
 def oops(self):
     g.pr("LeoMenu oops:", g.callers(4), "should be overridden in subclass")
示例#39
0
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.

"""),
]
示例#40
0
 def oops(self):
     g.pr("textGui oops", g.callers(), "should be implemented")
示例#41
0
    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="""
示例#42
0
 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")
示例#43
0
 def fail(self, msg=None):
     '''Mark an AtShadowTestCase as having failed.'''
     import leo.core.leoGlobals as g
     g.app.unitTestDict["fail"] = g.callers()
示例#44
0
 def fail(self, msg=None):
     """Mark an AtShadowTestCase as having failed."""
     g.app.unitTestDict["fail"] = g.callers()
示例#45
0
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 >>
]
示例#46
0
 def verbatim_error(self):
     x = self
     x.error('file syntax error: nothing follows verbatim sentinel')
     g.trace(g.callers())
示例#47
0
 def create_child_node(self, parent, line, headline):
     """Create a child node of parent."""
     assert False, g.callers()
示例#48
0
 def cut_stack(self, new_state, stack):
     """Cut back the stack until stack[-1] matches new_state."""
     assert False, g.callers()