Skip to content

Add brace matching for sigil delimiters #55

@mkaput

Description

@mkaput

Summary

Add brace matching support for sigil delimiters so that when the cursor is positioned near a sigil's opening delimiter, its matching closing delimiter is highlighted.

Elixir sigils support various delimiter pairs:

  • ~s(...), ~r(...) - parentheses
  • ~s[...], ~r[...] - brackets
  • ~s{...}, ~r{...} - braces
  • ~s<...>, ~r<...> - angle brackets
  • ~s|...|, ~r|...| - pipes
  • ~s/.../, ~r/.../ - slashes
  • ~s"...", ~r"..." - double quotes
  • ~s'...', ~r'...' - single quotes

Current Behavior

Currently, sigils are tokenized as a single EX_SIGIL token containing the entire sigil including its delimiters and content:

EX_SIGIL: ~r/pattern/i

As a single token, there's no way to match the opening / with the closing /.

Desired Behavior

When the cursor is near a sigil's opening delimiter, the matching closing delimiter should be highlighted. For example, in ~r/pattern/, positioning the cursor at the first / should highlight the second /.

Complexity considerations:

  • Symmetric delimiters (|, /, ", ') use the same token for open and close
  • Asymmetric delimiters ((), [], {}, <>) need distinct open/close tokens
  • IntelliJ-Elixir handles this with LINE_PROMOTER/LINE_TERMINATOR tokens

Reference

IntelliJ-Elixir implementation:

  • Paired.java - includes LINE_PROMOTER/LINE_TERMINATOR pair
  • The lexer uses states like SIGIL, GROUP, etc. to track context

Acceptance Criteria

  • Sigil opening delimiters match closing delimiters for all delimiter types:
    • () pairs
    • [] pairs
    • {} pairs
    • <> pairs
    • || pairs
    • // pairs
    • "" pairs
    • '' pairs
  • Heredoc-style sigils (~s"""...""") also work (may depend on Add brace matching for heredocs #54)
  • Sigil modifiers are still properly recognized
  • Parser tests continue to pass
  • Syntax highlighting continues to work correctly

Notes

This is a larger undertaking than heredoc support due to the variety of delimiter types. Consider implementing incrementally, starting with the most common delimiters.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions