--- a/eric6/QScintilla/DocstringGenerator/PyDocstringGenerator.py Fri Jan 22 16:55:43 2021 +0100 +++ b/eric6/QScintilla/DocstringGenerator/PyDocstringGenerator.py Sat Jan 23 12:02:52 2021 +0100 @@ -106,15 +106,73 @@ """ if fromStart: self.__functionStartLine = cursorPosition[0] - docstring, insertPos = self.__generateDocstringFromStart() + docstring, insertPos, newCursorLine = ( + self.__generateDocstringFromStart() + ) else: - docstring, insertPos = self.__generateDocstringFromBelow( - cursorPosition) + docstring, insertPos, newCursorLine = ( + self.__generateDocstringFromBelow(cursorPosition) + ) if docstring: self.editor.beginUndoAction() self.editor.insertAt(docstring, *insertPos) + + if not fromStart: + # correct triple quote indentation if neccessary + functionIndent = self.editor.indentation( + self.__functionStartLine) + quoteIndent = self.editor.indentation(insertPos[0]) + + # step 1: unindent quote line until indentation is zero + while quoteIndent > 0: + self.editor.unindent(insertPos[0]) + quoteIndent = self.editor.indentation(insertPos[0]) + + # step 2: indent quote line until indentation is one greater + # than function definition line + while quoteIndent <= functionIndent: + self.editor.indent(insertPos[0]) + quoteIndent = self.editor.indentation(insertPos[0]) + self.editor.endUndoAction() + self.editor.setCursorPosition( + newCursorLine, len(self.editor.text(newCursorLine)) - 1 + ) + + def insertDocstringFromShortcut(self, cursorPosition): + """ + Public method to insert a docstring for the function at the cursor + position initiated via a keyboard shortcut. + + @param cursorPosition position of the cursor (line and index) + @type tuple of (int, int) + """ + result = self.__getFunctionDefinitionFromBelow(cursorPosition) + if result is not None: + # cursor is on the line after the function definition + cline = cursorPosition[0] - 1 + while not self.isFunctionStart(self.editor.text(cline)): + cline -= 1 + self.__functionStartLine = cline + elif self.isFunctionStart(self.editor.text(cursorPosition[0])): + # cursor is on the start line of the function definition + self.__functionStartLine = cursorPosition[0] + else: + # neither after the function definition nor at the start + # just do nothing + return + + docstring, insertPos, newCursorLine = ( + self.__generateDocstringFromStart() + ) + if docstring: + self.editor.beginUndoAction() + self.editor.insertAt(docstring, *insertPos) + self.editor.endUndoAction() + self.editor.setCursorPosition( + newCursorLine, len(self.editor.text(newCursorLine)) - 1 + ) def __getIndentationInsertString(self, text): """ @@ -161,16 +219,18 @@ if docstringList: if self.getDocstringType() == "ericdoc": docstringList.insert(0, self.__quote3) + newCursorLine = insertLine + 1 else: docstringList[0] = self.__quote3 + docstringList[0] + newCursorLine = insertLine docstringList.append(self.__quote3) return ( indentation + "{0}{1}".format(sep, indentation).join(docstringList) + sep - ), (insertLine, 0) + ), (insertLine, 0), newCursorLine - return "", (0, 0) + return "", (0, 0), 0 def __getFunctionDefinitionFromStart(self): """ @@ -267,19 +327,24 @@ if self.__isTripleQuotesStart(lineTextToCursor): if self.getDocstringType() == "ericdoc": docstringList.insert(0, "") + newCursorLine = cursorPosition[0] + 1 + else: + newCursorLine = cursorPosition[0] docstringList.append("") else: if self.getDocstringType() == "ericdoc": docstringList.insert(0, self.__quote3) + newCursorLine = cursorPosition[0] + 1 else: docstringList[0] = self.__quote3 + docstringList[0] + newCursorLine = cursorPosition[0] docstringList.append(self.__quote3) docstring = ( "{0}{1}".format(sep, indentation).join(docstringList) ) - return docstring, cursorPosition + return docstring, cursorPosition, newCursorLine - return "", (0, 0) + return "", (0, 0), 0 def __getFunctionDefinitionFromBelow(self, cursorPosition): """ @@ -313,6 +378,8 @@ if self.isFunctionStart(text): # start of function definition reached + self.__functionStartLine = lineNo + # check, if function is decorated with a supported one if lineNo > 0: decoratorLine = self.editor.text(lineNo - 1)