Exemplo n.º 1
0
 def skipNewline(self, s, i, kind):
     '''
     Skip whitespace and comments up to a newline, then skip the newline.
     Unlike the base class:
     - we always skip to a newline, if any.
     - we do *not* issue an error if no newline is found.
     '''
     while i < len(s):
         progress = i
         i = self.skipWs(s, i)
         if self.startsComment(s, i):
             i = self.skipComment(s, i)
         else: break
         assert i > progress
     if i >= len(s):
         return len(s)
     elif g.match(s, i, '\n'):
         return i + 1
     else:
         # A hack, but probably good enough in most cases.
         while i < len(s) and s[i] in ' \t()};':
             i += 1
         if g.match(s, i, '\n'):
             i += 1
         return i
Exemplo n.º 2
0
    def skipToEndOfTag(self,s,i,start):

        '''Skip to the end of an open tag.

        return i,ok,complete

        where complete is True if the tag of the form <name/>
        '''

        trace = False
        complete,ok = False,False
        while i < len(s): 
            progress = i
            if i == '"':
                i = self.skipString(s,i)
            elif g.match(s,i,'<!--'):
                i = self.skipComment(s,i)
            elif g.match(s,i,'<'):
                complete,ok = False,False ; break
            elif g.match(s,i,'/>'):
                i = g.skip_ws(s,i+2)
                complete,ok = True,True ; break
            elif g.match(s,i,'>'):
                i += 1
                complete,ok = False,True ; break
            else:
                i += 1
            assert progress < i

        if trace: g.trace('ok',ok,repr(s[start:i]))
        return i,ok,complete
Exemplo n.º 3
0
 def tokenize(self, s):
     '''Tokenize comments, strings, identifiers, whitespace and operators.'''
     i, result = 0, []
     while i < len(s):
         # Loop invariant: at end: j > i and s[i:j] is the new token.
         j = i
         ch = s[i]
         if ch in '@\n': # Make *sure* these are separate tokens.
             j += 1
         elif ch == '#': # Preprocessor directive.
             j = g.skip_to_end_of_line(s, i)
         elif ch in ' \t':
             j = g.skip_ws(s, i)
         elif ch.isalpha() or ch == '_':
             j = g.skip_c_id(s, i)
         elif g.match(s, i, '//'):
             j = g.skip_line(s, i)
         elif g.match(s, i, '/*'):
             j = self.skip_block_comment(s, i)
         elif ch in "'\"":
             j = g.skip_string(s, i)
         else:
             j += 1
         assert j > i
         result.append(''.join(s[i: j]))
         i = j # Advance.
     return result
Exemplo n.º 4
0
 def skipSigTail(self, s, i, kind):
     """Skip from the end of the arg list to the start of the block."""
     trace = False and self.trace
     # Pascal interface has no tail.
     if kind == "class":
         return i, True
     start = i
     i = g.skip_ws(s, i)
     for z in self.sigFailTokens:
         if g.match(s, i, z):
             if trace:
                 g.trace("failToken", z, "line", g.skip_line(s, i))
             return i, False
     while i < len(s):
         if self.startsComment(s, i):
             i = self.skipComment(s, i)
         elif g.match(s, i, self.blockDelim1):
             if trace:
                 g.trace(repr(s[start:i]))
             return i, True
         else:
             i += 1
     if trace:
         g.trace("no block delim")
     return i, False
Exemplo n.º 5
0
    def skipCodeBlock (self,s,i,kind):

        trace = False ; verbose = True
        # if trace: g.trace('***',g.callers())
        startIndent = self.startSigIndent
        if trace: g.trace('startIndent',startIndent)
        assert startIndent is not None
        i = start = g.skip_ws_and_nl(s,i)
        parenCount = 0
        underIndentedStart = None # The start of trailing underindented blank or comment lines.
        while i < len(s):
            progress = i
            ch = s[i]
            if g.is_nl(s,i):
                if trace and verbose: g.trace(g.get_line(s,i))
                backslashNewline = (i > 0 and g.match(s,i-1,'\\\n'))
                if backslashNewline:
                    # An underindented line, including docstring,
                    # does not end the code block.
                    i += 1 # 2010/11/01
                else:
                    i = g.skip_nl(s,i)
                    j = g.skip_ws(s,i)
                    if g.is_nl(s,j):
                        pass # We have already made progress.
                    else:
                        i,underIndentedStart,breakFlag = self.pythonNewlineHelper(
                            s,i,parenCount,startIndent,underIndentedStart)
                        if breakFlag: break
            elif ch == '#':
                i = g.skip_to_end_of_line(s,i)
            elif ch == '"' or ch == '\'':
                i = g.skip_python_string(s,i)
            elif ch in '[{(':
                i += 1 ; parenCount += 1
                # g.trace('ch',ch,parenCount)
            elif ch in ']})':
                i += 1 ; parenCount -= 1
                # g.trace('ch',ch,parenCount)
            else: i += 1
            assert(progress < i)

        # The actual end of the block.
        if underIndentedStart is not None:
            i = underIndentedStart
            if trace: g.trace('***backtracking to underindent range')
            if trace: g.trace(g.get_line(s,i))

        if 0 < i < len(s) and not g.match(s,i-1,'\n'):
            g.trace('Can not happen: Python block does not end in a newline.')
            g.trace(g.get_line(s,i))
            return i,False

        # 2010/02/19: Include all following material
        # until the next 'def' or 'class'
        i = self.skipToTheNextClassOrFunction(s,i,startIndent)

        if (trace or self.trace) and s[start:i].strip():
            g.trace('%s returns\n' % (kind) + s[start:i])
        return i,True
Exemplo n.º 6
0
def deleteComments(self, event=None):
    #@+<< deleteComments docstring >>
    #@+node:ekr.20171123135625.37: *3* << deleteComments docstring >>
    #@@pagewidth 50
    '''
    Removes one level of comment delimiters from all
    selected lines.  The applicable @language directive
    determines the comment delimiters to be removed.

    Removes single-line comments if possible; removes
    block comments for languages like html that lack
    single-line comments.

    *See also*: add-comments.
    '''
    #@-<< deleteComments docstring >>
    c = self
    p = c.p
    head, lines, tail, oldSel, oldYview = self.getBodyLines()
    result = []
    if not lines:
        g.warning('no text selected')
        return
    # The default language in effect at p.
    language = c.frame.body.colorizer.scanLanguageDirectives(p)
    if c.hasAmbiguousLanguage(p):
        language = c.getLanguageAtCursor(p, language)
    d1, d2, d3 = g.set_delims_from_language(language)
    if d1:
        # Remove the single-line comment delim in front of each line
        d1b = d1 + ' '
        n1, n1b = len(d1), len(d1b)
        for s in lines:
            i = g.skip_ws(s, 0)
            if g.match(s, i, d1b):
                result.append(s[: i] + s[i + n1b:])
            elif g.match(s, i, d1):
                result.append(s[: i] + s[i + n1:])
            else:
                result.append(s)
    else:
        # Remove the block comment delimiters from each line.
        n2, n3 = len(d2), len(d3)
        for s in lines:
            i = g.skip_ws(s, 0)
            j = s.find(d3, i + n2)
            if g.match(s, i, d2) and j > -1:
                first = i + n2
                if g.match(s, first, ' '): first += 1
                last = j
                if g.match(s, last - 1, ' '): last -= 1
                result.append(s[: i] + s[first: last] + s[j + n3:])
            else:
                result.append(s)
    result = ''.join(result)
    c.updateBodyPane(head, result, tail, undoType='Delete Comments', oldSel=None, oldYview=oldYview)
Exemplo n.º 7
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
Exemplo n.º 8
0
    def extendSignature(self, s, i):
        '''Extend the text to be added to the class node following the signature.

        The text *must* end with a newline.'''
        # Add a docstring to the class node,
        # And everything on the line following it
        j = g.skip_ws_and_nl(s, i)
        if g.match(s, j, '"""') or g.match(s, j, "'''"):
            j = g.skip_python_string(s, j)
            if j < len(s): # No scanning error.
                # Return the docstring only if nothing but whitespace follows.
                j = g.skip_ws(s, j)
                if g.is_nl(s, j):
                    return j + 1
        return i
Exemplo n.º 9
0
 def skipSigTail(self, s, i, kind):
     '''Skip from the end of the arg list to the start of the block.'''
     if 1: # New code
         while i < len(s):
             ch = s[i]
             if ch == ':':
                 return i, True
             elif ch == '\n':
                 return i, False
             elif self.startsComment(s, i):
                 i = self.skipComment(s, i)
             else:
                 i += 1
         return i, False
     else: # old code
         while i < len(s):
             ch = s[i]
             if ch == '\n':
                 break
             elif ch in (' ', '\t',):
                 i += 1
             elif self.startsComment(s, i):
                 i = self.skipComment(s, i)
             else:
                 break
         return i, g.match(s, i, ':')
Exemplo n.º 10
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
Exemplo n.º 11
0
def parseHeadline(s):
    """
    Parse a headline of the form @kind:name=val
    Return (kind,name,val).
    Leo 4.11.1: Ignore everything after @data name.
    """
    kind = name = val = None
    if g.match(s, 0, g.u('@')):
        i = g.skip_id(s, 1, chars=g.u('-'))
        i = g.skip_ws(s, i)
        kind = s[1: i].strip()
        if kind:
            # name is everything up to '='
            if kind == g.u('data'):
                # i = g.skip_ws(s,i)
                j = s.find(g.u(' '), i)
                if j == -1:
                    name = s[i:].strip()
                else:
                    name = s[i: j].strip()
            else:
                j = s.find(g.u('='), i)
                if j == -1:
                    name = s[i:].strip()
                else:
                    name = s[i: j].strip()
                    # val is everything after the '='
                    val = s[j + 1:].strip()
    # g.trace("%50s %10s %s" %(name,kind,val))
    return kind, name, val
Exemplo n.º 12
0
    def handleAtPluginNode (self,p):

        '''Handle @plugin nodes.'''

        c = self.c
        tag = "@plugin"
        h = p.h
        assert(g.match(h,0,tag))

        # Get the name of the module.
        theFile = h[len(tag):].strip()
        
        # The following two lines break g.loadOnePlugin
        #if theFile[-3:] == ".py":
        #    theFile = theFile[:-3]
        
        # in fact, I believe the opposite behavior is intended: add .py if it doesn't exist
        if theFile[-3:] != ".py":
            theFile = theFile + ".py"
        
        theFile = g.toUnicode(theFile)

        if not self.atPluginNodes:
            g.warning("disabled @plugin: %s" % (theFile))
        # elif theFile in g.app.loadedPlugins:
        elif g.pluginIsLoaded(theFile):
            g.warning("plugin already loaded: %s" % (theFile))
        else:
            theModule = g.loadOnePlugin(theFile)
Exemplo n.º 13
0
 def skip_block_comment(self, s, i):
     assert(g.match(s, i, "/*"))
     j = s.find("*/", i)
     if j == -1:
         return len(s)
     else:
         return j + 2
Exemplo n.º 14
0
 def adjustDefStart(self, s, i):
     '''A hook to allow the Python importer to adjust the 
     start of a class or function to include decorators.
     '''
     # Invariant: i does not change.
     # Invariant: start is the present return value.
     try:
         assert s[i] != '\n'
         start = j = g.find_line_start(s, i) if i > 0 else 0
         # g.trace('entry',j,i,repr(s[j:i+10]))
         assert j == 0 or s[j - 1] == '\n'
         while j > 0:
             progress = j
             j1 = j = g.find_line_start(s, j - 2)
             # g.trace('line',repr(s[j:progress]))
             j = g.skip_ws(s, j)
             if not g.match(s, j, '@'):
                 break
             k = g.skip_id(s, j + 1)
             word = s[j: k]
             # Leo directives halt the scan.
             if word and word in g.globalDirectiveList:
                 break
             # A decorator.
             start = j = j1
             assert j < progress
         # g.trace('**returns %s, %s' % (repr(s[start:i]),repr(s[i:i+20])))
         return start
     except AssertionError:
         g.es_exception()
         return i
Exemplo n.º 15
0
 def startsHelper(self, s, i, kind, tags, tag=None):
     '''return True if s[i:] starts section.
     Sets sigStart, sigEnd, sigId and codeEnd ivars.'''
     trace = False
     self.codeEnd = self.sigEnd = self.sigId = None
     self.sigStart = i
     sigStart = i
     ok, sigId, i = self.isSectionLine(s, i)
     if not sigId or not ok:
         # if trace: g.trace('fail',repr(g.getLine(s,i)))
         return False
     i = sigEnd = g.skip_line(s, i)
     # Skip everything until the next section.
     while i < len(s):
         progress = i
         ok, junk, junk = self.isSectionLine(s, i)
         if ok: break # don't change i.
         i = g.skip_line(s, i)
         assert progress < i
     # Success: set the ivars.
     self.sigStart = sigStart
     self.codeEnd = i
     self.sigEnd = sigEnd
     self.sigId = sigId
     self.classId = None
     # Note: backing up here is safe because
     # we won't back up past scan's 'start' point.
     # Thus, characters will never be output twice.
     k = self.sigStart
     if not g.match(s, k, '\n'):
         self.sigStart = g.find_line_start(s, k)
     if trace: g.trace(sigId, 'returns\n' + s[self.sigStart: i] + '\nEND')
     return True
