Skip to content

Commit 7e4e160

Browse files
committed
feat(completion): add snippets
Fixes #37
1 parent c101452 commit 7e4e160

File tree

5 files changed

+178
-1
lines changed

5 files changed

+178
-1
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.tonstudio.tact.ide.templates
2+
3+
import com.intellij.ide.fileTemplates.DefaultTemplatePropertiesProvider
4+
import com.intellij.psi.PsiDirectory
5+
import java.util.*
6+
7+
class TactDefaultTemplatePropertiesProvider : DefaultTemplatePropertiesProvider {
8+
override fun fillProperties(directory: PsiDirectory, props: Properties) {}
9+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package org.tonstudio.tact.ide.templates
2+
3+
import com.intellij.codeInsight.template.EverywhereContextType
4+
import com.intellij.codeInsight.template.TemplateActionContext
5+
import com.intellij.codeInsight.template.TemplateContextType
6+
import com.intellij.psi.PsiComment
7+
import com.intellij.psi.PsiElement
8+
import com.intellij.psi.PsiWhiteSpace
9+
import com.intellij.psi.util.PsiUtilCore
10+
import com.intellij.psi.util.parentOfType
11+
import org.tonstudio.tact.lang.TactLanguage
12+
import org.tonstudio.tact.lang.completion.TactCompletionUtil
13+
import org.tonstudio.tact.lang.psi.TactFile
14+
import org.tonstudio.tact.lang.psi.TactImportDeclaration
15+
import org.tonstudio.tact.lang.psi.TactSimpleStatement
16+
import org.tonstudio.tact.utils.inside
17+
18+
@Suppress("DEPRECATION")
19+
abstract class TactTemplateContextType(
20+
id: String,
21+
presentableName: String,
22+
baseContextType: Class<out TemplateContextType>?
23+
) : TemplateContextType(id, presentableName, baseContextType) {
24+
25+
override fun isInContext(templateActionContext: TemplateActionContext): Boolean {
26+
val file = templateActionContext.file
27+
val offset = templateActionContext.startOffset
28+
29+
if (!PsiUtilCore.getLanguageAtOffset(file, offset).isKindOf(TactLanguage)) {
30+
return false
31+
}
32+
33+
var element = file.findElementAt(offset)
34+
if (element == null) {
35+
element = file.findElementAt(offset - 1)
36+
}
37+
38+
if (element == null) {
39+
return false
40+
}
41+
42+
if (TactCompletionUtil.shouldSuppressCompletion(element)) {
43+
return false
44+
}
45+
46+
when {
47+
element is PsiWhiteSpace -> return false
48+
element.parentOfType<PsiComment>() != null -> return isCommentInContext()
49+
element.parentOfType<TactImportDeclaration>() != null -> return false
50+
}
51+
52+
return isInContext(element)
53+
}
54+
55+
protected abstract fun isInContext(element: PsiElement): Boolean
56+
57+
protected open fun isCommentInContext() = false
58+
59+
class Generic : TactTemplateContextType("TACT_GENERIC", "Tact", EverywhereContextType::class.java) {
60+
override fun isInContext(element: PsiElement) = element.parent is TactFile || element.parent.parent is TactFile
61+
}
62+
63+
class TopLevel : TactTemplateContextType("TACT_TOPLEVEL", "Top-level", Generic::class.java) {
64+
override fun isInContext(element: PsiElement): Boolean {
65+
val simpleStatement = element.parentOfType<TactSimpleStatement>() ?: return false
66+
return simpleStatement.parent is TactFile
67+
}
68+
}
69+
70+
class Statement : TactTemplateContextType("TACT_STATEMENT", "Statement", Generic::class.java) {
71+
override fun isInContext(element: PsiElement) = element.inside<TactSimpleStatement>()
72+
}
73+
74+
class Comment : TactTemplateContextType("TACT_COMMENT", "Comment", Generic::class.java) {
75+
override fun isInContext(element: PsiElement) = false
76+
override fun isCommentInContext() = true
77+
}
78+
}

src/main/kotlin/org/tonstudio/tact/lang/completion/TactCompletionUtil.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import com.intellij.codeInsight.template.TemplateManager
1515
import com.intellij.codeInsight.template.impl.ConstantNode
1616
import com.intellij.openapi.editor.Editor
1717
import com.intellij.psi.PsiElement
18+
import com.intellij.psi.util.PsiTreeUtil
1819
import com.intellij.psi.util.parentOfType
1920
import org.tonstudio.tact.ide.ui.Icons
2021
import org.tonstudio.tact.lang.psi.*
@@ -460,4 +461,22 @@ object TactCompletionUtil {
460461
render(element, p)
461462
}
462463
}
464+
465+
fun shouldSuppressCompletion(element: PsiElement): Boolean {
466+
val parent = element.parent
467+
val grand = parent.parent
468+
if (grand is TactVarDeclaration && PsiTreeUtil.isAncestor(grand, element, false)) {
469+
return true
470+
}
471+
472+
if (parent is TactFunctionDeclaration) {
473+
return true
474+
}
475+
476+
return parent is TactStructType ||
477+
parent is TactMessageType ||
478+
parent is TactTraitType ||
479+
parent is TactContractType ||
480+
parent is TactPrimitiveDeclaration
481+
}
463482
}

src/main/resources/META-INF/plugin.xml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ Provides official support for <a href="https://tact-lang.org/">Tact</a> programm
104104
providerId="tact.inlay.hints.require.exit.code.info"/>
105105

