Ejemplo n.º 1
0
def alwaysIndentBody(self, event=None):
    """
    The always-indent-region command indents each line of the selected body
    text. The @tabwidth directive in effect determines amount of
    indentation.
    """
    c, p, u, w = self, self.p, self.undoer, self.frame.body.wrapper
    #
    # #1801: Don't rely on bindings to ensure that we are editing the body.
    event_w = event and event.w
    if event_w != w:
        c.insertCharFromEvent(event)
        return
    #
    # "Before" snapshot.
    bunch = u.beforeChangeBody(p)
    #
    # Initial data.
    sel_1, sel_2 = w.getSelectionRange()
    tab_width = c.getTabWidth(p)
    head, lines, tail, oldSel, oldYview = self.getBodyLines()
    #
    # Calculate the result.
    changed, result = False, []
    for line in lines:
        if line.strip():
            i, width = g.skip_leading_ws_with_indent(line, 0, tab_width)
            s = g.computeLeadingWhitespace(width + abs(tab_width),
                                           tab_width) + line[i:]
            result.append(s)
            if s != line:
                changed = True
        else:
            result.append('\n')  # #2418
    if not changed:
        return
    #
    # Set p.b and w's text first.
    middle = ''.join(result)
    all = head + middle + tail
    p.b = all  # Sets dirty and changed bits.
    w.setAllText(all)
    #
    # Calculate the proper selection range (i, j, ins).
    if sel_1 == sel_2:
        line = result[0]
        i, width = g.skip_leading_ws_with_indent(line, 0, tab_width)
        i = j = len(head) + i
    else:
        i = len(head)
        j = len(head) + len(middle)
        if middle.endswith('\n'):  # #1742.
            j -= 1
    #
    # Set the selection range and scroll position.
    w.setSelectionRange(i, j, insert=j)
    w.setYScrollPosition(oldYview)
    #
    # "after" snapshot.
    u.afterChangeBody(p, 'Indent Region', bunch)
Ejemplo n.º 2
0
 def pythonNewlineHelper(self, s, i, parenCount, startIndent,
                         underIndentedStart):
     trace = False
     breakFlag = False
     j, indent = g.skip_leading_ws_with_indent(s, i, self.tab_width)
     if trace:
         g.trace('startIndent', startIndent, 'indent', indent, 'parenCount',
                 parenCount, 'line', repr(g.get_line(s, j)))
     if indent <= startIndent and parenCount == 0:
         # An underindented line: it ends the block *unless*
         # it is a blank or comment line or (2008/9/1) the end of a triple-quoted string.
         if g.match(s, j, '#'):
             if trace: g.trace('underindent: comment')
             if underIndentedStart is None: underIndentedStart = i
             i = j
         elif g.match(s, j, '\n'):
             if trace: g.trace('underindent: blank line')
             # Blank lines never start the range of underindented lines.
             i = j
         else:
             if trace: g.trace('underindent: end of block')
             breakFlag = True  # The actual end of the block.
     else:
         if underIndentedStart and g.match(s, j, '\n'):
             # Add the blank line to the underindented range.
             if trace:
                 g.trace(
                     'properly indented blank line extends underindent range'
                 )
         elif underIndentedStart and g.match(s, j, '#'):
             # Add the (properly indented!) comment line to the underindented range.
             if trace:
                 g.trace(
                     'properly indented comment line extends underindent range'
                 )
         elif underIndentedStart is None:
             pass
         else:
             # A properly indented non-comment line.
             # Give a message for all underindented comments in underindented range.
             if trace:
                 g.trace(
                     'properly indented line generates underindent errors')
             s2 = s[underIndentedStart:i]
             lines = g.splitlines(s2)
             for line in lines:
                 if line.strip():
                     junk, indent = g.skip_leading_ws_with_indent(
                         line, 0, self.tab_width)
                     if indent <= startIndent:
                         if j not in self.errorLines:  # No error yet given.
                             self.errorLines.append(j)
                             self.underindentedComment(line)
             underIndentedStart = None
     if trace:
         g.trace('breakFlag', breakFlag, 'returns', i, 'underIndentedStart',
                 underIndentedStart)
     return i, underIndentedStart, breakFlag