Exemplo n.º 16
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
Exemplo n.º 17
0
    def skipToMatchingTag (self,s,i,tag,tags,start):

        '''Skip the entire class definition. Return i,ok.
        '''

        trace = False
        found,level,target_tag = False,1,tag.lower()
        while i < len(s): 
            progress = i
            if s[i] == '"':
                i = self.skipString(s,i)
            elif g.match(s,i,'<!--'):
                i = self.skipComment(s,i)
            elif g.match(s,i,'</'):
                j = i+2
                i = self.skipId(s,j)
                tag2 = s[j:i].lower()
                i,ok,complete = self.skipToEndOfTag(s,i,start=j)
                    # Sets complete if /> terminates the tag.
                if ok and tag2 == target_tag:
                    level -= 1
                    if level == 0:
                        found = True ; break
            elif g.match(s,i,'<'):
                # An open tag.
                j = g.skip_ws_and_nl(s,i+1)
                i = self.skipId(s,j)
                word = s[j:i].lower()
                i,ok,complete = self.skipToEndOfTag(s,i,start=j)
                # **Important**: only bump level for nested *target* tags.
                # This avoids problems when interior tags are not properly nested.
                if ok and word == target_tag and not complete:
                    level += 1
            elif g.match(s,i,'/>'):
                # This is a syntax error.
                # This should have been eaten by skipToEndOfTag.
                i += 2
                g.trace('syntax error: unmatched "/>"')
            else:
                i += 1

            assert progress < i

        if trace: g.trace('%sfound:%s\n%s\n\n*****end %s\n' % (
            '' if found else 'not ',target_tag,s[start:i],target_tag))

        return i,found
Exemplo n.º 18
0
 def startsString(self,s,i):
         
     '''Single quotes do *not* start strings in xml or html.'''
     
     # Fix bug 1208659: leo parsed the wrong line number of html file.
     # Note: the compare failure was caused by using BaseScanner.startsString.
     # The line number problem is a separate issue.
     return g.match(s,i,'"')
Exemplo n.º 19
0
 def killLine(self, event):
     '''Kill the line containing the cursor.'''
     w = self.editWidget(event)
     if not w: return
     s = w.getAllText()
     ins = w.getInsertPoint()
     i, j = g.getLine(s, ins)
     if ins >= len(s) and g.match(s, j - 1, '\n'):
         # Kill the trailing newline of the body text.
         i = max(0, len(s) - 1)
         j = len(s)
     elif j > i + 1 and g.match(s, j - 1, '\n'):
         # Kill the line, but not the newline.
         j -= 1
     else:
         pass # Kill the newline in the present line.
     self.kill(event, i, j, undoType='kill-line')
Exemplo n.º 20
0
 def scanFunction(self, parent, s, i):
     '''scan function(args) { body } and then rescan body.'''
     trace = True and not g.unitTesting
     # k1, k2 = g.getLine(s,i)
     # g.trace(s[k1:k2])
     i1 = i
     # Scan backward for '('
     i2 = i-1
     while 0 <= i2 and s[i2].isspace():
         i2 -= 1
     in_expr = s[i2] == '('
     assert g.match(s, i, 'function')
     i += len('function')
     i = g.skip_ws_and_nl(s, i)
     i = self.skipId(s, i)
     i = g.skip_ws_and_nl(s, i)
     # Skip the argument list.
     if not g.match(s, i, '('):
         if trace: g.trace('syntax error: no argument list',i)
         return i
     i = self.skipBlock(s, i,'(', ')')
         # skipBlock skips the ')'
     if i == len(s):
         g.trace('no args', g.get_line(s, i))
         return i
     # Skip the body.
     i = g.skip_ws_and_nl(s, i)
     if not g.match(s, i, '{'):
         if trace: g.trace('no function body', i)
         return i
     block_i1 = i
     block_i2 = i = self.skipBlock(s, i, '{', '}')
     j = g.skip_ws_and_nl(s,i)
     if g.match(s, j, '('):
         i = g.skip_parens(s, i)
     if in_expr:
         j = g.skip_ws_and_nl(s,i)
         if g.match(s, j, ')'):
             i = j + 1
     assert i > i1
     block_s = s[block_i1+1:block_i2-1].strip()
     if trace: g.trace('*** rescanning ***\n\n%s\n\n' % block_s)
     self.scanHelper(parent, block_s)
     return i
Exemplo n.º 21
0
 def doEnter(self, event):
     # set cursor to end of line to avoid line splitting
     trace = False and not g.unitTesting
     textCursor = self.textCursor()
     position   = len(self.document().toPlainText())
     textCursor.setPosition(position)
     self.setTextCursor(textCursor)
     lines = []
     block = self.document().lastBlock()
     # #792: python_console plugin doesn't handle copy/paste properly.
     while block:
         line = g.toUnicode(block.text())
         block = block.previous()
         done = g.match(line, 0, '>>>')
         if done: line = line [4:] # remove marker
         lines.insert(0, line.rstrip())
         if done: break
     if trace:
         g.trace()
         g.printObj(lines)
     self.historyIndex = -1
     if len(lines) > 1:
         # #792: python_console plugin doesn't handle copy/paste properly.
         self.append('')
         self.command = '\n'.join(lines).rstrip() + '\n'
         self.interpreter.runIt(self.command)
         self.command = ''
         self.marker()
         return
     if self.customCommands(line):
         return None
     self.haveLine = bool(line)
     if self.haveLine:
         self.history.insert(0, line)
         if line[-1] == ':':
             self.multiLine = True
     g.trace(self.haveLine, self.multiLine, repr(line))
     if self.haveLine:
         if self.multiLine:
             self.command += line + '\n' # + command and line
             self.append('')
         else:
             self.command = line
             self.append('')
             self.interpreter.runIt(self.command)
             self.command = ''
     else:
         if self.multiLine:
             self.append('')
             self.interpreter.runIt(self.command)
             self.command = ''
             self.multiLine = False # back to single line
         else: # Do nothing.
             self.append('')
     self.marker()
     return None
Exemplo n.º 22
0
 def startsString(self, s, i):
     '''Return True if s[i:] starts a JavaScript string.'''
     if g.match(s, i, '"') or g.match(s, i, "'"):
         # Count the number of preceding backslashes:
         n = 0; j = i - 1
         while j >= 0 and s[j] == '\\':
             n += 1
             j -= 1
         return (n % 2) == 0
     elif g.match(s, i, '//'):
         # Neither of these are valid in regexp literals.
         return False
     elif g.match(s, i, '/'):
         # could be a division operator or regexp literal.
         while i >= 0 and s[i - 1] in ' \t\n':
             i -= 1
         if i == 0: return True
         return s[i - 1] in (',([{=')
     else:
         return False
