11package com.github.lppedd.cc.liveTemplate
22
3- import com.github.lppedd.cc.*
43import com.github.lppedd.cc.annotation.Compatibility
54import com.github.lppedd.cc.lookupElement.TemplateSegment
5+ import com.github.lppedd.cc.moveCaretToOffset
6+ import com.github.lppedd.cc.runAndLogError
7+ import com.github.lppedd.cc.scheduleAutoPopup
68import com.intellij.codeInsight.template.Template
79import com.intellij.codeInsight.template.TemplateEditingAdapter
810import com.intellij.codeInsight.template.impl.TemplateState
911import com.intellij.codeInsight.template.impl.TemplateStateBase
10- import com.intellij.openapi.application.runWriteAction
1112import com.intellij.openapi.command.WriteCommandAction
1213import com.intellij.openapi.diagnostic.logger
1314import com.intellij.openapi.util.TextRange
@@ -74,33 +75,41 @@ internal class CCTemplateEditingListener : TemplateEditingAdapter() {
7475 predefinedValues.remove(segmentName)
7576 }
7677
77- if (oldIndex == TemplateSegment .BodyOrFooterType && newIndex > oldIndex) {
78- if (templateState.getSegmentRange(TemplateSegment .BodyOrFooterType ).isEmpty) {
79- deleteFooterValue(templateState)
80- templateState.gotoEnd()
81- return
82- }
83- }
84-
8578 val newOffset = templateState.getSegmentRange(newIndex).startOffset
8679 templateState.editor.moveCaretToOffset(newOffset)
8780 templateState.editor.scheduleAutoPopup()
8881 }
8982
9083 override fun beforeTemplateFinished (templateState : TemplateState , template : Template ) {
84+ val footerValueRange = templateState.getSegmentRange(TemplateSegment .FooterValue )
85+
86+ if (footerValueRange.isEmpty) {
87+ deleteFooterValue(templateState, footerValueRange)
88+ }
89+
9190 val bodyOrFooterTypeRange = templateState.getSegmentRange(TemplateSegment .BodyOrFooterType )
9291
9392 if (bodyOrFooterTypeRange.isEmpty) {
94- repositionCursorAfterSubjectAndCleanUp (templateState, bodyOrFooterTypeRange)
93+ deleteBodyOrFooter (templateState, bodyOrFooterTypeRange)
9594 }
9695
97- deleteScopeParenthesesIfEmpty(templateState)
96+ val scopeRange = templateState.getSegmentRange(TemplateSegment .Scope )
97+
98+ if (scopeRange.isEmpty) {
99+ deleteScopeParentheses(templateState, scopeRange)
100+ }
98101 }
99102
100- private fun repositionCursorAfterSubjectAndCleanUp (
101- templateState : TemplateState ,
102- bodyOrFooterTypeRange : TextRange ,
103- ) {
103+ private fun deleteFooterValue (templateState : TemplateState , footerValueRange : TextRange ) {
104+ val editor = templateState.editor
105+ val startOffset = max(footerValueRange.startOffset - 1 , 0 )
106+ WriteCommandAction .runWriteCommandAction(editor.project, " Delete empty footer value" , " " , {
107+ editor.document.deleteString(startOffset, footerValueRange.endOffset)
108+ editor.moveCaretToOffset(startOffset)
109+ })
110+ }
111+
112+ private fun deleteBodyOrFooter (templateState : TemplateState , bodyOrFooterTypeRange : TextRange ) {
104113 // If the body is empty, it means the user didn't need to insert it.
105114 // Thus, we can reposition the cursor at the end of the subject
106115 val newOffset = templateState.getSegmentRange(TemplateSegment .Subject ).endOffset
@@ -114,32 +123,17 @@ internal class CCTemplateEditingListener : TemplateEditingAdapter() {
114123 }
115124 }
116125
117- private fun deleteScopeParenthesesIfEmpty (templateState : TemplateState ) {
118- val (scopeStart, scopeEnd, isScopeEmpty) = templateState.getSegmentRange(TemplateSegment .Scope )
119-
120- // If the scope is empty, it means the user didn't need to insert it, thus we can remove it
121- if (isScopeEmpty) {
122- val editor = templateState.editor
123- val document = editor.document
124- val startOffset = max(scopeStart - 1 , 0 )
125-
126- // In some cases it seems the segment range is not yet up to date with document changes
127- if (startOffset <= document.textLength) {
128- val endOffset = min(scopeEnd + 1 , document.textLength)
129- WriteCommandAction .runWriteCommandAction(editor.project, " Delete scope's parentheses" , " " , {
130- document.deleteString(startOffset, endOffset)
131- })
132- }
133- }
134- }
135-
136- private fun deleteFooterValue (templateState : TemplateState ) {
137- val (start, end, isEmpty) = templateState.getSegmentRange(TemplateSegment .FooterValue )
126+ private fun deleteScopeParentheses (templateState : TemplateState , scopeRange : TextRange ) {
127+ val editor = templateState.editor
128+ val document = editor.document
129+ val startOffset = max(scopeRange.startOffset - 1 , 0 )
138130
139- if (! isEmpty) {
140- runWriteAction {
141- templateState.editor.document.deleteString(start, end)
142- }
131+ // In some cases it seems the segment range is not yet up to date with document changes
132+ if (startOffset <= document.textLength) {
133+ val endOffset = min(scopeRange.endOffset + 1 , document.textLength)
134+ WriteCommandAction .runWriteCommandAction(editor.project, " Delete scope's parentheses" , " " , {
135+ document.deleteString(startOffset, endOffset)
136+ })
143137 }
144138 }
145139
0 commit comments