Ejemplo n.º 3
0
def indentBody(self, event=None):
    '''
    The indent-region command indents each line of the selected body text,
    or each line of a node if there is no selected text. The @tabwidth directive
    in effect determines amount of indentation. (not yet) A numeric argument
    specifies the column to indent to.
    '''
    c, undoType = self, 'Indent Region'
    w = c.frame.body.wrapper
    sel_1, sel_2 = w.getSelectionRange()
    ins = w.getInsertPoint()
    tab_width = c.getTabWidth(c.p)
    head, lines, tail, oldSel, oldYview = self.getBodyLines()
    changed, result = False, []
    for line in lines:
        i, width = g.skip_leading_ws_with_indent(line, 0, tab_width)
        s = g.computeLeadingWhitespace(width + abs(tab_width), tab_width) + line[i:]
        if s != line: changed = True
        result.append(s)
    if changed:
        # Leo 5.6: preserve insert point.
        preserveSel = sel_1 == sel_2
        if preserveSel:
            ins += tab_width
            oldSel = ins, ins
        result = ''.join(result)
        c.updateBodyPane(head, result, tail, undoType, oldSel, oldYview, preserveSel)
Ejemplo n.º 4
0
 def regularize_whitespace(self, lines):
     """
     Regularize leading whitespace in s:
     Convert tabs to blanks or vice versa depending on the @tabwidth in effect.
     """
     kind = 'tabs' if self.tab_width > 0 else 'blanks'
     kind2 = 'blanks' if self.tab_width > 0 else 'tabs'
     fn = g.shortFileName(self.root.h)
     count, result, tab_width = 0, [], self.tab_width
     self.ws_error = False  # 2016/11/23
     if tab_width < 0:  # Convert tabs to blanks.
         for n, line in enumerate(lines):
             i, w = g.skip_leading_ws_with_indent(line, 0, tab_width)
             # Use negative width.
             s = g.computeLeadingWhitespace(w, -abs(tab_width)) + line[i:]
             if s != line:
                 count += 1
             result.append(s)
     elif tab_width > 0:  # Convert blanks to tabs.
         for n, line in enumerate(lines):
             # Use positive width.
             s = g.optimizeLeadingWhitespace(line, abs(tab_width))
             if s != line:
                 count += 1
             result.append(s)
     if count:
         self.ws_error = True  # A flag to check.
         if not g.unitTesting:
             # g.es_print('Warning: Intermixed tabs and blanks in', fn)
             # g.es_print('Perfect import test will ignoring leading whitespace.')
             g.es('changed leading %s to %s in %s line%s in %s' % (
                 kind2, kind, count, g.plural(count), fn))
         if g.unitTesting:  # Sets flag for unit tests.
             self.report('changed %s lines' % count)
     return result
Ejemplo n.º 5
0
def indentBody(self, event=None):
    '''
    The indent-region command indents each line of the selected body text,
    or each line of a node if there is no selected text. The @tabwidth directive
    in effect determines amount of indentation. (not yet) A numeric argument
    specifies the column to indent to.
    '''
    c, undoType = self, 'Indent Region'
    w = c.frame.body.wrapper
    sel_1, sel_2 = w.getSelectionRange()
    ins = w.getInsertPoint()
    tab_width = c.getTabWidth(c.p)
    head, lines, tail, oldSel, oldYview = self.getBodyLines()
    changed, result = False, []
    for line in lines:
        i, width = g.skip_leading_ws_with_indent(line, 0, tab_width)
        s = g.computeLeadingWhitespace(width + abs(tab_width),
                                       tab_width) + line[i:]
        if s != line: changed = True
        result.append(s)
    if changed:
        # Leo 5.6: preserve insert point.
        preserveSel = sel_1 == sel_2
        if preserveSel:
            ins += tab_width
            oldSel = ins, ins
        result = ''.join(result)
        c.updateBodyPane(head, result, tail, undoType, oldSel, oldYview,
                         preserveSel)
