This repository provides a Tree-sitter parser for the Raku programming language, specifically adapted for use with the Helix editor.
This project is a fork of the excellent tree-sitter-perl parser. While the changes made in this fork are minor compared to the incredible effort invested in the original tree-sitter-perl, they provide a significantly improved syntax highlighting experience for Raku code in Helix.
The default Tree-sitter parser for Perl is often applied to Raku files in Helix, which can lead to incorrect highlighting. This parser addresses that by making initial Raku-specific syntax adjustments, such as correctly handling hyphens in variable names (e.g., my $variable-name).
Follow these steps to build the parser and configure Helix to use it for Raku files.
Prerequisites:
- Node.js (v20 or higher) and npm are installed.
- The
tree-sitterCLI. If you don't have it, you can install it locally for the project withnpm install tree-sitter-cli.
First, clone this repository to your local machine and generate the parser files.
# Clone the repository
git clone https://github.com/acrion/tree-sitter-raku.git
cd tree-sitter-raku
# Generate the parser C code
npx tree-sitter generateNext, you need to tell Helix where to find the grammar and its associated query files.
-
Copy the Query Files: The query files (
highlights.scm,indents.scm, etc.) determine how Helix uses the parser for syntax highlighting, indentation, and more.# Create the necessary directory if it doesn't exist mkdir -p ~/.config/helix/runtime/queries/raku # Copy the queries from this repository cp -r queries/* ~/.config/helix/runtime/queries/raku/
-
Add the Grammar to
languages.toml: You need to register the new grammar in your Helix language configuration file (~/.config/helix/languages.toml). Add the following content to it. If the file doesn't exist, create it.[[language]] name = "raku" scope = "source.raku" file-types = ["raku", "rakumod", "rakutest", "rakudoc", "nqp", "p6", "pl6", "pm6"] shebangs = ["raku", "perl6"] comment-token = "#" indent = { tab-width = 4, unit = " " } [[grammar]] name = "raku" source = { git = "https://github.com/acrion/tree-sitter-raku", rev = "main" }
Finally, have Helix build the grammar and check that everything is configured correctly.
# Tell Helix to build any newly configured grammars
helix --grammar build
# Check the health of your Raku configuration
helix --health rakuYou should see checkmarks (✓) for the Tree-sitter parser and its queries, indicating a successful setup.
- Language Name: The grammar has been renamed from
perltorakuthroughout the project. - Raku Syntax: An initial adaptation was made in
lib/unicode_ranges.jsandsrc/grammar.jsonto allow hyphens within identifiers, a common feature in Raku. - Helix Integration:
- The
queriesfor highlighting, indentation, folding, and text objects were copied from the Helix repository (specifically theperlqueries) and adapted for this parser. - A sample
languages.tomlconfiguration is provided for easy integration.
- The
This project would not be possible without the work of others:
- tree-sitter-perl: The vast majority of the parsing logic comes from this project. Thank you to its maintainers and contributors.
- Helix Editor: The language query files (
.scm) are based on the ones provided by the Helix project for its built-in Perl support.
If you want to contribute to the parser itself, the process is straightforward.
After making any changes to the grammar definition in grammar.js, you must regenerate the C source code:
npx tree-sitter generateTests are located in the /test/corpus directory. You can run them using the Tree-sitter CLI:
npx tree-sitter testFor a full IDE-like experience, you can complement the Tree-sitter parser with a Language Server. RakuNavigator is a great option for Raku. Here is how to set it up for Helix.
# Choose a directory for third-party projects
cd /path/to/your/projects
# Clone the RakuNavigator repository
git clone https://github.com/bscan/RakuNavigator.git
cd RakuNavigator/server
# Install Node.js dependencies for the server
npm install
# Install TypeScript to compile the server (if not already installed)
npm install -g typescript
# Compile the server's TypeScript code to JavaScript
tscNow, add the following configuration to your ~/.config/helix/languages.toml file.
Replace /path/to/your/projects with the actual absolute path where you cloned RakuNavigator. Also, adjust the includePaths to point to the directories containing your Raku modules.
[language-server.raku-navigator]
command = "node"
args = ["/path/to/your/projects/RakuNavigator/server/out/server.js", "--stdio"]
[language-server.raku-navigator.config.raku]
# Specifies the path to your Raku executable.
# "raku" is usually sufficient if it's in your system's PATH.
rakuPath = "raku"
# This is crucial for the language server to find your custom Raku modules, especially
# those not installed via `zef` or in standard Raku module directories. It mimics the behavior
# of `use lib`, telling the language server where to look for `.rakumod` files when resolving
# `use` directives. Unlike your shell, where Raku implicitly finds modules based on your
# current directory, the language server often runs with a different working directory.
# Therefore, explicitly providing these paths ensures it can resolve `use` directives
# correctly and avoid "Syntax: Could not find ... in ..." errors.
includePaths = [
"/path/to/your/custom/raku/modules"
]
logging = trueRun the Helix health check again for Raku:
helix --health rakuYou should now see the raku-navigator language server listed with a checkmark.
When you see the following output:
Configured language servers:
✓ raku-navigator: /usr/bin/node
This is what it means:
✓ raku-navigator:Helix has successfully read the[language-server.raku-navigator]section from yourlanguages.toml./usr/bin/node: This is the resolved path to thecommandyou specified. Helix confirms it can find thenodeexecutable. The actual server logic is in the JavaScript file (out/server.js) that you passed as an argument, whichnodewill execute to start the Language Server Protocol (LSP) communication. Theconfig.rakusection is then passed internally to theraku-navigatorserver for its own configuration.