def _doIndentHere(self, scimoz, indentStyle, continueComments, style_info): # Returns either None or an indent string pos = scimoz.positionBefore(scimoz.currentPos) startPos = scimoz.currentPos style = scimoz.getStyleAt(pos) if style != scimoz.SCE_UDL_TPL_OPERATOR: return None if scimoz.getWCharAt(pos) != "]": return None pos -= 1 style = scimoz.getStyleAt(pos) if style != scimoz.SCE_UDL_TPL_OPERATOR: return None if scimoz.getWCharAt(pos) != "%": return None pos -= 1 curLineNo = scimoz.lineFromPosition(pos) lineStartPos = scimoz.positionFromLine(curLineNo) delta, numTags = self._getTagDiffDelta(scimoz, lineStartPos, startPos) if delta < 0 and numTags == 1 and curLineNo > 0: didDedent, dedentAmt = self.dedentThisLine(scimoz, curLineNo, startPos) if didDedent: return dedentAmt else: return None indentWidth = self._getIndentWidthForLine(scimoz, curLineNo) indent = scimoz.indent newIndentWidth = indentWidth + delta * indent if newIndentWidth < 0: newIndentWidth = 0 return scimozindent.makeIndentFromWidth(scimoz, newIndentWidth)
def _computeIndent(self, scimoz, indentStyle, continueComments, style_info, calculatedData=None): """ If the current line starts with an indenter, count all the keywords on the line to decide what the final indent should be. """ if calculatedData is None: calculatedData = self.getTokenDataForComputeIndent(scimoz, style_info) non_ws_tokens = calculatedData["non_ws_tokens"] if len(non_ws_tokens) == 0: return if non_ws_tokens[0].style not in style_info._keyword_styles: return if non_ws_tokens[0].text not in self._indenting_statements: # Do this only if the line starts with an indenter. # Otherwise we want to use the general language-service's indenter # to look for braces to match. return delta = 1 for tok in non_ws_tokens[1:]: if tok.style in style_info._keyword_styles: text = tok.text if text in self._indenting_statements: delta += 1 # not an elif, because some keywords are both indenters and dedenters # This works because if the first keyword is only counted as an indenter. if text in self._keyword_dedenting_keywords: delta -= 1 tok0 = calculatedData["tokens"][0] if tok0.style not in style_info._default_styles: currentIndentWidth = 0 else: currentIndentWidth = len(tok0.text.expandtabs(scimoz.tabWidth)) nextIndentWidth = currentIndentWidth + delta * scimoz.indent return scimozindent.makeIndentFromWidth(scimoz, nextIndentWidth)
def _doIndentHere(self, scimoz, indentStyle, continueComments, style_info): pos = scimoz.positionBefore(scimoz.currentPos) startPos = scimoz.currentPos style = scimoz.getStyleAt(pos) if style != scimoz.SCE_UDL_TPL_OPERATOR: return None if scimoz.getWCharAt(pos) != ">": return None pos -= 1 style = scimoz.getStyleAt(pos) if style != scimoz.SCE_UDL_TPL_OPERATOR: return None if scimoz.getWCharAt(pos) != "%": return None curLineNo = scimoz.lineFromPosition(pos) lineStartPos = scimoz.positionFromLine(curLineNo) delta, numTags = self._getTagDiffDelta(scimoz, lineStartPos, startPos) if delta < 0 and numTags == 1 and curLineNo > 0: didDedent, dedentAmt = self.dedentThisLine(scimoz, curLineNo, startPos) if didDedent: return dedentAmt else: # Since EJS tags end with a ">", keep the # HTML auto-indenter out of here. return self._getRawIndentForLine(scimoz, curLineNo) indentWidth = self._getIndentWidthForLine(scimoz, curLineNo) indent = scimoz.indent if not indent: indent = scimoz.tabWidth # if 0, Scintilla uses tabWidth newIndentWidth = indentWidth + delta * indent if newIndentWidth < 0: newIndentWidth = 0 #qlog.debug("new indent width: %d", newIndentWidth) return scimozindent.makeIndentFromWidth(scimoz, newIndentWidth)
def _doIndentHere(self, scimoz, indentStyle, continueComments, style_info): # Returns either None or an indent string pos = scimoz.positionBefore(scimoz.currentPos) startPos = scimoz.currentPos style = scimoz.getStyleAt(pos) if style != scimoz.SCE_UDL_TPL_OPERATOR: return None if scimoz.getWCharAt(pos) != "]": return None pos -= 1 style = scimoz.getStyleAt(pos) if style != scimoz.SCE_UDL_TPL_OPERATOR: return None if scimoz.getWCharAt(pos) != "%": return None pos -= 1 curLineNo = scimoz.lineFromPosition(pos) lineStartPos = scimoz.positionFromLine(curLineNo) delta, numTags = self._getTagDiffDelta(scimoz, lineStartPos, startPos) if delta < 0 and numTags == 1 and curLineNo > 0: didDedent, dedentAmt = self.dedentThisLine( scimoz, curLineNo, startPos) if didDedent: return dedentAmt else: return None indentWidth = self._getIndentWidthForLine(scimoz, curLineNo) indent = scimoz.indent newIndentWidth = indentWidth + delta * indent if newIndentWidth < 0: newIndentWidth = 0 return scimozindent.makeIndentFromWidth(scimoz, newIndentWidth)
def dedentThisLine(self, scimoz, curLineNo, startPos): # Used by UDL template languages # Returns a tuple: # First item: whether the current line needed to be dedented # Second item: the new indentation for the current line thisLinesIndent = scimoz.getLineIndentation(curLineNo) prevLinesIndent = scimoz.getLineIndentation(curLineNo - 1) if prevLinesIndent <= thisLinesIndent: # We need to dedent this line lineStartPos = scimoz.positionFromLine(curLineNo) text = scimoz.getTextRange(lineStartPos, startPos) m = self._leadingWSRE.match(text) if m: leadingWS = m.group(1) tabFreeLeadingWS = leadingWS.expandtabs(scimoz.tabWidth) currWidth = len(tabFreeLeadingWS) indent = scimoz.indent if not indent: indent = scimoz.tabWidth # if 0, Scintilla uses tabWidth targetWidth = currWidth - indent if targetWidth < 0: fixedLeadingWS = "" else: fixedLeadingWS = scimozindent.makeIndentFromWidth(scimoz, targetWidth) scimoz.targetStart = lineStartPos scimoz.targetEnd = lineStartPos + len(leadingWS) scimoz.replaceTarget(len(fixedLeadingWS), fixedLeadingWS) return (True, fixedLeadingWS) return (False, None)
def dedentThisLine(self, scimoz, curLineNo, startPos): # Used by UDL template languages # Returns a tuple: # First item: whether the current line needed to be dedented # Second item: the new indentation for the current line thisLinesIndent = scimoz.getLineIndentation(curLineNo) prevLinesIndent = scimoz.getLineIndentation(curLineNo - 1) if prevLinesIndent == thisLinesIndent: # We need to dedent this line lineStartPos = scimoz.positionFromLine(curLineNo) text = scimoz.getTextRange(lineStartPos, startPos) m = self._leadingWSRE.match(text) if m: leadingWS = m.group(1) tabFreeLeadingWS = leadingWS.expandtabs(scimoz.tabWidth) currWidth = len(tabFreeLeadingWS) targetWidth = currWidth - scimoz.indent if targetWidth < 0: fixedLeadingWS = "" else: fixedLeadingWS = scimozindent.makeIndentFromWidth( scimoz, targetWidth) scimoz.targetStart = lineStartPos scimoz.targetEnd = lineStartPos + len(leadingWS) scimoz.replaceTarget(len(fixedLeadingWS), fixedLeadingWS) return (True, fixedLeadingWS) return (False, None)
def _doIndentHere(self, scimoz, indentStyle, continueComments, style_info): # Returns either None or an indent string pos = scimoz.positionBefore(scimoz.currentPos) startPos = scimoz.currentPos style = scimoz.getStyleAt(pos) if style != scimoz.SCE_UDL_TPL_OPERATOR: return None if scimoz.getWCharAt(pos) != ">": return None pos -= 1 curLineNo = scimoz.lineFromPosition(pos) lineStartPos = scimoz.positionFromLine(curLineNo) delta, numTags = self._getTagDiffDelta(scimoz, lineStartPos, startPos) if delta < 0 and numTags == 1 and curLineNo > 0: didDedent, dedentAmt = self.dedentThisLine(scimoz, curLineNo, startPos) if didDedent: return dedentAmt else: # Since Mason tags end with a ">", keep the # HTML auto-indenter out of here. return self._getRawIndentForLine(scimoz, curLineNo) indentWidth = self._getIndentWidthForLine(scimoz, curLineNo) indent = scimoz.indent if not indent: indent = scimoz.tabWidth # if 0, Scintilla uses tabWidth newIndentWidth = indentWidth + delta * indent if newIndentWidth < 0: newIndentWidth = 0 return scimozindent.makeIndentFromWidth(scimoz, newIndentWidth)
def _doIndentHere(self, scimoz, indentStyle, continueComments, style_info): pos = scimoz.positionBefore(scimoz.currentPos) startPos = scimoz.currentPos style = scimoz.getStyleAt(pos) if style != scimoz.SCE_UDL_TPL_OPERATOR: return None if scimoz.getWCharAt(pos) != ">": return None pos -= 1 style = scimoz.getStyleAt(pos) if style != scimoz.SCE_UDL_TPL_OPERATOR: return None if scimoz.getWCharAt(pos) != "%": return None curLineNo = scimoz.lineFromPosition(pos) lineStartPos = scimoz.positionFromLine(curLineNo) delta, numTags = self._getTagDiffDelta(scimoz, lineStartPos, startPos) if delta < 0 and numTags == 1 and curLineNo > 0: didDedent, dedentAmt = self.dedentThisLine(scimoz, curLineNo, startPos) if didDedent: return dedentAmt else: # Since RHTML tags end with a ">", keep the # HTML auto-indenter out of here. return self._getRawIndentForLine(scimoz, curLineNo) indentWidth = self._getIndentWidthForLine(scimoz, curLineNo) indent = scimoz.indent newIndentWidth = indentWidth + delta * indent if newIndentWidth < 0: newIndentWidth = 0 #qlog.debug("new indent width: %d", newIndentWidth) return scimozindent.makeIndentFromWidth(scimoz, newIndentWidth)
def _computeIndent(self, scimoz, indentStyle, continueComments, style_info, calculatedData): if not self._lookingAtReturnFunction(calculatedData["non_ws_tokens"], style_info): return None tok0 = calculatedData["tokens"][0] if tok0.style in style_info._default_styles: currWSLen = len(tok0.text.expandtabs(scimoz.tabWidth)) newWSLen = currWSLen + scimoz.indent else: newWSLen = scimoz.indent return scimozindent.makeIndentFromWidth(scimoz, newWSLen)
def _computeIndent(self, scimoz, indentStyle, continueComments, style_info, calculatedData): if not self._lookingAtReturnFunction(calculatedData['non_ws_tokens'], style_info): return None tok0 = calculatedData['tokens'][0] if tok0.style in style_info._default_styles: currWSLen = len(tok0.text.expandtabs(scimoz.tabWidth)) newWSLen = currWSLen + scimoz.indent else: newWSLen = scimoz.indent return scimozindent.makeIndentFromWidth(scimoz, newWSLen)
def _computeIndent(self, scimoz, indentStyle, continueComments, style_info, calculatedData=None): """ If the current line starts with an indenter, count all the keywords on the line to decide what the final indent should be. """ if calculatedData is None: calculatedData = self.getTokenDataForComputeIndent( scimoz, style_info) non_ws_tokens = calculatedData['non_ws_tokens'] if len(non_ws_tokens) == 0: return if non_ws_tokens[0].style not in style_info._keyword_styles: return if non_ws_tokens[0].text not in self._indenting_statements: # Do this only if the line starts with an indenter. # Otherwise we want to use the general language-service's indenter # to look for braces to match. return delta = 1 for tok in non_ws_tokens[1:]: if tok.style in style_info._keyword_styles: text = tok.text if text in self._indenting_statements: delta += 1 # not an elif, because some keywords are both indenters and dedenters # This works because if the first keyword is only counted as an indenter. if text in self._keyword_dedenting_keywords: delta -= 1 tok0 = calculatedData['tokens'][0] if tok0.style not in style_info._default_styles: currentIndentWidth = 0 else: currentIndentWidth = len(tok0.text.expandtabs(scimoz.tabWidth)) indent = scimoz.indent if not indent: indent = scimoz.tabWidth # if 0, Scintilla uses tabWidth nextIndentWidth = currentIndentWidth + delta * indent return scimozindent.makeIndentFromWidth(scimoz, nextIndentWidth)
def _keyPressedAux(self, ch, scimoz, style_info): """ If we're at the start of a line, we're at the end of a dedenting_statement (Consult pref edit.indent.keyword.dedent_on_last_char to determine whether to do this on the last char of the keyword, or one after the last char), 1. get the parent indent 2. subtract one tabwidth from the current indent 3. convert the leading white-space to tabs, if necessary 4. replace the leading white-space with new white-space 5. Assume self._keyword_dedenting_keywords is non-empty. Otherwise why would the subclass be using this as a superclass? """ if not self._editAutoIndentStyle.startswith("smart"): return if ch in ('\n', '\r'): return self._checkIndentingCurrentAndPreviousLine(ch, scimoz, style_info) currentPos = scimoz.currentPos lastCharPos = scimoz.positionBefore(currentPos) currLineNo = scimoz.lineFromPosition(lastCharPos) if currLineNo == 0: # Nothing to do on the first line return lineStartPos = scimoz.positionFromLine(currLineNo) # If we aren't at the end of the line, back out. tokens = self._get_line_tokens(scimoz, lineStartPos, lastCharPos, style_info) if (len(tokens) not in (2, 3) or tokens[0].style not in style_info._default_styles): return if not self._dedent_on_last_char and len(tokens) == 2: return word2Style = tokens[1].style if len(tokens) == 3: if (tokens[2].style not in style_info._default_styles or len(tokens[2].text) != 1 or word2Style not in style_info._keyword_styles): return elif word2Style not in (style_info._keyword_styles + style_info._variable_styles): return # If the edit.indent.keyword.dedent_on_last_char pref is on, we can dedent # either on the last char on the pref, or one after. # If it's off, dedent only one after. if tokens[1].text not in self._keyword_dedenting_keywords: return # Next figure out what this line's indent should be based on the previous line. # If it's not the current indent, then the buffer's been changed, and don't # bother second-guessing the user. scimoz.currentPos = scimoz.getLineEndPosition(currLineNo - 1) try: expected_indent = self.computeIndent(scimoz, 'keyword', False) finally: scimoz.currentPos = currentPos leadingWS_sp = tokens[0].text.expandtabs(scimoz.tabWidth) currWSLen = len(leadingWS_sp) expected_indent_sp = expected_indent.expandtabs(scimoz.tabWidth) if len(expected_indent_sp) != currWSLen: return # If the parent line triggered a dedent (expected_indent < that line's # leading white-space, then we've already done it. # if self._thisLineAlreadyDedented(scimoz, currLineNo, expected_indent): return # Dedent! indent = scimoz.indent if not indent: indent = scimoz.tabWidth # if 0, Scintilla uses tabWidth newWSLen = currWSLen - indent if newWSLen <= 0: ws_reduced = "" else: ws_reduced = scimozindent.makeIndentFromWidth(scimoz, newWSLen) scimoz.targetStart = lineStartPos scimoz.targetEnd = lineStartPos + len(tokens[0].text) scimoz.beginUndoAction() try: scimoz.replaceTarget(len(ws_reduced), ws_reduced) finally: scimoz.endUndoAction() return True
def _checkIndentingCurrentAndPreviousLine(self, ch, scimoz, style_info): # This is complicated because the computeIndent was called to calculate # the indentation of the current line, so we need to check both this line # and the previous line. currentPos = scimoz.currentPos lastCharPos = scimoz.positionBefore(currentPos) currLineNo = scimoz.lineFromPosition(lastCharPos) if currLineNo <= 1: # Nothing to do on the first line return lineStartPos = scimoz.positionFromLine(currLineNo) # First make sure this line is all blank # If we aren't at the end of the line, back out. tokens = self._get_line_tokens(scimoz, lineStartPos, lastCharPos, style_info) if not tokens: # Nothing to do return if (len(tokens) != 1 or tokens[0].style not in style_info._default_styles): return # Now look at the previous line. prevLineNo = currLineNo - 1 prevLineStartPos = scimoz.positionFromLine(prevLineNo) prevLineEndPos = scimoz.getLineEndPosition(prevLineNo) prevTokens = self._get_line_tokens(scimoz, prevLineStartPos, prevLineEndPos - 1, style_info) if len(prevTokens) != 2: return if prevTokens[0].style not in style_info._default_styles: return if (prevTokens[1].style not in style_info._keyword_styles or prevTokens[1].text not in self._keyword_dedenting_keywords): return if len(prevTokens[0].text) > len(tokens[0].text): return # So now figure out what currLine - 2 indentation should have been currentPos = scimoz.currentPos scimoz.currentPos = scimoz.getLineEndPosition(prevLineNo - 1) try: expected_indent = self.computeIndent(scimoz, 'keyword', False) finally: scimoz.currentPos = currentPos expected_indent_sp = expected_indent.expandtabs(scimoz.tabWidth) leadingWS_sp = prevTokens[0].text.expandtabs(scimoz.tabWidth) currWSLen = len(leadingWS_sp) if len(expected_indent_sp) != currWSLen: return if self._thisLineAlreadyDedented(scimoz, prevLineNo, expected_indent): return # Dedent! ws_reduced = [None, None] indent = scimoz.indent if not indent: indent = scimoz.tabWidth # if 0, Scintilla uses tabWidth newWSLen = currWSLen - indent if newWSLen <= 0: ws_reduced[0] = "" posDelta = len(tokens[0].text) else: ws_reduced[0] = scimozindent.makeIndentFromWidth(scimoz, newWSLen) posDelta = indent currWSLen = len(prevTokens[0].text.expandtabs(scimoz.tabWidth)) newWSLen = currWSLen - indent if newWSLen <= 0: ws_reduced[1] = "" posDelta += len(prevTokens[0].text) else: ws_reduced[1] = scimozindent.makeIndentFromWidth(scimoz, newWSLen) posDelta += indent scimoz.beginUndoAction() try: # Dedent the second line first scimoz.targetStart = tokens[0].start_pos scimoz.targetEnd = tokens[0].start_pos + len(tokens[0].text) scimoz.replaceTarget(len(ws_reduced[0]), ws_reduced[0]) scimoz.targetStart = prevTokens[0].start_pos scimoz.targetEnd = prevTokens[0].start_pos + len(prevTokens[0].text) scimoz.replaceTarget(len(ws_reduced[1]), ws_reduced[1]) scimoz.currentPos = scimoz.anchor = currentPos - posDelta finally: scimoz.endUndoAction() return True
def insertInternalNewline_Special(self, scimoz, indentStyle, currentPos, allowExtraNewline, style_info): """ Handle cases where the user presses newline between the end of a start-tag and the start of the following end-tag. Tag names must match. Precondition: the current pos is between two characters, so we know 0 < currentPos < scimoz.length, so we don't have to test for those boundaries. """ if indentStyle is None: return None if scimoz.getStyleAt(currentPos) != scimoz.SCE_UDL_M_ETAGO: return None startTagLineNo = self._immediatelyPrecedingStartTagLineNo(scimoz, currentPos) if startTagLineNo is None: # returns (startTag:s, startTag:e, endTag:s, endTag:e) startTagInfo = scimozindent.startTagInfo_from_endTagPos(scimoz, currentPos) if startTagInfo is None: return None startTagLineNo = scimoz.lineFromPosition(startTagInfo[0]) allowExtraNewline = False indentStyle = 'plain' # Don't indent new part closeIndentWidth = self._getIndentWidthForLine(scimoz, startTagLineNo) if indentStyle == 'smart' and self.supportsSmartIndent == 'XML': """ i<foo>|</foo> ==> i<foo> i....<|> i</foo> where "i" denotes the current leading indentation """ intermediateLineIndentWidth = self._getNextLineIndent(scimoz, startTagLineNo) else: """ i<foo>|</foo> ==> i<foo> i<|> i</foo> Note that the indentation of inner attr lines are ignored, even in block-indent mode: i<foo i........attr="val">|</foo> => i<foo i........attr="val"> i</foo> On ctrl-shift-newline, we don't get an extra blank line before the end-tag. """ intermediateLineIndentWidth = closeIndentWidth currentEOL = eollib.eol2eolStr[eollib.scimozEOL2eol[scimoz.eOLMode]] textToInsert = currentEOL + scimozindent.makeIndentFromWidth(scimoz, intermediateLineIndentWidth) finalPosn = currentPos + len(textToInsert) #ascii-safe if allowExtraNewline: textToInsert += currentEOL + scimozindent.makeIndentFromWidth(scimoz, closeIndentWidth) scimoz.addText(len(textToInsert), textToInsert) #ascii-safe return finalPosn
def _keyPressedAux(self, ch, scimoz, style_info): """ If we're at the start of a line, we're at the end of a dedenting_statement (Consult pref edit.indent.keyword.dedent_on_last_char to determine whether to do this on the last char of the keyword, or one after the last char), 1. get the parent indent 2. subtract one tabwidth from the current indent 3. convert the leading white-space to tabs, if necessary 4. replace the leading white-space with new white-space 5. Assume self._keyword_dedenting_keywords is non-empty. Otherwise why would the subclass be using this as a superclass? """ if self._editAutoIndentStyle != "smart": return if ch in ('\n', '\r'): return self._checkIndentingCurrentAndPreviousLine( ch, scimoz, style_info) currentPos = scimoz.currentPos lastCharPos = scimoz.positionBefore(currentPos) currLineNo = scimoz.lineFromPosition(lastCharPos) if currLineNo == 0: # Nothing to do on the first line return lineStartPos = scimoz.positionFromLine(currLineNo) # If we aren't at the end of the line, back out. tokens = self._get_line_tokens(scimoz, lineStartPos, lastCharPos, style_info) if (len(tokens) not in (2, 3) or tokens[0].style not in style_info._default_styles): return if not self._dedent_on_last_char and len(tokens) == 2: return word2Style = tokens[1].style if len(tokens) == 3: if (tokens[2].style not in style_info._default_styles or len(tokens[2].text) != 1 or word2Style not in style_info._keyword_styles): return elif word2Style not in (style_info._keyword_styles + style_info._variable_styles): return # If the edit.indent.keyword.dedent_on_last_char pref is on, we can dedent # either on the last char on the pref, or one after. # If it's off, dedent only one after. if tokens[1].text not in self._keyword_dedenting_keywords: return # Next figure out what this line's indent should be based on the previous line. # If it's not the current indent, then the buffer's been changed, and don't # bother second-guessing the user. scimoz.currentPos = scimoz.getLineEndPosition(currLineNo - 1) try: expected_indent = self.computeIndent(scimoz, 'keyword', False) finally: scimoz.currentPos = currentPos leadingWS_sp = tokens[0].text.expandtabs(scimoz.tabWidth) currWSLen = len(leadingWS_sp) expected_indent_sp = expected_indent.expandtabs(scimoz.tabWidth) if len(expected_indent_sp) != currWSLen: return # If the parent line triggered a dedent (expected_indent < that line's # leading white-space, then we've already done it. # if self._thisLineAlreadyDedented(scimoz, currLineNo, expected_indent): return # Dedent! newWSLen = currWSLen - scimoz.indent if newWSLen <= 0: ws_reduced = "" else: ws_reduced = scimozindent.makeIndentFromWidth(scimoz, newWSLen) scimoz.targetStart = lineStartPos scimoz.targetEnd = lineStartPos + len(tokens[0].text) scimoz.beginUndoAction() try: scimoz.replaceTarget(len(ws_reduced), ws_reduced) finally: scimoz.endUndoAction() return True
def _checkIndentingCurrentAndPreviousLine(self, ch, scimoz, style_info): # This is complicated because the computeIndent was called to calculate # the indentation of the current line, so we need to check both this line # and the previous line. currentPos = scimoz.currentPos lastCharPos = scimoz.positionBefore(currentPos) currLineNo = scimoz.lineFromPosition(lastCharPos) if currLineNo <= 1: # Nothing to do on the first line return lineStartPos = scimoz.positionFromLine(currLineNo) # First make sure this line is all blank # If we aren't at the end of the line, back out. tokens = self._get_line_tokens(scimoz, lineStartPos, lastCharPos, style_info) if not tokens: # Nothing to do return if (len(tokens) != 1 or tokens[0].style not in style_info._default_styles): return # Now look at the previous line. prevLineNo = currLineNo - 1 prevLineStartPos = scimoz.positionFromLine(prevLineNo) prevLineEndPos = scimoz.getLineEndPosition(prevLineNo) prevTokens = self._get_line_tokens(scimoz, prevLineStartPos, prevLineEndPos - 1, style_info) if len(prevTokens) != 2: return if prevTokens[0].style not in style_info._default_styles: return if (prevTokens[1].style not in style_info._keyword_styles or prevTokens[1].text not in self._keyword_dedenting_keywords): return if len(prevTokens[0].text) > len(tokens[0].text): return # So now figure out what currLine - 2 indentation should have been currentPos = scimoz.currentPos scimoz.currentPos = scimoz.getLineEndPosition(prevLineNo - 1) try: expected_indent = self.computeIndent(scimoz, 'keyword', False) finally: scimoz.currentPos = currentPos expected_indent_sp = expected_indent.expandtabs(scimoz.tabWidth) leadingWS_sp = prevTokens[0].text.expandtabs(scimoz.tabWidth) currWSLen = len(leadingWS_sp) if len(expected_indent_sp) != currWSLen: return if self._thisLineAlreadyDedented(scimoz, prevLineNo, expected_indent): return # Dedent! ws_reduced = [None, None] newWSLen = currWSLen - scimoz.indent if newWSLen <= 0: ws_reduced[0] = "" posDelta = len(tokens[0].text) else: ws_reduced[0] = scimozindent.makeIndentFromWidth(scimoz, newWSLen) posDelta = scimoz.indent currWSLen = len(prevTokens[0].text.expandtabs(scimoz.tabWidth)) newWSLen = currWSLen - scimoz.indent if newWSLen <= 0: ws_reduced[1] = "" posDelta += len(prevTokens[0].text) else: ws_reduced[1] = scimozindent.makeIndentFromWidth(scimoz, newWSLen) posDelta += scimoz.indent scimoz.beginUndoAction() try: # Dedent the second line first scimoz.targetStart = tokens[0].start_pos scimoz.targetEnd = tokens[0].start_pos + len(tokens[0].text) scimoz.replaceTarget(len(ws_reduced[0]), ws_reduced[0]) scimoz.targetStart = prevTokens[0].start_pos scimoz.targetEnd = prevTokens[0].start_pos + len( prevTokens[0].text) scimoz.replaceTarget(len(ws_reduced[1]), ws_reduced[1]) scimoz.currentPos = scimoz.anchor = currentPos - posDelta finally: scimoz.endUndoAction() return True
def insertInternalNewline_Special(self, scimoz, indentStyle, currentPos, allowExtraNewline, style_info): """ Handle cases where the user presses newline between the end of a start-tag and the start of the following end-tag. Tag names must match. Precondition: the current pos is between two characters, so we know 0 < currentPos < scimoz.length, so we don't have to test for those boundaries. """ if indentStyle is None: return None if scimoz.getStyleAt(currentPos) != scimoz.SCE_UDL_M_ETAGO: return None startTagLineNo = self._immediatelyPrecedingStartTagLineNo( scimoz, currentPos) if startTagLineNo is None: # returns (startTag:s, startTag:e, endTag:s, endTag:e) startTagInfo = scimozindent.startTagInfo_from_endTagPos( scimoz, currentPos) if startTagInfo is None: return None startTagLineNo = scimoz.lineFromPosition(startTagInfo[0]) allowExtraNewline = False indentStyle = 'plain' # Don't indent new part closeIndentWidth = self._getIndentWidthForLine(scimoz, startTagLineNo) if indentStyle == 'smart' and self.supportsSmartIndent == 'XML': """ i<foo>|</foo> ==> i<foo> i....<|> i</foo> where "i" denotes the current leading indentation """ intermediateLineIndentWidth = self._getNextLineIndent( scimoz, startTagLineNo) else: """ i<foo>|</foo> ==> i<foo> i<|> i</foo> Note that the indentation of inner attr lines are ignored, even in block-indent mode: i<foo i........attr="val">|</foo> => i<foo i........attr="val"> i</foo> On ctrl-shift-newline, we don't get an extra blank line before the end-tag. """ intermediateLineIndentWidth = closeIndentWidth currentEOL = eollib.eol2eolStr[eollib.scimozEOL2eol[scimoz.eOLMode]] textToInsert = currentEOL + scimozindent.makeIndentFromWidth( scimoz, intermediateLineIndentWidth) finalPosn = currentPos + len(textToInsert) #ascii-safe if allowExtraNewline: textToInsert += currentEOL + scimozindent.makeIndentFromWidth( scimoz, closeIndentWidth) scimoz.addText(len(textToInsert), textToInsert) #ascii-safe return finalPosn
def insertInternalNewline_Special(self, scimoz, indentStyle, currentPos, allowExtraNewline, style_info): """ Split %|% so the %'s are on separate lines, and there's a blank line in the middle. """ if indentStyle is None or currentPos < 2: return None if scimoz.getStyleAt(currentPos) != scimoz.SCE_UDL_TPL_OPERATOR: return None percentChar = ord("%") if scimoz.getCharAt(currentPos) != percentChar: return None prevPos = currentPos - 1 # ascii if scimoz.getStyleAt(prevPos) != scimoz.SCE_UDL_TPL_OPERATOR: return None if scimoz.getCharAt(prevPos) != percentChar: return None prev2Pos = prevPos - 1 if scimoz.getStyleAt(prev2Pos) != scimoz.SCE_UDL_TPL_OPERATOR: return None if scimoz.getCharAt(prev2Pos) != ord("<"): return None lineNo = scimoz.lineFromPosition(currentPos) closeIndentWidth = self._getIndentWidthForLine(scimoz, lineNo) if indentStyle == 'smart': """ i<%|% ==> i<% i....<|> i% where "i" denotes the current leading indentation """ intermediateLineIndentWidth = self._getNextLineIndent( scimoz, lineNo) else: """ i<%|% ==> i<% i<|> i% Note that the indentation of inner attr lines are ignored, even in block-indent mode: i<foo i........attr="val">|</foo> => i<foo i........attr="val"> i</foo> """ intermediateLineIndentWidth = closeIndentWidth currentEOL = eollib.eol2eolStr[eollib.scimozEOL2eol[scimoz.eOLMode]] textToInsert = currentEOL + scimozindent.makeIndentFromWidth( scimoz, intermediateLineIndentWidth) finalPosn = currentPos + len(textToInsert) #ascii-safe if allowExtraNewline: textToInsert += currentEOL + scimozindent.makeIndentFromWidth( scimoz, closeIndentWidth) scimoz.addText(len(textToInsert), textToInsert) #ascii-safe return finalPosn
def insertInternalNewline_Special(self, scimoz, indentStyle, currentPos, allowExtraNewline, style_info): """ Split %|% so the %'s are on separate lines, and there's a blank line in the middle. """ if indentStyle is None or currentPos < 2: return None if scimoz.getStyleAt(currentPos) != scimoz.SCE_UDL_TPL_OPERATOR: return None percentChar = ord("%") if scimoz.getCharAt(currentPos) != percentChar: return None prevPos = currentPos - 1 # ascii if scimoz.getStyleAt(prevPos) != scimoz.SCE_UDL_TPL_OPERATOR: return None if scimoz.getCharAt(prevPos) != percentChar: return None prev2Pos = prevPos - 1 if scimoz.getStyleAt(prev2Pos) != scimoz.SCE_UDL_TPL_OPERATOR: return None if scimoz.getCharAt(prev2Pos) != ord("<"): return None lineNo = scimoz.lineFromPosition(currentPos) closeIndentWidth = self._getIndentWidthForLine(scimoz, lineNo) if indentStyle.startswith('smart'): """ i<%|% ==> i<% i....<|> i% where "i" denotes the current leading indentation """ intermediateLineIndentWidth = self._getNextLineIndent(scimoz, lineNo) else: """ i<%|% ==> i<% i<|> i% Note that the indentation of inner attr lines are ignored, even in block-indent mode: i<foo i........attr="val">|</foo> => i<foo i........attr="val"> i</foo> """ intermediateLineIndentWidth = closeIndentWidth currentEOL = eollib.eol2eolStr[eollib.scimozEOL2eol[scimoz.eOLMode]] textToInsert = currentEOL + scimozindent.makeIndentFromWidth(scimoz, intermediateLineIndentWidth) finalPosn = currentPos + len(textToInsert) #ascii-safe if allowExtraNewline: textToInsert += currentEOL + scimozindent.makeIndentFromWidth(scimoz, closeIndentWidth) scimoz.addText(len(textToInsert), textToInsert) #ascii-safe return finalPosn