Ejemplo n.º 6
0
 def regularizeWhitespace(self, s):
     '''Regularize leading whitespace in s:
     Convert tabs to blanks or vice versa depending on the @tabwidth in effect.
     This is only called for strict languages.'''
     changed = False
     lines = g.splitLines(s)
     result = []
     tab_width = self.tab_width
     if tab_width < 0:  # Convert tabs to blanks.
         for line in lines:
             i, w = g.skip_leading_ws_with_indent(line, 0, tab_width)
             s = g.computeLeadingWhitespace(
                 w, -abs(tab_width)) + line[i:]  # Use negative width.
             if s != line: changed = True
             result.append(s)
     elif tab_width > 0:  # Convert blanks to tabs.
         for line in lines:
             s = g.optimizeLeadingWhitespace(
                 line, abs(tab_width))  # Use positive width.
             if s != line: changed = True
             result.append(s)
     if changed:
         action = 'tabs converted to blanks' if self.tab_width < 0 else 'blanks converted to tabs'
         message = 'inconsistent leading whitespace. %s' % action
         self.report(message)
     return ''.join(result)
Ejemplo n.º 7
0
def convertTabs(self, event=None):
    '''Convert all tabs to blanks in the selected node.'''
    c = self
    changed = False
    dirtyVnodeList = []
    head, lines, tail, oldSel, oldYview = self.getBodyLines(
        expandSelection=True)
    # Use the relative @tabwidth, not the global one.
    theDict = c.scanAllDirectives()
    tabWidth = theDict.get("tabwidth")
    if tabWidth:
        result = []
        for line in lines:
            i, w = g.skip_leading_ws_with_indent(line, 0, tabWidth)
            s = g.computeLeadingWhitespace(
                w, -abs(tabWidth)) + line[i:]  # use negative width.
            if s != line: changed = True
            result.append(s)
        if changed:
            undoType = 'Convert Tabs'
            result = ''.join(result)
            oldSel = None
            dirtyVnodeList = c.updateBodyPane(head, result, tail, undoType,
                                              oldSel, oldYview)  # Handles undo
    return changed, dirtyVnodeList
Ejemplo n.º 8
0
    def pythonNewlineHelper (self,s,i,parenCount,startIndent,underIndentedStart):

        trace = False
        breakFlag = False
        j, indent = g.skip_leading_ws_with_indent(s,i,self.tab_width)
        if trace: g.trace(
            'startIndent',startIndent,'indent',indent,'parenCount',parenCount,
            'line',repr(g.get_line(s,j)))
        if indent <= startIndent and parenCount == 0:
            # An underindented line: it ends the block *unless*
            # it is a blank or comment line or (2008/9/1) the end of a triple-quoted string.
            if g.match(s,j,'#'):
                if trace: g.trace('underindent: comment')
                if underIndentedStart is None: underIndentedStart = i
                i = j
            elif g.match(s,j,'\n'):
                if trace: g.trace('underindent: blank line')
                # Blank lines never start the range of underindented lines.
                i = j
            else:
                if trace: g.trace('underindent: end of block')
                breakFlag = True # The actual end of the block.
        else:
            if underIndentedStart and g.match(s,j,'\n'):
                # Add the blank line to the underindented range.
                if trace: g.trace('properly indented blank line extends underindent range')
            elif underIndentedStart and g.match(s,j,'#'):
                # Add the (properly indented!) comment line to the underindented range.
                if trace: g.trace('properly indented comment line extends underindent range')
            elif underIndentedStart is None:
                pass
            else:
                # A properly indented non-comment line.
                # Give a message for all underindented comments in underindented range.
                if trace: g.trace('properly indented line generates underindent errors')
                s2 = s[underIndentedStart:i]
                lines = g.splitlines(s2)
                for line in lines:
                    if line.strip():
                        junk, indent = g.skip_leading_ws_with_indent(line,0,self.tab_width)
                        if indent <= startIndent:
                            if j not in self.errorLines: # No error yet given.
                                self.errorLines.append(j)
                                self.underindentedComment(line)
                underIndentedStart = None
        if trace: g.trace('breakFlag',breakFlag,'returns',i,'underIndentedStart',underIndentedStart)
        return i,underIndentedStart,breakFlag
