syntaxcompletion

package
v0.0.0-...-6b1f02c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 14, 2026 License: GPL-2.0 Imports: 29 Imported by: 0

README

syntaxcompletion

Config-driven syntax completion engine for editor keystrokes.

This package loads language rules from YAML and returns deterministic edit operations with caret placement.

Config File

The embedded default config is in default_rules.yaml.

Top-level schema:

languages:
  <language-name>:
    context_guard: {}
    pairs: []
    list_continuation: {}
    auto_close_tags: {}

Notes:

  • Language names are matched case-insensitively by the engine.
  • Unknown YAML keys are rejected (yaml.Decoder.KnownFields(true)).

Supported Directives

languages

Map of language id to language-specific rule block.

Example:

languages:
  go:
    pairs:
      - open: "["
        close: "]"
pairs

List of pair-completion rules for trigger characters.

Fields:

  • open (string, required): the typed trigger.
  • close (string, required): the inserted closing text.
  • skip_close (bool, optional): if true and the immediate next source text already equals close, no text is inserted and the caret moves forward by len(close).
  • wrap_selection (bool, optional): reserved for future behavior. Current engine wraps active selection whenever a matching pair rule is applied, regardless of this flag.

Behavior:

  • Trigger must match exactly (for example open: "[" triggers only on [).
  • With selection: replaces selection with open + selection + close.
  • Without selection: inserts open + close and places caret between them.

Example:

languages:
  json:
    pairs:
      - open: "{"
        close: "}"
      - open: "\""
        close: "\""
        skip_close: true
context_guard

Syntax-context guard used to suppress completions in disallowed regions.

Fields:

  • enabled (bool): enables syntax context checks.
  • disallow_in (string array): contexts where completions should be blocked. Supported values are comment and string (case-insensitive).

Behavior:

  • Checks run before pair/list/tag completion logic.
  • Current implementation uses tree-sitter when cgo is enabled and a parser is available for the language.
  • If tree-sitter is unavailable (for example non-cgo builds) or a language parser is not configured, the guard is effectively skipped.
  • On classifier errors, typing is fail-open (completion is not blocked due to guard failure).

Example:

languages:
  go:
    context_guard:
      enabled: true
      disallow_in: ["comment", "string"]
    pairs:
      - open: "["
        close: "]"
list_continuation

Markdown-style Enter behavior for list items.

Fields:

  • enabled (bool): enables list continuation for newline trigger ("\n").
  • unordered_markers (string array): allowed unordered markers (for example -, *, +). If empty, any marker matched by engine regex is allowed.
  • ordered (bool): enables ordered list continuation (1., 2), etc).
  • exit_on_empty_item (bool): if current list item body is empty, pressing Enter exits the list and keeps indentation only.

Behavior constraints:

  • Only runs when trigger is newline ("\n").
  • Only runs when caret is at end of current line.
  • Current line must match supported list patterns.

Example:

languages:
  markdown:
    list_continuation:
      enabled: true
      unordered_markers: ["-", "*", "+"]
      ordered: true
      exit_on_empty_item: true
auto_close_tags

HTML tag auto-close behavior for > trigger.

Fields:

  • enabled (bool): enables auto closing for HTML-like open tags.
  • allowed (string array): whitelist of tag names (case-insensitive). If empty, all detected open tags are allowed.

Behavior:

  • Only runs when trigger is ">".
  • Detects open tag pattern immediately to the left of caret.
  • Does not apply for closing tags (for example </p>) or self-closing tags (for example <br/>).
  • Inserts </tag> at caret and keeps caret before the inserted close tag.

Example:

languages:
  html:
    auto_close_tags:
      enabled: true
      allowed: ["p", "div", "span"]

Runtime Trigger Mapping

Current trigger-to-rule mapping in engine:

  • Any trigger string: matched against pairs[*].open.
  • "\n": used for list_continuation.
  • ">": used for auto_close_tags.

Context guards run independently of trigger mapping and can suppress all completion kinds.

Request/Result Contract

