Syntax highlighting #
Micro no longer ships a built-in regex engine. Syntax highlighting is
provided by extensions through the micro/syntax Lua module. A file with no
provider is not an error: it opens normally with its filetype detected and no
colors.
Provider contract #
A provider registers a matcher and a request(ctx, reply) function:
local syntax = import("micro/syntax")
syntax.register {
name = "my-provider", -- required
filetype = "go", -- exact match against the buffer filetype
filename = "\\.go$", -- optional Go regexp against the full path
header = "^package ", -- optional Go regexp against line 0
signature = "^// Code generated", -- optional Go regexp for tie-breaking
priority = 10, -- higher wins; default 0
request = function(ctx, reply)
-- reply takes a flat array of line, startByte, endByte, group
reply {
0, 2, 7, "preproc",
1, 4, 9, "constant.string",
}
end,
}
syntax.unregister(name) removes a provider. syntax.invalidate(buf) asks for
fresh spans. syntax.has_color(name) reports whether the current colorscheme
defines a group or one of its dotted prefixes. syntax.providers() returns the
registered names.
Context #
ctx contains:
| field | meaning |
|---|---|
buf |
the Buffer |
id |
stable numeric id shared by split views of one buffer |
text |
the whole buffer as UTF-8, lines joined with \n |
path |
the buffer path |
filetype |
the detected or explicitly set filetype |
first, last |
inclusive line range; currently the whole buffer |
generation |
monotonic counter for stale-reply checks |
cause |
"open", "edit", "manual", or "reload" |
Spans #
A span is four values: zero-based line, zero-based byte start, exclusive byte end, and a group name. Spans must stay on one line. Convert multi-line constructs by emitting one span per line. Later spans win over earlier ones; an empty group name clears its range. Offsets are bytes, not rune or display columns, so UTF-8 and combining marks map correctly.
A reply replaces every span in the buffer. Lines the reply does not mention
are cleared. Groups are looked up by config.GetColor, which already handles
dotted prefixes such as constant.string falling back to constant.
Matching #
An explicit filetype setting wins. Otherwise micro detects the filetype from
its generated filename/header/signature table. A provider for that filetype is
chosen by priority. If the filetype is unknown, providers are matched by
filename first, then first line, with signatures breaking ties, then priority.
Detection still works with no provider registered.
Async replies #
request and reply run on the main goroutine. A provider may keep reply
and call it later, for example from micro.After or a micro/shell job
callback. Edits are debounced (~25 ms), and at most one request is in flight
per buffer. Replies for an older generation are dropped. A provider that
errors three times is disabled.