Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Luau API

What plugins and your config get from require("@greed"): the module first, then the types it hands out. Positions are 0-based byte offsets and lines are 0-based, as language servers count them.

Greed

command

command: (spec: CommandSpec) -> ()

cli

cli: (spec: CliSpec) -> ()

Adds a command line command, greed NAME ARGS; see CliSpec.

run

run: (name: string, opts: { args: { string }?, force: boolean?, count: number?, wait: boolean? }?) -> ()

Runs a command by name, optionally with arguments, force and a count. It returns once the command waits for something (a key, a prompt, a reply); with wait, a command or handler instead waits until it has finished, without blocking the editor. The command can do only what this plugin may too, unless it has “commands”.

eval

eval: (source: string, opts: { sandbox: boolean? }?) -> (boolean, string)

Runs Luau code in a scratch environment whose globals persist, like a REPL. Returns true and the values as text (tab-separated), or false and the error. The code has every capability; calling it needs eval from every plugin involved. With sandbox, it runs in a fresh environment that can read the editor and edit buffers and nothing else: what it would do beyond that (run programs or commands, change keys, reach files) fails with an error starting “needs approval:”.

on

on: ((event: "mode.changed", handler: (event: ModeChanged) -> ()) -> ())
	& ((event: "buffer.changed", handler: (event: BufferChanged) -> ()) -> ())
	& ((event: "keys.pending", handler: (event: KeysPending) -> ()) -> ())
	& ((event: "command.run", handler: (event: CommandRun) -> ()) -> ())
	& ((event: "lsp.diagnostics", handler: (event: DiagnosticsChanged) -> ()) -> ())
	& ((event: "control.request", handler: (event: ControlRequest) -> ()) -> ())
	& ((event: "control.closed", handler: (event: ControlClosed) -> ()) -> ())
	& ((event: "client.attached", handler: (event: ClientAttached) -> ()) -> ())
	& ((event: "client.detached", handler: (event: ClientDetached) -> ()) -> ())
	& ((event: "client.paste", handler: (event: ClientPaste) -> ()) -> ())
	& ((event: "buffer.opened", handler: (event: BufferChanged) -> ()) -> ())
	& ((event: "buffer.saved", handler: (event: BufferChanged) -> ()) -> ())
	& ((event: "buffer.closed", handler: (event: BufferClosed) -> ()) -> ())
	& ((event: "view.closed", handler: (event: ViewClosed) -> ()) -> ())
	& ((event: "view.resized", handler: (event: ViewResized) -> ()) -> ())
	& ((event: "pane.opened", handler: (event: PaneOpened) -> ()) -> ())
	& ((event: "view.scrolled", handler: (event: ViewScrolled) -> ()) -> ())
	& ((event: "selection.changed", handler: (event: SelectionChanged) -> ()) -> ())
	& ((event: "view.focused", handler: (event: ViewFocused) -> ()) -> ())
	& ((event: "mouse", handler: (event: MouseEvent) -> ()) -> ())
	& ((event: "option.changed", handler: (event: OptionChanged) -> ()) -> ())
	& ((event: "plugin.loaded", handler: (event: PluginLoaded) -> ()) -> ())
	& ((event: "file.changed", handler: (event: FileChanged) -> ()) -> ())
	& ((event: "plugin.unloaded", handler: (event: PluginUnloaded) -> ()) -> ())
	& ((event: "editor.started", handler: (event: {}) -> ()) -> ())
	& ((event: "editor.quitting", handler: (event: {}) -> ()) -> ())
	& ((event: "terminal.output", handler: (event: TerminalOutput) -> ()) -> ())
	& ((event: "terminal.exited", handler: (event: TerminalExited) -> ()) -> ())

Calls handler every time event happens, until greed.off removes it or the plugin unloads.

off

off: (event: EventName, handler: (event: any) -> ()) -> ()

Removes handler, added by this plugin with greed.on(event, handler). Does nothing if it’s not there.

echo

echo: (...any) -> ()

Shows a message to the user.

messages

messages: () -> { string }

The last messages shown, oldest first and whole (the status line shows a message’s first line).

view

view: () -> View

The focused view.

quit

quit: () -> ()

Asks the editor to exit.

line_numbers

line_numbers: (style: "absolute" | "relative" | "hybrid") -> ()

How line numbers count, where buffers show them: each line’s own number, “relative” to the cursor’s line (0 on it), or “hybrid”, relative with the cursor’s line showing its own.

reveal

reveal: (how: "line" | "cursor" | "never") -> ()

When text hidden by marks whose reveal is “auto” shows: “line” (on a cursor’s line, the default), “cursor” or “never”, as for a mark’s own reveal. Core sets it as the mode changes (see core.reveal).

detach

detach: () -> ()

Lets the attached terminal go and keeps the editor running in the background, for greed attach to come back to.

sleep

sleep: (ms: number) -> ()

Waits ms milliseconds without blocking the editor. Works in commands and event handlers.

spawn

spawn: (f: (...any) -> ...any, ...any) -> ()

Runs f on its own, the way a command runs, and returns at once: it can wait (greed.sleep, greed.process.run, …) while the editor and the code that started it go on. For work in the background, like a status line piece refreshing.

stalls

stalls: () -> { { ms: number, plugin: string?, what: string, time: number } }

Runs of plugin code that held the editor up (50 ms or more), newest first, for tracing a freeze to its plugin and what it was doing: a command’s name, “the status line”, “loading”. ms is how long it took; time is when, in seconds since 1970 (as os.time() counts, with a fraction).

errors

errors: () -> { { plugin: string?, what: string, message: string, traceback: string, time: number } }

Errors from plugin code that nothing caught (a command, an event handler or a task failing), newest first, up to 100: the plugin, what it ran (“on buffer.opened”, a command’s name), the message, where in its Luau it failed, and when, in seconds since 1970.

profile

profile: { start: () -> (), stop: () -> { ProfileRow }, running: () -> boolean }

Counting where the editor’s time goes: every run of plugin code (each command, event handler, status line) and the editor’s own work (handling a key, parsing, drawing), by plugin and what it did. start begins, stop ends and returns the rows, the most time first; running says whether one is being taken.

now

now: () -> number

Milliseconds on the editor’s clock, for timing animations. While a timer wakes code, it reads the time the timer was due.

hostname

hostname: () -> string?

This machine’s name, or nil if the system doesn’t say.

animate

animate: (ms: number, step: (t: number) -> ()) -> ()

Calls step(t) about once a frame for ms milliseconds, with t going from 0 to 1, e.g. to fade a theme color or move a decoration. Works in commands and event handlers.

next_key

next_key: () -> string

Waits for the next key press and returns its name, e.g. “g” or “ctrl-s”. The key doesn’t run anything. Works in commands and event handlers.

keys

keys: Keys

See Keys.

process

process: Process

See Process.

http

http: Http

See Http.

secrets

secrets: Secrets

See Secrets.

terminal

terminal: Terminals

See Terminals.

image

image: Images

See Images.

pdf

pdf: Pdfs

See Pdfs.

signal

signal: () -> Signal

A one-shot value that one piece of code waits for and another sends, e.g. a tool waiting for the user’s review. wait works in commands and event handlers; a value sent before anyone waits is kept for them.

vouch

vouch: <A..., R...>(f: (A...) -> R..., A...) -> R...

Runs f with ... as your plugin’s own action: only your capabilities count for what it does, not those of the plugins whose code called you or started what runs. For services that check what they do themselves, like the models plugin sending a key only to its provider. Anything you vouch for, any plugin can make you do: vouch only for narrow, checked operations. It can wait.

statusline

statusline: (build: (ctx: StatusContext) -> StatusParts) -> ()

Sets the function that builds the status line. It runs for every frame.

set_menus

set_menus: (menus: { { title: string, items: { { label: string, command: string } } } }) -> ()

Sets the menus a window shows as its menu bar (on macOS, the system’s), replacing those before; each item runs its command. The core plugin keeps them, so add to require("@core").menus rather than calling this.

create_buffer

create_buffer: (kind: string, text: string?, opts: { readonly: boolean?, language: string? }?) -> Buffer

A new buffer that isn’t shown anywhere yet. It goes away when the last view showing it closes.

language_of

language_of: (path: string) -> string?

The language of the file at path, by its name or extension.

filetype

filetype: (language: string, spec: { extensions: { string }?, names: { string }? }) -> ()

Makes files with these extensions (without the dot) or exact names, like “Makefile”, be in language, replacing whatever it had before.

grammars

grammars: () -> { string }

The languages Greed has a grammar for, built in or loaded, sorted.

which

which: (program: string) -> string?

Where program is on PATH, or nil if it isn’t installed.

float

float: (buffer: Buffer, spec: FloatSpec?) -> View

Shows buffer in a view floating over the main one, and focuses it.

floats

floats: (opts: { hidden: boolean? }?) -> { View }

The floating views shown, the one in front last; with hidden = true, the hidden ones too.

panel

panel: (buffer: Buffer, spec: { side: ("left" | "right")?, width: (number | string)?, title: string?, focus: boolean? }?) -> View

Shows buffer in a panel beside the main view, which gives up the room. Defaults: the left side, 30 cells wide, focused. Close it with view:close().

buffers

buffers: () -> { Buffer }

Every open buffer.

open

open: (path: string) -> ()

Opens a file in the main view.

load

load: (path: string) -> Buffer

The buffer for the file at path, opening it without showing it.

buffer_for

buffer_for: (path: string) -> Buffer?

The open buffer for the file at path, or nil when it isn’t open; it doesn’t open it. ~, . and .. are worked out and a relative path is from the folder Greed started in, so every spelling of a file finds its buffer.

diff

diff: (old: string, new: string) -> { { from: number, to: number, text: string } }

The changes that turn old into new, whole lines at a time: each replaces from..to (byte offsets into old) with text. Sorted.