Ejemplo n.º 9
0
def extract(self, event=None):
    r'''
    Create child node from the selected body text.

    1. If the selection starts with a section reference, the section
       name becomes the child's headline. All following lines become
       the child's body text. The section reference line remains in
       the original body text.

    2. If the selection looks like a definition line (for the Python,
       JavaScript, CoffeeScript or Clojure languages) the
       class/function/method name becomes the child's headline and all
       selected lines become the child's body text.
       
       You may add additional regex patterns for definition lines using
       @data extract-patterns nodes. Each line of the body text should a
       valid regex pattern. Lines starting with # are comment lines. Use \#
       for patterns starting with #.

    3. Otherwise, the first line becomes the child's headline, and all
       selected lines become the child's body text.
    '''
    c = self
    current = c.p  # Unchanging.
    u, undoType = c.undoer, 'Extract'
    head, lines, tail, oldSel, oldYview = c.getBodyLines()
    if not lines:
        return  # Nothing selected.
    # Remove leading whitespace.
    junk, ws = g.skip_leading_ws_with_indent(lines[0], 0, c.tab_width)
    lines = [g.removeLeadingWhitespace(s, ws, c.tab_width) for s in lines]
    h = lines[0].strip()
    ref_h = extractRef(c, h).strip()
    def_h = extractDef_find(c, lines)
    if ref_h:
        # h,b,middle = ref_h,lines[1:],lines[0]
        # 2012/02/27: Change suggested by vitalije ([email protected])
        h, b, middle = ref_h, lines[1:], ' ' * ws + lines[0]
    elif def_h:
        h, b, middle = def_h, lines, ''
    else:
        h, b, middle = lines[0].strip(), lines[1:], ''
    u.beforeChangeGroup(current, undoType)
    undoData = u.beforeInsertNode(current)
    p = createLastChildNode(c, current, h, ''.join(b))
    u.afterInsertNode(p, undoType, undoData)
    c.updateBodyPane(head,
                     middle,
                     tail,
                     undoType=undoType,
                     oldSel=None,
                     oldYview=oldYview)
    u.afterChangeGroup(current, undoType=undoType)
    p.parent().expand()
    c.redraw(p.parent())  # A bit more convenient than p.
    c.bodyWantsFocus()
Ejemplo n.º 10
0
def dedentBody(self, event=None):
    """Remove one tab's worth of indentation from all presently selected lines."""
    c, p, u, w = self, self.p, self.undoer, self.frame.body.wrapper
    #
    # Initial data.
    sel_1, sel_2 = w.getSelectionRange()
    tab_width = c.getTabWidth(c.p)
    head, lines, tail, oldSel, oldYview = self.getBodyLines()
    bunch = u.beforeChangeBody(p)
    #
    # Calculate the result.
    changed, result = False, []
    for line in lines:
        i, width = g.skip_leading_ws_with_indent(line, 0, tab_width)
        s = g.computeLeadingWhitespace(width - abs(tab_width),
                                       tab_width) + line[i:]
        if s != line:
            changed = True
        result.append(s)
    if not changed:
        return
    #
    # Set p.b and w's text first.
    middle = ''.join(result)
    all = head + middle + tail
    p.b = all  # Sets dirty and changed bits.
    w.setAllText(all)
    #
    # Calculate the proper selection range (i, j, ins).
    if sel_1 == sel_2:
        line = result[0]
        ins, width = g.skip_leading_ws_with_indent(line, 0, tab_width)
        i = j = len(head) + ins
    else:
        i = len(head)
        j = len(head) + len(middle)
        if middle.endswith('\n'):  # #1742.
            j -= 1
    #
    # Set the selection range and scroll position.
    w.setSelectionRange(i, j, insert=j)
    w.setYScrollPosition(oldYview)
    u.afterChangeBody(p, 'Unindent Region', bunch)