Request describes source state before the trigger is applied by the editor adapter:

  • Language: language id.
  • Source: full document/source text.
  • Cursor: caret byte index in Source.
  • SelectionStart, SelectionEnd: byte indexes. If either is < 0, no selection is assumed.
  • Trigger: typed key/text (for example [, \n, >).

Result describes a single replacement edit:

  • Applied: true if a rule matched.
  • Start, End: replacement range in original source.
  • Text: replacement text.
  • Cursor: new caret byte index after edit.

Use Apply(source, result) to apply and validate the edit.

Default Rules Included

The embedded defaults currently include:

  • go: bracket/brace/quote pairs.
  • json: brace/bracket/quote pairs.
  • markdown: pair rules + list continuation.
  • html: quote pairs + tag auto-close.

Tree-sitter context guard parsers are currently wired for:

  • bash
  • c
  • cpp
  • csharp
  • css
  • go
  • html
  • java
  • javascript
  • json
  • julia
  • ocaml
  • php
  • python
  • ruby
  • rust
  • scala
  • typescript
  • verilog

Common aliases are also recognized (for example c++, c#, js, ts, tsx, py, sh, shell).

Runtime introspection helpers:

  • SupportedTreeSitterLanguages() []string: reports grammar ids compiled into the default backend for the current build.
  • (*Engine).SupportedTreeSitterLanguages() []string: reports grammar ids available to that engine instance.

In non-cgo builds these functions return an empty list.

See default_rules.yaml for exact defaults.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Apply

func Apply(source string, res Result) (string, int, error)

func SupportedTreeSitterLanguages

func SupportedTreeSitterLanguages() []string

SupportedTreeSitterLanguages returns tree-sitter language ids that are compiled into the default backend for this build.

Types

type AutoCloseTagsRule

type AutoCloseTagsRule struct {
	Enabled bool     `yaml:"enabled"`
	Allowed []string `yaml:"allowed"`
}

type Config

type Config struct {
	Languages map[string]LanguageConfig `yaml:"languages"`
}

func LoadConfig

func LoadConfig(yml []byte) (*Config, error)

func LoadDefaultConfig

func LoadDefaultConfig() (*Config, error)

type ContextClassifier

type ContextClassifier interface {
	Detect(language, source string, cursor int) (ContextState, error)
}

ContextClassifier detects cursor context for a language. Implementations should be fast and best-effort; they can return a zero state when the language is unsupported.

type ContextGuardRule

type ContextGuardRule struct {
	Enabled    bool     `yaml:"enabled"`
	DisallowIn []string `yaml:"disallow_in"`
}

type ContextState

type ContextState struct {
	InString  bool
	InComment bool
}

ContextState describes the syntax context around a cursor position.

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

func NewDefaultEngine

func NewDefaultEngine() (*Engine, error)

func NewEngineFromYAML

func NewEngineFromYAML(yml []byte) (*Engine, error)

func (*Engine) Complete

func (e *Engine) Complete(req Request) (Result, error)

func (*Engine) SupportedTreeSitterLanguages

func (e *Engine) SupportedTreeSitterLanguages() []string

SupportedTreeSitterLanguages returns tree-sitter language ids available to this engine instance's classifier.

type LanguageConfig

type LanguageConfig struct {
	Pairs            []PairRule            `yaml:"pairs"`
	ListContinuation *ListContinuationRule `yaml:"list_continuation"`
	AutoCloseTags    *AutoCloseTagsRule    `yaml:"auto_close_tags"`
	ContextGuard     *ContextGuardRule     `yaml:"context_guard"`
}

type ListContinuationRule

type ListContinuationRule struct {
	Enabled          bool     `yaml:"enabled"`
	UnorderedMarkers []string `yaml:"unordered_markers"`
	Ordered          bool     `yaml:"ordered"`
	ExitOnEmptyItem  bool     `yaml:"exit_on_empty_item"`
}

type PairRule

type PairRule struct {
	Open          string `yaml:"open"`
	Close         string `yaml:"close"`
	SkipClose     bool   `yaml:"skip_close"`
	WrapSelection bool   `yaml:"wrap_selection"`
}

type Request

type Request struct {
	Language       string
	Source         string
	Cursor         int
	SelectionStart int
	SelectionEnd   int
	Trigger        string
}

Request represents editor state before a key-trigger is applied.

type Result

type Result struct {
	Applied bool
	Start   int
	End     int
	Text    string
	Cursor  int
}

Result describes a single editor edit and where the caret should land.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL