Skip to content

Add Language support

Dinesh edited this page Sep 3, 2022 · 12 revisions

How to add VSCode highlighting for a new language?

In this example we will be adding additional highlighting for GoLang.

Prerequisite:

  1. Intellij IDE installed on your machine. (Either Community version or the EAP version)

  2. JDK v11 (Preferably OpenJDK or ZuluJDK) Install

    brew install openjdk@11
    
    # Create Symbolic Link
    mkdir -p /Library/Java/JavaVirtualMachines
    cd /Library/Java/JavaVirtualMachines
    ln -s /opt/homebrew/opt/openjdk@11/libexec/openjdk.jdk openjdk-11.jdk
    

    edit ~/.zprofile

    vi ~/.zprofile
    

    and add the following JDK env variables

    # Java
    export JAVA_HOME="/opt/homebrew/opt/openjdk@11/libexec/openjdk.jdk/Contents/Home"
    export PATH="$JAVA_HOME/bin:$PATH"
    export CPPFLAGS="-I$JAVA_HOME/include"
    

Workspace Setup

  1. Clone the repository (Internal Developer) or Fork the repository (External Developers).

    git clone https://github.com/dinbtechit/vscode-theme

    Note: if you already have the SSH keys feel free to use the SSH URL.

  2. Create a new feature branch.

    Provide a descriptive name for the feature branch. <GITHUB_ISSUE#>-<BRIEF_DESCRIPTION>.

    git checkout -b feature/15-golang-vscode-syntax-support
  3. Open the project in IntelliJ. Intellij should start syncing all the Gradle dependencies and might take a while.

    Note: Gradle dependencies gets cached in your home directory ($HOME/.gradle/caches). Just like maven or npm. Over time they take a significant amount of the disk space. Its a good practice to clean up the cache when you are done developing.

Add Dependencies

  1. In this case, we are going to add GoLang dependency (org.jetbrains.plugins.go:221.5591.52) to the platformPlugins. As shown below

    gradle.properties

    platformPlugins = ..., org.jetbrains.plugins.go:221.5591.52

    Note: You can get the dependency information (i.e., pluginID + Version) from Jetbrains MarketPlace by searching for the plugin -> Plugin homepage -> under the Versions tab -> click on the version.

Configure Language

  1. Navigate to src/main/resources/META-INF/lang-config and create a new xml config file for Go, dinbtechit-go.xml (i.e., dinbtechit-[LANG].xml). And update the contents as shown below.

    <idea-plugin>
      <extensions defaultExtensionNs="com.intellij">
         <annotator language="go" order="last"
                    implementationClass="com.github.dinbtechit.vscodetheme.annotators.GoAnnotator"/>
      </extensions>
    </idea-plugin>
  2. Add a new depends tag in src/main/resources/META-INF/plugin.xml to include the language config, dinbtechit-go.xml that we just created. Add it to the bottom of the existing depends tags (As shown below)

    plugin.xml

    <!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
    <idea-plugin require-restart="true">
     . . .
     
     <depends config-file="lang-config/dinbtechit-go.xml" optional="true">org.jetbrains.plugins.go</depends>
    
     . . .
    <idea-plugin>

Add Annotator Logic for the additional Syntax highlighting

  1. Navigate to src/main/kotlin/com/github/dinbtechit/vscodetheme/annotators and create a new kotlin Class file, GoAnnotator, and update the contents as shown below.
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors
import com.intellij.openapi.editor.colors.TextAttributesKey
import com.intellij.psi.PsiElement
import com.intellij.util.ObjectUtils

class GoAnnotator : BaseAnnotator() {
    companion object {
        val DEFAULT_KEYWORD: TextAttributesKey = ObjectUtils.notNull(
            TextAttributesKey.find("DEFAULT_KEYWORD"), DefaultLanguageHighlighterColors.KEYWORD
        )
        val SECONDARY_KEYWORD: TextAttributesKey = TextAttributesKey.createTextAttributesKey(
            "DEFAULT_SECONDARY_KEYWORD",
            DEFAULT_KEYWORD
        )
        val SECONDARY_KEYWORD_BG: TextAttributesKey = TextAttributesKey.createTextAttributesKey(
            "DEFAULT_SECONDARY_KEYWORD_WITH_BG",
            DEFAULT_KEYWORD
        )
    }
    override fun getKeywordType(element: PsiElement): TextAttributesKey? {
        var type: TextAttributesKey? = null
        when (element.text) {
            "if", "else", "goto", "switch", "select", "case", "default", "break", "continue" -> type = SECONDARY_KEYWORD
            "defer", "go", "fallthrough" -> type = SECONDARY_KEYWORD
            "for", "range" -> type = SECONDARY_KEYWORD
            "return" -> type = SECONDARY_KEYWORD
            else -> {}
        }
        return type
    }

}

Note: Currently there are no unit tests for this project. But I'm working on a plan to incorporate testing in the near future.

Submit a pull request to review and release your changes:

Awesome, you have successfully completed the coding. You are almost there!

  1. Increment the pluginVersion in gradle.properties. We are using semantic versioning. Adding new language support is a minor release so we will increment the version from 1.5.4 to 1.6.0

  2. Update CHANGELOG.md - Add the following under the ## [Unreleased]. Github actions will automatically update the Unreleased to the appropriate version from gradle.properties

    ## [Unreleased]
    ### Added
    - (feature #15) Added extensive syntax highlighting for Go
  3. Update README.md:

    1. In Supported Languages section -> move the Go from Basic Syntax highlighting to the Advance Syntax highlighting.
    2. In the RoadMap section -> Remove GoLang
  4. Commit all your changes, push the branch to remote and Submit a Pull Request against the main branch.

    Note once your PR is approved and merged to the main branch. Github actions will automatically kick off a build and release the plugin to the Jetbrains Market place. Once it is released in the market place it will take about a day or two for Jetbrains to approve the new version of the plugin and show up in your IDE.

Done!