Ejemplo n.º 11
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
Ejemplo n.º 12
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
Ejemplo n.º 13
0
def extract(self, event=None):
    r'''
    Create child node from the selected body text.

    1. If the selection starts with a section reference, the section
       name becomes the child's headline. All following lines become
       the child's body text. The section reference line remains in
       the original body text.

    2. If the selection looks like a definition line (for the Python,
       JavaScript, CoffeeScript or Clojure languages) the
       class/function/method name becomes the child's headline and all
       selected lines become the child's body text.
       
       You may add additional regex patterns for definition lines using
       @data extract-patterns nodes. Each line of the body text should a
       valid regex pattern. Lines starting with # are comment lines. Use \#
       for patterns starting with #.

    3. Otherwise, the first line becomes the child's headline, and all
       selected lines become the child's body text.
    '''
    c = self
    current = c.p # Unchanging.
    u, undoType = c.undoer, 'Extract'
    head, lines, tail, oldSel, oldYview = c.getBodyLines()
    if not lines:
        return # Nothing selected.
    # Remove leading whitespace.
    junk, ws = g.skip_leading_ws_with_indent(lines[0], 0, c.tab_width)
    lines = [g.removeLeadingWhitespace(s, ws, c.tab_width) for s in lines]
    h = lines[0].strip()
    ref_h = extractRef(c, h).strip()
    def_h = extractDef_find(c, lines)
    if ref_h:
        # h,b,middle = ref_h,lines[1:],lines[0]
        # 2012/02/27: Change suggested by vitalije ([email protected])
        h, b, middle = ref_h, lines[1:], ' ' * ws + lines[0]
    elif def_h:
        h, b, middle = def_h, lines, ''
    else:
        h, b, middle = lines[0].strip(), lines[1:], ''
    u.beforeChangeGroup(current, undoType)
    undoData = u.beforeInsertNode(current)
    p = createLastChildNode(c, current, h, ''.join(b))
    u.afterInsertNode(p, undoType, undoData)
    c.updateBodyPane(head, middle, tail,
        undoType=undoType, oldSel=None, oldYview=oldYview)
    u.afterChangeGroup(current, undoType=undoType)
    p.parent().expand()
    c.redraw(p.parent()) # A bit more convenient than p.
    c.bodyWantsFocus()
Ejemplo n.º 14
0
def convertAllBlanks(self, event=None):
    '''Convert all blanks to tabs in the selected outline.'''
    c = self
    u = c.undoer
    undoType = 'Convert All Blanks'
    current = c.p
    if g.app.batchMode:
        c.notValidInBatchMode(undoType)
        return
    d = c.scanAllDirectives()
    tabWidth = d.get("tabwidth")
    count = 0
    dirtyVnodeList = []
    u.beforeChangeGroup(current, undoType)
    for p in current.self_and_subtree():
        # g.trace(p.h,tabWidth)
        innerUndoData = u.beforeChangeNodeContents(p)
        if p == current:
            changed, dirtyVnodeList2 = c.convertBlanks(event)
            if changed:
                count += 1
                dirtyVnodeList.extend(dirtyVnodeList2)
        else:
            changed = False
            result = []
            text = p.v.b
            lines = text.split('\n')
            for line in lines:
                i, w = g.skip_leading_ws_with_indent(line, 0, tabWidth)
                s = g.computeLeadingWhitespace(
                    w, abs(tabWidth)) + line[i:]  # use positive width.
                if s != line: changed = True
                result.append(s)
            if changed:
                count += 1
                dirtyVnodeList2 = p.setDirty()
                dirtyVnodeList.extend(dirtyVnodeList2)
                result = '\n'.join(result)
                p.setBodyString(result)
                u.afterChangeNodeContents(p, undoType, innerUndoData)
    u.afterChangeGroup(current, undoType, dirtyVnodeList=dirtyVnodeList)
    if not g.unitTesting:
        g.es("blanks converted to tabs in", count, "nodes")
        # Must come before c.redraw().
    if count > 0:
        c.redraw_after_icons_changed()
Ejemplo n.º 15
0
def convertTabs(self, event=None):
    """Convert all tabs to blanks in the selected node."""
    c, p, u, w = self, self.p, self.undoer, self.frame.body.wrapper
    #
    # "Before" snapshot.
    bunch = u.beforeChangeBody(p)
    #
    # Data...
    w.selectAllText()
    head, lines, tail, oldSel, oldYview = self.getBodyLines()
    # Use the relative @tabwidth, not the global one.
    theDict = c.scanAllDirectives(p)
    tabWidth = theDict.get("tabwidth")
    if not tabWidth:
        return False
    #
    # Calculate the result.
    changed, result = False, []
    for line in lines:
        i, width = g.skip_leading_ws_with_indent(line, 0, tabWidth)
        s = g.computeLeadingWhitespace(
            width, -abs(tabWidth)) + line[i:]  # use negative width.
        if s != line:
            changed = True
        result.append(s)
    if not changed:
        return False
    #
    # Set p.b and w's text first.
    middle = ''.join(result)
    p.b = head + middle + tail  # Sets dirty and changed bits.
    w.setAllText(head + middle + tail)
    #
    # Calculate the proper selection range (i, j, ins).
    i = len(head)
    j = max(i, len(head) + len(middle) - 1)
    #
    # Set the selection range and scroll position.
    w.setSelectionRange(i, j, insert=j)
    w.setYScrollPosition(oldYview)
    #
    # "after" snapshot.
    u.afterChangeBody(p, 'Add Comments', bunch)
    return True