Exemplo n.º 23
0
 def killToEndOfLine(self, event):
     '''Kill from the cursor to end of the line.'''
     w = self.editWidget(event)
     if not w: return
     s = w.getAllText()
     ins = w.getInsertPoint()
     i, j = g.getLine(s, ins)
     if ins >= len(s) and g.match(s, j - 1, '\n'):
         # Kill the trailing newline of the body text.
         i = max(0, len(s) - 1)
         j = len(s)
     elif ins + 1 < j and s[ins: j - 1].strip() and g.match(s, j - 1, '\n'):
         # Kill the line, but not the newline.
         i, j = ins, j - 1
     elif g.match(s, j - 1, '\n'):
         i = ins # Kill the newline in the present line.
     else:
         i = j
     if i < j:
         self.kill(event, i, j, undoType='kill-line')
Exemplo n.º 24
0
def startsParagraph(s):
    '''Return True if line s starts a paragraph.'''
    if not s.strip():
        val = False
    elif s.strip() in ('"""', "'''"):
        val = True
    elif s[0].isdigit():
        i = 0
        while i < len(s) and s[i].isdigit():
            i += 1
        val = g.match(s, i, ')') or g.match(s, i, '.')
    elif s[0].isalpha():
        # Careful: single characters only.
        # This could cause problems in some situations.
        val = (
            (g.match(s, 1, ')') or g.match(s, 1, '.')) and
            (len(s) < 2 or s[2] in (' \t\n')))
    else:
        val = s.startswith('@') or s.startswith('-')
    return val
Exemplo n.º 25
0
 def isSectionLine(self, s, i):
     i = g.skip_ws(s, i)
     if not g.match(s, i, '['):
         return False, None, i
     k = s.find('\n', i + 1)
     if k == -1: k = len(s)
     j = s.find(']', i + 1)
     if -1 < j < k:
         return True, s[i: j + 1], i
     else:
         return False, None, i
Exemplo n.º 26
0
 def getColor(self, h):
     '''Returns the background color from the given headline string'''
     color = None
     tag = '@color'
     i = h.find(tag)
     if i > -1:
         j = g.skip_ws(h, i + len(tag))
         if g.match(h, j, '='): j += 1
         k = h.find('@', j + 1)
         if k == -1: k = len(h)
         color = h[j: k].strip()
     return color
Exemplo n.º 27
0
 def getColor(self, h):
     '''Returns the background color from the given headline string'''
     color = None
     tag = '@color'
     i = h.find(tag)
     if i > -1:
         j = g.skip_ws(h, i + len(tag))
         if g.match(h, j, '='): j += 1
         k = h.find('@', j + 1)
         if k == -1: k = len(h)
         color = h[j: k].strip()
     return color
Exemplo n.º 28
0
 def skipSigTail(self, s, i, kind=None):
     '''Skip from the end of the arg list to the start of the block.'''
     trace = False and self.trace
     i1 = i
     i = self.skipWs(s, i)
     for z in self.sigFailTokens:
         if g.match(s, i, z):
             if trace: g.trace('failToken', z, 'line', g.skip_line(s, i))
             return i, False
     while i < len(s):
         progress = i
         if self.startsComment(s, i):
             i = self.skipComment(s, i)
         elif g.match(s, i, self.blockDelim1):
             if trace: g.trace(repr(s[i1: i]))
             return i, True
         else:
             i += 1
         assert progress < i
     if trace: g.trace('no block delim')
     return i, False
Exemplo n.º 29
0
 def skipSigTail(self, s, i, kind=None):
     '''Skip from the end of the arg list to the start of the block.'''
     trace = False and self.trace
     i1 = i
     i = self.skipWs(s, i)
     for z in self.sigFailTokens:
         if g.match(s, i, z):
             if trace: g.trace('failToken', z, 'line', g.skip_line(s, i))
             return i, False
     while i < len(s):
         progress = i
         if self.startsComment(s, i):
             i = self.skipComment(s, i)
         elif g.match(s, i, self.blockDelim1):
             if trace: g.trace(repr(s[i1:i]))
             return i, True
         else:
             i += 1
         assert progress < i
     if trace: g.trace('no block delim')
     return i, False
Exemplo n.º 30
0
 def startsFunction(self, s, i):
     '''Return True if s[i:] starts a function.
     Sets sigStart, sigEnd, sigId and codeEnd ivars.'''
     self.startSigIndent = self.getLeadingIndent(s, i)
     self.sigStart = i
     self.codeEnd = self.sigEnd = self.sigId = None
     if not g.match(s, i, '('): return False
     end = self.skipBlock(s, i)
     # g.trace('%3s %15s block: %s' % (i,repr(s[i:i+10]),repr(s[i:end])))
     if not g.match(s, end - 1, ')'): return False
     i = g.skip_ws(s, i + 1)
     if not g.match_word(s, i, 'defun'): return False
     i += len('defun')
     sigEnd = i = g.skip_ws_and_nl(s, i)
     j = self.skipId(s, i) # Bug fix: 2009/09/30
     word = s[i: j]
     if not word: return False
     self.codeEnd = end + 1
     self.sigEnd = sigEnd
     self.sigId = word
     return True
Exemplo n.º 31
0
 def skipSigTail(self, s, i, kind):
     '''Skip from the end of the arg list to the start of the block.'''
     while i < len(s):
         ch = s[i]
         if ch == '\n':
             break
         elif ch in (' ', '\t',):
             i += 1
         elif self.startsComment(s, i):
             i = self.skipComment(s, i)
         else:
             break
     return i, g.match(s, i, ':')
Exemplo n.º 32
0
 def skipSigTail(self, s, i, kind):
     '''Skip from the end of the arg list to the start of the block.'''
     trace = False and self.trace
     # Pascal interface has no tail.
     if kind == 'class':
         return i, True
     start = i
     i = g.skip_ws(s, i)
     for z in self.sigFailTokens:
         if g.match(s, i, z):
             if trace: g.trace('failToken', z, 'line', g.skip_line(s, i))
             return i, False
     while i < len(s):
         if self.startsComment(s, i):
             i = self.skipComment(s, i)
         elif g.match(s, i, self.blockDelim1):
             if trace: g.trace(repr(s[start:i]))
             return i, True
         else:
             i += 1
     if trace: g.trace('no block delim')
     return i, False