commands

commands: () -> { CommandInfo }

Every command, sorted by name.

handlers

handlers: () -> { HandlerInfo }

Every event handler, by event and then the order they were added.

fuzzy

fuzzy: (query: string, items: { string }, opts: { case: ("smart" | "ignore" | "match")? }?) -> { number }

The 1-based indices of items that match query, best first. case says how it minds case: “smart” (the default: only when query has a capital letter), “ignore” or “match”; core.search.case() gives what the user chose.

fuzzy_positions

fuzzy_positions: (query: string, text: string, opts: { case: ("smart" | "ignore" | "match")? }?) -> { number }

The byte offsets of the characters in text that query matches, for highlighting them; empty if it doesn’t match. case as for fuzzy.

files

files: (dir: string?) -> { string }

Files under dir (default: the current directory), skipping hidden and ignored files.

keymap

keymap: Keymap

See Keymap.

mode

mode: Mode

See Mode.

option

option: Options

See Options.

history

history: History

See History.

clipboard

clipboard: Clipboard

See Clipboard.

base64

base64: { encode: (bytes: string) -> string, decode: (text: string) -> string? }

Base64, as data goes in JSON, like an image for a model: encode takes bytes, decode gives them back, or nil for text that isn’t base64.

client

client: Client

See Client.

lsp

lsp: Lsp

See Lsp.

fs

fs: Fs

See Fs.

hash

hash: Hash

See Hash.

control

control: Control

See Control.

json

json: Json

See Json.

project

project: Projects

See Projects.

tab

tab: Tabs

See Tabs.

session

session: Sessions

See Sessions.

plugin

plugin: Plugins

See Plugins.

syntax

syntax: Syntax

See Syntax.

theme

theme: Theme

See Theme.

Range

A range of text. anchor is where it started and head is where the cursor is; a cursor is a range where the two are equal.

anchor

anchor: number
head: number

Selection

One or more ranges, sorted and never overlapping. primary is the 1-based index of the main range.

ranges

ranges: { Range }

primary

primary: number

Edits

Collects the edits made inside Buffer:edit. They are applied together, as one undoable change, when the callback returns.

insert

insert: (self: Edits, pos: number, text: string) -> ()

delete

delete: (self: Edits, from: number, to: number) -> ()

replace

replace: (self: Edits, from: number, to: number, text: string) -> ()

select

select: (self: Edits, selection: Selection) -> ()

Sets the selection after the edit (of every view showing the buffer, when the buffer didn’t come from a view). Without this, the current selection is moved along with the text: a cursor ends up after text inserted where it is, and after the new text of a replace or delete that covers it; a range doesn’t grow to take in text inserted at its edges.

Buffer

Open text, backed by a file or not. Two handles to the same buffer are equal (==).

id

id: (self: Buffer) -> number

Its id, even after it was closed.

valid

valid: (self: Buffer) -> boolean

Whether it is still open. Other methods fail once it was closed.

len

len: (self: Buffer) -> number

Length in bytes.

text

text: (self: Buffer) -> string

slice

slice: (self: Buffer, from: number, to: number) -> string

line_count

line_count: (self: Buffer) -> number

line_of

line_of: (self: Buffer, pos: number) -> number

The line pos is on.

line_start

line_start: (self: Buffer, line: number) -> number

line_end

line_end: (self: Buffer, line: number) -> number

The end of line, before its line break.

line_text

line_text: (self: Buffer, line: number) -> string

The text of line, without its line break.

display_column

display_column: (self: Buffer, pos: number, tab_width: number?) -> number

The screen column pos is drawn at in its line: wide characters take two columns and tabs reach the next tab stop, every tab_width columns (4 if not given).

at_display_column

at_display_column: (self: Buffer, line: number, col: number, tab_width: number?) -> number

The position in line drawn at screen column col: the start of the character covering it, or the line’s end if the line is shorter.

char_at

char_at: (self: Buffer, pos: number) -> string?

The character at pos, or nil at the end of the buffer.

next_char

next_char: (self: Buffer, pos: number) -> number

prev_char

prev_char: (self: Buffer, pos: number) -> number

sentence

sentence: (self: Buffer, pos: number) -> (number, number)

The start and end of the sentence around pos, without the spaces after it. Sentences end at blank lines.

kind

kind: (self: Buffer) -> string

What the buffer is: “file”, “terminal”, …

path

path: (self: Buffer) -> string?

project

project: (self: Buffer) -> number?

The id of the project it was opened in.

readonly

readonly: (self: Buffer) -> boolean

True if only plugins can change the text: edits from keys and undo are refused.

set_readonly

set_readonly: (self: Buffer, readonly: boolean) -> ()

name

name: (self: Buffer) -> string?

The name it was given, for a buffer without a file, like a terminal’s “nu ~/src”.

set_name

set_name: (self: Buffer, name: string?) -> ()

Names it where it shows (the tab line, float titles, the status line); nil or “” leaves it unnamed.

title

title: (self: Buffer) -> string

What it’s called where it shows: its file’s name, the name it was given, “untitled” for a file not saved yet, or its kind.

line_numbers

line_numbers: (self: Buffer) -> boolean

Whether the main view shows line numbers beside it (the default).

set_line_numbers

set_line_numbers: (self: Buffer, on: boolean) -> ()

views

views: (self: Buffer) -> { View }

The views showing it.

kept

kept: (self: Buffer) -> boolean

Whether it stays open while nothing shows it, though it has no file.

set_kept

set_kept: (self: Buffer, kept: boolean) -> ()

Keeps it open while nothing shows it, like a terminal to come back to; with false it goes once nothing shows it (right away if nothing does now).

set_screen_size

set_screen_size: (self: Buffer, size: { rows: number, cols: number, note: string?, cursor_row: number? }?) -> ()

Lays the text out at rows by cols in every view, whatever room a view has, like a terminal whose program has one screen size for one client: the screen is the buffer’s last rows lines. A client whose view is another size crops it (a terminal), keeping row cursor_row (0-based, where the program’s cursor is) in sight, or scales it (a window), and shows note (default “COLSxROWS”) in the room left over. nil lays it out at each view’s own size again.

screen_size

screen_size: (self: Buffer) -> { rows: number, cols: number, note: string?, cursor_row: number? }?

The size set_screen_size set, if any.

set_keys

set_keys: (self: Buffer, keys: { [string]: string }?) -> ()

Binds single keys for this buffer alone, e.g. { y = "answer-yes" }, in every mode and ahead of every other binding, while it has focus. Replaces what was bound for it before; nil drops them.

forget_history

forget_history: (self: Buffer) -> ()

Stops keeping undo history, for buffers whose edits nobody undoes, like a terminal’s: what’s kept goes, and later edits aren’t kept.

clear_history

clear_history: (self: Buffer) -> ()

Lets go of the undo history so far and keeps later edits: undo can’t go back past now, as at a shell’s prompt after a command runs.

language

language: (self: Buffer) -> string?

The language the text is highlighted as, e.g. “rust”.

set_language

set_language: (self: Buffer, language: string?) -> ()

Sets the language, or with nil goes back to the one the file’s extension implies.

tree

tree: (self: Buffer) -> Node?

The root of the syntax tree, or nil if the language has no grammar or the buffer is too big to parse. Just after an edit, when parsing again would hold the editor up, it’s the tree before with the edit applied (nodes moved with the text) until the new one is in.

node_at

node_at: (self: Buffer, from: number, to: number?) -> Node?

The smallest named node covering from..to (default: just from).

query

query: (self: Buffer, source: string, range: { from: number?, to: number? }?) -> { { [string]: Node } }

Runs a tree-sitter query over the buffer, or only for matches overlapping from..to, e.g. "(function_item name: (identifier) @name) @fn". One table per match, from capture name to node. Errors on a query the language’s grammar can’t compile; a buffer without a grammar has no matches, so any query gives an empty list there.

edit

edit: (self: Buffer, f: (e: Edits) -> (), opts: { undo: boolean? }?) -> ()

Edits the buffer: f records edits on e, and they are applied together, as one undoable change, when it returns. With undo = false the change isn’t kept to undo, like output streaming in above where someone types: undo skips it and still takes back only what the steps before it did (redo branches are dropped).

save

save: (self: Buffer, path: string?) -> ()

Writes the buffer to its file, or to path, which becomes its file.

modified

modified: (self: Buffer) -> boolean

True if the text changed since it was opened or last saved.

version

version: (self: Buffer) -> number

A number that grows with every edit, for caches that follow the text.

reload

reload: (self: Buffer) -> boolean

Reads its file again, as an edit by “external” that undo can take back, and counts it as saved. Returns whether the text changed.

close

close: (self: Buffer) -> ()

Closes the buffer, unsaved changes and all. Errors while a view shows it: show something else there first. Plugins hear “buffer.closed”.

decorate

decorate: (self: Buffer, ns: string, marks: { Mark }, within: { from: number, to: number? }?) -> ()

Replaces the marks in namespace ns (pick one per plugin feature, e.g. “search”). Marks move with edits; {} clears them. With within, only those starting from from up to (not at) to (default: the end) are replaced, e.g. on the lines an edit changed.

decorations

decorations: (self: Buffer, ns: string) -> { Mark }

The marks in namespace ns, where they are now.

marks_at

marks_at: (self: Buffer, pos: number) -> { Mark & { ns: string } }

The marks over pos in every namespace, each with its ns: those whose range holds it, and empty ones that start there.

track

track: (self: Buffer, pos: number, opts: { gravity: ("left" | "right")? }?) -> Anchor

Follows pos through edits. Text inserted exactly there goes before it with gravity = "right" (the default) and after it with “left”. Deleting text around it moves it to where the deletion was.

track_range

track_range: (self: Buffer, from: number, to: number, opts: { from: ("left" | "right")?, to: ("left" | "right")? }?) -> Tracked

Follows from..to through edits. from and to in opts are each end’s gravity, as for track; by default text inserted at either end stays outside. It’s deleted once all of its text is.

find

find: (self: Buffer, pattern: string, from: number?, opts: { backward: boolean?, wrap: boolean? }?) -> (number?, number?, string?)

The first match of the regex pattern starting at or after from (default 0), or with backward the last one starting before it; wrap goes round the other end. Returns its start and end, nil when nothing matches, or nil, nil and the error for a bad pattern.

find_all

find_all: (self: Buffer, pattern: string, from: number?, to: number?) -> ({ { from: number, to: number } }?, string?)

Every match of the regex pattern between from and to (default: the whole buffer), or nil and the error for a bad pattern.

find_groups

find_groups: (self: Buffer, pattern: string, from: number?, to: number?) -> ({ { { from: number, to: number } | false } }?, string?)

Like find_all, but each match is the whole match’s range followed by each group’s, false for a group that took no part.

history

history: (self: Buffer, filter: HistoryFilter?) -> { HistoryEntry }

The transactions applied to it, newest first: by author (“user”, “plugin”, “agent” or “external”), plugin, cause (the command that made them, “undo”, …), group, made at or after since (seconds, like time), at most limit.

text_before

text_before: (self: Buffer, id: number) -> string?

The text as it was before transaction id, or nil if the buffer has none by that id.

undo_tree

undo_tree: (self: Buffer) -> { nodes: { UndoNode }, current: number }

The undo tree: every state the text has been in, from node 0 (as it was loaded) on, each with the step before it as parent; undo goes to the parent and redo to the last child. current is the node the text is at.

Node

A node in a buffer’s syntax tree, from buffer:tree(), buffer:node_at() or buffer:query(). It describes the buffer as it was when found; after an edit, find it again. tostring(node) shows its subtree, handy for writing queries.

kind

kind: string