Ejemplo n.º 16
0
def convertTabs(self, event=None):
    '''Convert all tabs to blanks in the selected node.'''
    c = self; changed = False; dirtyVnodeList = []
    head, lines, tail, oldSel, oldYview = self.getBodyLines(expandSelection=True)
    # Use the relative @tabwidth, not the global one.
    theDict = c.scanAllDirectives()
    tabWidth = theDict.get("tabwidth")
    if tabWidth:
        result = []
        for line in lines:
            i, w = g.skip_leading_ws_with_indent(line, 0, tabWidth)
            s = g.computeLeadingWhitespace(w, -abs(tabWidth)) + line[i:] # use negative width.
            if s != line: changed = True
            result.append(s)
        if changed:
            undoType = 'Convert Tabs'
            result = ''.join(result)
            oldSel = None
            dirtyVnodeList = c.updateBodyPane(head, result, tail, undoType, oldSel, oldYview) # Handles undo
    return changed, dirtyVnodeList
Ejemplo n.º 17
0
def convertAllTabs(self, event=None):
    """Convert all tabs to blanks in the selected outline."""
    c = self
    u = c.undoer
    undoType = 'Convert All Tabs'
    current = c.p
    if g.app.batchMode:
        c.notValidInBatchMode(undoType)
        return
    theDict = c.scanAllDirectives(c.p)
    tabWidth = theDict.get("tabwidth")
    count = 0
    u.beforeChangeGroup(current, undoType)
    for p in current.self_and_subtree():
        undoData = u.beforeChangeNodeContents(p)
        if p == current:
            changed = self.convertTabs(event)
            if changed:
                count += 1
        else:
            result = []
            changed = False
            text = p.v.b
            lines = text.split('\n')
            for line in lines:
                i, w = g.skip_leading_ws_with_indent(line, 0, tabWidth)
                s = g.computeLeadingWhitespace(
                    w, -abs(tabWidth)) + line[i:]  # use negative width.
                if s != line:
                    changed = True
                result.append(s)
            if changed:
                count += 1
                p.setDirty()
                p.setBodyString('\n'.join(result))
                u.afterChangeNodeContents(p, undoType, undoData)
    u.afterChangeGroup(current, undoType)
    if not g.unitTesting:
        g.es("tabs converted to blanks in", count, "nodes")
    if count > 0:
        c.redraw_after_icons_changed()
Ejemplo n.º 18
0
 def regularizeWhitespace(self, s):
     '''Regularize leading whitespace in s:
     Convert tabs to blanks or vice versa depending on the @tabwidth in effect.
     This is only called for strict languages.'''
     changed = False; lines = g.splitLines(s); result = []; tab_width = self.tab_width
     if tab_width < 0: # Convert tabs to blanks.
         for line in lines:
             i, w = g.skip_leading_ws_with_indent(line, 0, tab_width)
             s = g.computeLeadingWhitespace(w, -abs(tab_width)) + line[i:] # Use negative width.
             if s != line: changed = True
             result.append(s)
     elif tab_width > 0: # Convert blanks to tabs.
         for line in lines:
             s = g.optimizeLeadingWhitespace(line, abs(tab_width)) # Use positive width.
             if s != line: changed = True
             result.append(s)
     if changed:
         action = 'tabs converted to blanks' if self.tab_width < 0 else 'blanks converted to tabs'
         message = 'inconsistent leading whitespace. %s' % action
         self.report(message)
     return ''.join(result)