Exemplo n.º 33
0
def startsParagraph(s):
    '''Return True if line s starts a paragraph.'''
    trace = False and not g.unitTesting
    if not s.strip():
        val = False
    elif s.strip() in ('"""', "'''"):
        val = True
    elif s[0].isdigit():
        i = 0
        while i < len(s) and s[i].isdigit():
            i += 1
        val = g.match(s, i, ')') or g.match(s, i, '.')
    elif s[0].isalpha():
        # Careful: single characters only.
        # This could cause problems in some situations.
        val = (
            (g.match(s, 1, ')') or g.match(s, 1, '.')) and
            (len(s) < 2 or s[2] in (' \t\n')))
    else:
        val = s.startswith('@') or s.startswith('-')
    if trace: g.trace(val, repr(s))
    return val
Exemplo n.º 34
0
def rp_wrap_all_lines(c, indents, leading_ws, lines, pageWidth):
    '''Compute the result of wrapping all lines.'''
    trailingNL = lines and lines[-1].endswith('\n')
    lines = [z[: -1] if z.endswith('\n') else z for z in lines]
    if lines: # Bug fix: 2013/12/22.
        s = lines[0]
        if startsParagraph(s):
            # Adjust indents[1]
            # Similar to code in startsParagraph(s)
            i = 0
            if s[0].isdigit():
                while i < len(s) and s[i].isdigit():
                    i += 1
                if g.match(s, i, ')') or g.match(s, i, '.'):
                    i += 1
            elif s[0].isalpha():
                if g.match(s, 1, ')') or g.match(s, 1, '.'):
                    i = 2
            elif s[0] == '-':
                i = 1
            # Never decrease indentation.
            i = g.skip_ws(s, i + 1)
            if i > indents[1]:
                indents[1] = i
                leading_ws[1] = ' ' * i
    # Wrap the lines, decreasing the page width by indent.
    result = g.wrap_lines(lines,
        pageWidth - indents[1],
        pageWidth - indents[0])
    # prefix with the leading whitespace, if any
    paddedResult = []
    paddedResult.append(leading_ws[0] + result[0])
    for line in result[1:]:
        paddedResult.append(leading_ws[1] + line)
    # Convert the result to a string.
    result = '\n'.join(paddedResult)
    if trailingNL: result = result + '\n'
    return result
Exemplo n.º 35
0
def rp_wrap_all_lines(c, indents, leading_ws, lines, pageWidth):
    '''Compute the result of wrapping all lines.'''
    trailingNL = lines and lines[-1].endswith('\n')
    lines = [z[: -1] if z.endswith('\n') else z for z in lines]
    if lines: # Bug fix: 2013/12/22.
        s = lines[0]
        if startsParagraph(s):
            # Adjust indents[1]
            # Similar to code in startsParagraph(s)
            i = 0
            if s[0].isdigit():
                while i < len(s) and s[i].isdigit():
                    i += 1
                if g.match(s, i, ')') or g.match(s, i, '.'):
                    i += 1
            elif s[0].isalpha():
                if g.match(s, 1, ')') or g.match(s, 1, '.'):
                    i = 2
            elif s[0] == '-':
                i = 1
            # Never decrease indentation.
            i = g.skip_ws(s, i + 1)
            if i > indents[1]:
                indents[1] = i
                leading_ws[1] = ' ' * i
    # Wrap the lines, decreasing the page width by indent.
    result = g.wrap_lines(lines,
        pageWidth - indents[1],
        pageWidth - indents[0])
    # prefix with the leading whitespace, if any
    paddedResult = []
    paddedResult.append(leading_ws[0] + result[0])
    for line in result[1:]:
        paddedResult.append(leading_ws[1] + line)
    # Convert the result to a string.
    result = '\n'.join(paddedResult)
    if trailingNL: result = result + '\n'
    return result
Exemplo n.º 36
0
    def skipArgs(self, s, i, kind):
        '''Skip the argument or class list.  Return i, ok

        kind is in ('class','function')'''
        start = i
        i = g.skip_ws_and_nl(s, i)
        if not g.match(s, i, '('):
            return start, kind == 'class'
        i = self.skipParens(s, i)
        # skipParens skips the ')'
        if i >= len(s):
            return start, False
        else:
            return i, True
Exemplo n.º 37
0
 def getShortcut(self, h):
     '''Return the keyboard shortcut from the given headline string'''
     shortcut = None
     i = h.find('@key')
     if i > -1:
         j = g.skip_ws(h, i + len('@key'))
         if g.match(h, j, '='): j += 1
         if 0:
             shortcut = h[j:].strip()
         else: # new logic 1/3/2014 Jake Peck
             k = h.find('@', j + 1)
             if k == -1: k = len(h)
             shortcut = h[j: k].strip()
     return shortcut
Exemplo n.º 38
0
 def truncateButtonText(self, s):
     # 2011/10/16: Remove @button here only.
     i = 0
     while g.match(s, i, '@'):
         i += 1
     if g.match_word(s, i, 'button'):
         i += 6
     s = s[i:]
     if self.maxButtonSize > 10:
         s = s[:self.maxButtonSize]
         if s.endswith('-'):
             s = s[:-1]
     s = s.strip('-')
     return s.strip()
Exemplo n.º 39
0
 def getShortcut(self, h):
     '''Return the keyboard shortcut from the given headline string'''
     shortcut = None
     i = h.find('@key')
     if i > -1:
         j = g.skip_ws(h, i + len('@key'))
         if g.match(h, j, '='): j += 1
         if 0:
             shortcut = h[j:].strip()
         else:  # new logic 1/3/2014 Jake Peck
             k = h.find('@', j + 1)
             if k == -1: k = len(h)
             shortcut = h[j:k].strip()
     return shortcut
Exemplo n.º 40
0
 def skipNewline(self, s, i, kind):
     '''
     Skip whitespace and comments up to a newline, then skip the newline.
     Unlike the base class:
     - we always skip to a newline, if any.
     - we do *not* issue an error if no newline is found.
     '''
     while i < len(s):
         i = self.skipWs(s, i)
         if self.startsComment(s, i):
             i = self.skipComment(s, i)
         else:
             break
     if i >= len(s):
         return len(s)
     elif g.match(s, i, '\n'):
         return i + 1
     else:
         # A hack, but probably good enough in most cases.
         while i < len(s) and s[i] in ' \t()};':
             i += 1
         if g.match(s, i, '\n'):
             i += 1
         return i
Exemplo n.º 41
0
    def skip_heredoc_string(self, s, i):
        #@+<< skip_heredoc docstrig >>
        #@+node:ekr.20161130044051.2: *4* << skip_heredoc docstrig >>
        #@@nocolor-node
        '''
        08-SEP-2002 DTHEIN:  added function skip_heredoc_string
        A heredoc string in PHP looks like:

          <<<EOS
          This is my string.
          It is mine. I own it.
          No one else has it.
          EOS

        It begins with <<< plus a token (naming same as PHP variable names).
        It ends with the token on a line by itself (must start in first position.
        '''
        #@-<< skip_heredoc docstrig >>
        j = i
        assert (g.match(s, i, "<<<"))
        # pylint: disable=anomalous-backslash-in-string
        m = re.match("\<\<\<([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)", s[i:])
        if m is None:
            i += 3
            return i
        # 14-SEP-2002 DTHEIN: needed to add \n to find word, not just string
        delim = m.group(1) + '\n'
        i = g.skip_line(s, i)  # 14-SEP-2002 DTHEIN: look after \n, not before
        n = len(s)
        while i < n and not g.match(s, i, delim):
            i = g.skip_line(s, i)  # 14-SEP-2002 DTHEIN: move past \n
        if i >= n:
            g.scanError("Run on string: " + s[j:i])
        elif g.match(s, i, delim):
            i += len(delim)
        return i
Exemplo n.º 42
0
    def getArgs(self, h):

        args = []
        tag = '@args'
        i = h.find(tag)
        if i > -1:
            j = g.skip_ws(h, i + len(tag))
            # 2011/10/16: Make '=' sign optional.
            if g.match(h, j, '='): j += 1
            s = h[j + 1:].strip()
            args = s.split(',')
            args = [z.strip() for z in args]

        # g.trace('args',repr(args))
        return args
Exemplo n.º 43
0
 def handleAtScriptNode(self, p):
     '''Handle @script nodes.'''
     c = self.c
     tag = "@script"
     assert (g.match(p.h, 0, tag))
     name = p.h[len(tag):].strip()
     args = self.getArgs(p)
     if self.atScriptNodes:
         g.blue("executing script %s" % (name))
         c.executeScript(args=args, p=p, useSelectedText=False, silent=True)
     else:
         g.warning("disabled @script: %s" % (name))
     if 0:
         # Do not assume the script will want to remain in this commander.
         c.bodyWantsFocus()
Exemplo n.º 44
0
def pasteOutline(self,
    event=None,
    redrawFlag=True,
    s=None,
    undoFlag=True
):
    """
    Paste an outline into the present outline from the clipboard.
    Nodes do *not* retain their original identify.
    """
    c = self
    if s is None:
        s = g.app.gui.getTextFromClipboard()
    c.endEditing()
    if not s or not c.canPasteOutline(s):
        return None  # This should never happen.
    isLeo = g.match(s, 0, g.app.prolog_prefix_string)
    if not isLeo:
        return None
    # Get *position* to be pasted.
    pasted = c.fileCommands.getLeoOutlineFromClipboard(s)
    if not pasted:
        # Leo no longer supports MORE outlines. Use import-MORE-files instead.
        return None
    # Validate.
    c.validateOutline()
    c.checkOutline()
    # Handle the "before" data for undo.
    if undoFlag:
        undoData = c.undoer.beforeInsertNode(c.p,
            pasteAsClone=False,
            copiedBunchList=[],
        )
    # Paste the node into the outline.
    c.selectPosition(pasted)
    pasted.setDirty()
    c.setChanged(redrawFlag=redrawFlag)
        # Prevent flash when fixing #387.
    back = pasted.back()
    if back and back.hasChildren() and back.isExpanded():
        pasted.moveToNthChildOf(back, 0)
    # Finish the command.
    if undoFlag:
        c.undoer.afterInsertNode(pasted, 'Paste Node', undoData)
    if redrawFlag:
        c.redraw(pasted)
        c.recolor()
    return pasted
Exemplo n.º 45
0
 def scanObject(self, parent, s, i):
     '''
     Scan an object, creating child nodes of prarent for objects that have
     inner functions.
     '''
     assert s[i] == '{'
     g.trace(s[i:])
     i1 = i
     i = self.skipBlock(s, i, '{', '}')
     if g.match(s, i - 1, '}'):
         g.trace('returns:\n\n%s\n\n' % s[i1:i + 1])
         object_s = s[i1 + 1:i - 1].strip()
         self.scanHelper(parent, object_s)
     else:
         g.trace('==== no object')
     return i
Exemplo n.º 46
0
    def parseOptionLine(self, s):
        '''Parse a line containing name=val and return (name,value) or None.

        If no value is found, default to True.'''

        s = s.strip()
        if s.endswith(','): s = s[:-1]
        # Get name.  Names may contain '-' and '_'.
        i = g.skip_id(s, 0, chars='-_')
        name = s[:i]
        if not name: return None
        j = g.skip_ws(s, i)
        if g.match(s, j, '='):
            val = s[j + 1:].strip()
            # g.trace(val)
            return name, val
        else:
            # g.trace('*True')
            return name, 'True'
Exemplo n.º 47
0
def parseFontLine(line, d):
    s = line.strip()
    if not s: return
    if g.match(s, 0, '#'):
        s = s[1:].strip()
        comments = d.get('comments')
        comments.append(s)
        d['comments'] = comments
    else:
        # name is everything up to '='
        i = s.find('=')
        if i == -1:
            name = s; val = None
        else:
            name = s[: i].strip()
            val = s[i + 1:].strip()
            val = val.lstrip('"').rstrip('"')
            val = val.lstrip("'").rstrip("'")
        if name.endswith(('_family', '_size', '_slant', '_weight')):
            d[name.rsplit('_', 1)[1]] = name, val
Exemplo n.º 48
0
    def getArgs(self, h):
        args = []
        tag = '@args'

        i = h.find(tag)
        if i > -1:
            j = g.skip_ws(h, i + len(tag))
            # 2011/10/16: Make '=' sign optional.
            if g.match(h, j, '='): j += 1
            if 0:
                s = h[j + 1:].strip()
            else:  # new logic 1/3/2014 Jake Peck
                k = h.find('@', j + 1)
                if k == -1: k = len(h)
                s = h[j:k].strip()
            args = s.split(',')
            args = [z.strip() for z in args]
            # g.trace('args',repr(args))

        return args
Exemplo n.º 49
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
Exemplo n.º 50
0
    def handleAtPluginNode(self, p):
        '''Handle @plugin nodes.'''

        c = self.c
        tag = "@plugin"
        h = p.h
        assert (g.match(h, 0, tag))

        # Get the name of the module.
        theFile = h[len(tag):].strip()
        if theFile[-3:] == ".py":
            theFile = theFile[:-3]
        theFile = g.toUnicode(theFile)

        if not self.atPluginNodes:
            g.warning("disabled @plugin: %s" % (theFile))
        # elif theFile in g.app.loadedPlugins:
        elif g.pluginIsLoaded(theFile):
            g.warning("plugin already loaded: %s" % (theFile))
        else:
            theModule = g.loadOnePlugin(theFile)
