VladRassokhin / intellij-hcl

HCL language support for IntelliJ platform based IDEs
Apache License 2.0
244 stars 47 forks source link

"Show Terraform Documentation" intentionAction #221

Closed hsz closed 5 years ago

hsz commented 5 years ago

This feature implementation introduces an intentionAction attached to the HCLStringLiterals Psi elements that are preceded by HCLIdentifier with resource or data text values. Above matching elements get the IntentionAction with Show Terraform Documentation label. Invoking this action opens an URL to the Terraform documentation in the browser.

Example:

image

resource "aws_acm_certificate_validation" "default" {
  certificate_arn = "foo"
}

links to the https://www.terraform.io/docs/providers/aws/r/acm_certificate_validation.html

URL generator supports dynamic provider, resource/data and identifier.

VladRassokhin commented 5 years ago

Hi Jakub, thank you for contributing. Right now I'm on vacation but would try to take a look as soon as I can. As you may probably know new releases of plugin are released from closed-sources, are you agree to include your patch there? For that you'd need to sign JetBrains CLA.

hsz commented 5 years ago

Hi Vladislav!

I didn't notice that you have closed the sources - just searched the gh repository today. I've signed CLA. Take your time and enjoy your vacations!

BR, Jakub

czw., 6 cze 2019, 11:18 użytkownik Vladislav Rassokhin < notifications@github.com> napisał:

Hi Jakub, thank you for contributing. Right now I'm on vacation but would try to take a look as soon as I can. As you may probably know new releases of plugin are released from closed-sources, are you agree to include your patch there? For that you'd need to sign JetBrains CLA https://www.jetbrains.com/agreements/cla/.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/VladRassokhin/intellij-hcl/pull/221?email_source=notifications&email_token=AAA2OLMDG63UGNCZF3IQKKLPZDI7LA5CNFSM4HU375O2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODXCIBIQ#issuecomment-499417250, or mute the thread https://github.com/notifications/unsubscribe-auth/AAA2OLNY5Y5YS2EL22LTJLDPZDI7LANCNFSM4HU375OQ .

VladRassokhin commented 5 years ago

Thank you for inspiration, I've managed to perform almost the same result using default DocumentationProvider. I don't think that there should be separate intention action, since 'Quick Documentation' is now able to show link to terraform.io.

Here's a patch if you're interested:

Index: src/kotlin/org/intellij/plugins/hcl/terraform/config/TerraformDocumentationProvider.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/kotlin/org/intellij/plugins/hcl/terraform/config/TerraformDocumentationProvider.kt  (revision e8dd5c19b1004b8823cba06add89458f8963925d)
+++ src/kotlin/org/intellij/plugins/hcl/terraform/config/TerraformDocumentationProvider.kt  (revision d47ab5135da24c89514e1c5422e20cf0b5b58eaf)
@@ -23,6 +23,7 @@
 import org.intellij.plugins.hcl.terraform.config.model.BlockType
 import org.intellij.plugins.hcl.terraform.config.model.PropertyType
 import org.intellij.plugins.hcl.terraform.config.model.TypeModel
+import org.intellij.plugins.hcl.terraform.config.patterns.TerraformPatterns

 class TerraformDocumentationProvider : AbstractDocumentationProvider() {
   override fun getQuickNavigateInfo(element: PsiElement?, originalElement: PsiElement?): String? {
@@ -97,4 +98,34 @@
     }
     return null
   }
+
+  override fun getUrlFor(element: PsiElement?, originalElement: PsiElement?): List<String>? {
+    if (element !is HCLIdentifier && element !is HCLStringLiteral) return null
+
+    val parent = element.parent
+    if (parent is HCLBlock && parent.nameElements.contains(element)) {
+      if (TerraformPatterns.RootBlock.accepts(parent)) {
+        val identifier = parent.getNameElementUnquoted(1) ?: return null
+        return when (parent.getNameElementUnquoted(0)) {
+          "resource" -> listOf(getResourceOrDataSourceUrl(identifier, 'r'))
+          "data" -> listOf(getResourceOrDataSourceUrl(identifier, 'd'))
+          "provider" -> listOf(getProviderUrl(identifier))
+          else -> null
+        }
+      }
+    }
+
+    return null
+  }
+
+  // https://www.terraform.io/docs/providers/$PROVIDER/index.html
+  private fun getProviderUrl(provider: String): String {
+    return "https://www.terraform.io/docs/providers/$provider/index.html"
+  }
+
+  //https://www.terraform.io/docs/providers/$PROVIDER/$TYPE/$NAME.html
+  private fun getResourceOrDataSourceUrl(identifier: String, type: Char): String {
+    val (provider, id) = identifier.split("_", limit = 2)
+    return "https://www.terraform.io/docs/providers/$provider/$type/$id.html"
+  }
 }