Ejemplo n.º 19
0
def convertAllBlanks(self, event=None):
    '''Convert all blanks to tabs in the selected outline.'''
    c = self; u = c.undoer; undoType = 'Convert All Blanks'
    current = c.p
    if g.app.batchMode:
        c.notValidInBatchMode(undoType)
        return
    d = c.scanAllDirectives()
    tabWidth = d.get("tabwidth")
    count = 0; dirtyVnodeList = []
    u.beforeChangeGroup(current, undoType)
    for p in current.self_and_subtree():
        innerUndoData = u.beforeChangeNodeContents(p)
        if p == current:
            changed, dirtyVnodeList2 = c.convertBlanks(event)
            if changed:
                count += 1
                dirtyVnodeList.extend(dirtyVnodeList2)
        else:
            changed = False; result = []
            text = p.v.b
            lines = text.split('\n')
            for line in lines:
                i, w = g.skip_leading_ws_with_indent(line, 0, tabWidth)
                s = g.computeLeadingWhitespace(w, abs(tabWidth)) + line[i:] # use positive width.
                if s != line: changed = True
                result.append(s)
            if changed:
                count += 1
                dirtyVnodeList2 = p.setDirty()
                dirtyVnodeList.extend(dirtyVnodeList2)
                result = '\n'.join(result)
                p.setBodyString(result)
                u.afterChangeNodeContents(p, undoType, innerUndoData)
    u.afterChangeGroup(current, undoType, dirtyVnodeList=dirtyVnodeList)
    if not g.unitTesting:
        g.es("blanks converted to tabs in", count, "nodes")
            # Must come before c.redraw().
    if count > 0:
        c.redraw_after_icons_changed()
Ejemplo n.º 20
0
def dedentBody(self, event=None):
    '''Remove one tab's worth of indentation from all presently selected lines.'''
    c, undoType = self, 'Unindent'
    w = c.frame.body.wrapper
    sel_1, sel_2 = w.getSelectionRange()
    ins = w.getInsertPoint()
    tab_width = c.getTabWidth(c.p)
    head, lines, tail, oldSel, oldYview = self.getBodyLines()
    changed, result = False, []
    for line in lines:
        i, width = g.skip_leading_ws_with_indent(line, 0, tab_width)
        s = g.computeLeadingWhitespace(width - abs(tab_width), tab_width) + line[i:]
        if s != line: changed = True
        result.append(s)
    if changed:
        # Leo 5.6: preserve insert point.
        preserveSel = sel_1 == sel_2
        if preserveSel:
            ins = max(len(head), len(result[0]) - len(lines[0]) + ins)
            oldSel = ins, ins
        result = ''.join(result)
        c.updateBodyPane(head, result, tail, undoType, oldSel, oldYview, preserveSel)
Ejemplo n.º 21
0
def dedentBody(self, event=None):
    '''Remove one tab's worth of indentation from all presently selected lines.'''
    c, undoType = self, 'Unindent'
    w = c.frame.body.wrapper
    sel_1, sel_2 = w.getSelectionRange()
    ins = w.getInsertPoint()
    tab_width = c.getTabWidth(c.p)
    head, lines, tail, oldSel, oldYview = self.getBodyLines()
    changed, result = False, []
    for line in lines:
        i, width = g.skip_leading_ws_with_indent(line, 0, tab_width)
        s = g.computeLeadingWhitespace(width - abs(tab_width), tab_width) + line[i:]
        if s != line: changed = True
        result.append(s)
    if changed:
        result = ''.join(result)
        # Leo 5.6: preserve insert point.
        preserveSel = sel_1 == sel_2
        if preserveSel:
            ins = max(0, ins - abs(tab_width))
            oldSel = ins, ins
        c.updateBodyPane(head, result, tail, undoType, oldSel, oldYview, preserveSel)
