Skip to content

Commit 9934e5a

Browse files
committed
add basic language support
1 parent aca6250 commit 9934e5a

File tree

7 files changed

+166
-2
lines changed

7 files changed

+166
-2
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.github.xepozz.crontab.language
2+
3+
import com.github.xepozz.crontab.language.psi.CrontabSchedule
4+
import com.intellij.lang.annotation.AnnotationHolder
5+
import com.intellij.lang.annotation.Annotator
6+
import com.intellij.lang.annotation.HighlightSeverity
7+
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors
8+
import com.intellij.openapi.editor.colors.TextAttributesKey
9+
import com.intellij.psi.PsiElement
10+
11+
class CrontabAnnotator : Annotator {
12+
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
13+
when (element) {
14+
is CrontabSchedule -> {
15+
holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
16+
.range(element.textRange)
17+
.textAttributes(SCHEDULE_HIGHLIGHT)
18+
.create()
19+
}
20+
21+
// is CrontabCommand -> {
22+
// holder.newSilentAnnotation(HighlightSeverity.INFORMATION)
23+
// .range(element.textRange)
24+
// .textAttributes(COMMAND_HIGHLIGHT)
25+
// .create()
26+
// }
27+
}
28+
}
29+
30+
companion object {
31+
private val SCHEDULE_HIGHLIGHT = TextAttributesKey.createTextAttributesKey(
32+
"CRONTAB_SCHEDULE",
33+
DefaultLanguageHighlighterColors.FUNCTION_DECLARATION,
34+
)
35+
// private val COMMAND_HIGHLIGHT = TextAttributesKey.createTextAttributesKey(
36+
// "CRONTAB_COMMAND",
37+
// DefaultLanguageHighlighterColors.STRING,
38+
// )
39+
}
40+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.github.xepozz.crontab.language
2+
3+
import com.github.xepozz.crontab.language.psi.CrontabCommand
4+
import com.intellij.lang.Language
5+
import com.intellij.lang.injection.MultiHostInjector
6+
import com.intellij.lang.injection.MultiHostRegistrar
7+
import com.intellij.openapi.util.TextRange
8+
import com.intellij.psi.PsiElement
9+
import com.intellij.psi.PsiLanguageInjectionHost
10+
11+
class CrontabLanguageInjector : MultiHostInjector {
12+
val shellLanguage = Language.findLanguageByID("Shell Script")
13+
override fun getLanguagesToInject(registrar: MultiHostRegistrar, element: PsiElement) {
14+
if (shellLanguage == null) return
15+
16+
when (element) {
17+
is CrontabCommand -> {
18+
registrar.startInjecting(shellLanguage)
19+
.addPlace(null, null, element, TextRange(0, element.textLength))
20+
.doneInjecting()
21+
}
22+
}
23+
}
24+
25+
override fun elementsToInjectIn(): List<Class<out PsiElement>> {
26+
return listOf(PsiLanguageInjectionHost::class.java)
27+
}
28+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.github.xepozz.crontab.language
2+
3+
import com.github.xepozz.crontab.language.parser.CrontabLexerAdapter
4+
import com.github.xepozz.crontab.language.psi.CrontabTypes
5+
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors
6+
import com.intellij.openapi.editor.HighlighterColors
7+
import com.intellij.openapi.editor.colors.TextAttributesKey
8+
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase
9+
import com.intellij.psi.TokenType
10+
import com.intellij.psi.tree.IElementType
11+
12+
class CrontabSyntaxHighlighter : SyntaxHighlighterBase() {
13+
override fun getHighlightingLexer() = CrontabLexerAdapter()
14+
15+
override fun getTokenHighlights(tokenType: IElementType) = when (tokenType) {
16+
// CrontabTypes.SCHEDULE -> COMMENT_KEYS
17+
// CrontabTypes.TIME_POINTER -> CONSTANT_KEYS
18+
// CrontabTypes.COMMAND -> KEYWORD_KEYS
19+
20+
CrontabTypes.COMMENT -> COMMENT_KEYS
21+
TokenType.BAD_CHARACTER -> BAD_CHAR_KEYS
22+
else -> EMPTY_KEYS
23+
}
24+
25+
companion object {
26+
private val BAD_CHAR_KEYS = arrayOf(
27+
HighlighterColors.BAD_CHARACTER,
28+
)
29+
30+
// private val KEYWORD_KEYS = arrayOf(
31+
// DefaultLanguageHighlighterColors.KEYWORD
32+
// )
33+
// private val CONSTANT_KEYS = arrayOf(
34+
// DefaultLanguageHighlighterColors.CONSTANT
35+
// )
36+
private val COMMENT_KEYS = arrayOf(
37+
DefaultLanguageHighlighterColors.DOC_COMMENT
38+
)
39+
private val EMPTY_KEYS = emptyArray<TextAttributesKey>()
40+
}
41+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.github.xepozz.crontab.language
2+
3+
import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory
4+
import com.intellij.openapi.project.Project
5+
import com.intellij.openapi.vfs.VirtualFile
6+
7+
internal class CrontabSyntaxHighlighterFactory : SyntaxHighlighterFactory() {
8+
override fun getSyntaxHighlighter(project: Project?, virtualFile: VirtualFile?) = CrontabSyntaxHighlighter()
9+
}

src/main/kotlin/com/github/xepozz/crontab/language/parser/Crontab.bnf

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,13 @@ SCHEDULE ::= (TIME_POINTER+)
2626
{
2727
pin=1
2828
}
29-
private TIME_POINTER ::= ((STAR SLASH NUMBER) | STAR | NUMBER)
29+
30+
TIME_POINTER ::= ((STAR SLASH NUMBER) | STAR | NUMBER)
3031

3132
COMMAND ::= CONTENT
33+
{
34+
implements=["com.intellij.psi.PsiLanguageInjectionHost"]
35+
extends="com.github.xepozz.crontab.language.psi.impl.CrontabCommandBaseImpl"
36+
}
3237

3338
COMMENT ::= SINGLE_COMMENT
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.github.xepozz.crontab.language.psi.impl
2+
3+
import com.github.xepozz.crontab.language.psi.CrontabCommand
4+
import com.github.xepozz.crontab.language.psi.CrontabTypes
5+
import com.intellij.extapi.psi.ASTWrapperPsiElement
6+
import com.intellij.lang.ASTNode
7+
import com.intellij.psi.LiteralTextEscaper
8+
import com.intellij.psi.PsiLanguageInjectionHost
9+
import com.intellij.psi.impl.source.tree.LeafElement
10+
11+
abstract class CrontabCommandBaseImpl : ASTWrapperPsiElement, CrontabCommand, PsiLanguageInjectionHost {
12+
constructor(node: ASTNode) : super(node)
13+
14+
override fun getText(): String {
15+
val keyNode = this.node.findChildByType(CrontabTypes.CONTENT)
16+
17+
return keyNode?.text ?: ""
18+
}
19+
20+
override fun isValidHost() = true
21+
22+
override fun updateText(newText: String): PsiLanguageInjectionHost? {
23+
val keyNode = this.node.findChildByType(CrontabTypes.CONTENT) as? LeafElement ?: return null
24+
keyNode.replaceWithText(newText)
25+
26+
return this
27+
}
28+
29+
override fun createLiteralTextEscaper(): LiteralTextEscaper<out PsiLanguageInjectionHost?> {
30+
return LiteralTextEscaper.createSimple(this, true)
31+
}
32+
}

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,18 @@
1414
implementationClass="com.github.xepozz.crontab.language.CrontabFileType"
1515
fieldName="INSTANCE"
1616
language="Crontab"
17-
extensions=""/>
17+
extensions="crontab,cron"
18+
/>
1819
<lang.parserDefinition
1920
language="Crontab"
2021
implementationClass="com.github.xepozz.crontab.language.parser.CrontabParserDefinition"/>
22+
<lang.syntaxHighlighterFactory
23+
language="Crontab"
24+
implementationClass="com.github.xepozz.crontab.language.CrontabSyntaxHighlighterFactory"/>
25+
<annotator
26+
language="Crontab"
27+
implementationClass="com.github.xepozz.crontab.language.CrontabAnnotator"/>
28+
<multiHostInjector
29+
implementation="com.github.xepozz.crontab.language.CrontabLanguageInjector"/>
2130
</extensions>
2231
</idea-plugin>

0 commit comments

Comments
 (0)