106106
<!--suppress PluginXmlCapitalization -->
107-
<codeInsight.declarativeInlayProvider language="tact"
107+
<codeInsight.declarativeInlayProvider language="tact"
108108
bundle="messages.TactBundle"
109109
nameKey="tact.inlay.hints.implicit.as.int257"
110110
group="VALUES_GROUP"
@@ -179,6 +179,17 @@ Provides official support for <a href="https://tact-lang.org/">Tact</a> programm
179179
<additionalTextAttributes scheme="New Dark" file="colorSchemes/TactAddonsNewDark.xml"/>
180180
<!-- endregion Color Schemes -->
181181

182+
<!-- region Live Templates -->
183+
<defaultLiveTemplates file="/liveTemplates/Tact.xml"/>
184+
<liveTemplateContext implementation="org.tonstudio.tact.ide.templates.TactTemplateContextType$Comment" contextId="TACT_COMMENT"/>
185+
<liveTemplateContext implementation="org.tonstudio.tact.ide.templates.TactTemplateContextType$Generic" contextId="TACT_GENERIC"/>
186+
<liveTemplateContext implementation="org.tonstudio.tact.ide.templates.TactTemplateContextType$TopLevel" contextId="TACT_TOPLEVEL"/>
187+
<liveTemplateContext implementation="org.tonstudio.tact.ide.templates.TactTemplateContextType$Statement" contextId="TACT_STATEMENT"/>
188+
189+
<defaultTemplatePropertiesProvider
190+
implementation="org.tonstudio.tact.ide.templates.TactDefaultTemplatePropertiesProvider"/>
191+
<!-- endregion Live Templates -->
192+
182193
<!-- region Editor -->
183194
<postStartupActivity implementation="org.tonstudio.tact.ide.TactPostStartupActivity"/>
184195
<lang.formatter language="tact"
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<templateSet group="Tact">
2+
<template name="let" value="let $name$ = $value$;$END$" description="Variable binding" toReformat="true" toShortenFQNames="true">
3+
<variable name="name" expression="&quot;name&quot;" defaultValue="name" alwaysStopAt="true" />
4+
<variable name="value" expression="&quot;10&quot;" defaultValue="10" alwaysStopAt="true" />
5+
<context>
6+
<option name="TACT_STATEMENT" value="true" />
7+
</context>
8+
</template>
9+
<template name="lett" value="let $name$: $type$ = $value$;$END$" description="Variable binding with explicit type" toReformat="true" toShortenFQNames="true">
10+
<variable name="name" expression="&quot;name&quot;" defaultValue="name" alwaysStopAt="true" />
11+
<variable name="type" expression="&quot;Int&quot;" defaultValue="Int" alwaysStopAt="true" />
12+
<variable name="value" expression="&quot;10&quot;" defaultValue="10" alwaysStopAt="true" />
13+
<context>
14+
<option name="TACT_STATEMENT" value="true" />
15+
</context>
16+
</template>
17+
<template name="while" value="while ($cond$) {$END$}" description="While loop" toReformat="true" toShortenFQNames="true">
18+
<variable name="cond" expression="&quot;true&quot;" defaultValue="true" alwaysStopAt="true" />
19+
<context>
20+
<option name="TACT_STATEMENT" value="true" />
21+
</context>
22+
</template>
23+
<template name="until" value="do {$END$} until ($cond$);" description="Do-until loop" toReformat="true" toShortenFQNames="true">
24+
<variable name="cond" expression="&quot;true&quot;" defaultValue="true" alwaysStopAt="true" />
25+
<context>
26+
<option name="TACT_STATEMENT" value="true" />
27+
</context>
28+
</template>
29+
<template name="do" value="do {$END$} until ($cond$);" description="Do-until loop" toReformat="true" toShortenFQNames="true">
30+
<variable name="cond" expression="&quot;true&quot;" defaultValue="true" alwaysStopAt="true" />
31+
<context>
32+
<option name="TACT_STATEMENT" value="true" />
33+
</context>
34+
</template>
35+
<template name="repeat" value="repeat($value$) {$END$}" description="Repeat loop" toReformat="true" toShortenFQNames="true">
36+
<variable name="value" expression="&quot;10&quot;" defaultValue="10" alwaysStopAt="true" />
37+
<context>
38+
<option name="TACT_STATEMENT" value="true" />
39+
</context>
40+
</template>
41+
<template name="foreach" value="foreach ($key$, $value$ in $mapping$) {$END$}" description="Foreach loop" toReformat="true" toShortenFQNames="true">
42+
<variable name="key" expression="&quot;key&quot;" defaultValue="key" alwaysStopAt="true" />
43+
<variable name="value" expression="&quot;value&quot;" defaultValue="value" alwaysStopAt="true" />
44+
<variable name="mapping" expression="&quot;mapping&quot;" defaultValue="mapping" alwaysStopAt="true" />
45+
<context>
46+
<option name="TACT_STATEMENT" value="true" />
47+
</context>
48+
</template>
49+
<template name="try" value="try {$END$}" description="Try statement" toReformat="true" toShortenFQNames="true">
50+
<context>
51+
<option name="TACT_STATEMENT" value="true" />
52+
</context>
53+
</template>
54+
<template name="trycatch" value="try {$END$} catch ($error$) {}" description="Try-catch statement" toReformat="true" toShortenFQNames="true">
55+
<variable name="error" expression="&quot;error&quot;" defaultValue="error" alwaysStopAt="true" />
56+
<context>
57+
<option name="TACT_STATEMENT" value="true" />
58+
</context>
59+
</template>
60+
</templateSet>

0 commit comments

Comments
 (0)