Ejemplo n.º 22
0
 def regularize_whitespace(self, s):
     '''
     Regularize leading whitespace in s:
     Convert tabs to blanks or vice versa depending on the @tabwidth in effect.
     '''
     kind = 'tabs' if self.tab_width > 0 else 'blanks'
     kind2 = 'blanks' if self.tab_width > 0 else 'tabs'
     fn = g.shortFileName(self.root.h)
     lines = g.splitLines(s)
     count, result, tab_width = 0, [], self.tab_width
     self.ws_error = False # 2016/11/23
     if tab_width < 0: # Convert tabs to blanks.
         for n, line in enumerate(lines):
             i, w = g.skip_leading_ws_with_indent(line, 0, tab_width)
             s = g.computeLeadingWhitespace(w, -abs(tab_width)) + line[i:]
                 # Use negative width.
             if s != line:
                 count += 1
             result.append(s)
     elif tab_width > 0: # Convert blanks to tabs.
         for n, line in enumerate(lines):
             s = g.optimizeLeadingWhitespace(line, abs(tab_width))
                 # Use positive width.
             if s != line:
                 count += 1
             result.append(s)
     if count:
         self.ws_error = True # A flag to check.
         if not g.unitTesting:
             # g.es_print('Warning: Intermixed tabs and blanks in', fn)
             # g.es_print('Perfect import test will ignoring leading whitespace.')
             g.es('changed leading %s to %s in %s line%s in %s' % (
                 kind2, kind, count, g.plural(count), fn))
         if g.unitTesting: # Sets flag for unit tests.
             self.report('changed %s lines' % count)
     return ''.join(result)
Ejemplo n.º 23
0
def extract(self, event=None):
    #@+<< docstring for extract command >>
    #@+node:ekr.20201113130021.1: *3* << docstring for extract command >>
    r"""
    Create child node from the selected body text.

    1. If the selection starts with a section reference, the section
       name becomes the child's headline. All following lines become
       the child's body text. The section reference line remains in
       the original body text.

    2. If the selection looks like a definition line (for the Python,
       JavaScript, CoffeeScript or Clojure languages) the
       class/function/method name becomes the child's headline and all
       selected lines become the child's body text.

       You may add additional regex patterns for definition lines using
       @data extract-patterns nodes. Each line of the body text should a
       valid regex pattern. Lines starting with # are comment lines. Use \#
       for patterns starting with #.

    3. Otherwise, the first line becomes the child's headline, and all
       selected lines become the child's body text.
    """
    #@-<< docstring for extract command >>
    c, u, w = self, self.undoer, self.frame.body.wrapper
    undoType = 'Extract'
    # Set data.
    head, lines, tail, oldSel, oldYview = c.getBodyLines()
    if not lines:
        return  # Nothing selected.
    #
    # Remove leading whitespace.
    junk, ws = g.skip_leading_ws_with_indent(lines[0], 0, c.tab_width)
    lines = [g.removeLeadingWhitespace(s, ws, c.tab_width) for s in lines]
    h = lines[0].strip()
    ref_h = extractRef(c, h).strip()
    def_h = extractDef_find(c, lines)
    if ref_h:
        h, b, middle = ref_h, lines[1:], ' ' * ws + lines[0]  # By vitalije.
    elif def_h:
        h, b, middle = def_h, lines, ''
    else:
        h, b, middle = lines[0].strip(), lines[1:], ''
    #
    # Start the outer undo group.
    u.beforeChangeGroup(c.p, undoType)
    undoData = u.beforeInsertNode(c.p)
    p = createLastChildNode(c, c.p, h, ''.join(b))
    u.afterInsertNode(p, undoType, undoData)
    #
    # Start inner undo.
    if oldSel:
        i, j = oldSel
        w.setSelectionRange(i, j, insert=j)
    bunch = u.beforeChangeBody(c.p)  # Not p.
    #
    # Update the text and selection
    c.p.v.b = head + middle + tail  # Don't redraw.
    w.setAllText(head + middle + tail)
    i = len(head)
    j = max(i, len(head) + len(middle) - 1)
    w.setSelectionRange(i, j, insert=j)
    #
    # End the inner undo.
    u.afterChangeBody(c.p, undoType, bunch)
    #
    # Scroll as necessary.
    if oldYview:
        w.setYScrollPosition(oldYview)
    else:
        w.seeInsertPoint()
    #
    # Add the changes to the outer undo group.
    u.afterChangeGroup(c.p, undoType=undoType)
    p.parent().expand()
    c.redraw(p.parent())  # A bit more convenient than p.
    c.bodyWantsFocus()