The grammar’s name for it, e.g. “function_item” or “(”.

from

from: number

to

to: number

named

named: boolean

False for punctuation and keywords the grammar doesn’t name.

error

error: boolean

True for text the grammar couldn’t parse, or a missing piece it assumed.

field

field: string?

Its field name in its parent, e.g. “name” or “body”, if it has one.

parent

parent: (self: Node) -> Node?

children

children: (self: Node) -> { Node }

named_children

named_children: (self: Node) -> { Node }

Its children without the unnamed ones (punctuation, keywords).

child

child: (self: Node, field: string) -> Node?

The child in field field, e.g. fn:child("body").

next

next: (self: Node) -> Node?

The next named sibling.

prev

prev: (self: Node) -> Node?

The previous named sibling.

text

text: (self: Node) -> string

Its text. Errors if the buffer changed since the node was found.

Anchor

A position that moves with edits, from buffer:track. It goes when forgotten, when its buffer closes, or when the plugin that made it is unloaded.

pos

pos: (self: Anchor) -> number?

Where it is now, or nil once it’s gone.

forget

forget: (self: Anchor) -> ()

Stops following it.

Tracked

A range that moves with edits, from buffer:track_range. It goes as an Anchor does.

range

range: (self: Tracked) -> (number?, number?)

Where it is now, or nil once its text was deleted or it’s gone.

deleted

deleted: (self: Tracked) -> boolean

Whether all of its text was deleted, or it’s gone. Undo bringing the text back doesn’t change that.

forget

forget: (self: Tracked) -> ()

Stops following it.

MarkLine

A line a mark shows under its range: text, or pieces with styles of their own. On a float’s border (label, footer), a piece’s action is a command that a click on it runs, with any arguments after its name (“float-go 3”).

MarkLine = string | { { text: string, style: string?, action: string? } }

Mark

Text drawn with a style name, e.g. { from = 6, to = 11, style = "match" }. Text typed at either edge stays outside it.

from

from: number

to

to: number

style

style: string

line

line: boolean?

Style every whole line the mark touches, not just its text.

text

text: string?

Text to show that isn’t in the buffer, like an inlay hint, before the character at from. The cursor skips over it.

eol

eol: boolean?

Show text after the end of the line instead, cut off at the edge.

sign

sign: string?

A symbol for the sign column next to the line numbers, e.g. “E”.

gutter

gutter: string?

A style for the line number of each line the mark touches, e.g. “ui.gutter.diagnostic.error”.

above

above: boolean?

Draw over selections and cursors rather than under them.

overlay

overlay: boolean?

Draw text over the characters from from instead of inserting it, like a jump label. The text doesn’t move.

conceal

conceal: boolean?

Hide the text, showing text (if any) in its place, e.g. the brackets of a [[link]], except where reveal says.

reveal

reveal: ("line" | "cursor" | "never" | "auto")?

When concealed text shows: “line” (the default) when a cursor is on its line, “cursor” when a cursor is inside it past its start (a click leaves it hidden), “never”, or “auto” as greed.reveal last said, so the marks needn’t be drawn again when that changes.

fold

fold: boolean?

Hide the lines after the first one, up to the last, unless a cursor is in them, like a section folded under its heading.

plain

plain: boolean?

Draw the text without syntax highlighting, like a tool’s output in a Markdown buffer.

lines

lines: { MarkLine }?

Lines shown under the last line that aren’t in the buffer, like backlinks. The cursor never goes on them. Each is a string, or pieces with styles of their own on top of the mark’s, e.g. { { text = "x = " }, { text = "2", style = "diff.plus.change" } }.

image

image: { id: number, cols: number, rows: number, col: number?, row: number? }?

An image (from greed.image) drawn over cols by rows cells right of and below from, whatever text is there. col and row say which of its cells is at from, for an image cut off at the top or left. Shown in terminals that can show images.

action

action: string?

A command that clicking text runs, with the cursor put at from first, so the text works as a button, e.g. “proposal-accept”.

scale

scale: number?

How many times bigger the range’s text (and text) is, 1 to 4, e.g. 2 for a heading: each character takes that many cells across, and its row that many rows down. The window draws it big, and so does kitty (its text sizing); other terminals show it at the normal size.

data

data: any?

Anything to keep with the mark, given back where it is read: plain data (tables, strings, numbers, booleans), never drawn.

View

A buffer shown on screen, with its own selection. Two handles to the same view are equal (==).

id

id: (self: View) -> number

Its id, even after it was closed.

valid

valid: (self: View) -> boolean

Whether it is still open. Other methods fail once it was closed.

selection

selection: (self: View) -> Selection

set_selection

set_selection: (self: View, selection: Selection) -> ()

cursor

cursor: (self: View) -> number

The head of the primary selection.

set_cursor

set_cursor: (self: View, pos: number) -> ()

Makes the selection a single cursor at pos.

visible

visible: (self: View) -> (number, number)

The start and end of the text on screen when the view was last drawn, or of the whole buffer before that.

size

size: (self: View) -> (number?, number?)

The rows and columns of text it had room for when last drawn; nil before it’s drawn. “view.resized” says when they change.

area

area: (self: View) -> { x: number, y: number, width: number, height: number }?

Where it was last drawn on the screen, in cells, its gutter included; nil before it’s drawn.

hidden_lines

hidden_lines: (self: View) -> { { from: number, to: number } }

The lines folds hide, 0-based and inclusive.

scroll

scroll: (self: View) -> number

The 0-based line at the top of the view.

set_scroll

set_scroll: (self: View, line: number) -> ()

Scrolls so line is at the top. Drawing scrolls again if the primary cursor would be off screen, so move it first.

buffer

buffer: (self: View) -> Buffer

show

show: (self: View, buffer: Buffer) -> ()

Shows another buffer in this view.

focus

focus: (self: View) -> ()

Focuses this view, so keys go to it, showing its tab and project if it’s a pane or panel.

close

close: (self: View) -> boolean

Closes the view. Closing a tab’s last pane closes the tab; the project’s last pane can’t be closed, and returns false.

configure

configure: (self: View, spec: FloatSpec) -> boolean

Changes how a floating view is shown; fields left out stay as they are. False, changing nothing, if it isn’t floating; fails if it was closed.

raise

raise: (self: View) -> boolean

Brings a floating view in front of the other floats; false if it isn’t floating.

float_spec

float_spec: (self: View) -> FloatSpec?

How a floating view is shown, as greed.float takes it; nil if it isn’t floating.

is_pane

is_pane: (self: View) -> boolean

Whether it’s a pane of a tab, rather than a panel or a floating view.

split

split: (self: View, dir: "left" | "right" | "up" | "down", buffer: Buffer?) -> View

Opens a pane beside this one on its dir side, showing buffer, or this view’s buffer as it shows it, and focuses it. Fails if this view isn’t a pane.

neighbor

neighbor: (self: View, dir: "left" | "right" | "up" | "down") -> View?

The pane next to this one on its dir side, as last drawn: of several, the one active most recently.

resize

resize: (self: View, dir: "left" | "right" | "up" | "down", cells: number) -> boolean

Moves this pane’s edge on its dir side by cells (negative to shrink). False when no pane is on that side. A panel moves the edge by the main view, and only that.

undo

undo: (self: View) -> boolean

Undoes the last change. Returns false if there was nothing to undo.

undo_to

undo_to: (self: View, id: number) -> boolean

Takes the buffer to node id of its undo tree, undoing and redoing on the way, as one move; redo follows that branch from then on. False if there’s no such node or the text is there already.

redo

redo: (self: View) -> boolean

Context

What a command gets when it runs.

view

view: View

See View.

buffer

buffer: Buffer

See Buffer.

keys

keys: string?

The keys that ran the command, e.g. “g g”.

char

char: string?

The character typed, when a single printable key ran the command.

args

args: { string }

Arguments, e.g. from the command line; empty when a key ran it.

force

force: boolean

Go ahead even if the command would normally refuse, like :q! quitting with unsaved changes.

count

count: number?

The number typed before the keys, in modes with counts on.

client

client: number

The id of the client it runs for, whose view and selections these are.

ArgSpec

An argument a command takes, for completion and help.

name

name: string

doc

doc: string?

complete

complete: string?

What completes it, e.g. “file”, “command”, “option” or “buffer”.

CommandSpec

name

name: string

Plain words with dashes, e.g. “select-line”.

doc

doc: string?

args

args: { ArgSpec }?

run

run: (ctx: Context) -> ()

CliSpec

A command for the command line, run as greed NAME ARGS in an editor with no screen. run can wait like a command; what it echoes and returns is printed, and an error makes greed fail.

name

name: string

Plain words with dashes, e.g. “bring”.

doc

doc: string?

usage

usage: string?

What follows the name, e.g. “HOST [PLUGIN]”.

run

run: (args: { string }) -> string?

Layer

A keymap layer. Leave mode or kind out to match any. In place of a mode: layer names a layer that isn’t a mode, like the “leader”, which every editing style enters its own way (space, or ctrl-space without modes); role is an editing role (“command”, “typing”, “selecting”) in every style, and with style in that style only.

mode

mode: string?

layer

layer: string?

role

role: string?

style

style: string?

kind

kind: string?

Keymap

bind

bind: (layer: string | Layer, bindings: { [string]: string }) -> ()

Binds key sequences to command names, e.g. { ["g g"] = "goto-start" }. layer is a mode name or a Layer.

unbind

unbind: (layer: string | Layer, keys: { string }) -> ()

Hides what each key sequence runs in layer, e.g. { "w", "g g" }. Removing (or reloading) the plugin that unbound them brings them back.

clear

clear: (layer: string | Layer) -> ()

Hides everything bound in layer so far, to start it over. Bindings made afterwards, by any plugin, apply as usual.

counts

counts: (mode: string) -> ()

Makes digits typed before a key sequence in mode a count, which the command gets as ctx.count. A leading 0 stays a key.

isolate

isolate: (mode: string) -> ()

Makes mode use only keys bound in it (and its fallback), skipping inherited ones and those bound for every mode or for a buffer kind, e.g. for a terminal that takes every key.

inherit

inherit: (mode: string, parent: string | Layer, prefixes: { string }?) -> ()

Makes mode fall back to parent’s keys for sequences starting with one of prefixes (e.g. { "space", ":" }), or for every key without them. Keys bound in mode itself come first; what parent inherits applies in turn. parent can be a layer like { role = "typing" }.

inherit_first

inherit_first: (mode: string, parent: string | Layer) -> ()

Makes mode use parent’s keys ahead of its own, e.g. { style = "vim", role = "command" } for the Vim style’s command mode. core.style.define does this for each style’s roles.

enter

enter: (mode: string, keys: string, layer: string) -> ()

Makes keys typed in mode lead into layer, so what’s bound there works after them, e.g. enter("helix", "space", "leader"). It comes ahead of the mode’s own keys. core.style.define does this for each style’s leader.

fallback

fallback: (mode: string, command: string) -> ()

The command that handles a single unbound key in mode. A mode without one uses that of a mode it inherits every key from.

next

next: (keys: string?) -> { { key: string, command: string? } }

The keys that can follow keys (e.g. “space”) in the current mode, and the command each runs. Keys without a command start longer sequences.

find

find: (command: string?) -> { { layer: string, keys: string, command: string } }

Every key sequence that runs command (every binding, without one), the layer it’s bound in (a mode name, a named layer like “leader”, “role:typing” or “vim:command”, or “global”) and its command.

active

active: () -> { { keys: string, command: string } }

Every key sequence that runs a command in the current mode and buffer, through the layers it enters and inherits (the leader’s as “space f”), less those a more specific layer hides.

overlay

overlay: (bindings: { [string]: string }?) -> ()

Binds single keys for the next key press only, over every layer, e.g. { ["1"] = "hint-1" }; any other key drops them and does what it always does. Nil drops them now.

resolve

resolve: (keys: string) -> (string?, boolean)

What keys runs in the current mode: the command, or nil and whether more keys could still finish a sequence.

Mode

get

get: () -> string

set

set: (name: string) -> ()

Switches mode, emitting “mode.changed” if it changed.

set_cursor

set_cursor: (mode: string, shape: "block" | "bar" | "underline") -> ()

Sets how the cursor looks in mode; modes without a shape get a block.

cursor_of

cursor_of: (mode: string?) -> "block" | "bar" | "underline"

The cursor shape of mode, or of the current mode. A block or underline sits on a character, the last of a selection going forward; a bar sits between characters.

cursor

cursor: (mode: string, shape: "block" | "bar" | "underline") -> ()

The older name of set_cursor.

shape

shape: (mode: string?) -> "block" | "bar" | "underline"

The older name of cursor_of.

OptionValue

OptionValue = boolean | number | string

Options

define

define: (spec: { name: string, doc: string?, default: OptionValue, choices: { OptionValue }?, needs: string? }) -> ()

Defines an option. With choices, it takes only those values (the default among them), and :set completes them. With needs, a capability like “proc”, only code that has it, or you yourself (:set, your config), may set it: for an option whose value is run, like a command line. A plugin can’t define an option another plugin defined.

get

get: (name: string) -> OptionValue?

The option’s value for the acting client: its own, if it has one, else everyone’s.

set

set: (name: string, value: OptionValue?, opts: { client: boolean? }?) -> ()

Sets an option for every client; fails on an unknown name, the wrong type or a value that isn’t one of its choices. With client, sets a value of the acting client’s own instead, like a window’s font size, which nil takes away again; setting it for every client takes away each client’s own.

list

list: () -> { OptionInfo }

Every option, sorted by name.

OptionInfo

name

name: string

doc

doc: string

value

value: OptionValue

See OptionValue.

default

default: OptionValue

See OptionValue.

choices

choices: { OptionValue }

The values it can take; empty when any value of its type will do.

owner

owner: string

The plugin that defined it.

set_by

set_by: string?

The plugin that last set it (your config is a plugin too), if anything has.

source

source: string?

Where it was defined, e.g. “core/edit.luau:12”, and the file and line when that file is on disk.

path

path: string?

line

line: number?

HandlerInfo

An event handler, as greed.handlers() lists it.

event

event: string

owner

owner: string

The plugin that added it.

source

source: string?

path

path: string?

line

line: number?

Keys

Recording what’s typed and feeding keys back, for macros and repeating changes. Recordings have names (macros use the default, “”), so several can run at once.

record

record: (name: string?, opts: { fed: boolean? }?) -> ()

Starts keeping every key typed in the recording name, until stop; with fed, keys feed presses too.

stop

stop: (name: string?) -> { string }?

Stops the recording name and returns the keys typed, e.g. { "i", "x", "esc" }, or nil if it wasn’t recording.

recording

recording: (name: string?) -> boolean

feed

feed: (keys: string) -> ()

Presses the keys of a space-separated sequence as if they were typed. Only recordings started with fed keep them. What they run can do only what this plugin may (unless it has “commands”), and they don’t answer a command waiting for you to press a key. A command that works long enough to give the editor a turn finishes before the next key; one waiting on a timer or a job doesn’t hold them up.

HttpRequest

A request for greed.http. method defaults to POST with a body and GET without; timeout is in milliseconds, for the whole request. With save, request writes a successful (2xx) response’s body to that file as it arrives, creating its folders, and returns an empty body; the file appears only once it’s whole. Other responses come back as usual and nothing is written. Saving needs “fs.write”.

url

url: string

method

method: string?

headers

headers: { [string]: string }?

body

body: string?

timeout

timeout: number?

save

save: string?

HttpResponse

A whole response. Header names are lowercase.

status

status: number

headers

headers: { [string]: string }

body

body: string

HttpStream

A response whose body arrives in pieces. read waits for the next piece and returns it, nil at the end, or nil and why it failed; close stops reading.

status

status: number

headers

headers: { [string]: string }

read

read: (self: HttpStream) -> (string?, string?)

close

close: (self: HttpStream) -> ()

Http

Requests over the network, each on a thread of its own so the editor never waits. Both wait like greed.sleep, so they work in commands and event handlers. A plugin needs the “net” capability, or “net:HOST” for one host.

request

request: (request: HttpRequest) -> (HttpResponse?, string?)

Sends a request and returns the whole response, or nil and why.

stream

stream: (request: HttpRequest) -> (HttpStream?, string?)

Sends a request and returns once the status and headers are in; read the body as it arrives, e.g. tokens from a model.

Secrets

Secrets like API keys, kept out of config and plugin source: from the environment (GREED_SECRET_NAME, or the usual variable, e.g. ANTHROPIC_API_KEY), the system keyring, or Greed’s own secrets file. Both wait like greed.sleep. A plugin needs “secrets:NAME” for each secret it reads, or “secrets” for all.

get

get: (name: string) -> (string?, string?)

The secret name, or nil if it isn’t set anywhere.

set

set: (name: string, value: string) -> (string?, string?)

Keeps value as the secret name: in the keyring if there is one, otherwise in Greed’s secrets file. Returns where it went, or nil and why not.

variable

variable: (name: string) -> string

The environment variable that sets the secret name, to tell someone: the usual one, like ANTHROPIC_API_KEY, or GREED_SECRET_NAME. Reads nothing, so it needs no capability.

Process

Running other programs.

run

run: (
	command: { string },
	opts: { stdin: string?, cwd: string? }?
) -> ({ code: number?, stdout: string, stderr: string }?, string?)

Runs command (the program, then its arguments), with stdin as its input and cwd as its folder, and returns how it exited and what it printed; nil and the error if it couldn’t start. It runs in the background and waits like greed.sleep, so only in commands, event handlers and greed.spawn.

spawn

spawn: (command: { string }, opts: { cwd: string?, env: { [string]: string | false }?, stderr: ("keep" | "stream")?, group: boolean? }?) -> (Child?, string?)

Starts command to talk to over its input and output, like an agent speaking JSON-RPC, and returns at once; nil and the error if it couldn’t start. It runs until it exits, is killed, or the plugin that started it unloads. In env, false leaves a variable out of what it inherits. With stderr = "stream", what it prints as errors arrives from read too, in the order it comes; by default it’s only kept for child:stderr(). With group, it starts a process group of its own, which kill and signal reach, so the programs it starts end with it.

Child

A program started with greed.process.spawn.

pid

pid: number

write

write: (self: Child, text: string) -> boolean

Sends text to its input; false once that’s closed.

read

read: (self: Child) -> (string?, ("stdout" | "stderr")?)

Waits for the next piece of what it prints, and returns it with the output it came from, “stdout” or “stderr” (only with stderr = "stream"); nil once it exited and everything was read. Only in commands, event handlers and greed.spawn.

close

close: (self: Child) -> ()

Closes its input, which tells most programs to finish.

kill

kill: (self: Child) -> ()

Ends it (and with group, its process group) with KILL.

signal

signal: (self: Child, name: string) -> boolean

Sends it a signal by name, like “INT”, “TERM”, “HUP” or “QUIT”; with group, to its process group, even after it exited, as a shell signals a job. Returns whether it went.

wait

wait: (self: Child) -> (number?, string?)

Waits for it to exit and returns its exit code, or nil and the name of the signal that ended it, like “INT”.

stderr

stderr: (self: Child) -> string

The end of what it printed as errors so far.

TerminalRow

A line of a terminal: its text, and the parts with a style of their own (byte offsets, 0-based, to exclusive), styled with inline names like “=fg:red bold”.

text

text: string

spans

spans: { { from: number, to: number, style: string } }

images

images: { { from: number, id: number, col: number, row: number, cols: number, rows: number } }

Images on the row, as runs of cells from byte from: from the image’s cell (col, row) on, of an image cols by rows cells. id is a greed.image id, for a mark’s image.

links: { TerminalLink }

Links the program printed (OSC 8), as byte ranges and where they go.

wrapped

wrapped: boolean

Whether the line carries on on the next row: the program printed past the last column and the terminal wrapped it.

TerminalModes

The modes a terminal’s program set, from terminal:modes().

alternate

alternate: boolean

A full screen program, like an editor or a pager, is showing.

canonical

canonical: boolean

Input goes to the program a line at a time; off in raw mode, which editors and prompts set.

echo

echo: boolean

Typed text is echoed; off while a program reads a password.

mouse

mouse: boolean

The program asked for mouse events.

app_cursor

app_cursor: boolean

Arrow keys are sent in application mode.

bracketed_paste

bracketed_paste: boolean

Pastes are marked as pastes.

TerminalLink = { from: number, to: number, uri: string }

TerminalScreen

What a terminal shows.

rows

rows: { TerminalRow }

cursor

cursor: { row: number, col: number }?

The cursor’s row (0-based) and byte offset in it, unless the program hid it.

alternate

alternate: boolean

Whether a full screen program, like an editor or a pager, is showing.

Terminal

A program running in a terminal. Two handles to the same terminal are equal (==).

id

id: (self: Terminal) -> number

Its id, even after it was closed.

valid

valid: (self: Terminal) -> boolean

Whether it is still open. Other methods fail once it was closed.

screen

screen: (self: Terminal) -> TerminalScreen

scrollback

scrollback: (self: Terminal, from: number?) -> { first: number, rows: { TerminalRow } }

The lines that scrolled off the top, from line from (counting from the terminal’s first line) on, or from the oldest one kept. first is the number of the first line returned.

marks

marks: (self: Terminal, from: number?) -> { TerminalMark }

The places the shell marked (OSC 133) on line from (counting as scrollback does) and after, oldest first: where a prompt starts, where the typed command starts, where its output starts, and where it was done, with its exit code if the shell said. col is a byte in the line’s text.

marks_made

marks_made: (self: Terminal) -> number

How many marks the shell has made so far, to tell when there are new ones without asking for them all.

cwd

cwd: (self: Terminal) -> string?

The folder the shell last said it’s in (OSC 7), or the one it started in.

write

write: (self: Terminal, text: string) -> ()

Sends text to the program as if typed. This and the other methods that send input need “proc”: the plugin that started the terminal has it through the handle it got; others with one from an event need their own.

key

key: (self: Terminal, name: string) -> ()

Sends a key, e.g. “ctrl-c” or “up”, as a terminal encodes it.

paste

paste: (self: Terminal, text: string) -> ()

Sends pasted text, marked as a paste if the program asked for that.

resize

resize: (self: Terminal, rows: number, cols: number) -> ()

Changes its size, kept to between 1 by 1 and 1024 rows by 2048 columns.

wants_mouse

wants_mouse: (self: Terminal) -> boolean

Whether the program asked for mouse events, as editors and htop do.

modes

modes: (self: Terminal) -> TerminalModes

The modes the program set: the alternate screen, line input and echo (from the terminal’s settings), mouse, application cursor keys and bracketed paste.

mouse

mouse: (self: Terminal, kind: string, col: number, row: number, which: string?, mods: { ctrl: boolean?, alt: boolean?, shift: boolean? }?) -> boolean

Sends a mouse event at the program’s screen cell (col, row), 0-based, if it asked for that kind: kind as in a MouseEvent, with a button or a scroll direction. Returns whether it was sent.

title

title: (self: Terminal) -> string?

What the program called its window, if it did.

program

program: (self: Terminal) -> string

The name of the program it started, like “nu” or “cargo”: its file name, or the shell’s for a terminal started without a command.

exit_code

exit_code: (self: Terminal) -> number?

The program’s exit code, once it has ended.

busy

busy: (self: Terminal) -> boolean

Whether a program other than the one it started is in the foreground, like a command its shell runs. False once it has ended.

kill

kill: (self: Terminal) -> ()

Asks the program to end.

close

close: (self: Terminal) -> ()

Ends the program and lets the terminal go; its handle stops working.

Terminals

Programs in terminals. A terminal belongs to the plugin that started it.

spawn

spawn: (spec: { command: { string }?, cwd: string?, env: { [string]: string | false }?, rows: number, cols: number, scrollback: number? }) -> Terminal

Starts command (the program, then its arguments; the user’s shell without) in a terminal of rows by cols. Its output arrives as “terminal.output” events and its end as “terminal.exited”. scrollback lines are kept above the screen (default 10000). The size is kept to between 1 by 1 and 1024 rows by 2048 columns. In env, false leaves a variable out of what the program inherits.

TerminalMark

A place a shell marked in a terminal, from terminal:marks().

line

line: number

col

col: number

kind

kind: "prompt" | "command" | "output" | "done"

code

code: number?

The exit code, for “done”, if the shell said.

TerminalOutput

A terminal printed something; read it with terminal:screen().

terminal

terminal: Terminal

See Terminal.

TerminalExited

The program in a terminal ended.

terminal

terminal: Terminal

See Terminal.

code

code: number

UndoNode

A state of a buffer’s text in its undo tree, from buffer:undo_tree().

id

id: number

0 is the text as loaded; later states have higher ids.

parent

parent: number?

children

children: { number }

Oldest first; redo follows the last.

time

time: number?

When the step was last added to, in seconds like os.time(); nil for node 0.

HistoryEntry

A transaction applied to a buffer, from buffer:history().

id

id: number

author

author: "user" | "plugin" | "agent" | "external"

plugin

plugin: string?

The plugin, for edits a plugin made.

cause

cause: string?

Why: the command it was made for, “undo”, “redo”, …

group

group: number?

The undo group it was made in.

time

time: number

When, in seconds since 1970.

changes

changes: { { from: number, to: number, text: string } }

What it replaced, in the text before it, in order.

HistoryFilter

author

author: string?

plugin

plugin: string?

cause

cause: string?

group

group: number?

since

since: number?

limit

limit: number?

History

start_group

start_group: () -> ()

Edits until end_group become one undo step.

end_group

end_group: () -> ()

new_group

new_group: () -> number

A group id nothing has used yet, for set_group.

group

group: () -> number?

The group edits go into now, if any.

set_group

set_group: (group: number?) -> ()

Puts the edits that follow, in every buffer, into group (one used before carries on), or with nil into none. Edits in a group undo as one step.

cause

cause: () -> string?

Why edits are being made: by default the command running.

set_cause

set_cause: (cause: string?) -> ()

Sets why the edits that follow are made, for the rest of this command.

undo_group

undo_group: (group: number) -> (number?, string?)

Undoes group in every buffer it changed, as one step. Returns how many buffers changed (0 if it was undone already), or nil and why not, when something was done on top of it since.

FloatSpec

How a floating view looks. Sizes are cells, or a share of the screen as a string like “60%” or “37.5%”, which keeps the float in proportion on clients with screens of other sizes; both default to “60%”.

title

title: string?

width

width: (number | string)?

height

height: (number | string)?

anchor

anchor: ("center" | "top" | "bottom" | "left" | "right" | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "cursor" | "above-cursor")?

Where it goes when x or y is left out: in the middle, at an edge or in a corner. “cursor” opens it just below the cursor (or above, near the bottom), like a completion menu; “above-cursor” prefers above, like signature help.

focus

focus: boolean?

Whether the view takes focus. Defaults to true.

x

x: (number | string)?

Where the outside of the border goes, from the screen’s left and top edges, in cells or like “37.5%”. Left out, the float goes where anchor says on that axis. It’s always kept on screen.

y

y: (number | string)?

tab

tab: boolean?

Whether it belongs to the tab it opens in: shown only with that tab, and closed with it, like a floating terminal. Otherwise it floats over every tab, like a picker. Defaults to false.

shared

shared: boolean?

Whether every client is shown it, like a review meant for everyone. Otherwise only the client it opened for is (the one acting then), as with a picker or a prompt, unless it belongs to a tab, which every client showing the tab sees. Defaults to false.

label

label: MarkLine?

Text at the right end of the top border, e.g. “‹ 2/5 ›”, or pieces with styles of their own. “” takes it off.

See MarkLine.

footer: MarkLine?

Text in the middle of the bottom border, as label takes it.

See MarkLine.

border

border: boolean?

Whether it has a border; defaults to true. Without one its text fills its whole box, like a one-line strip.

hidden

hidden: boolean?

Hides it: its view and buffer stay (a terminal keeps running), but it isn’t drawn, greed.floats() leaves it out and focus moves on. Focusing it shows it again.

CommandInfo

name

name: string

doc

doc: string

args

args: { ArgSpec }

owner

owner: string

The plugin that defined it.

source

source: string?

Where it was defined, e.g. “core/motions.luau:120”.

path

path: string?

The file and line it was defined on, when that file is on disk.

line

line: number?

BufferClosed

A buffer was closed. Only its id is left.

id

id: number

BufferChanged

buffer

buffer: Buffer

See Buffer.

from_line

from_line: number?

On “buffer.changed”: the first and last line (0-based, as the text is now) of what changed since the last “buffer.changed” for the buffer.

to_line

to_line: number?

ControlRequest

A request from the session socket, e.g. from greed ctl or an agent. Answer it with greed.control.reply.

id

id: number

client

client: string

“socket” for the session socket (greed ctl, greed mcp), “ide” for Claude Code’s IDE connection.

connection

connection: number?

The session socket connection it came on, for greed.control.send; nil for Claude Code’s IDE connection.

method

method: string

params

params: any

ControlClosed

A session socket connection closed, after its last request came.

connection

connection: number

The connection, as ControlRequest.connection gave it.

Signal

wait

wait: (self: Signal) -> any

Waits until a value is sent, and returns it.

send

send: (self: Signal, value: any) -> ()

Sends value to whoever waits. Only the first send counts.

ProjectInfo

A project: a folder with its own main view and panels.

id

id: number

root

root: string

current

current: boolean

Whether it’s the one shown.

Projects

list

list: () -> { ProjectInfo }

Every open project, in the order they were opened.

current

current: () -> ProjectInfo

open

open: (root: string) -> number

Opens a project rooted at root, with an empty main view, and shows it. Returns its id.

switch

switch: (id: number) -> boolean

Shows project id. False if there is none.

close

close: (id: number) -> boolean

Closes project id with its views and the buffers opened in it. The last project can’t be closed; false then.

Images

Images for marks to show. Each is kept until forgotten.

load

load: (path: string) -> (number?, string?)

Reads a PNG, JPEG or GIF file. Returns the image’s id, or nil and why not.

decode

decode: (bytes: string) -> (number?, string?)

The same, from the file’s bytes.

size

size: (id: number) -> (number?, number?)

Its width and height in pixels.

cells

cells: (id: number) -> (number?, number?)

How many cells it covers at its own size on the attached screen.

cell_size

cell_size: () -> (number, number)

A cell’s width and height in pixels on the attached screen.

forget

forget: (id: number) -> ()

Pdfs

PDF documents.

open

open: (path: string) -> (PdfDocument?, string?)

Reads the PDF at path. Returns the document, or nil and why not. It waits like greed.sleep, so only in commands, event handlers and greed.spawn.

PdfDocument

A PDF read with greed.pdf.open. Pages count from 1.

pages

pages: number

size

size: (self: PdfDocument, page: number) -> (number?, number?)

A page’s width and height in points (1/72 inch).

render

render: (self: PdfDocument, page: number, scale: number?) -> (number?, string?)

Draws a page at scale pixels per point (1 if not given) and returns it as a greed.image id, or nil and why not. Forget the image when done with it. Waits like greed.sleep.

text

text: (self: PdfDocument, page: number) -> (string?, string?)

The text on a page, line by line from the top, or nil and why not. Waits like greed.sleep.

TabInfo

A tab of the shown project: panes laid out side by side and one above another.

id

id: number

name

name: string?

The name it was given, if any.

current

current: boolean

Whether it’s the one shown.

zoomed

zoomed: boolean

Whether only its active pane is shown.

panes

panes: { View }

Its panes, left to right and top to bottom.

active

active: View

The pane keys go to while it’s shown.

See View.

Tabs

list

list: () -> { TabInfo }

The shown project’s tabs, in order.

current

current: () -> TabInfo

new

new: (buffer: Buffer?) -> number

Opens a tab after the shown one, with a pane showing buffer (or an empty buffer), and shows it. Returns its id.

switch

switch: (id: number) -> boolean

Shows tab id, of whichever project, and its project. False if there’s no such tab.

close

close: (id: number) -> boolean

Closes tab id and its panes. The last tab can’t be closed; false then.

rename

rename: (id: number, name: string?) -> boolean

Names tab id; nil or “” names it after what it shows again.

set_zoomed

set_zoomed: (zoomed: boolean) -> ()

Shows only the active pane of the shown tab, or all of them again.

layout

layout: (id: number?) -> any

How tab id (the shown one by default) lays out its panes, as a PaneLayout, with sizes adding up to 1 in each split.

set_layout

set_layout: (layout: any, id: number?) -> ()

Lays tab id’s panes out as layout (a PaneLayout) instead. It arranges the panes the tab has, so it has to hold each of them once; opening and closing panes is view:split and view:close. A split of one pane is that pane; splits nest at most 64 deep.

PaneLayout

A tab’s panes: a pane is its view, a split lays out its children side by side (“row”) or one above another (“column”), sharing the room by sizes, which are relative to each other (equal when left out).

PaneLayout = View | { split: "row" | "column", children: { PaneLayout }, sizes: { number }? }

PaneOpened

A pane was opened, beside from.

view

view: View

See View.

from

from: View

See View.

SessionInfo

A session running on this machine: an editor process of its own.

name

name: string

root

root: string?

The project it was started for.

current

current: boolean

Whether it’s this session.

Sessions

list

list: () -> { SessionInfo }

The sessions running on this machine, by name.

current

current: () -> string?

This session’s name, when the editor runs as one.

remote

remote: () -> boolean

Whether the attached client (or the last one) came over greed ssh; before any attached, whether greed ssh started the session.

attached

attached: () -> boolean

Whether a terminal or window is attached to the session.

program

program: () -> string?

Where the greed program running this editor is, to start greed mcp or greed ctl for this session.

switch

switch: (to: { name: string?, path: string?, new: boolean?, host: string? }) -> ()

Sends the attached client to the session name, or to the session for the project path is in (opening it there), starting it if it isn’t running. This session goes on without the client. With new, a new session for path’s project, even when one is running for it. With host, the session is on that machine, reached as greed ssh does.

Json

JSON. Tables with keys 1..n become arrays, other tables objects; an empty table is an object unless it came from array.

encode

encode: (value: any) -> string

value as JSON. Text that isn’t UTF-8, like a program’s binary output, has its broken bytes written as U+FFFD.

decode

decode: (text: string) -> (any, string?)

The value, or nil and why the text isn’t JSON. null becomes nil.

array

array: <T>(items: { T }?) -> { T }

Marks items (or a new table) to encode as an array even when empty.

Control

Needs the “control” capability (and serve_ide “net” too).

reply

reply: (id: number, result: any, message: string?) -> ()

Answers request id with result, or with an error message. Every request needs exactly one answer.

send

send: (connection: number?, method: string, params: any) -> boolean

Sends a notification of method with params to the session socket connection a request came on (its connection), e.g. MCP’s “notifications/tools/list_changed”. False if that connection has closed.

serve_ide

serve_ide: (folders: { string }, lock_dir: string?) -> number

Lets Claude Code find this editor with /ide: listens on a localhost WebSocket and writes a lock file naming folders as open, in lock_dir (default ~/.claude/ide). Its requests come with client “ide”. Returns the port; calling it again replaces the connection.

notify

notify: (method: string, params: any) -> ()

Sends a notification, e.g. “selection_changed”, to Claude Code.

ProfileRow

One row of greed.profile.stop(): what a plugin (nil for the editor itself) spent doing one thing, in all and at most once, in milliseconds.

ProfileRow = { plugin: string?, what: string, ms: number, longest: number, runs: number }

ClientAttached

A client attached, e.g. greed FILE in a session that was running. Handlers run as that client.

client

client: number

The client’s id.

path

path: string?

The file or folder it asked to open, if any.

terminal

terminal: boolean

Whether it asked for a terminal, e.g. greed ssh HOST --terminal.

remote

remote: boolean

Whether it came over greed ssh.

ClientDetached

A client went; the session goes on. Handlers run as that client, just before it’s gone.

client

client: number

ClientPaste

Text pasted into the client from the system clipboard: a terminal’s paste, or a window’s paste keys (ctrl-shift-v, shift-insert, cmd-v). The core plugin puts it at the cursors.

client

client: number

The client it was pasted into, which handlers run as.

text

text: string

ViewClosed

A view was closed. Its handle no longer works, but its id can be compared with view:id().

view

view: number

MouseEvent

What the mouse did, and what was under it.

client

client: number

The client whose mouse it was, which handlers run as.

kind

kind: "press" | "release" | "drag" | "move" | "scroll"

button

button: ("left" | "middle" | "right")?

For a press, release or drag.

dir

dir: ("up" | "down" | "left" | "right")?

For a scroll.

col

col: number

The screen cell, from the top left.

row

row: number

ctrl

ctrl: boolean

alt

alt: boolean

shift

shift: boolean

view

view: View?

The view under it, if any.

See View.

pos

pos: number?

The place in the view’s buffer under it: the character there, or the end of the line past it. Over a mark’s text, where the mark starts.

action

action: string?

The action of the mark whose text it’s over, or of the status line segment (with no view), if that has one.

x

x: number?

The cell in the view’s text, from its top left, right of the gutter.

y

y: number?

tab

tab: number?

The tab whose name it’s over, in the tab line.

border

border: ("top" | "bottom" | "left" | "right" | "top-left" | "top-right" | "bottom-left" | "bottom-right")?

On a floating view’s border (with view set), which part: “top” (the title’s), “bottom”, “left”, “right”, or a corner like “bottom-right”.

edge

edge: ("left" | "right" | "down")?

On the line between a pane or panel (view) and its neighbor, the side of view it’s on: “right” or “down” for panes, the side by the main view for panels. Dragging it resizes view with resize.

ViewResized

A view was drawn for a client with room for a different number of rows or columns of text than before. Handlers run as that client.

client

client: number

view

view: View

See View.

rows

rows: number

cols

cols: number

ViewScrolled

A view was drawn for a client starting at a different line than before. What a handler changes shows in the same frame, so a view can scroll another along with it. Handlers run as that client.

client

client: number

view

view: View

See View.

line

line: number

The 0-based line now at the top.

SelectionChanged

A view’s selection changed for a client, or it shows another buffer, since the last frame: told once a frame however many changes there were, whatever made them (keys, the mouse, undo, a plugin or an agent). Handlers run as that client.

client

client: number

view

view: View

See View.

ViewFocused

Another view has a client’s focus. from had it before; nil when it was closed. Handlers run as that client.

client

client: number

view

view: View

See View.

from

from: View?

See View.

moved

moved: boolean

The focus was moved under the client rather than by it: what it had focused went out of sight by another client’s doing (another tab or project shown, a pane closed), or it followed the others again. Its half-typed keys were dropped.

OptionChanged

An option was set, with greed.option.set or :set.

name

name: string

value

value: OptionValue

Its value now, as the client it was set for has it.

See OptionValue.

client

client: number?

The client it was set for, when one got a value of its own.

FileChanged

A file watched with greed.fs.watch was written, created or removed.

path

path: string

PluginLoaded

A plugin was loaded (or reloaded) and its entry file ran.

name

name: string

dir

dir: string?

Its folder, for plugins loaded from one.

PluginUnloaded

A plugin was unloaded, and everything it registered removed.

name

name: string

CommandRun

client

client: number

The client it runs for, which handlers run as.

name

name: string

The command about to run.

keys

keys: string?

The keys that ran it, when keys did, e.g. “g g”.

count

count: number?

The number typed before the keys.

KeysPending

client

client: number

The client typing them, which handlers run as.

keys

keys: string

The unfinished key sequence, e.g. “space”; “” once it’s finished.

StatusSegment

A piece of the status line: plain text, or text with a style.

text

text: string

style

style: string?

A style name, e.g. “ui.statusline.mode”, drawn over “ui.statusline”.

action

action: string?

A command a click on it runs.

StatusContext

What a status line function gets, for the main view.

view

view: View

See View.

buffer

buffer: Buffer

See Buffer.

mode

mode: string

message

message: string?

The latest message or error, if there is one to show.

width

width: number

The width of the screen in cells.

StatusParts

Segments for each side. The space between is padded; if the line is too long, the last segment on the left keeps only its end.

left

left: { StatusSegment }?
right: { StatusSegment }?

Clipboard

Copied text. Each copy holds one piece per selection it came from, so pasting into the same number of selections puts each piece back.

set

set: (pieces: string | { string }) -> ()

get

get: () -> { string }?

The latest copy.

history

history: () -> { { string } }

Recent copies, newest first.

image

image: () -> string?

The image on the system clipboard of the client acting now, as PNG bytes, read on that client’s own machine (so with greed ssh, your laptop’s); nil when there’s none or the client can’t read it. Waits like greed.sleep.

ClientInfo

A client attached to the editor: a terminal or window, on this machine or over greed ssh.

id

id: number

name

name: string

Its kind and machine, like “tui@laptop”; a client coming back with the same name gets its cursors, focus and mode back.

kind

kind: string

“tui”, “gui”, “headless” (the editor’s own, with nothing attached) or “test”.

remote

remote: boolean

Whether it came over greed ssh.

size

size: { width: number, height: number }?

Its screen in cells, once it has said.

layout

layout: "follow" | "independent"

“follow”: it shows the project, tab and panes the other followers do, with its own focus and zoom. “independent”: a layout of its own.

color

color: number

Which of the peer colors (1 to 6) its cursors show in for the other clients, as ui.cursor.peer.N.

person

person: string

Who it belongs to: “owner”, the session’s owner, for now.

Client

The clients you see the editor through. Commands, keys and event handlers act for one client at a time: the one that typed, clicked or ran them, or the one an event is about.

current

current: () -> ClientInfo

The client the running code acts for.

id

id: () -> number

The id of the client the running code acts for: current().id, without building the rest. For keeping what each client has open apart, like a picker of its own.

list

list: () -> { ClientInfo }

Every client, in the order they attached.

notify

notify: (title: string, body: string?) -> ()

Sends a notification to your desktop through the acting client: a terminal shows it with its notification escape (OSC 9, or OSC 777 in foot and urxvt) and a bell, while it isn’t focused. Without a client attached it goes nowhere.

set_layout

set_layout: (layout: "follow" | "independent", client: number?) -> boolean

Lays a client (the acting one by default) out on its own, “independent”, starting from a copy of the tabs, panes and panels it had, with views of its own; or has it “follow” the others again, closing those views (their buffers stay). Returns whether it changed.

Diagnostic

A problem a language server found.

from

from: number

to

to: number

severity

severity: number

1 error, 2 warning, 3 information, 4 hint.

message

message: string

source

source: string?

LspError

The error a language server answered a request with.

code

code: number

message

message: string

data

data: any?

LspPosition

A position as language servers count it.

line

line: number

character

character: number

Lsp

Language servers. A server runs per language and project root, started the first time a file that needs it is open, and started again if it stops.

server

server: (spec: { language: string, command: { string }?, commands: { { string } }?, root_markers: { string }? }) -> ()

Sets the server for a language, e.g. { language = "rust", command = { "rust-analyzer" }, root_markers = { "Cargo.toml" } }. With commands, the first one whose program is installed runs, when a file of the language first opens; with none installed, nothing does. A server runs in the topmost folder with one of root_markers inside the file’s project, or the project’s root without one.

remove

remove: (language: string) -> ()

Stops starting a server for a language; one running keeps running.

restart

restart: (language: string?) -> number

Stops the servers running for language (every language without one) and starts them again, as after they got stuck. Returns how many were running. Needs “proc”.

servers

servers: () -> { [string]: { { string } } }

The commands set for each language’s server, by language.

running

running: () -> { LspServer }

The servers running now, by language and then root.

root

root: (buffer: Buffer) -> string?

The folder the buffer’s server runs in, or would: nil without a file or a server set for its language.

request

request: (buffer: Buffer, method: string, params: any) -> (any, LspError?)

Sends a request to the buffer’s server and waits for the answer. Returns the result, or nil and the error; a server that stops before answering gives the error “the language server stopped”. Works in commands and event handlers. “workspace/executeCommand” needs “proc”, since a server’s commands can do anything.

uri

uri: (buffer: Buffer) -> string

The buffer’s file as a URI, for request parameters.

path

path: (uri: string) -> string?

The file path in a file:// URI.

position

position: (buffer: Buffer, pos: number) -> LspPosition

Byte offset pos as the buffer’s server counts positions.

offset

offset: (buffer: Buffer, position: LspPosition) -> number

The byte offset of a server position.

diagnostics

diagnostics: (buffer: Buffer) -> { Diagnostic }

The buffer’s latest diagnostics, where they are now: they move with edits. They are marks in the buffer’s “diagnostics” namespace, with { severity, message, source } as their data.

problems

problems: () -> { LspProblem }

Every file’s latest problems, including files that aren’t open, with ranges as the server counts positions. Those in open files are where they are now.

capabilities

capabilities: (buffer: Buffer) -> any

What the buffer’s server said it can do (its ServerCapabilities), or nil without a running server.

on_request

on_request: (method: string, handler: (params: any) -> any) -> ()

Answers requests of method from servers, e.g. “workspace/applyEdit”, with what handler returns. It can wait, e.g. to ask you; the server gets the answer when it returns.

on_notification

on_notification: (method: string, handler: (params: any, language: string, root: string) -> ()) -> ()

Hears notifications of method from servers that the editor doesn’t deal with itself, e.g. “$/progress”, with the language and root of the server that sent it.

LspServer

A language server that’s running.

language

language: string

root

root: string

The folder it runs in.

command

command: { string }

ready

ready: boolean

Whether it has answered initialize.

stderr

stderr: { string }

The last lines it wrote to stderr.

LspProblem

uri

uri: string

range

range: { start: LspPosition, ["end"]: LspPosition }

severity

severity: number

message

message: string

source

source: string?

DiagnosticsChanged

buffer

buffer: Buffer

See Buffer.

ModeChanged

A client’s mode changed. Handlers run as that client.

client

client: number

from

from: string

to

to: string

DirEntry

name

name: string

dir

dir: boolean

FileInfo

kind

kind: "file" | "dir" | "other"

size

size: number

Size in bytes; 0 for a directory.

mode

mode: number

Its permission bits, like 420 (644 in octal, as string.format("%o", mode) shows).

modified

modified: number?

When it last changed, in seconds since 1970, where the system says.

Hash

SHA-256 digests as lowercase hex, for checking a download or telling whether some text changed.

sha256

sha256: (data: string) -> string

The digest of data.

sha256_file

sha256_file: (path: string) -> (string?, string?)

The digest of the file at path, read in pieces, or nil and why. Needs “fs.read”.

Fs

Reading and writing the file system. Failures return nil and a message.

list

list: (dir: string, opts: { hidden: boolean?, ignored: boolean? }?) -> ({ DirEntry }?, string?)

The entries directly in dir, folders first, then by name. Hidden entries and ones .gitignore excludes are left out unless asked for.

read

read: (path: string, limit: number?) -> (string?, string?)

The file’s text, or its first limit bytes.

read_bytes

read_bytes: (path: string) -> (string?, string?)

The file’s bytes as they are, for a file that isn’t text, like an image.

stat

stat: (path: string) -> (FileInfo?, string?)

What’s at path; nil if nothing is, and nil and why when it can’t tell, as when a folder above it can’t be read.

write

write: (path: string, text: string, opts: { private: boolean? }?) -> (boolean?, string?)

Replaces the file’s contents with text, creating it and its folders if needed. It’s written whole or not at all. With private, only you can read it (mode 0600), and folders made for it are only yours.

mkdir

mkdir: (path: string) -> (boolean?, string?)

Makes the folder at path and any missing folders above it. Needs “fs.write”.

remove

remove: (path: string, opts: { recursive: boolean? }?) -> (boolean?, string?)

Removes the file, link or empty folder at path; with recursive, a folder and everything in it. Nothing being there counts as removed. It refuses (an error) the root, your home folder, a path with .. and a folder holding Greed’s approvals or secrets. Needs “fs.write”.

rename

rename: (from: string, to: string) -> (boolean?, string?)

Moves or renames from to to, replacing a file there. It refuses what remove does. Needs “fs.write”.

copy

copy: (from: string, to: string) -> (boolean?, string?)

Copies the file from to to, creating its folders. Needs “fs.read” and “fs.write”.

watch

watch: (path: string) -> ()

Watches the file at path: whenever it changes, from inside the editor or out, plugins hear “file.changed”. It needn’t exist yet.

cwd

cwd: () -> string

The directory Greed was started in.

dirs

dirs: () -> { home: string?, config: string?, cache: string?, data: string?, brought: string? }

Your home folder, Greed’s config folder (where init.luau and plugins/ were read from), its cache folder, its data folder (where plugins made in the editor go when the config can’t be written) and, on the far end of greed ssh, the copy of your config it brought.

grep

grep: (
	pattern: string,
	dir: string?,
	opts: { hidden: boolean?, ignored: boolean?, limit: number? }?
) -> ({ GrepLine }?, string?)

The lines matching the regex pattern in the text files under dir (default: the current directory), sorted by path and line. It searches in the background and waits like greed.sleep (commands, handlers, greed.spawn). Hidden and ignored files are skipped unless asked for; limit (default 10000) caps the lines returned. A bad pattern gives nil and why.

GrepLine

A line greed.fs.grep found.

path

path: string

Relative to the directory searched.

line

line: number

0-based.

text

text: string

The line, without its line break.

matches

matches: { { from: number, to: number } }

Byte offsets of the matches in text.

PluginCheck

What greed.plugin.check found. types.skipped says why types weren’t checked; tests.error why the tests couldn’t run.

types

types: { ok: boolean?, output: string?, skipped: string? }

tests

tests: { passed: number?, failed: { { file: string, name: string, message: string } }?, error: string? }

warnings

warnings: { string }

What looks wrong once it’s loaded with the others: a command it replaces from another plugin, keys bound to commands that don’t exist.

Plugins

list

list: () -> { string }

The names of the loaded plugins, sorted.

unload

unload: (name: string) -> ()

Removes a plugin and everything it registered: commands, keys, options and event handlers. Fails while another loaded plugin requires it. To turn off a default plugin, call this from your config.

load

load: (dir: string, name: string?) -> string

Loads (or reloads) the plugin in dir and returns its name. With name, a folder without a plugin.toml loads too, with init.luau as its entry.

dirs

dirs: () -> { [string]: string }

The folder of each plugin loaded from one, by name.

check

check: (dir: string) -> PluginCheck

Checks the plugin in dir without loading it: strict types against Greed’s API (if luau-analyze is installed), then its tests with the loaded plugins. Waits, like greed.sleep, while it runs. A plugin that needs approving is tested with only what you approved for it, so what needs more fails with “needs approval”, through the plugins it calls and the commands it runs too.

describe

describe: (dir: string) -> PluginInfo

What the plugin in dir is and asks for, from its plugin.toml.

pending

pending: () -> { PluginInfo }

The plugins waiting until what they use is approved.

approve

approve: (dir: string) -> string

Approves what the plugin in dir declares, loads it, and loads the plugins that waited for it. Returns its name. Fails when a plugin without “plugins” started what runs: approving is yours to do.

caller

caller: () -> string?

The plugin whose code called yours: the innermost other plugin on the stack, or the one whose command, handler or task is running; nil if none but yours.

started_within

started_within: (capability: string) -> boolean

Whether everything that started the code running now may use capability: you (keys, the command line, your config), or plugins that have it. A vouch doesn’t hide what started it. For actions only you should take, like accepting a review.

within

within: <A..., R...>(name: string?, f: (A...) -> R..., A...) -> R...

Runs f with ... within the limit of the plugin name too, as if it had started it: for running what a plugin registered (a formatter, a runner, a source) later, from your plugin, so it can do no more than its plugin may. Config and unknown names add nothing. It can wait.

tie

tie: (remove: () -> ()) -> string?

For registries: runs remove when the plugin whose code called yours (see caller) is unloaded or reloaded, so what it added goes with it. Returns that plugin’s name, or nil (and does nothing) if none but yours called.

PluginInfo

A plugin, as greed.plugin.describe tells it, for a review.

name

name: string

dir

dir: string

requires

requires: { string }

capabilities

capabilities: { { name: string, what: string } }

What it declares, each with what it lets the plugin do in words.

missing

missing: { string }

The capabilities not approved yet; empty when it may load.

Style

How text looks. Colors are “red”, “bright-blue” and the other 16 terminal colors, “default”, or “#rrggbb”. Fields left out leave whatever is underneath, so styles layer.

fg

fg: string?

bg

bg: string?

underline

underline: (boolean | string)?

true, or “line”, “curl”, “dotted”, “dashed” or “double”.

underline_color

underline_color: string?

bold

bold: boolean?

italic

italic: boolean?

dim

dim: boolean?

reverse

reverse: boolean?

strikethrough

strikethrough: boolean?

rounded

rounded: boolean?

For floats in the window (ui.float, in its gui part): rounded corners and an outline instead of box lines, and a soft shadow.

shadow

shadow: boolean?

badge

badge: boolean?

For text in the window: its background as a badge, a box with rounded corners a little inside its cells, as motion hints have.

checkbox

checkbox: ("empty" | "checked" | "choice" | "chosen")?

In the window, drawn as a control over the cells of its text: a checkbox (“empty” or “checked”, for todos) or a choice (“choice” or “chosen”). Terminals show the text.

font

font: ("mono" | "prose")?

The window’s font for the text: “mono”, the grid’s (gui-font), or “prose”, a proportional one (gui-font-prose) fitted into the same cells. Terminals have only the one.

ThemeEntry

A theme entry: a style for every client, with changes for the terminal (tui) or a graphical client (gui).

tui

tui: Style?

See Style.

gui

gui: Style?

See Style.

Syntax

The tree-sitter queries each language uses: “highlights” for highlighting, “injections” for languages inside others (code blocks in Markdown), and others (“textobjects”, …) that plugins read. The languages plugin sets them from the queries/<language>/<kind>.scm files in plugins and your config.

set_query

set_query: (language: string, kind: string, source: string?) -> ()

Sets the kind query for language, or with nil takes this plugin’s away. Errors if the language’s grammar can’t compile it. The newest one set is used, and unloading a plugin takes its queries away.

query

query: (language: string, kind: string) -> string?

The kind query in use for language: the one set, or for “highlights” and “injections” the one that comes with the grammar.

load_grammar

load_grammar: (language: string, path: string, symbol: string?) -> ()

Loads the grammar for language from a WebAssembly file, like one built with tree-sitter build --wasm, so buffers in it get a syntax tree. symbol is the grammar’s own name when it differs, e.g. “c_sharp” for “c-sharp”; by default the language with “-” as “_”. Queries come separately. Needs “fs.read”.

tags

tags: (dir: string?, opts: { limit: number? }?) -> { FileTags }

What the source files under dir (default: the current directory) define and use, from their syntax trees: the functions and types their “textobjects” query finds and how often each name appears, sorted by path. Hidden and ignored files are skipped; limit (default 10000) caps the files. It parses in the background and waits like greed.sleep. Needs “fs.read”.

FileTags

What one file defines and uses, from greed.syntax.tags.

path

path: string

Relative to the directory searched.

language

language: string

definitions

definitions: { { name: string, kind: "function" | "type", line: number, signature: string } }

Each with its 0-based line and its first line as signature.

references

references: { [string]: number }

How often each name appears in the file.

Theme

What style names look like. Everything on screen has one: “ui.text”, “ui.selection”, “ui.statusline.mode”, “ui.float.border”, “keyword”, “diagnostic.error”, or a name a plugin made up. Names fall back to their parent, so “markup.heading.1” uses “markup.heading” if it has no entry.

set

set: (entries: { [string]: ThemeEntry }) -> ()

Sets entries by name. Each changes only the fields it gives of the theme’s entry underneath, and replaces what was set for that name before.

base

base: (entries: { [string]: ThemeEntry }) -> ()

Replaces the base theme, the entries under those set with set: a theme plugin calls it to switch themes without touching what your config or other plugins set.

get

get: (name: string) -> ThemeEntry?

The entry for exactly name, if there is one.

EventName

The events greed.on and greed.off take; any other name is an error.

EventName =