def apply(self, document): """Replace the current line with the populated template. IN: document: <IDocument> The edited document. OUT: None. """ self.vars['newline'] = PyAction.getDelimiter(document) sNewCode = self.template % self.vars # Move to insert point: iStartLineOffset = self.selection.getLineOffset() iEndLineOffset = iStartLineOffset + len(self.current_line) self.editor.setSelection(iEndLineOffset, 0) self.selection = PySelection(self.editor) # Replace the old code with the new assignment expression: self.selection.replaceLineContentsToSelection(sNewCode) #mark the value so that the user can change it selection = PySelection(self.editor) absoluteCursorOffset = selection.getAbsoluteCursorOffset() val = self.vars['value'] self.editor.selectAndReveal(absoluteCursorOffset-len(val),len(val))
def apply(self, document): """Replace the current line with the populated template. IN: document: <IDocument> The edited document. OUT: None. """ self.vars['newline'] = PyAction.getDelimiter(document) sNewCode = self.template % self.vars # Move to insert point: iStartLineOffset = self.selection.getLineOffset() iEndLineOffset = iStartLineOffset + len(self.current_line) self.editor.setSelection(iEndLineOffset, 0) self.selection = PySelection(self.editor) # Replace the old code with the new assignment expression: self.selection.replaceLineContentsToSelection(sNewCode) #mark the value so that the user can change it selection = PySelection(self.editor) absoluteCursorOffset = selection.getAbsoluteCursorOffset() val = self.vars['value'] self.editor.selectAndReveal(absoluteCursorOffset - len(val), len(val))
def run(self): import tempfile import os try: ps = PySelection(editor) doc = ps.getDoc() startLine = ps.getStartLineIndex() p1 = tempfile.mktemp() p2 = tempfile.mktemp() f1 = FileWriter(p1) formatAll = False if ps.getTextSelection().getLength() == 0: # format all. c = doc.get() f1.write(c) formatAll = True else: # format selection. #c = ps.getSelectedText() #f1.write(ps.getSelectedText()) print "Format selected text is not supported yet." f1.write("") # A kind of solution is to insert a special comment in # front and end of selection text, pythontidy it, and # extract text according that comment. f1.close() os.system('PythonTidy.py "%s" "%s"' % (p1, p2)) f2 = open(p2, "r") result = f2.read() f2.close() os.remove(p1) os.remove(p2) if startLine >= doc.getNumberOfLines(): startLine = doc.getNumberOfLines() - 1 if formatAll: doc.set(result) else: #doc.replace(doc.getLineOffset(startLine), 0, result) pass sel = TextSelection(doc, doc.getLineOffset(startLine), 0) self.getTextEditor().getSelectionProvider().setSelection(sel) except java.lang.Exception, e: self.beep(e)
def run(self): import tempfile import os try: ps = PySelection(editor) doc = ps.getDoc() startLine = ps.getStartLineIndex() p1 = tempfile.mktemp() p2 = tempfile.mktemp() f1 = FileWriter(p1) formatAll = False if ps.getTextSelection().getLength() == 0: # format all. c = doc.get() f1.write(c) formatAll = True else: # format selection. #c = ps.getSelectedText() #f1.write(ps.getSelectedText()) print("Format selected text is not supported yet.") f1.write("") # A kind of solution is to insert a special comment in # front and end of selection text, pythontidy it, and # extract text according that comment. f1.close() os.system('PythonTidy.py "%s" "%s"' % (p1, p2)) f2 = open(p2, "r") result = f2.read() f2.close() os.remove(p1) os.remove(p2) if startLine >= doc.getNumberOfLines(): startLine = doc.getNumberOfLines() - 1 if formatAll: doc.set(result) else: #doc.replace(doc.getLineOffset(startLine), 0, result) pass sel = TextSelection(doc, doc.getLineOffset(startLine), 0) self.getTextEditor().getSelectionProvider().setSelection(sel) except java.lang.Exception as e: self.beep(e)
def align_selected_code_on_character(character): selection = PySelection(editor) selection.selectCompleteLine() # change selection to entire lines lines = StringUtils.splitInLines(selection.getSelectedText()) adjusted_lines = align_on_character(lines, character) replacement = ''.join(adjusted_lines) selection.getDoc().replace(selection.getStartLine().getOffset(), selection.getSelLength(), replacement)
def run(self): sel = PySelection(editor) txt = sel.getSelectedText() delimiter = sel.getEndLineDelim() indent = sel.getIndentationFromLine() splitted = SplitTextInCommas(txt) doc = sel.getDoc() sel = sel.getTextSelection() doc.replace(sel.getOffset(), sel.getLength(), (delimiter + indent).join([x.strip() + ', ' for x in splitted]))
def CheckCase1(self, types): doc = '''class A(object): # line 0 def m1(self): #line 2 pass def m2(self): #line 5 pass ''' from org.eclipse.jface.text import Document from org.python.pydev.core.docutils import PySelection doc = Document(doc) self._selection = PySelection(doc, 1, 0) context = Context(doc) self.assertEqual(['A'], types['current_class'].resolveAll(context)) self.assertEqual([''], types['current_method'].resolveAll(context)) self.assertEqual(['A'], types['current_qualified_scope'].resolveAll(context)) self.assertEqual(['A'], types['prev_class_or_method'].resolveAll(context)) self.assertEqual(['m1'], types['next_class_or_method'].resolveAll(context)) self.assertEqual(['object'], types['superclass'].resolveAll(context))
def _CreateSelection(context): ''' Created method so that it can be mocked on tests. ''' from org.python.pydev.core.docutils import PySelection selection = PySelection(context.getDocument(), context.getStart()) return selection
def run(self): #gotten here (and not in the class resolution as before) because we want it to be resolved #when we execute it, and not when setting it ps = self.editor.createPySelection() oDocument = ps.getDoc() if not self.isScriptApplicable(ps): return None oParamInfo = ps.getInsideParentesisToks(True) lsParams = list(oParamInfo.o1) # Determine insert point: iClosingParOffset = oParamInfo.o2 iClosingParLine = ps.getLineOfOffset(iClosingParOffset) iInsertAfterLine = iClosingParLine currentIndent = ps.getIndentationFromLine() sIndent = currentIndent + self.editor.getIndentPrefs().getIndentationString() parsingUtils = ParsingUtils.create(oDocument) # Is there a docstring? In that case we need to skip past it. sDocstrFirstLine = ps.getLine(iClosingParLine + 1) sDocstrStart = sDocstrFirstLine.strip()[:2] if sDocstrStart and (sDocstrStart[0] in ['"', "'"] or sDocstrStart in ['r"', "r'"]): iDocstrLine = iClosingParLine + 1 iDocstrLineOffset = ps.getLineOffset(iDocstrLine) li = [sDocstrFirstLine.find(s) for s in ['"', "'"]] iDocstrStartCol = min([i for i in li if i >= 0]) iDocstrStart = iDocstrLineOffset + iDocstrStartCol iDocstrEnd = parsingUtils.eatLiterals(None, iDocstrStart) iInsertAfterLine = ps.getLineOfOffset(iDocstrEnd) sIndent = PySelection.getIndentationFromLine(sDocstrFirstLine) # Workaround for bug in PySelection.addLine() in # pydev < v1.0.6. Inserting at the last line in the file # would raise an exception if the line wasn't newline # terminated. iDocLength = oDocument.getLength() iLastLine = ps.getLineOfOffset(iDocLength) sLastChar = str(parsingUtils.charAt(iDocLength - 1)) endLineDelimiter = ps.getEndLineDelim() if iInsertAfterLine == iLastLine and not endLineDelimiter.endswith(sLastChar): oDocument.replace(iDocLength, 0, endLineDelimiter) line = ps.getLine(iInsertAfterLine + 1) if line.strip() == 'pass': ps.deleteLine(iInsertAfterLine + 1) # Assemble assignment lines and insert them into the document: sAssignments = self._assignmentLines(endLineDelimiter, lsParams, sIndent) ps.addLine(sAssignments, iInsertAfterLine) # Leave cursor at the last char of the new lines. iNewOffset = ps.getLineOffset(iInsertAfterLine + 1) + len(sAssignments) self.editor.setSelection(iNewOffset, 0)
def check(self, initial_doc, final_doc): from org.eclipse.jface.text import Document #@UnresolvedImport from org.python.pydev.core.docutils import PySelection from assign_params_to_attributes_action import AssignToAttribsOfSelf doc = Document(initial_doc) editor = TestEditor(doc, PySelection(doc, 1, 2)) assign_to_attribs_of_self = AssignToAttribsOfSelf(editor) assign_to_attribs_of_self.run() self.assertEqual(final_doc, doc.get())
def run(self): sel = PySelection(editor) txt = sel.getSelectedText() splitted = re.split('\\.|\\ ', txt) new_text = '.'.join( [x for x in splitted if x not in ('from', 'import')]) new_text = splitted[-1] + ' = ' + '\'' + new_text + '\'' doc = sel.getDoc() sel = sel.getTextSelection() doc.replace(sel.getOffset(), sel.getLength(), new_text)
def __init__(self): self.selection = PySelection(editor) self.document = editor.getDocument() self.offset = self.selection.getAbsoluteCursorOffset() self.currentLineNo = self.selection.getLineOfOffset(self.offset) self.docDelimiter = self.selection.getDelimiter(self.document) self.currentLine = self.selection.getLine(self.currentLineNo) self.pattern = r'''(\s*#\s*|\s*"""\s*|''' \ + r"""\s*'''\s*|""" \ + r'''\s*"\s*|''' \ + r"""\s*'\s*|\s*)""" self.compiledRe = re.compile(self.pattern) self.leadingString, self.mainText = \ self._splitLine(self.currentLine) self.offsetOfOriginalParagraph = 0 self.lengthOfOriginalParagraph = 0 self.numberOfLinesInDocument = self.document.getNumberOfLines()
def run(self): sel = PySelection(editor) txt = sel.getSelectedText() splitted = re.split('\\.|\\ ', txt) new_text = '.'.join([x for x in splitted if x not in ('from', 'import')]) new_text = splitted[-1] + ' = ' + '\'' + new_text + '\'' doc = sel.getDoc() sel = sel.getTextSelection() doc.replace(sel.getOffset(), sel.getLength(), new_text)
def __init__(self): self.selection = PySelection(editor) self.document = editor.getDocument() self.offset = self.selection.getAbsoluteCursorOffset() self.currentLineNo = self.selection.getLineOfOffset(self.offset) self.docDelimiter = self.selection.getDelimiter(self.document) self.currentLine = self.selection.getLine(self.currentLineNo) self.pattern = r'''(\s*#\s*|\s*"""\s*|''' + r"""\s*'''\s*|""" + r"""\s*"\s*|""" + r"""\s*'\s*|\s*)""" self.compiledRe = re.compile(self.pattern) self.leadingString, self.mainText = self._splitLine(self.currentLine) self.offsetOfOriginalParagraph = 0 self.lengthOfOriginalParagraph = 0 self.numberOfLinesInDocument = self.document.getNumberOfLines()
def _indent(self, sel): """Return the indent of the current line as a str. @param sel: The current selection as a PySelection. """ return PySelection.getIndentationFromLine(sel.getCursorLineContents())
def run(self): #gotten here (and not in the class resolution as before) because we want it to be resolved #when we execute it, and not when setting it oSelection = PySelection(self.editor) oDocument = self.editor.getDocument() if not self.isScriptApplicable(oSelection): return None oParamInfo = oSelection.getInsideParentesisToks(True) lsParams = list(oParamInfo.o1) # Determine insert point: iClosingParOffset = oParamInfo.o2 iClosingParLine = oSelection.getLineOfOffset(iClosingParOffset) iInsertAfterLine = iClosingParLine sIndent = self._indent( oSelection) + PyAction.getStaticIndentationString(self.editor) parsingUtils = ParsingUtils.create(oDocument) # Is there a docstring? In that case we need to skip past it. sDocstrFirstLine = oSelection.getLine(iClosingParLine + 1) sDocstrStart = sDocstrFirstLine.strip()[:2] if sDocstrStart and (sDocstrStart[0] in ['"', "'"] or sDocstrStart in ['r"', "r'"]): iDocstrLine = iClosingParLine + 1 iDocstrLineOffset = oSelection.getLineOffset(iDocstrLine) li = [sDocstrFirstLine.find(s) for s in ['"', "'"]] iDocstrStartCol = min([i for i in li if i >= 0]) iDocstrStart = iDocstrLineOffset + iDocstrStartCol iDocstrEnd = parsingUtils.eatLiterals(None, iDocstrStart) iInsertAfterLine = oSelection.getLineOfOffset(iDocstrEnd) sIndent = PySelection.getIndentationFromLine(sDocstrFirstLine) # Workaround for bug in PySelection.addLine() in # pydev < v1.0.6. Inserting at the last line in the file # would raise an exception if the line wasn't newline # terminated. iDocLength = oDocument.getLength() iLastLine = oSelection.getLineOfOffset(iDocLength) sLastChar = str(parsingUtils.charAt(iDocLength - 1)) if (iInsertAfterLine == iLastLine and not self.getNewLineDelim().endswith(sLastChar)): oDocument.replace(iDocLength, 0, self.getNewLineDelim()) # Assemble assignment lines and insert them into the document: sAssignments = self._assignmentLines(lsParams, sIndent) oSelection.addLine(sAssignments, iInsertAfterLine) # Leave cursor at the last char of the new lines. iNewOffset = oSelection.getLineOffset(iInsertAfterLine + 1) + len(sAssignments) self.editor.setSelection(iNewOffset, 0) del oSelection
def getFuncArgs(idocument, beginLine): ''' This method recieves a document object and the start lines of a function definition who's args we want to retrieve. It then creates an AST parsed document structure, which gets worked through until a method is found that occurs on the same line as the beginLine that was sent as an arg to this method. Once this is found it searches for the args in that method and also whether the method has return value. It then sends this information to prepOutputMethodString2 method that will convert this into a nicely formatted docstring. :param idocument: input context object :type idocument: org.python.pydev.editor.codecompletion.templates.PyDocumentTemplateContext :param beginLine: the integer that the function starts on. :type beginLine: int :returns: a sphinx restructured text docstring template for method from which the method was called. :rtype: string ''' print 'getClassArgs called' # from org.python.pydev.core.docutils import PySelection from org.python.pydev.parser import PyParser from org.python.pydev.parser.visitors import NodeUtils from org.python.pydev.core.docutils import PySelection doc = idocument.getDocument() # creating a parser object. The 12 is a constant that # defines python syntax. See org.python.pydev.core.IGrammarVersionProvider # different numbers are: # 2.4 10 # 2.5 11 # 2.6 12 # 2.7 13 # etc... grammarVersion = idocument.getGrammarVersion() print 'grammarVersion:', grammarVersion parseInfoObj = PyParser.ParserInfo(doc, grammarVersion) # parsign the document into the different node types # from the root node you can access all elements of the # doc. (hierarchical parser) # nodes is a Tuple object of type: # com.aptana.shared_core.structure.Tuple nodes = PyParser.reparseDocument(parseInfoObj) print 'node type:', nodes.getClass().getName() # nodes.01 contains SimpleNode #x = nodes.o1 #print 'xtype ', x.getClass().getName() # getting the document body body = NodeUtils.getBody(nodes.ast) print 'body', body # getting the function that starts on the line: begtinLine funcDef = searchFuncs(body, beginLine) print 'funcDef', funcDef argList = parseFunc(funcDef) returnState = hasReturn(funcDef) #doc = idocument.getDocument() # doc = idocument.getDocument() # 2 - get a selection object for the current line selection = PySelection(idocument.getDocument(), idocument.getStart()) startLineNumber = doc.getLineOfOffset(idocument.getStart()) startLineContents = selection.getLine(startLineNumber) indentation = selection.getIndentationFromLine(startLineContents) docString = prepOutputMethodString2(indentation, argList, returnState) print 'return: ', returnState return docString
def GetMethodArg(idocument): ''' This is an older version of the GetMethodArg2 function. After figuring out how to parse a document using the pydev parsers rewrote the method parsing functions. This will get deleted once I am comfortable that the the GetMethodArg2 is working well. :param idocument: an idocument object containing the entire module that was created for this method. :type idocument: org.python.pydev.editor.codecompletion.templates.PyDocumentTemplateContext :returns: a formatted docstring template for the method on which this function was called :rtype: string ''' # TODO: parse the method looking for the return type from org.python.pydev.parser.jython.ast import FunctionDef from org.python.pydev.parser.fastparser import FastParser from org.python.pydev.core.docutils import PySelection # 1 - get the current document doc = idocument.getDocument() # 2 - get a selection object for the current line selection = PySelection(idocument.getDocument(), idocument.getStart()) startLineNumber = doc.getLineOfOffset(idocument.getStart()) startLineContents = selection.getLine(startLineNumber) startIndentation = selection.getIndentationFromLine(startLineContents) print 'the line is', startLineNumber print 'contents is', startLineContents # 3 - create a parser object with the hierarchy of methods, classes etc to which the current line belongs parser = FastParser.parseToKnowGloballyAccessiblePath( idocument.getDocument(), selection.getStartLineIndex()) if parser: # only continuing if the parser found a method definition. print 'parser', parser print 'begin line', parser[0].beginLine print 'rettype', type(parser) print 'start is', idocument.getStart() from java.util import Collections Collections.reverse(parser) # 4 - iterate through the parser object for stmt in parser: print 'stmt', stmt print type(stmt) # 5 - if the parser contains a method definition if isinstance(stmt, FunctionDef): # 6 - get the line number for the method definition print 'method line', stmt.beginLine functionDefinitionStmt = selection.getLine(stmt.beginLine-1) print 'defstatement:', functionDefinitionStmt print 'woke up' afterLine = stmt.beginLine - 1 # listOfStringLines = [] string2Add = prepOutputMethodString(startIndentation, functionDefinitionStmt) #selection.addLine( indentationString + string2Add, stmt.beginLine - 1) offset = doc.getLineInformation(afterLine + 1).getOffset(); print 'offset 1 - ', offset if doc.getNumberOfLines() > stmt.beginLine - 1: offset = doc.getLineInformation(afterLine + 1).getOffset(); print 'offset 2 - ', offset else: offset = doc.getLineInformation(afterLine).getOffset() print 'offset 2 - ', offset #doc.replace(offset, 0, string2Add) # inserting into the doc immediately after the method is # not working, instead will return the doc string return string2Add #selection.addLine( indentationString + string2Add, stmt.beginLine - 1) #offset = doc.getLineInformation(afterLine + 1).getOffset(); #selection = PySelection(idocument.getDocument(), idocument.getStart()) #offset = doc.getLineInformation(stmt.beginLine).getOffset() #print 'offset is now ',offset #print 'on line number', selection.getLineNumber() #args = NodeUtils.getNodeArgs(stmt) #print 'args are', args #print '.getRepresentationString' , NodeUtils.getRepresentationString(stmt) #print 'full rep string:', NodeUtils.getFullRepresentationString(stmt) #return NodeUtils.getRepresentationString(stmt) # if nothing was found then return null. return ""
class RegexBasedAssistProposal(assist_proposal.AssistProposal): """Base class for regex driven Quick Assist proposals. More docs available in base class source. New class data members ====================== regex = re.compile(r'^(?P<initial>\s*)(?P<name>\w+)\s*$'): <regex> Must .match() current line for .isValid() to return true. Any named groups will be available in self.vars. template = "%(initial)sprint 'Hello World!'": <str> This will replace what's currently on the line on .apply(). May use string formatters with names from self.vars. base_vars = {}: <dict <str>:<str>> Used to initiallize self.vars. New instance data members ========================= vars = <dict <str>:<str>> Variables used with self.template to produce the code that replaces the current line. This will contain values from self.base_vars, all named groups in self.regex, as well with these two additional ones: 'indent': the static indentation string 'newline': the line delimiter string selection, current_line, editor, offset: Same as the corresponding args to .isValid(). """ template = "" base_vars = {} regex = re.compile(r'^(?P<initial>\s*)(?P<name>\w+)\s*$') def isValid(self, selection, current_line, editor, offset): """Is this proposal applicable to this line of code? If current_line .match():es against self.regex then we will store a lot of information on the match and environment, and return True. Otherwise return False. IN: pyselection: <PySelection> The current selection. Highly useful. current_line: <str> The text on the current line. editor: <PyEdit> The current editor. offset: <int> The current position in the editor. OUT: Boolean. Is the proposal applicable in the current situation? """ m = self.regex.match(current_line) if not m: return False self.vars = {'indent': editor.getIndentPrefs().getIndentationString()} self.vars.update(self.base_vars) self.vars.update(m.groupdict()) self.selection = selection self.current_line = current_line self.editor = editor self.offset = offset return True def apply(self, document): """Replace the current line with the populated template. IN: document: <IDocument> The edited document. OUT: None. """ self.vars['newline'] = PyAction.getDelimiter(document) sNewCode = self.template % self.vars # Move to insert point: iStartLineOffset = self.selection.getLineOffset() iEndLineOffset = iStartLineOffset + len(self.current_line) self.editor.setSelection(iEndLineOffset, 0) self.selection = PySelection(self.editor) # Replace the old code with the new assignment expression: self.selection.replaceLineContentsToSelection(sNewCode) #mark the value so that the user can change it selection = PySelection(self.editor) absoluteCursorOffset = selection.getAbsoluteCursorOffset() val = self.vars['value'] self.editor.selectAndReveal(absoluteCursorOffset-len(val),len(val))
class Paragrapher: ''' Provides tools to process a paragraph of text in the Pydev editor. ''' def __init__(self): self.selection = PySelection(editor) self.document = editor.getDocument() self.offset = self.selection.getAbsoluteCursorOffset() self.currentLineNo = self.selection.getLineOfOffset(self.offset) self.docDelimiter = self.selection.getDelimiter(self.document) self.currentLine = self.selection.getLine(self.currentLineNo) self.pattern = r'''(\s*#\s*|\s*"""\s*|''' \ + r"""\s*'''\s*|""" \ + r'''\s*"\s*|''' \ + r"""\s*'\s*|\s*)""" self.compiledRe = re.compile(self.pattern) self.leadingString, self.mainText = \ self._splitLine(self.currentLine) self.offsetOfOriginalParagraph = 0 self.lengthOfOriginalParagraph = 0 self.numberOfLinesInDocument = self.document.getNumberOfLines() def _splitLine(self, line): ''' _splitLine(string: line) -> (string: leadingString,\ string: mainText) Split the line into two parts - a leading string and the remaining text. ''' matched = self.compiledRe.match(line) leadingString = line[0:matched.end()] mainText = line[matched.end():] return (leadingString, mainText) def getCurrentLine(self): ''' getCurrentLine() -> string Return the main part of the text of the current line as a string. ''' self.currentLine = self.selection.getLine(self.currentLineNo) self.mainText = self._splitLine(self.currentLine)[1] return self.mainText def previousLineIsInParagraph(self): ''' previousLineIsInParagraph() -> bool ''' previousLine = self.selection.getLine(self.currentLineNo - 1) leadingStringOfPreviousLine, mainTextOfPreviousLine = \ self._splitLine(previousLine) if (self.currentLineNo == 0) |\ (mainTextOfPreviousLine.strip() == "") | \ (leadingStringOfPreviousLine != self.leadingString): # diff para [1] line = self.selection.getLine(self.currentLineNo) lineEndsAt = self.selection.getEndLineOffset( self.currentLineNo) self.offsetOfOriginalParagraph = lineEndsAt - len(line) return False else: return True # same para # [1] The current line is the first line of a paragraph. Calculate # starting offset of the first character of the original paragraph. def nextLineIsInParagraph(self): ''' nextLineIsInParagraph() -> bool ''' nextLine = self.selection.getLine(self.currentLineNo + 1) leadingStringOfNextLine, mainTextOfNextLine = \ self._splitLine(nextLine) if (self.currentLineNo + 1 == self.numberOfLinesInDocument) | \ (mainTextOfNextLine.strip() == "") | \ (leadingStringOfNextLine != self.leadingString): # diff para [1] self.lengthOfOriginalParagraph = \ self.selection.getEndLineOffset(self.currentLineNo) - \ self.offsetOfOriginalParagraph return False else: return True # same para
def CheckCase2(self, types): from org.eclipse.jface.text import Document from org.python.pydev.core.docutils import PySelection doc = '''class A(object ''' doc = Document(doc) self._selection = PySelection(doc, 1, 0) context = Context(doc) self.assertEqual(['A'], types['current_class'].resolveAll(context)) self.assertEqual([''], types['current_method'].resolveAll(context)) self.assertEqual(['A'], types['current_qualified_scope'].resolveAll(context)) self.assertEqual(['A'], types['prev_class_or_method'].resolveAll(context)) self.assertEqual([''], types['next_class_or_method'].resolveAll(context)) self.assertEqual([''], types['superclass'].resolveAll(context)) doc = '''class A(object, obj, foo) ''' doc = Document(doc) self._selection = PySelection(doc, 1, 0) context = Context(doc) self.assertEqual(['A'], types['current_class'].resolveAll(context)) self.assertEqual([''], types['current_method'].resolveAll(context)) self.assertEqual(['A'], types['current_qualified_scope'].resolveAll(context)) self.assertEqual(['A'], types['prev_class_or_method'].resolveAll(context)) self.assertEqual([''], types['next_class_or_method'].resolveAll(context)) self.assertEqual(['object', 'obj', 'foo'], types['superclass'].resolveAll(context)) doc = '''class A(object, #comment obj, foo) ''' doc = Document(doc) self._selection = PySelection(doc, 1, 0) context = Context(doc) self.assertEqual(['A'], types['current_class'].resolveAll(context)) self.assertEqual([''], types['current_method'].resolveAll(context)) self.assertEqual(['A'], types['current_qualified_scope'].resolveAll(context)) self.assertEqual(['A'], types['prev_class_or_method'].resolveAll(context)) self.assertEqual([''], types['next_class_or_method'].resolveAll(context)) self.assertEqual(['object', 'obj', 'foo'], types['superclass'].resolveAll(context))
class RegexBasedAssistProposal(assist_proposal.AssistProposal): r"""Base class for regex driven Quick Assist proposals. More docs available in base class source. New class data members ====================== regex = re.compile(r'^(?P<initial>\s*)(?P<name>\w+)\s*$'): <regex> Must .match() current line for .isValid() to return true. Any named groups will be available in self.vars. template = "%(initial)sprint 'Hello World!'": <str> This will replace what's currently on the line on .apply(). May use string formatters with names from self.vars. base_vars = {}: <dict <str>:<str>> Used to initiallize self.vars. New instance data members ========================= vars = <dict <str>:<str>> Variables used with self.template to produce the code that replaces the current line. This will contain values from self.base_vars, all named groups in self.regex, as well with these two additional ones: 'indent': the static indentation string 'newline': the line delimiter string selection, current_line, editor, offset: Same as the corresponding args to .isValid(). """ template = "" base_vars = {} regex = re.compile(r'^(?P<initial>\s*)(?P<name>\w+)\s*$') def isValid(self, selection, current_line, editor, offset): """Is this proposal applicable to this line of code? If current_line .match():es against self.regex then we will store a lot of information on the match and environment, and return True. Otherwise return False. IN: pyselection: <PySelection> The current selection. Highly useful. current_line: <str> The text on the current line. editor: <PyEdit> The current editor. offset: <int> The current position in the editor. OUT: Boolean. Is the proposal applicable in the current situation? """ m = self.regex.match(current_line) if not m: return False self.vars = {'indent': editor.getIndentPrefs().getIndentationString()} self.vars.update(self.base_vars) self.vars.update(m.groupdict()) self.selection = selection self.current_line = current_line self.editor = editor self.offset = offset return True def apply(self, document): """Replace the current line with the populated template. IN: document: <IDocument> The edited document. OUT: None. """ self.vars['newline'] = PyAction.getDelimiter(document) sNewCode = self.template % self.vars # Move to insert point: iStartLineOffset = self.selection.getLineOffset() iEndLineOffset = iStartLineOffset + len(self.current_line) self.editor.setSelection(iEndLineOffset, 0) self.selection = PySelection(self.editor) # Replace the old code with the new assignment expression: self.selection.replaceLineContentsToSelection(sNewCode) #mark the value so that the user can change it selection = PySelection(self.editor) absoluteCursorOffset = selection.getAbsoluteCursorOffset() val = self.vars['value'] self.editor.selectAndReveal(absoluteCursorOffset - len(val), len(val))
class Paragrapher: ''' Provides tools to process a paragraph of text in the Pydev editor. ''' def __init__(self): self.selection = PySelection(editor) self.document = editor.getDocument() self.offset = self.selection.getAbsoluteCursorOffset() self.currentLineNo = self.selection.getLineOfOffset(self.offset) self.docDelimiter = self.selection.getDelimiter(self.document) self.currentLine = self.selection.getLine(self.currentLineNo) self.pattern = r'''(\s*#\s*|\s*"""\s*|''' \ + r"""\s*'''\s*|""" \ + r'''\s*"\s*|''' \ + r"""\s*'\s*|\s*)""" self.compiledRe = re.compile(self.pattern) self.leadingString, self.mainText = \ self._splitLine(self.currentLine) self.offsetOfOriginalParagraph = 0 self.lengthOfOriginalParagraph = 0 self.numberOfLinesInDocument = self.document.getNumberOfLines() def _splitLine(self, line): ''' _splitLine(string: line) -> (string: leadingString,\ string: mainText) Split the line into two parts - a leading string and the remaining text. ''' matched = self.compiledRe.match(line) leadingString = line[0:matched.end()] mainText = line[matched.end():] return (leadingString, mainText) def getCurrentLine(self): ''' getCurrentLine() -> string Return the main part of the text of the current line as a string. ''' self.currentLine = self.selection.getLine(self.currentLineNo) self.mainText = self._splitLine(self.currentLine)[1] return self.mainText def previousLineIsInParagraph(self): ''' previousLineIsInParagraph() -> bool ''' previousLine = self.selection.getLine(self.currentLineNo - 1) leadingStringOfPreviousLine, mainTextOfPreviousLine = \ self._splitLine(previousLine) if (self.currentLineNo == 0) |\ (mainTextOfPreviousLine.strip() == "") | \ (leadingStringOfPreviousLine != self.leadingString): # diff para [1] line = self.selection.getLine(self.currentLineNo) lineEndsAt = self.selection.getEndLineOffset(self.currentLineNo) self.offsetOfOriginalParagraph = lineEndsAt - len(line) return False else: return True # same para # [1] The current line is the first line of a paragraph. Calculate # starting offset of the first character of the original paragraph. def nextLineIsInParagraph(self): ''' nextLineIsInParagraph() -> bool ''' nextLine = self.selection.getLine(self.currentLineNo + 1) leadingStringOfNextLine, mainTextOfNextLine = \ self._splitLine(nextLine) if (self.currentLineNo + 1 == self.numberOfLinesInDocument) | \ (mainTextOfNextLine.strip() == "") | \ (leadingStringOfNextLine != self.leadingString): # diff para [1] self.lengthOfOriginalParagraph = \ self.selection.getEndLineOffset(self.currentLineNo) - \ self.offsetOfOriginalParagraph return False else: return True # same para