Exemplo n.º 51
0
 def handleAtPluginNode(self, p):
     '''Handle @plugin nodes.'''
     tag = "@plugin"
     h = p.h
     assert (g.match(h, 0, tag))
     # Get the name of the module.
     theFile = h[len(tag):].strip()
     # The following two lines break g.loadOnePlugin
     #if theFile[-3:] == ".py":
     #    theFile = theFile[:-3]
     # in fact, I believe the opposite behavior is intended: add .py if it doesn't exist
     if theFile[-3:] != ".py":
         theFile = theFile + ".py"
     theFile = g.toUnicode(theFile)
     if not self.atPluginNodes:
         g.warning("disabled @plugin: %s" % (theFile))
     # elif theFile in g.app.loadedPlugins:
     elif g.pluginIsLoaded(theFile):
         g.warning("plugin already loaded: %s" % (theFile))
     else:
         g.loadOnePlugin(theFile)
Exemplo n.º 52
0
 def getArgs(self, p):
     '''Return the list of @args field of p.h.'''
     args = []
     if not p:
         return args
     h, tag = p.h, '@args'
     i = h.find(tag)
     if i > -1:
         j = g.skip_ws(h, i + len(tag))
         # 2011/10/16: Make '=' sign optional.
         if g.match(h, j, '='): j += 1
         if 0:
             s = h[j + 1:].strip()
         else:  # new logic 1/3/2014 Jake Peck
             k = h.find('@', j + 1)
             if k == -1: k = len(h)
             s = h[j:k].strip()
         args = s.split(',')
         args = [z.strip() for z in args]
     # if args: g.trace(args)
     return args
Exemplo n.º 53
0
def deleteComments(self, event=None):
    #@+<< deleteComments docstring >>
    #@+node:ekr.20171123135625.37: *3* << deleteComments docstring >>
    #@@pagewidth 50
    '''
    Removes one level of comment delimiters from all
    selected lines.  The applicable @language directive
    determines the comment delimiters to be removed.

    Removes single-line comments if possible; removes
    block comments for languages like html that lack
    single-line comments.

    *See also*: add-comments.
    '''
    #@-<< deleteComments docstring >>
    c = self
    p = c.p
    head, lines, tail, oldSel, oldYview = self.getBodyLines()
    result = []
    if not lines:
        g.warning('no text selected')
        return
    # The default language in effect at p.
    language = c.frame.body.colorizer.scanLanguageDirectives(p)
    if c.hasAmbiguousLanguage(p):
        language = c.getLanguageAtCursor(p, language)
    d1, d2, d3 = g.set_delims_from_language(language)
    if d1:
        # Remove the single-line comment delim in front of each line
        d1b = d1 + ' '
        n1, n1b = len(d1), len(d1b)
        for s in lines:
            i = g.skip_ws(s, 0)
            if g.match(s, i, d1b):
                result.append(s[:i] + s[i + n1b:])
            elif g.match(s, i, d1):
                result.append(s[:i] + s[i + n1:])
            else:
                result.append(s)
    else:
        # Remove the block comment delimiters from each line.
        n2, n3 = len(d2), len(d3)
        for s in lines:
            i = g.skip_ws(s, 0)
            j = s.find(d3, i + n2)
            if g.match(s, i, d2) and j > -1:
                first = i + n2
                if g.match(s, first, ' '): first += 1
                last = j
                if g.match(s, last - 1, ' '): last -= 1
                result.append(s[:i] + s[first:last] + s[j + n3:])
            else:
                result.append(s)
    result = ''.join(result)
    c.updateBodyPane(head,
                     result,
                     tail,
                     undoType='Delete Comments',
                     oldSel=None,
                     oldYview=oldYview)
Exemplo n.º 54
0
    def scan_line(self, s, prev_state):
        '''
        Update the scan state at the *end* of the line by scanning all of s.

        Distinguishing the the start of a regex from a div operator is tricky:
        http://stackoverflow.com/questions/4726295/
        http://stackoverflow.com/questions/5519596/
        (, [, {, ;, and binops can only be followed by a regexp.
        ), ], }, ids, strings and numbers can only be followed by a div operator.
        '''
        context = prev_state.context
        curlies, parens = prev_state.curlies, prev_state.parens
        expect = None  # (None, 'regex', 'div')
        i = 0
        # Special case for the start of a *file*
        # if not context:
        # i = g.skip_ws(s, i)
        # m = self.start_pattern.match(s, i)
        # if m:
        # i += len(m.group(0))
        # if g.match(s, i, '/'):
        # i = self.skip_regex(s, i)
        while i < len(s):
            assert expect is None, expect
            progress = i
            ch, s2 = s[i], s[i:i + 2]
            if context == '/*':
                if s2 == '*/':
                    i += 2
                    context = ''
                    expect = 'div'
                else:
                    i += 1  # Eat the next comment char.
            elif context:
                assert context in ('"', "'", '`'), repr(context)
                # #651: support back tick
                if ch == '\\':
                    i += 2
                elif context == ch:
                    i += 1
                    context = ''  # End the string.
                    expect = 'regex'
                else:
                    i += 1  # Eat the string character.
            elif s2 == '//':
                break  # The single-line comment ends the line.
            elif s2 == '/*':
                # Start a comment.
                i += 2
                context = '/*'
            elif ch in (
                    '"',
                    "'",
                    '`',
            ):
                # #651: support back tick
                # Start a string.
                i += 1
                context = ch
            elif ch in '_$' or ch.isalpha():
                # An identifier. Only *approximately* correct.
                # http://stackoverflow.com/questions/1661197/
                i += 1
                while i < len(s) and (s[i] in '_$' or s[i].isalnum()):
                    i += 1
                expect = 'div'
            elif ch.isdigit():
                i += 1
                # Only *approximately* correct.
                while i < len(s) and (s[i] in '.+-e' or s[i].isdigit()):
                    i += 1
                # This should work even if the scan ends with '+' or '-'
                expect = 'div'
            elif ch in '?:':
                i += 1
                expect = 'regex'
            elif ch in ';,':
                i += 1
                expect = 'regex'
            elif ch == '\\':
                i += 2
            elif ch == '{':
                i += 1
                curlies += 1
                expect = 'regex'
            elif ch == '}':
                i += 1
                curlies -= 1
                expect = 'div'
            elif ch == '(':
                i += 1
                parens += 1
                expect = 'regex'
            elif ch == ')':
                i += 1
                parens -= 1
                expect = 'div'
            elif ch == '[':
                i += 1
                expect = 'regex'
            elif ch == ']':
                i += 1
                expect = 'div'
            else:
                m = self.op_pattern.match(s, i)
                if m:
                    i += len(m.group(0))
                    expect = 'regex'
                elif ch == '/':
                    g.trace('no lookahead for "/"', repr(s))
                    assert False, i
                else:
                    i += 1
                    expect = None
            # Look for a '/' in the expected context.
            if expect:
                assert not context, repr(context)
                i = g.skip_ws(s, i)
                # Careful // is the comment operator.
                if g.match(s, i, '//'):
                    break
                elif g.match(s, i, '/'):
                    if expect == 'div':
                        i += 1
                    else:
                        assert expect == 'regex', repr(expect)
                        i = self.skip_regex(s, i)
            expect = None
            assert progress < i
        d = {'context': context, 'curlies': curlies, 'parens': parens}
        state = JS_ScanState(d)
        return state
Exemplo n.º 55
0
 def skipString(self, s, i):
     if g.match(s, i, '"') or g.match(s, i, "'"):
         return g.skip_string(s, i)
     else:
         return g.skip_heredoc_string(s, i)
Exemplo n.º 56
0
def deleteComments(self, event=None):
    #@+<< deleteComments docstring >>
    #@+node:ekr.20171123135625.37: *3* << deleteComments docstring >>
    #@@pagewidth 50
    """
    Removes one level of comment delimiters from all
    selected lines.  The applicable @language directive
    determines the comment delimiters to be removed.

    Removes single-line comments if possible; removes
    block comments for languages like html that lack
    single-line comments.

    *See also*: add-comments.
    """
    #@-<< deleteComments docstring >>
    c, p, u, w = self, self.p, self.undoer, self.frame.body.wrapper
    #
    # "Before" snapshot.
    bunch = u.beforeChangeBody(p)
    #
    # Initial data.
    head, lines, tail, oldSel, oldYview = self.getBodyLines()
    if not lines:
        g.warning('no text selected')
        return
    # The default language in effect at p.
    language = c.frame.body.colorizer.scanLanguageDirectives(p)
    if c.hasAmbiguousLanguage(p):
        language = c.getLanguageAtCursor(p, language)
    d1, d2, d3 = g.set_delims_from_language(language)
    #
    # Calculate the result.
    changed, result = False, []
    if d1:
        # Remove the single-line comment delim in front of each line
        d1b = d1 + ' '
        n1, n1b = len(d1), len(d1b)
        for s in lines:
            i = g.skip_ws(s, 0)
            if g.match(s, i, d1b):
                result.append(s[:i] + s[i + n1b:])
                changed = True
            elif g.match(s, i, d1):
                result.append(s[:i] + s[i + n1:])
                changed = True
            else:
                result.append(s)
    else:
        # Remove the block comment delimiters from each line.
        n2, n3 = len(d2), len(d3)
        for s in lines:
            i = g.skip_ws(s, 0)
            j = s.find(d3, i + n2)
            if g.match(s, i, d2) and j > -1:
                first = i + n2
                if g.match(s, first, ' '):
                    first += 1
                last = j
                if g.match(s, last - 1, ' '):
                    last -= 1
                result.append(s[:i] + s[first:last] + s[j + n3:])
                changed = True
            else:
                result.append(s)
    if not changed:
        return
    #
    # 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)
    #
    # Set the selection range and scroll position.
    i = len(head)
    j = ins = max(i, len(head) + len(middle) - 1)
    w.setSelectionRange(i, j, insert=ins)
    w.setYScrollPosition(oldYview)
    #
    # "after" snapshot.
    u.afterChangeBody(p, 'Indent Region', bunch)
Exemplo n.º 57
0
 def skip_block_comment(self, s, i):
     assert g.match(s, i, "/*")
     j = s.find("*/", i)
     if j == -1:
         return len(s)
     return j + 2
Exemplo n.º 58
0
def OpenProcess(p):

    global RunNode,WorkDir
    global In,OutThread,ErrThread,ExitCode

    command = p.h[4:].strip() # Remove @run
    if not command: return
    #@+<< set the working directory or return >>
    #@+node:ekr.20040910094754: *3* << set the working directory or return >>
    args = command.split(' ')

    path,fname = os.path.split(args[0])

    if g.match(fname,0,'#'):
        return

    if path:
        if os.access(path,os.F_OK) == 1:
            WorkDir=os.getcwd()
            os.chdir(path)
        else:
            g.error("@run: invalid path: %s" % (path))
            return
    #@-<< set the working directory or return >>
    #@+<< set the command, removing all args following '#' >>
    #@+node:ekr.20040910100935: *3* << set the command, removing all args following '#' >>
    command = fname

    for arg in args[1:]:
        if g.match(arg,0,'#'):
            break
        else:
            command += ' ' + arg.strip()
    #@-<< set the command, removing all args following '#' >>
    if not command.strip():
        return
    RunNode=p
    args = []
    #@+<< append arguments from child nodes to command >>
    #@+node:ekr.20040910095147: *3* << append arguments from child nodes to command >>
    for child in p.children():
        h = child.h
        if g.match_word(h,0,"@arg"):
            arg = h[4:].strip()
            args.append(arg)
        else:
            if (
                not g.match_word(h,0,"@run") and
                not g.match_word(h,0,"@in") and
                not g.match_word(h,0,"@input")
            ):
                args.append(child.b.strip())
    #@-<< append arguments from child nodes to command >>

    g.blue("@run %s>%s" % (os.getcwd(),command))
    for arg in args:
        g.blue("@arg %s" % arg)
    command += ' ' + ' '.join(args)

    # Start the threads and open the pipe.
    OutThread = readingThread()
    ErrThread = readingThread()

    # In,OutThread.File,ErrThread.File	= os.popen3(command,"t")
    # OutThread.File,In,ErrThread.File = os.popen3(command,"t")
    # PIPE = subprocess.PIPE
    proc = subprocess.Popen(command, shell=True)
        # bufsize=bufsize,
        # stdin=PIPE,
        # stdout=PIPE,
        # stderr=PIPE) ,close_fds=True)
    In             = proc.stdin
    OutThread.File = proc.stdout
    ErrThread.File = proc.stderr
    OutThread.start()
    ErrThread.start()
    # Mark and select the node.
    RunNode.setMarked()
    c = RunNode.v.context
    c.selectPosition(RunNode)
    if os.name in ("nt","dos"):
        c.redraw()
Exemplo n.º 59
0
 def startsString(self, s, i):
     return g.match(s, i, '"') or g.match(s, i, "'") or g.match(s, i, '<<<')
Exemplo n.º 60
0
    def isSentinel(self, s, sentinelComment):

        i = g.skip_ws(s, 0)
        return g.match(s, i, sentinelComment)