@@ -19,21 +19,23 @@ package cc.unitmesh.pycharm.provider
19
19
import cc.unitmesh.devti.custom.document.LivingDocumentationType
20
20
import cc.unitmesh.devti.provider.LivingDocumentation
21
21
import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil
22
- import com.intellij.openapi.editor.Document
22
+ import com.intellij.openapi.command.WriteCommandAction
23
23
import com.intellij.openapi.editor.Editor
24
24
import com.intellij.openapi.editor.SelectionModel
25
- import com.intellij.openapi.project.Project
25
+ import com.intellij.psi.PsiDocumentManager
26
26
import com.intellij.psi.PsiElement
27
27
import com.intellij.psi.PsiNameIdentifierOwner
28
28
import com.intellij.psi.PsiWhiteSpace
29
29
import com.intellij.psi.util.PsiTreeUtil
30
30
import com.intellij.util.IncorrectOperationException
31
- import com.jetbrains.python.documentation.docstrings.PyDocstringGenerator
32
31
import com.jetbrains.python.psi.*
33
32
34
33
35
34
class PythonLivingDocumentation : LivingDocumentation {
36
- override val forbiddenRules: List <String > = listOf ()
35
+ override val forbiddenRules: List <String > = listOf (
36
+ " do not return any code, just documentation." ,
37
+ " write Docstring" ,
38
+ )
37
39
38
40
override fun startEndString (type : LivingDocumentationType ): Pair <String , String > {
39
41
return Pair (" \"\"\" " , " \"\"\" " )
@@ -44,8 +46,9 @@ class PythonLivingDocumentation : LivingDocumentation {
44
46
throw IncorrectOperationException ()
45
47
}
46
48
47
- val docstringGenerator = PyDocstringGenerator .forDocStringOwner((target as PyDocStringOwner ? )!! )
48
- docstringGenerator.buildAndInsert(newDoc, target)
49
+ WriteCommandAction .runWriteCommandAction(target.project, " Living Document" , " cc.unitmesh.livingDoc" , {
50
+ buildAndInsert(newDoc, target)
51
+ });
49
52
}
50
53
51
54
override fun findNearestDocumentationTarget (psiElement : PsiElement ): PsiNameIdentifierOwner ? {
@@ -113,47 +116,47 @@ class PythonLivingDocumentation : LivingDocumentation {
113
116
private fun containsElement (selectionModel : SelectionModel , element : PsiElement ): Boolean {
114
117
return selectionModel.selectionStart <= element.textRange.startOffset && element.textRange.endOffset <= selectionModel.selectionEnd
115
118
}
116
-
117
119
}
118
120
119
- fun PyDocstringGenerator.buildAndInsert (replacementText : String , myDocStringOwner : PyDocStringOwner ): PyDocStringOwner {
120
- val project: Project = myDocStringOwner.getProject()
121
- val elementGenerator = PyElementGenerator .getInstance(project)
121
+ fun buildAndInsert (replacementText : String , anchor : PyDocStringOwner ): PyDocStringOwner {
122
+ val elementGenerator = PyElementGenerator .getInstance(anchor.project)
122
123
val replacement = elementGenerator.createDocstring(replacementText)
123
124
124
- val docStringExpression: PyStringLiteralExpression ? = myDocStringOwner.getDocStringExpression()
125
+ val docStringExpression: PyStringLiteralExpression ? = anchor.docStringExpression
125
126
if (docStringExpression != null ) {
126
127
docStringExpression.replace(replacement.expression)
127
- } else {
128
- val container = PyUtil .`as `(
129
- myDocStringOwner,
130
- PyStatementListContainer ::class .java
131
- ) ? : throw IncorrectOperationException (" Cannot find container for docstring, Should be a function or class" )
128
+ return anchor
129
+ }
132
130
133
- val statements = container.statementList
134
- val indentation = PyIndentUtil .getElementIndent(statements)
131
+ val container = PyUtil .`as `(
132
+ anchor,
133
+ PyStatementListContainer ::class .java
134
+ ) ? : throw IncorrectOperationException (" Cannot find container for docstring, Should be a function or class" )
135
135
136
- PyUtil .updateDocumentUnblockedAndCommitted(myDocStringOwner) { document: Document ->
137
- val beforeStatements = statements.prevSibling
138
- var replacementWithLineBreaks = """
136
+ val statements = container.statementList
137
+ val indentation = PyIndentUtil .getElementIndent(statements)
138
+
139
+ val manager = PsiDocumentManager .getInstance(anchor.project)
140
+ val document = manager.getDocument(anchor.containingFile)!!
141
+ val beforeStatements = statements.prevSibling
142
+ var replacementWithLineBreaks = """
139
143
140
144
$indentation$replacementText
141
145
""" .trimIndent()
142
- if (statements.statements.isNotEmpty()) {
143
- replacementWithLineBreaks + = """
146
+ if (statements.statements.isNotEmpty()) {
147
+ replacementWithLineBreaks + = """
144
148
145
149
$indentation
146
150
""" .trimIndent()
147
- }
148
- val range = beforeStatements.textRange
149
- if (beforeStatements !is PsiWhiteSpace ) {
150
- document.insertString(range.endOffset, replacementWithLineBreaks)
151
- } else if (statements.statements.isEmpty() && beforeStatements.textContains(' \n ' )) {
152
- document.insertString(range.startOffset, replacementWithLineBreaks)
153
- } else {
154
- document.replaceString(range.startOffset, range.endOffset, replacementWithLineBreaks)
155
- }
156
- }
157
151
}
158
- return myDocStringOwner
152
+ val range = beforeStatements.textRange
153
+ if (beforeStatements !is PsiWhiteSpace ) {
154
+ document.insertString(range.endOffset, replacementWithLineBreaks)
155
+ } else if (statements.statements.isEmpty() && beforeStatements.textContains(' \n ' )) {
156
+ document.insertString(range.startOffset, replacementWithLineBreaks)
157
+ } else {
158
+ document.replaceString(range.startOffset, range.endOffset, replacementWithLineBreaks)
159
+ }
160
+
161
+ return anchor
159
162
}
0 commit comments