Support .tf and .tfvars extensions in HCL lexer
Name of the lexer HCL
Code sample
A .tf or .tfvars file (standard Terraform file extensions) is not highlighted when rendered via Rouge, because the lexer does not recognize these extensions.
Example .tf file content:
output = data.name
provider "aws" {
region = "us-west-2"
}
resource "aws_s3_bucket" "example" {
bucket = "my-example-bucket"
acl = "private"
}
You can reproduce this using the Dingus by uploading a .tf file — syntax highlighting is not applied unless the lexer is explicitly forced to HCL.
You'll see a red dot, which is caused by this.
Additional context
The HCL lexer currently recognizes .hcl and .nomad extensions, but not .tf or .tfvars, which are widely used in modern infrastructure-as-code projects.
Since the lexer itself works correctly when forced, this appears to be a filename recognition issue rather than a parsing one.
Rouge version is 4.5.2
I’d be happy to contribute a fix for this if that would be helpful!
@kumarmunish Thank you for raising the issue. According to the spec, Terraform's configuration language is based on HCL. .tf and .tfvars are Terraform extensions so they must use the Terraform lexer. In other words, I don't think it is the filename recognition issue but the Terraform lexer itself that fails to parse the dot character.
Could you include the language spec for the .tfvars file that states the above syntax output = data.name is valid? I fail to find any references in https://developer.hashicorp.com/terraform/language/values.
@tancnle, thanks for the clarification — you're absolutely right, the syntax I referenced (output = data.name) isn’t valid in .tfvars files, and I appreciate you pointing that out. I saw similar syntax was reported on an open issue on Gitlab(which uses Rouge), so I thought it was because if .tf files are not handled in the HCL lexer. I should have been more specific in my example — that was a mix-up on my part..
That said, I’m curious about the current behavior of the Rouge HCL lexer. It includes support for .hcl and .nomad extensions, but not .tf and .tfvars, even though Terraform is by far the most widespread use case of HCL in practice.
Is there a particular reason those extensions were excluded initially? Given their popularity and the fact that the underlying syntax is still HCL, it feels like a natural addition to support them alongside .nomad.
https://github.com/rouge-ruby/rouge/blob/master/lib/rouge/lexers/hcl.rb#L8
@kumarmunish In Rouge, Terraform lexer inherits from HCL lexer. I would expect it supports majority of HCL syntax with some additional Terraform specific keywords and features.
Is there a particular reason those extensions were excluded initially?
HCL lexer is meant to support bare-bones HCL, rather than flavours of it.