Documentation
¶
Overview ¶
Package emacs contains infrastructure to write dynamic modules for Emacs in Go. See Emacs Dynamic Modules and Writing Dynamically-Loaded Modules for background on Emacs modules.
To build an Emacs module, you have to build your Go code as a shared C library, e.g., using go build ‑buildmode=c‑shared. If you import the emacs package, the shared library is loadable as an Emacs module.
This package contains high-level as well as lower-level functions. The high-level functions help reducing boilerplate when exporting functions to Emacs and calling Emacs functions from Go. The lower-level functions are more type-safe, support more exotic use cases, and have less overhead.
Export and Import ¶
At the highest level, use the Export function to export Go functions to Emacs, and the Import function to import Emacs functions so that they can be called from Go. These functions automatically convert between Go and Emacs types as necessary. This export functionality is unrelated to exported Go names or the Cgo export functionality. Functions exported to Emacs don’t have to be exported in the Go or Cgo sense.
The automatic type conversion behaves as follows. Go bool values are become the Emacs symbols nil and t. When converting to Go bool, only nil becomes false, any other value becomes true. This matches the Emacs convention that all non-nil values represent a logically true value. Go integral values become Emacs integer values and vice versa. Go floating-point values become Emacs floating-point values and vice versa. Go strings become Emacs strings and vice versa. Go []byte arrays and slices become Emacs unibyte strings. Emacs unibyte strings become Go []byte slices. Other Go arrays and slices become Emacs vectors. Emacs vectors become Go slices. Go maps become Emacs hash tables and vice versa. All types that implement In can be converted to Emacs. All types that implement Out can be converted from Emacs. You can implement In or Out yourself to extend the type conversion machinery. A reflect.Value behaves like its underlying value.
Functions exported via Export don’t have a documentation string by default. To add one, pass a Doc value to Export. Since argument names aren’t available at runtime, the documentation by default lacks argument names. Use Usage to add argument names.
As an alternative to Import, you can call functions directly using Env.Invoke. Env.Invoke uses the same autoconversion rules as Import, but allows you to specify an arbitrary function value.
At a slightly lower level, you can use Env.Call and Env.CallOut to call Emacs functions. These functions use the In and Out interfaces to convert from and to Emacs values. The primary disadvantage of this approach is that you can’t use primitive types like int or string directly. Use wrapper types like Int and String instead. On the other hand, Env.Call and Env.CallOut are more type-safe than [Invoke]. If you use [Call] or [CallOut], the compiler will detect unsupported types. By contrast, when using Export, Import, or [Invoke], they will only be detected at runtime and cause runtime panics or errors.
To reduce boilerplate when using Env.Call and Env.CallOut, this package contains several convenience types that implement In or Out. Most primitive types have corresponding wrapper types, such as Int, Float, or String. Types such as List, Cons, or Hash allow you to pass common Lisp structures without much boilerplate. There are also some destructuring types such as ListOut or Uncons.
At an even lower level, you can use ExportFunc, ImportFunc, and Env.Funcall as alternatives to Export, Import, and Env.Call, respectively. They have the same behavior, but don’t do any type conversion at all.
Env and Value ¶
The fundamental types for interacting with Emacs are Env and Value. They represent Emacs module environments and values as described in Writing Module Functions. These types are opaque, and their zero values are invalid. You can’t use Env and Value values once they are no longer live. This is described in Writing Module Functions and Conversion Between Lisp and Module Values. As a best practice, don’t let these values escape exported functions. You also can’t interact with Emacs from other threads, cf. Writing Module Functions. These rules are a bit subtle, but you are usually on the safe side if you don’t store Env and Value values in struct fields or global variables, and don’t pass them to other goroutines.
Error handling ¶
All functions in this package translate between Go errors and Emacs nonlocal exits. See Nonlocal Exits in Modules. This package represents Emacs nonlocal exits as ordinary Go errors.
Each call to a function fetches and clears nonlocal exit information after the actual call and converts it to an error of type Signal or Throw. This means that the Go bindings don’t exhibit the saturating error behavior described at Nonlocal Exits in Modules. Instead, they behave like normal Go functions: an erroneous return doesn’t affect future function calls.
When returning from an exported function, this package converts errors back to Emacs nonlocal exits. If you return a Signal or Error, Emacs will raise a signal using the signal function. If you return a Throw, Emacs will throw to a catch using the throw function. If you return any other type of error, Emacs will signal an error of type go‑error, with the error string as signal data.
You can define your own error symbols using DefineError. There are also a couple of factory functions for builtin errors such as WrongTypeArgument and OverflowError.
Variables ¶
You can use Var to define a dynamic variable.
User pointers and handles ¶
This package intentionally doesn’t support wrapping pointers to arbitrary Go values in Emacs user pointer objects. Attempting to do that wouldn’t work well with Go’s garbage collection and CGo’s pointer-passing rules; see Passing pointers. Instead, prefer using handles, e.g. simple integers as map keys. See the “Handles” example.
Long-running operations ¶
A long-running operation should periodically call Env.ProcessInput to process pending input and to check whether the user wants to quit the operation. If so, you should cancel the operation as soon as possible. See the documentation of Env.ProcessInput for a concrete example.
As an alternative, this package provides limited support for asynchronous operations. Such operations are represented using the AsyncHandle type. You can use the Async type to create and manage asynchronous operations. Async requires a way to notify Emacs about a pending asynchronous result; this package supports notification using pipes or sockets.
Initialization ¶
If you want to run code while Emacs is loading the module, use OnInit to register initialization functions. Loading the module will call all initialization functions in order.
ERT tests ¶
You can use ERTTest to define ERT tests backed by Go functions. This works similar to Export, but defines ERT tests instead of functions.
Example (Handles) ¶
package main import ( "errors" "fmt" "math" "os" "sync" ) func main() { Export(createGoFile, Doc(`Create a file with the given NAME and return a handle to it.`), Usage("NAME")) Export(closeGoFile, Doc(`Close the file with the given HANDLE. HANDLE must be opened using ‘create-go-file’.`), Usage("HANDLE")) Export(writeGoFile, Doc(`Write CONTENTS to the file with the given HANDLE. Return the number of bytes written. HANDLE must be opened using ‘create-go-file’. CONTENTS must be a unibyte string.`), Usage("HANDLE CONTENTS")) } type fileHandle Uint func createGoFile(name string) (fileHandle, error) { fd, err := os.Create(name) if err != nil { return 0, err } h, err := registerFile(fd) if err != nil { fd.Close() return 0, err } return h, nil } func closeGoFile(h fileHandle) error { fd := popFile(h) if fd == nil { return fmt.Errorf("close-go-file: invalid file handle %d", h) } return fd.Close() } func writeGoFile(h fileHandle, b []byte) (int, error) { fd := getFile(h) if fd == nil { return 0, fmt.Errorf("write-go-file: invalid file handle %d", h) } return fd.Write(b) } var ( fileMu sync.Mutex files = make(map[fileHandle]*os.File) nextFile fileHandle ) func registerFile(fd *os.File) (fileHandle, error) { fileMu.Lock() defer fileMu.Unlock() h := nextFile if h == math.MaxUint64 { fd.Close() return 0, errors.New("too many files") } nextFile++ files[h] = fd return h, nil } func getFile(h fileHandle) *os.File { fileMu.Lock() defer fileMu.Unlock() return files[h] } func popFile(h fileHandle) *os.File { fileMu.Lock() defer fileMu.Unlock() fd := files[h] delete(files, h) return fd } func init() { Example_handles() }
Output:
Index ¶
- func AutoFunc(fun interface{}, opts ...Option) (Name, Func, Arity, Doc)
- func ERTTest(fun ERTTestFunc, opts ...Option)
- func Export(fun interface{}, opts ...Option)
- func ExportFunc(name Name, fun Func, arity Arity, doc Doc)
- func Import(name Name, fp interface{})
- func MajorVersion() int
- func NotifyListener(listener net.Listener) chan<- struct{}
- func NotifyWriter(w io.Writer) chan<- struct{}
- func OnInit(i InitFunc)
- func OverflowError(val string) error
- func Provide(feature Name)
- func WrongTypeArgument(pred Symbol, arg In) error
- type Anonymous
- type Arity
- type Async
- type AsyncData
- type AsyncHandle
- type BigInt
- type Binding
- type Bool
- type Bytes
- type Car
- type Cdr
- type Cons
- type CustomHasher
- type DeleteFunc
- type Doc
- type Duration
- type ERTTestFunc
- type Env
- func (e Env) BigInt(v Value, z *big.Int) error
- func (e Env) Bytes(v Value) ([]byte, error)
- func (e Env) Call(fun Name, in ...In) (Value, error)
- func (e Env) CallOut(fun Name, out Out, in ...In) error
- func (e Env) Car(list In) (Value, error)
- func (e Env) CarOut(list In, car Out) error
- func (e Env) Cdr(list In) (Value, error)
- func (e Env) CdrOut(list In, cdr Out) error
- func (e Env) Cons(car, cdr In) (Value, error)
- func (e Env) Defalias(name Name, def Value) error
- func (e Env) DefineError(name Name, message string, parents ...ErrorSymbol) (ErrorSymbol, error)
- func (e Env) Defvar(name Name, init In, doc Doc) error
- func (e Env) Dolist(list Value, f func(Value) error) error
- func (e Env) Duration(v Value) (time.Duration, error)
- func (e Env) ERTDeftest(name Name, fun Func, doc Doc) error
- func (e Env) ERTTest(fun ERTTestFunc, opts ...Option) error
- func (e Env) Emacs(v interface{}) (Value, error)
- func (e Env) Eq(a, b Value) bool
- func (e Env) Eval(form In) (Value, error)
- func (e Env) Export(fun interface{}, opts ...Option) (Value, error)
- func (e Env) ExportFunc(name Name, fun Func, arity Arity, doc Doc) (Value, error)
- func (e Env) Float(v Value) (float64, error)
- func (e Env) FormatMessage(format string, args ...In) string
- func (e Env) Funcall(fun Value, args []Value) (Value, error)
- func (e Env) Gethash(key In, table Value) (value Value, ok bool, err error)
- func (e Env) GethashDef(key In, table Value, def Value) (Value, error)
- func (e Env) Go(v Value, p interface{}) error
- func (e Env) Int(v Value) (int64, error)
- func (e Env) Intern(s Symbol) (Value, error)
- func (e Env) Invoke(fun interface{}, out interface{}, in ...interface{}) error
- func (e Env) IsNil(v Value) bool
- func (e Env) IsNotNil(v Value) bool
- func (e Env) IsOverflowError(err error) bool
- func (e Env) IsWrongTypeArgument(err error) bool
- func (e Env) Iter(list Value, elem Out, err *error) *Iter
- func (e Env) Lambda(fun interface{}, opts ...Option) (Value, DeleteFunc, error)
- func (e Env) LambdaFunc(fun Func, arity Arity, doc Doc) (Value, DeleteFunc, error)
- func (e Env) Length(seq Value) (int, error)
- func (e Env) Let(variable Name, value In, body func() (Value, error)) (Value, error)
- func (e Env) LetMany(bindings []Binding, body func() (Value, error)) (Value, error)
- func (e Env) List(os ...In) (Value, error)
- func (e Env) MakeHash(test HashTest, sizeHint int) (Value, error)
- func (e Env) MakeInteractive(fun, spec Value) error
- func (e Env) MakeVector(n int, init In) (Value, error)
- func (e Env) Maphash(fun func(key, val Value) error, table Value) error
- func (e Env) MaybeIntern(nameOrValue interface{}) (Value, error)
- func (e Env) Message(err error) string
- func (e Env) Nil() (Value, error)
- func (e Env) OpenPipe(process Value) (*os.File, error)
- func (e Env) ProcessInput() error
- func (e Env) Puthash(key, value In, table Value) error
- func (e Env) ShouldQuit() booldeprecated
- func (e Env) Str(v Value) (string, error)
- func (e Env) Symbol(v Value) (Symbol, error)
- func (e Env) Time(v Value) (time.Time, error)
- func (e Env) Uint(v Value) (uint64, error)
- func (e Env) Uncons(cons Value) (car Value, cdr Value, err error)
- func (e Env) UnconsOut(cons Value, car, cdr Out) error
- func (e Env) Var(name Name, init In, doc Doc) error
- func (e Env) VecGet(vector Value, i int) (Value, error)
- func (e Env) VecGetOut(vector Value, i int, elem Out) error
- func (e Env) VecSet(v Value, i int, elem Value) error
- func (e Env) VecSetIn(v Value, i int, elem In) error
- func (e Env) VecSize(v Value) (int, error)
- type Error
- type ErrorSymbol
- type Float
- type Func
- type Hash
- type HashOut
- type HashTest
- type Ignore
- type In
- type InFunc
- type InitFunc
- type Int
- type Iter
- type Lambda
- type List
- type ListOut
- type Manager
- type ManagerFlag
- type Name
- type Option
- type Out
- type OutFunc
- type QueuedItem
- type Reflect
- type Result
- type Signal
- type String
- type Symbol
- type Throw
- type Time
- type Uint
- type Uncons
- type UnpackList
- type UnpackVector
- type Usage
- type Value
- type Vector
- type VectorOut
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AutoFunc ¶
AutoFunc converts an arbitrary Go function to a Func. When calling the exported function from Emacs, arguments and return values are converted as described in the package documentation.
The function may accept any number of arguments. Optionally, the first argument may be of type Env. In this case, Emacs passes a live environment value that you can use to interact with Emacs. All other arguments are converted from Emacs as described in the package documentation. If not all arguments are convertible from Emacs values, AutoFunc panics.
The function must return either zero, one, or two results. If the last or only result is of type error, a non-nil value causes Emacs to trigger a non-local exit as appropriate. There may be at most one non-error result. Its value will be converted to an Emacs value as described in the package documentation. If the type of the non-error result can’t be converted to an Emacs value, AutoFunc panics. If there are invalid result patterns, AutoFunc panics.
By default, AutoFunc derives the function’s name from its Go name by Lisp-casing it. For example, MyFunc becomes my-func. To specify a different name, pass a Name option. To make the function anonymous, pass an Anonymous option. If there’s no name and the function isn’t anonymous, AutoFunc panics.
By default, the function has no documentation string. To add one, pass a Doc option.
You can call AutoFunc safely from multiple goroutines.
func ERTTest ¶
func ERTTest(fun ERTTestFunc, opts ...Option)
ERTTest arranges for a Go function to be exported as an ERT test. Call ERTTest in an init function. Loading the dynamic module will then define the ERT test. If you want to define ERT tests after the module has been initialized, use the Env.ERTTest method instead. If the function returns an error, the ERT test fails.
By default, ERTTest derives the test’s name from the function’s Go name by Lisp-casing it. For example, MyTest becomes my-test. To specify a different name, pass a Name option. If there’s no name or the name is already registered, ERTTest panics.
By default, the ERT test has no documentation string. To add one, pass a Doc option.
You can call ERTTest safely from multiple goroutines.
Example ¶
package main import "log" func main() { ERTTest(exampleERTTest, Name("example-ert-test"), Doc("Run an example ERT test.")) } // Once Emacs has successfully loaded the module, ERT will see a test named // example-ert-test that calls exampleERTTest. func exampleERTTest(e Env) error { log.Print("running example test") return nil } func init() { // We would normally call ExampleERTTest here, but the test runner // already calls it for us. }
Output:
func Export ¶
func Export(fun interface{}, opts ...Option)
Export arranges for a Go function to be exported to Emacs. Call Export in an init function. Loading the dynamic module will then define the Emacs function. The function fun can be any Go function. When calling the exported function from Emacs, arguments and return values are converted as described in the package documentation. If you don’t want this autoconversion or need more control, use ExportFunc instead and convert arguments yourself. If you want to export functions to Emacs after the module has been initialized, use the Env.Export method instead.
The function may accept any number of arguments. Optionally, the first argument may be of type Env. In this case, Emacs passes a live environment value that you can use to interact with Emacs. All other arguments are converted from Emacs as described in the package documentation. If not all arguments are convertible from Emacs values, Export panics.
The function must return either zero, one, or two results. If the last or only result is of type error, a non-nil value causes Emacs to trigger a nonlocal exit as appropriate. There may be at most one non-error result. Its value will be converted to an Emacs value as described in the package documentation. If the type of the non-error result can’t be converted to an Emacs value, Export panics. If there are invalid result patterns, Export panics.
By default, Export derives the function’s name from its Go name by Lisp-casing it. For example, MyFunc becomes my-func. To specify a different name, pass a Name option. If there’s no name or the name is already registered, Export panics.
By default, the function has no documentation string. To add one, pass a Doc option.
You can call Export safely from multiple goroutines.
Example ¶
package main import ( "fmt" "strings" ) func main() { Export(goUppercase, Doc("Concatenate STRINGS and return the uppercase version of the result.").WithUsage("strings")) // Export panics when encountering an invalid type. defer func() { fmt.Println("panic:", recover()) }() Export(func(chan int) {}, Name("invalid-function")) } // Once Emacs has successfully loaded the module, Emacs Lisp code can call // exampleFunc under the name go-uppercase. For example, (go-uppercase "hi") // will return "HI". func goUppercase(s ...string) string { return strings.ToUpper(strings.Join(s, " ")) } func init() { // We would normally call ExampleExport here, but the test runner // already calls it for us. }
Output: panic: function invalid-function: don’t know how to convert argument 0: Wrong type argument: go-known-type-p, "chan int"
func ExportFunc ¶
ExportFunc arranges for a Go function to be exported to Emacs. Call ExportFunc in an init function. Loading the dynamic module will then define the Emacs function. Unlike Export, functions registered by ExportFunc don’t automatically convert their arguments and return values to and from Emacs. If name is empty, ExportFunc panics. If doc is empty, the function won’t have a documentation string. If you want to export functions to Emacs after the module has been initialized, use the Env.ExportFunc method instead.
You can call ExportFunc safely from multiple goroutines.
func Import ¶
func Import(name Name, fp interface{})
Import imports an Emacs function as a Go function. name must be the Emacs symbol name of the function. fp must be a pointer to a variable of function type. Import sets *fp to a function that calls the Emacs function name.
Import must be called before Emacs loads the module. Typically you should call Import from an init function.
The dynamic type of *fp must have one of the following two forms:
func(Env, Args...) (Ret, error) func(Env, Args...) error
Here Args is a (possibly empty) list of argument types, and Ret is the return type. If the function type has any other form, Import panics.
Calling the Go function converts all arguments to Emacs, calls the Emacs function name, and potentially converts the return value back to the Ret type. If any of the involved types can’t be represented as Emacs value, Import panics.
If you don’t want argument autoconversion, use ImportFunc instead.
You can call Import safely from multiple goroutines, provided that setting *fp is race-free.
Example ¶
package main import ( "fmt" "time" ) func main() { Import("format-time-string", &formatTimeString) Export(goPrintNow) // Import panics when encountering nonconvertible types. defer func() { fmt.Println("panic:", recover()) }() Import("format-time-string", &invalidType) } var ( formatTimeString func(Env, string, time.Time, bool) (string, error) // Can’t convert channel types to Emacs. invalidType func(Env, chan int) error ) func goPrintNow(e Env, format string) (string, error) { // Functions that have access to a live environment can now call the // Emacs message function, like so: r, err := formatTimeString(e, format, time.Now(), true) if err != nil { return "", err } _, err = fmt.Println("Time from Emacs:", r) return r, err } func init() { // We would normally call ExampleExport here, but the test runner // already calls it for us. }
Output: panic: can’t import format-time-string: don’t know how to convert argument 1: Wrong type argument: go-known-type-p, "chan int"
func MajorVersion ¶
func MajorVersion() int
MajorVersion returns the major version of the Emacs instance in which the module is loaded. It can only be called after the module has been loaded. Module functions and functions registered by OnInit can call MajorVersion if they have been called from Emacs. MajorVersion panics if the module isn’t yet initialized.
func NotifyListener ¶
NotifyListener returns a channel that causes some arbitrary content to be sent to the client of the given listener whenever something is written to the channel. NotifyListener will wait (in the background) for exactly one client to connect to the server and then close the listener. You can create the listener using net.Listen or similar. A common use case is a Unix domain socket server; the socket name should be reported to Emacs Lisp using other means. The return value of this function is useful as argument to NewAsync.
func NotifyWriter ¶
NotifyWriter returns a channel that causes some arbitrary content to be written to the given writer whenever something is written to the channel. The writer will typically be either a pipe created by Env.OpenPipe or a socket connection to a Unix domain socket created by net.Dial or similar. The return value of this function is useful as argument to NewAsync.
func OnInit ¶
func OnInit(i InitFunc)
OnInit arranges for the given function to run while Emacs is loading the module. Initialization functions registered with OnInit will be called in sequence, in the same order in which they’ve been registered. You need to call OnInit before loading the module for the initializer to run. Typically, you should call OnInit in an init function. You can call OnInit safely from multiple goroutines.
Example ¶
package main import "fmt" func main() { OnInit(func(e Env) error { _, err := fmt.Println("Hi from Go!") return err }) } func init() { ExampleOnInit() }
Output:
func OverflowError ¶
OverflowError returns an error that will cause Emacs to signal an error of type overflow‑error. Use this if you notice that an integer doesn’t fit into its target type. val is the string representation of the overflowing value. val is a string instead of an In to avoid further overflows when converting it to an Emacs value.
func Provide ¶
func Provide(feature Name)
Provide arranges for (provide feature) to be called on module initialization.
func WrongTypeArgument ¶
WrongTypeArgument returns an error that will cause Emacs to signal an error of type wrong‑type‑argument. Use this if some argument has an unexpected type. pred should be a predicate-like symbol such as natnump. arg is the argument whose type is invalid.
Types ¶
type Anonymous ¶
type Anonymous struct{}
Anonymous is an Option that tells AutoFunc and friends that the new function should be anonymous. Anonymous is mutually exclusive with Name; if both are given, AutoFunc panics.
type Arity ¶
type Arity struct{ Min, Max int }
Arity contains how many arguments an Emacs function accepts. Min must be nonnegative. Max must either be negative (indicating a variadic function) or at least Min.
type Async ¶
type Async struct {
// contains filtered or unexported fields
}
Async manages asynchronous operations. Create a new Async object using NewAsync; the zero Async isn’t valid, and Async objects may not be copied once created. An asynchronous operation can use Async.Start to allocate an operation handle and a channel. It can then start an operation in the background and report its result asynchronously using the channel.
Async requires a way to notify Emacs about pending asynchronous results; use NotifyWriter or NotifyListener to create notification channels. When notified about asynchronous operations, Emacs should then use Async.Flush to return the pending results.
Async doesn’t prescribe any specific programming model on the Emacs side; the example uses the “aio” package.
Example ¶
package main import ( "errors" "log" "net" "os" "path/filepath" "sync" ) func main() { Export(mersennePrimeAsyncP, Doc("Return a promise that resolves to a Boolean value indicating whether 2^N − 1 is probably prime."), Usage("N")) Export(asyncSocket, Doc("Return a filename of a socket to connect to")) Export(asyncFlush, Doc("Return a vector of asynchronous promise results")) } func mersennePrimeAsyncP(n uint16) AsyncHandle { h, ch := async.Start() boolCh := make(chan bool) go testMersennePrime(n, boolCh) go wrapBool(ch, boolCh) return h } func wrapBool(ch chan<- Result, boolCh <-chan bool) { ch <- Result{Bool(<-boolCh), nil} } var ( asyncOnce sync.Once async *Async socket string ) func asyncSocket() (string, error) { asyncOnce.Do(initAsync) if socket == "" { return "", errors.New("error initializing asynchronous socket") } return socket, nil } func asyncFlush() []AsyncData { return async.Flush() } func initAsync() { dir, err := os.MkdirTemp("", "emacs-") if err != nil { panic(err) } sock := filepath.Join(dir, "socket") listener, err := net.Listen("unix", sock) if err != nil { panic(err) } log.Printf("Created socket %s for asynchronous communication", sock) async = NewAsync(NotifyListener(listener)) socket = sock } func init() { ExampleAsync() }
Output:
func NewAsync ¶
func NewAsync(notifyCh chan<- struct{}) *Async
NewAsync creates a new Async object. It will use the given notification channel to signal completion of an asynchronous operation to Emacs; use NotifyWriter or NotifyListener to create usable channels.
func (*Async) Flush ¶
Flush returns and removes all pending asynchronous operation results. You should call this method from Emacs Lisp when notified about pending asynchronous results.
func (*Async) Start ¶
func (a *Async) Start() (AsyncHandle, chan<- Result)
Start starts a new asynchronous operation. It returns a handle for the operation and a channel. Return the operation handle to Emacs so that it can associate pending operations with e.g. a promise structure. The operation can then use the channel to write exactly one result (error or value); any further writes or closes are ignored and will block. The typical usage pattern is:
func operation() AsyncHandle { h, ch := async.Start() go performOperation(ch) return h }
Here, performOperation should write the result to the channel once available.
type AsyncData ¶
type AsyncData struct { Handle AsyncHandle Result }
AsyncData contains the result of an asynchronous operation, together with the associated operation handle. It is returned by Async.Flush.
type AsyncHandle ¶
type AsyncHandle uint64
AsyncHandle is an opaque reference to a pending asynchronous operation. Use Async.Start to create AsyncHandle objects.
type BigInt ¶
BigInt is a type with underlying type big.Int that knows how to convert itself to and from an Emacs value.
func (*BigInt) Emacs ¶
Emacs creates an Emacs value representing the given integer. It returns an error if the integer value is too big for Emacs.
type Bool ¶
type Bool bool
Bool is a type with underlying type bool that knows how to convert itself to and from an Emacs value.
func (Bool) Emacs ¶
Emacs returns t if v is true and nil if it’s false. It can only fail if interning nil or t fails.
type Bytes ¶
type Bytes []byte
Bytes is a type with underlying type []byte that knows how to convert itself to an Emacs unibyte string.
type CustomHasher ¶
type CustomHasher interface { // Hash returns a hash code for the given value. Hash(Env, Value) (int64, error) // Equal returns whether the given values are considered equal // according to this hash test. Equal(Env, Value, Value) (bool, error) }
CustomHasher defines the hashing and equality functions for a custom hash test. Use RegisterHashTest to register such a custom hash test. The hashing and equality functions must be compatible, i. e., if Equal(e, a, b) is true, then Hash(e, a) = Hash(e, b) must be fulfilled.
type DeleteFunc ¶
type DeleteFunc func()
DeleteFunc is a function returned by Env.Lambda and Env.LambdaFunc. Call this function to delete the created function. After deletion the function can’t be called any more from Emacs.
type Doc ¶
type Doc string
Doc contains a documentation string for a function or variable. An empty doc string becomes nil. As described in Documentation Strings of Functions, a documentation string can contain usage information. Use Doc.SplitUsage to extract the usage information from a documentation string. Use Doc.WithUsage to add usage information to a documentation string. Documentation strings must be valid UTF-8 strings without embedded null bytes. You can use a Doc as an Option in Export and ERTTest to set the function or test documentation string.
func (Doc) SplitUsage ¶
SplitUsage splits d into the actual docstring and the usage information. hasUsage specifies whether a usage information is present. Absence of usage information is not the same as an empty usage.
type Duration ¶
Duration is a type with underlying type time.Duration that knows how to convert itself from and to an Emacs time value.
func (Duration) Emacs ¶
Emacs returns an Emacs timestamp as a pair (ticks . hz) or a quadruple (high low μs ps) in the same format as the Emacs function current-time.
func (*Duration) FromEmacs ¶
FromEmacs sets *d to the Go equivalent of the Emacs time value in v, interpreted as a duration. v can be any time value: nil (for the current time), a number of seconds, a pair (ticks . hz), a pair (high low), a triple (high low μs), or a quadruple (high low μs ps). The picosecond value is truncated to nanosecond precision. If the Emacs time value would overflow a Go duration, FromEmacs returns an error.
func (Duration) String ¶
String formats the duration as a string. It calls time.Duration.String.
type ERTTestFunc ¶
ERTTestFunc is a function that implements an ERT test. Use ERTTest to register ERTTestFunc functions. If the function returns an error, the ERT test fails.
type Env ¶
type Env struct {
// contains filtered or unexported fields
}
Env represents an Emacs module environment. The zero Env is not valid. Exported functions and module initializers will receive a valid Env value. That Env value only remains valid (or “live”) while the exported function or module initializer is active. Env values are only valid in the same goroutine as the exported function or module initializer. So don’t store them or pass them to other goroutines. See https://www.gnu.org/software/emacs/manual/html_node/elisp/Module-Functions.html for details.
func (Env) BigInt ¶
BigInt sets z to the integer stored in v. It returns an error if v is not an integer.
func (Env) Bytes ¶
Bytes returns the unibyte string stored in v. It returns an error if v is not a unibyte string.
func (Env) Call ¶
Call calls the Emacs named fun with the given arguments.
Example ¶
// Assumes that env is a valid Env value. _, err := env.Call("message", String("It is %s"), Time(time.Now())) if err != nil { panic(err) }
Output:
func (Env) CallOut ¶
CallOut calls a the Emacs function named fun with the given arguments and assigns the result to out.
Example ¶
// Assumes that env is a valid Env value. var now Time err := env.CallOut("current-time", &now) if err != nil { panic(err) }
Output:
func (Env) DefineError ¶
func (e Env) DefineError(name Name, message string, parents ...ErrorSymbol) (ErrorSymbol, error)
DefineError is like the global DefineError function, except that it requires a live environment, defines the error symbol immediately, and returns errors instead of panicking.
func (Env) Dolist ¶
Dolist calls f for each element in list. It returns an error if list is not a list. If f returns an error, the loop terminates and Dolist returns the same error. If list is a circular list, Dolist may loop forever.
Example ¶
// Assumes that env is a valid Env value. var sum int64 if err := env.Dolist(list, func(x Value) error { i, err := env.Int(x) if err != nil { return err } sum += i return nil }); err != nil { panic(err) } fmt.Printf("sum is %d\n", sum)
Output:
func (Env) Duration ¶
Duration returns the Go equivalent of the Emacs time value in v, interpreted as a duration. v can be any time value: nil (for the current time), a number of seconds, a pair (ticks . hz) a pair (high low), a triple (high low μs), or a quadruple (high low μs ps). The picosecond value is truncated to nanosecond precision. If the Emacs time value would overflow a Go duration, Duration returns an error.
func (Env) ERTDeftest ¶
ERTDeftest defines an ERT test with the given name and documentation string. The test calls the Go function fun. It succeeds if fun returns nil. This is the Go equivalent of the ert-deftest macro.
func (Env) ERTTest ¶
func (e Env) ERTTest(fun ERTTestFunc, opts ...Option) error
ERTTest exports a Go function as an ERT test. Unlike the global ERTTest function, Env.ERTTest requires a live environment and defines the ERT test immediately. If the function returns an error, the ERT test fails.
By default, ERTTest derives the test’s name from the function’s Go name by Lisp-casing it. For example, MyTest becomes my-test. To specify a different name, pass a Name option. If there’s no name or the name is already registered, ERTTest panics.
By default, the ERT test has no documentation string. To add one, pass a Doc option.
func (Env) Emacs ¶
Emacs converts v to an Emacs value and returns the value. See NewIn for details of the conversion process.
func (Env) Export ¶
Export exports a Go function to Emacs. Unlike the global Export function, Env.Export requires a live environment and defines the Emacs function immediately. The function fun can be any Go function. When calling the exported function from Emacs, arguments and return values are converted as described in the package documentation. If you don’t want this autoconversion or need more control, use Env.ExportFunc instead and convert arguments yourself.
The function may accept any number of arguments. Optionally, the first argument may be of type Env. In this case, Emacs passes a live environment value that you can use to interact with Emacs. All other arguments are converted from Emacs as described in the package documentation. If not all arguments are convertible from Emacs values, Export panics.
The function must return either zero, one, or two results. If the last or only result is of type error, a non-nil value causes Emacs to trigger a non-local exit as appropriate. There may be at most one non-error result. Its value will be converted to an Emacs value as described in the package documentation. If the type of the non-error result can’t be converted to an Emacs value, Export panics. If there are invalid result patterns, Export panics.
By default, Export derives the function’s name from its Go name by Lisp-casing it. For example, MyFunc becomes my-func. To specify a different name, pass a Name option. To make the function anonymous, pass an Anonymous option. If there’s no name and the function isn’t anonymous, Export panics. If the name of a non-anonymous function is already registered, Export panics.
By default, the function has no documentation string. To add one, pass a Doc option.
func (Env) ExportFunc ¶
ExportFunc exports a Go function to Emacs. Unlike the global ExportFunc function, Env.ExportFunc requires a live environment and defines the Emacs function immediately. Unlike Env.Export, functions defined by ExportFunc don’t automatically convert their arguments and return values to and from Emacs. ExportFunc returns the Emacs function object of the new function. If name is empty, the function is anonymous. If name is not empty, it is bound to the new function. If doc is empty, the function won’t have a documentation string.
func (Env) Float ¶
Float returns the floating-point number stored in v. It returns an error if v is not a floating-point value.
func (Env) FormatMessage ¶
FormatMessage calls the Emacs function format-message with the given format string and arguments. If the call to format-message fails, FormatMessage returns a descriptive error string. Note that the syntax of the format string for FormatMessage is similar but not identical to the format strings for the fmt.Printf family.
func (Env) Funcall ¶
Funcall calls the Emacs function fun with the given arguments. Both function and arguments must be Emacs values. Use Env.Call or Env.Invoke if you want them to be autoconverted.
func (Env) Gethash ¶
Gethash returns the hash table value with the given key. ok specifies whether the key is present.
func (Env) GethashDef ¶
GethashDef returns the hash table value with the given key. If the key is not present, it returns def.
func (Env) Go ¶
Go converts v to a Go value and stores it in p. See NewOut for details of the conversion process.
func (Env) Int ¶
Int returns the integer stored in v. It returns an error if v is not an integer, or if it doesn’t fit into an int64.
func (Env) Intern ¶
Intern interns the given symbol name in the default obarray and returns the symbol object.
func (Env) Invoke ¶
Invoke calls a named Emacs function or function value. fun may be a string, Symbol, Name, or Value. If it’s not a value, Invoke interns it first. Invoke then calls the Emacs functions with the given arguments and assigns the result to out. It converts arguments and the return value as described in the package documentation.
Example ¶
// Assumes that env is a valid Env value. var now time.Time err := env.Invoke("current-time", &now) if err != nil { panic(err) }
Output:
func (Env) IsOverflowError ¶
IsOverflowError returns whether err is an Emacs signal of type overflow-error. This function detects both Error and Signal.
func (Env) IsWrongTypeArgument ¶
IsWrongTypeArgument returns whether err is an Emacs signal of type wrong-type-argument. This function detects both Error and Signal.
func (Env) Iter ¶
Iter creates an Iter value that iterates over list. Iter.Next will set elem to the elements of the list, and *err to any error. Iter assumes that list is a true list. If list is circular, the iteration may never terminate.
Typical use, with *T implementing the Out interface:
var elem T var err error for i := env.Iter(list, &elem, &err); i.Ok(); i.Next() { // … } if err != nil { return err }
See [Dolist] for a simpler iteration method.
func (Env) Lambda ¶
func (e Env) Lambda(fun interface{}, opts ...Option) (Value, DeleteFunc, error)
Lambda exports the given function to Emacs as an anonymous lambda function. Unlike the global AutoLambda function, Env.Lambda requires a live environment and defines the Emacs function immediately. When calling the exported function from Emacs, arguments and return values are converted as described in the package documentation and the documentation for the AutoLambda function.
When you don’t need the function any more, unregister it by calling the returned DeleteFunc function (typically using defer). If you don’t call the delete function, the function will remain registered and require a bit of memory. After calling the delete function, calling the function from Emacs panics.
The function is always anonymous. Any Name option in opts is ignored.
By default, the function has no documentation string. To add one, pass a Doc option.
You can call Lambda safely from multiple goroutines.
func (Env) LambdaFunc ¶
[LambdaFunc] exports the given function to Emacs as an anonymous lambda function. Unlike the global AutoLambda function, Env.LambdaFunc requires a live environment and defines the Emacs function immediately. Unlike Env.Lambda, functions registered by LambdaFunc don’t automatically convert their arguments and return values to and from Emacs.
When you don’t need the function any more, unregister it by calling the returned DeleteFunc function (typically using defer). If you don’t call the delete function, the function will remain registered and require a bit of memory. After calling the delete function, calling the function from Emacs panics.
You can call LambdaFunc safely from multiple goroutines.
func (Env) Length ¶
Length returns the length of the sequence represented by seq. It returns an error if seq is not a sequence. Just like the Emacs length function, it may loop forever if seq is a circular object.
func (Env) Let ¶
Let locally binds the variable to the value within body. This is like the Emacs Lisp let special form. Let returns the value and error returned by body, unless some other error occurs.
func (Env) LetMany ¶
LetMany locally binds the given variables value within body. This is like the Emacs Lisp let special form. LetMany returns the value and error returned by body, unless some other error occurs.
func (Env) MakeInteractive ¶
MakeInteractive sets the interactive specification of the given function. The function must refer to a module function.
func (Env) MakeVector ¶
MakeVector creates and returns an Emacs vector of size n. It initializes all elements to init.
func (Env) Maphash ¶
Maphash calls fun for each key–value pair in table. The order is arbitrary. If table is modified during iteration, the results are unpredictable.
func (Env) MaybeIntern ¶
MaybeIntern returns nameOrValue as-is if it’s a Value and calls Env.Intern if it’s a Symbol, Name, or string. Otherwise it returns an error.
func (Env) Message ¶
Message returns an error message for err. If err is an Emacs error, it uses error-message-string to obtain the Emacs error message. Otherwise, it returns err.Error().
func (Env) OpenPipe ¶
OpenPipe opens a writable pipe to the given Emacs pipe process. The pipe process must have been created with make-pipe-process. You can write to the returned pipe to provide input to the pipe process.
func (Env) ProcessInput ¶
ProcessInput processes pending input and returns whether the user has requested a quit. If ProcessInput returns an error, the caller should return the error to Emacs as soon as possible to allow Emacs to process the quit. Once Emacs regains control, it will quit and ignore the return value. Note that processing input can run arbitrary Lisp code, so don’t rely on global state staying the same after calling ProcessInput.
Example ¶
package main import ( "log" "math/big" "time" ) func main() { Export(mersennePrimeP, Doc("Return whether 2^N − 1 is probably prime."), Usage("N")) } func mersennePrimeP(e Env, n uint16) (bool, error) { tick := time.NewTicker(100 * time.Millisecond) defer tick.Stop() // Start long-running operation in another goroutine. Note that we // don’t pass any Env or Value values to the goroutine. ch := make(chan bool) go testMersennePrime(n, ch) // Wait for either the operation to finish or the user to quit. for { select { case r := <-ch: return r, nil case <-tick.C: if err := e.ProcessInput(); err != nil { log.Print("quitting") return false, err // Emacs will ignore the return value } } } } func testMersennePrime(n uint16, ch chan<- bool) { x := big.NewInt(1) x.Lsh(x, uint(n)) x.Sub(x, one) ch <- x.ProbablyPrime(10) log.Print("testMersennePrime finished") } var one = big.NewInt(1) func init() { ExampleEnv_ProcessInput() }
Output:
func (Env) ShouldQuit
deprecated
ShouldQuit returns whether the user has requested a quit. If ShouldQuit returns true, the caller should return to Emacs as soon as possible to allow Emacs to process the quit. Once Emacs regains control, it will quit and ignore the return value.
Deprecated: Use Env.ProcessInput instead.
func (Env) Str ¶
Str returns the string stored in v. It returns an error if v is not a string, or if it’s not a valid Unicode scalar value sequence. Str is not named String to avoid confusion with the fmt.Stringer.String method.
func (Env) Symbol ¶
Symbol returns the name of the Emacs symbol v. It returns an error if v is not a symbol.
func (Env) Time ¶
Time returns the Go equivalent of the Emacs time value in v. v can be any time value: nil (for the current time), a number of seconds since the epoch, a pair (ticks . hz), a pair (high low), a triple (high low μs), or a quadruple (high low μs ps). The picosecond value is truncated to nanosecond precision. If the Emacs time value would overflow a Go time, Time returns an error.
func (Env) Uint ¶
Uint returns the integer stored in v. It returns an error if v is not an integer, or if it doesn’t fit into an uint64.
func (Env) Uncons ¶
Uncons returns the car and cdr of cons. It returns an error if cons is not a cons cell.
func (Env) UnconsOut ¶
UnconsOut sets car and cdr to the car and cdr of cons. It returns an error if cons is not a cons cell. If UnconsOut fails, it is unspecified whether car and cdr have been modified.
func (Env) Var ¶
Var is like the global Var function, except that it requires a live environment, defines the variable immediately, and returns errors instead of panicking.
func (Env) VecGet ¶
VecGet returns the i-th element of vector. It returns an error if vector is not a vector.
func (Env) VecGetOut ¶
VecGetOut sets elem to the value of the i-th element of vector. It returns an error if vector is not a vector.
type Error ¶
type Error struct { // The error symbol. Symbol ErrorSymbol // The unevaluated error data. Data List }
Error is an error that causes to signal an error with the given symbol and data. Signaling an error will evaluate symbol and data lazily. The evaluation is best-effort since it can itself fail. If it fails the symbol and/or data might be lost, but Emacs will signal some error in any case. If you already have an evaluated symbol and data value, use Signal instead. ErrorSymbol.Error is a convenience factory function for Error values.
Example ¶
package main import "fmt" func main() { Export(goError, Doc("Signal an error of type ‘example-error’.").WithUsage("int float vec")) err := exampleError.Error(Int(123), Vector{String("foo"), Float(0.7), T}) fmt.Println(err) } func goError(f float32, v []uint16) (uint8, error) { return 55, exampleError.Error(Float(f), NewIn(v)) } var exampleError = DefineError("example-error", "Example error")
Output: Example error: 123, ["foo" 0.7 t]
type ErrorSymbol ¶
type ErrorSymbol struct {
// contains filtered or unexported fields
}
ErrorSymbol represents an error symbol. Use DefineError to create ErrorSymbol values. The zero ErrorSymbol is not a valid error symbol.
func DefineError ¶
func DefineError(name Name, message string, parents ...ErrorSymbol) ErrorSymbol
DefineError arranges for an error symbol to be defined using the Emacs function define‑error. Call it from an init function (i.e., before loading the dynamic module into Emacs) to define additional error symbols for your module. DefineError panics if name or message is empty, or if name is duplicate.
func (ErrorSymbol) Emacs ¶
func (s ErrorSymbol) Emacs(e Env) (Value, error)
Emacs interns the error symbol in the default obarray and returns the symbol value.
func (ErrorSymbol) Error ¶
func (s ErrorSymbol) Error(data ...In) error
Error returns an error that causes to signal an error with the given symbol and data. The return value is of type Error. Signaling an error will evaluate symbol and data lazily. The evaluation is best-effort since it can itself fail. If it fails the symbol and/or data might be lost, but Emacs will signal some error in any case. If you already have an evaluated symbol and data value, use Signal instead.
func (ErrorSymbol) String ¶
func (s ErrorSymbol) String() string
String returns the message of the error symbol.
type Float ¶
type Float float64
Float is a type with underlying type float64 that knows how to convert itself into an Emacs value.
type Func ¶
Func is a Go function exported to Emacs. It has access to a live environment, takes arguments as a slice, and can return a value or an error.
func ImportFunc ¶
ImportFunc imports an Emacs function as a Go function. name must be the Emacs symbol name of the function. ImportFunc returns a new Func that calls the Emacs function name. Unlike Import, there is no type autoconversion.
ImportFunc must be called before Emacs loads the module. Typically you should initialize a global variable with the return value of ImportFunc.
You can call ImportFunc safely from multiple goroutines.
type HashOut ¶
type HashOut struct { // New must return a new key and value each time it’s called. New func() (Out, Out) // FromEmacs fills Data with the pairs from the hash table. Data map[Out]Out }
HashOut is an Out that converts an Emacs hash table to the map Data. The concrete key and value types are determined by the return values of the [HashOut.New] function.
func (*HashOut) FromEmacs ¶
FromEmacs sets h.Data to a new map containing the same key–value pairs as the Emacs hash table in v. It returns an error if v is not a hash table. FromEmacs calls h.New for each key–value pair in v. h.New must return a new pair of Out values for the pair’s key and value. If FromEmacs returns an error, h.Data is not modified.
FromEmacs ignores the Emacs hash table test for v. This means that there may be multiple Emacs keys mapping to a single Go key if the hash functions aren’t consistent. For example, an Emacs hash table with string keys and hash test eq may contain two keys that are equal when converted to Go strings. In such a case, FromEmacs returns an error.
type HashTest ¶
type HashTest Symbol
HashTest represents a test function for an Emacs hash table.
Predefined hash table tests. To define your own test, use RegisterHashTest.
func HashTestFor ¶
HashTestFor returns a hash table test that is appropriate for the given type. It returns Eq for integral types, Eql for floating-point types, and Equal otherwise. HashTestFor ignores custom hash tests registered with RegisterHashTest.
func RegisterHashTest ¶
func RegisterHashTest(name HashTest, hash CustomHasher) HashTest
RegisterHashTest registers a new custom hash table test. The name must be a unique nonempty name for the test, and hash must define the hash function and equality predicate. RegisterHashTest returns name.
type In ¶
type In interface { // Emacs returns an Emacs object corresponding to the receiver, or an // error if the conversion fails. Implementations should document // whether it always returns a new object or not. They should also // document potential side effects. Emacs(Env) (Value, error) }
In is a value that knows how to convert itself into an Emacs object. You can implement In for your own types if you want this package to convert them to Emacs values automatically. This package also defines a few wrapper implementations for primitive types such as In or String.
func NewIn ¶
func NewIn(v interface{}) In
NewIn returns an In value that converts the dynamic type of v to an Emacs value. If v already implements In, NewIn returns it directly. Otherwise, if the dynamic type of v is known, NewIn returns one of the predefined In implementations (Int, Float, String, Reflect, …). Otherwise, NewIn returns an In instance that uses reflection to convert itself to Emacs.
type InitFunc ¶
InitFunc is an initializer function that should be run during module initialization. Use OnInit to register InitFunc functions. If an initialization function returns an error, the module loading itself will fail.
type Int ¶
type Int int64
Int is a type with underlying type int64 that knows how to convert itself into an Emacs value.
type Iter ¶
type Iter struct {
// contains filtered or unexported fields
}
Iter is an iterator over a list. Use Env.Iter to create Iter values. The zero Iter is not a valid iterator. Iter values can’t outlive the environment that created them. Don’t pass Iter values to other goroutines.
Typical use, with *T implementing the Out interface:
var elem T var err error for i := env.Iter(list, &elem, &err); i.Ok(); i.Next() { // … } if err != nil { return err }
Example ¶
// Assumes that env is a valid Env value. sum := 0 var elem Int var err error for i := env.Iter(list, &elem, &err); i.Ok(); i.Next() { sum += int(elem) } if err != nil { panic(err) } fmt.Printf("sum is %d\n", sum)
Output:
type Lambda ¶
Lambda represents an anonymous function. When converting to Emacs, it exports Fun as an Emacs lambda function.
func AutoLambda ¶
AutoLambda returns a Lambda object that exports the given function to Emacs as an anonymous lambda function. When calling the exported function from Emacs, arguments and return values are converted as described in the package documentation.
The function may accept any number of arguments. Optionally, the first argument may be of type Env. In this case, Emacs passes a live environment value that you can use to interact with Emacs. All other arguments are converted from Emacs as described in the package documentation. If not all arguments are convertible from Emacs values, AutoLambda panics.
The function must return either zero, one, or two results. If the last or only result is of type error, a non-nil value causes Emacs to trigger a non-local exit as appropriate. There may be at most one non-error result. Its value will be converted to an Emacs value as described in the package documentation. If the type of the non-error result can’t be converted to an Emacs value, AutoLambda panics. If there are invalid result patterns, AutoLambda panics.
The function is always anonymous. Any Name option in opts is ignored.
By default, the function has no documentation string. To add one, pass a Doc option.
You can call AutoLambda safely from multiple goroutines.
type ListOut ¶
type ListOut struct { // New must return a new list element each time it’s called. New func() Out // FromEmacs fills Data with the elements from the list. Data []Out }
ListOut is an Out that converts an Emacs list to the slice Data. The concrete element type is determined by the return value of the New function.
func (*ListOut) FromEmacs ¶
FromEmacs sets l.Data to a new slice containing the elements of the Emacs list v. It returns an error if v is not a list. FromEmacs calls l.New for each element in v. l.New must return a new Out value for the element. If FromEmacs returns an error, it doesn’t modify l.Data. FromEmacs assumes that v is a true list. In particular, it may loop forever if v is circular.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager simplifies registering and maintaining Emacs entities. Often, entities such as functions, variables, or error symbols should be registered during initialization of the Go package, when Emacs hasn’t yet loaded the module. In a second phase, these entities then have to be defined as soon as Emacs has loaded the module. To support this form of two-phase initialization, Manager maintains a queue of QueuedItem objects for later definition.
Optionally, you can use a Manager to ensure that entities are named and/or that names are unique within the scope of the manager.
You can use NewManager to create Manager objects. The zero Manager is valid and equivalent to NewManager(0). Manager objects can’t be copied once they are initialized.
Usually you’d create one global manager object per entity type. All methods of Manager are safe for concurrent use, assuming the QueuedItems aren’t modified after registering them, and [QueuedItem.Define] is safe for concurrent use.
Example ¶
package main import "fmt" // We assume that we want to allow module authors to register a Foo entity. // Registration should be possible eagerly (if an Emacs environment is // available) as well as lazily (before Emacs has loaded the module). For that // we use a Manager and pass DefineOnInit. var foos = NewManager(RequireUniqueName | DefineOnInit) // Define a type to hold the necessary information about a Foo. The type needs // to implement the QueuedItem interface. type foo struct { name Name message string } func (f foo) Define(e Env) error { return e.Invoke("message", Ignore{}, "defining foo %s: %s", f.name, f.message) // In real code you’d probably do something like // return e.Invoke("define-foo", Ignore{}, f.name, f.message) } // Define convenience functions to register definition of a Foo. func DefineFooNow(e Env, name Name, message string) error { return foos.RegisterAndDefine(e, name, foo{name, message}) } func DefineFooEventually(name Name, message string) error { return foos.Enqueue(name, foo{name, message}) } func main() { for _, n := range []Name{"foo-1", "foo-1", ""} { if err := DefineFooEventually(n, fmt.Sprintf("hi from foo %q", n)); err != nil { fmt.Println(err) } } } func init() { // We would normally call ExampleManager here, but the test runner // already calls it for us. }
Output: duplicate name foo-1
func NewManager ¶
func NewManager(flags ManagerFlag) *Manager
NewManager creates a new Manager object with the given flags. If flags includes RequireName, then all entities registered on this manager must have a nonempty name. If flags includes RequireUniqueName, then all named entities must have unique names. If flags includes DefineOnInit, NewManager arranges for Manager.DefineQueued to be called when the module is initialized. NewManager(0) is equivalent to new(Manager).
Having flags include RequireUniqueName but not RequireName is valid; in this case names are optional (i. e. the registration functions accept empty names), but if an entity is named, its name must be unique.
func (*Manager) DefineQueued ¶
DefineQueued defines all queued items using the given environment. DefineQueued may be called at most once. Usually, you should call it during module initialization, either using OnInit or by passing the DefineOnInit flag to NewManager. Once DefineQueued has been called, Manager.Enqueue and Manager.MustEnqueue can no longer be used. DefineQueued returns the error of the first failed definition, or nil if all definitions succeeded.
func (*Manager) Enqueue ¶
func (m *Manager) Enqueue(name Name, item QueuedItem) error
Enqueue registers a QueuedItem for later definition. Enqueue is usually called from an init function, before Emacs has loaded the module. The name may not be empty if the flag RequireName has been passed to NewManager. The name must be unique if it’s nonempty and the flag RequireUniqueName has been passed to NewManager. If neither flag was passed, the name is ignored. Enqueue returns an error if Manager.RegisterAndDefine has already been called.
func (*Manager) MustEnqueue ¶
func (m *Manager) MustEnqueue(name Name, item QueuedItem)
MustEnqueue registers a QueuedItem for later definition. MustEnqueue is usually called from an init function, before Emacs has loaded the module. The name may not be empty if the flag RequireName has been passed to NewManager. The name must be unique if it’s nonempty and the flag RequireUniqueName has been passed to NewManager. If neither flag was passed, the name is ignored. MustEnqueue panics if the name is invalid or if Manager.RegisterAndDefine has already been called. MustEnqueue is like Manager.Enqueue, except that it panics on all errors.
func (*Manager) RegisterAndDefine ¶
func (m *Manager) RegisterAndDefine(e Env, name Name, item QueuedItem) error
RegisterAndDefine registers a QueuedItem and defines it immediately. Unlike Enqueue and MustEnqueue, RegisterAndDefine requires a live Env object and therefore only works after Emacs has loaded the module. The name may not be empty if the flag RequireName has been passed to NewManager. The name must be unique if it’s nonempty and the flag RequireUniqueName has been passed to NewManager. If neither flag was passed, the name is ignored.
type ManagerFlag ¶
type ManagerFlag uint
ManagerFlag defines flags for NewManager.
const ( // RequireName causes a [Manager] to fail if the name of an entity to // be managed is empty. RequireName ManagerFlag = 1 << iota // RequireUniqueName causes a [Manager] to fail if two named entities // have the same name. RequireUniqueName // DefineOnInit arranges for [Manager.DefineQueued] to be called when // the module is initialized. DefineOnInit )
type Name ¶
type Name Symbol
Name is a Symbol that names a definition such as a function or error symbol. You can use a Name as an Option in Export and ERTTest to set the function or test name.
func Var ¶
Var arranges for an Emacs dynamic variable to be defined once the module is loaded. If doc is empty, the variable won’t have a documentation string. Var panics if the name is empty or already registered. Var returns name so you can assign it directly to a Go variable if you want.
Example ¶
package main import "fmt" func main() { // Var panics when trying to export a variable name twice. defer func() { fmt.Println("panic:", recover()) }() Var("go-var", nil, "") } var _ = Var("go-var", String("hi"), "Example variable.")
Output: panic: duplicate name go-var
func (Name) Emacs ¶
Emacs interns the given symbol name in the default obarray and returns the symbol object.
type Option ¶
type Option interface {
// contains filtered or unexported methods
}
Option is an option for Export, AutoFunc, AutoLambda, and ERTTest. Its implementations are Name, Anonymous, Doc, and Usage.
type Out ¶
type Out interface { // FromEmacs sets the receiver to a Go value corresponding to the Emacs // object. Implementations should document whether FromEmacs modifies // the receiver in case of an error. FromEmacs(Env, Value) error }
Out is a value that knows how to convert itself from an Emacs object. You can implement In for your own types if you want this package to convert them from Emacs values automatically. Pointers to wrapper implementations for In, such as *Int or *String, implement Out.
func NewOut ¶
func NewOut(p interface{}) Out
NewOut returns an Out value that sets p to the Go representation of an Emacs value. Typically p is a pointer. Only a few types such as reflect.Value can be set without indirection. If p already implements Out, NewOut returns it directly. Otherwise, if the dynamic type of v is known, NewOut returns one of the predefined Out implementations (*Int, *Float, *String, Reflect, …). Otherwise, NewOut returns an Out instance that uses reflection to convert Emacs values.
type QueuedItem ¶
type QueuedItem interface { // Define should define the item using the given Emacs environment. Define(Env) error }
QueuedItem is an item stored in a Manager’s queue.
type Reflect ¶
Reflect is a type with underlying type reflect.Value that knows how to convert itself to and from an Emacs value.
type Result ¶
Result contains the result of an asynchronous operation. If Err is set, Value is ignored.
type Signal ¶
type Signal struct{ Symbol, Data Value }
Signal is an error that that causes Emacs to signal an error with the given symbol and data. This is the equivalent to Error if you already have an evaluated symbol and data value.
func (Signal) Error ¶
Error implements the error interface. Error returns a static string. Use Signal.Message to return the actual Emacs error message.
type String ¶
type String string
String is a type with underlying type string that knows how to convert itself to an Emacs string.
func (String) Emacs ¶
Emacs creates an Emacs value representing the given string. It returns an error if the string isn’t a valid UTF-8 string.
type Symbol ¶
type Symbol string
Symbol represents an Emacs symbol. Env.Call interns Symbol values instead of converting them to an Emacs string.
func (Symbol) Emacs ¶
Emacs interns the given symbol name in the default obarray and returns the symbol object.
type Throw ¶
type Throw struct{ Tag, Value Value }
Throw is an error that triggers the Emacs throw function.
type Time ¶
Time is a type with underlying type time.Time that knows how to convert itself from and to an Emacs time value.
func (Time) Emacs ¶
Emacs returns an Emacs timestamp as a pair (ticks . hz) or a quadruple (high low μs ps) in the same format as the Emacs function current-time.
func (*Time) FromEmacs ¶
FromEmacs sets *t to the Go equivalent of the Emacs time value in v. v can be any time value: nil (for the current time), a number of seconds since the epoch, a pair (ticks . hz), a pair (high low), a triple (high low μs), or a quadruple (high low μs ps). The picosecond value is truncated to nanosecond precision. If the Emacs time value would overflow a Go time, FromEmacs returns an error.
func (Time) String ¶
String formats the time as a string. It calls time.Time.String.
type Uint ¶
type Uint uint64
Uint is a type with underlying type uint64 that knows how to convert itself into an Emacs value.
type Uncons ¶
type Uncons struct{ Car, Cdr Out }
Uncons represents a destructuring binding of a cons cell.
type UnpackList ¶
type UnpackList []Out
UnpackList represents a destructuring binding on an Emacs list.
func (*UnpackList) FromEmacs ¶
func (u *UnpackList) FromEmacs(e Env, v Value) error
FromEmacs fills *u with elements from the list v. It returns an error if v is not a list. If the list is shorter than *u, FromEmacs sets the length of *u to the length of the list. If the list is longer than *u, FromEmacs converts only the first len(*u) elements of the list and ignores the rest. FromEmacs assumes that v is a true list. If v is dotted or cyclic, the contents of *u are unspecified. If FromEmacs returns an error, the contents of *u are also unspecified.
type UnpackVector ¶
type UnpackVector []Out
UnpackVector represents a destructuring binding on an Emacs vector.
func (*UnpackVector) FromEmacs ¶
func (u *UnpackVector) FromEmacs(e Env, v Value) error
FromEmacs fills *u with elements from the vector v. It returns an error if v is not a vector. If the vector is shorter than *u, FromEmacs sets the length of *u to the length of the vector. If the vector is longer than *u, FromEmacs converts only the first len(*u) elements of the vector and ignores the rest. If FromEmacs returns an error, the contents of *u are unspecified.
type Usage ¶
type Usage string
Usage contains a list of argument names to be added to a documentation string. It should contain a plain space-separated list of argument names without enclosing parentheses. See Documentation Strings of Functions. Usage strings must be valid UTF-8 strings without embedded null characters or newlines. You can use a Usage as an Option in Export to set the argument list in the documentation string.
type Value ¶
type Value struct {
// contains filtered or unexported fields
}
Value represents an Emacs object. The zero Value is not valid. Various functions in this package return Value values. These functions are either methods on the Env type or take an Env argument. In any case, the returned Value values are only valid (or “live”) as long as the Env used to create them is valid. Don’t pass Value values to other goroutines. Two different Value values may represent the same Emacs value. Use Env.Eq instead of the == operator to compare values. See Conversion Between Lisp and Module Values for details.
type VectorOut ¶
type VectorOut struct { // New must return a new vector element each time it’s called. New func() Out // [VectorOut.FromEmacs] fills Data with the elements from the vector. Data []Out }
VectorOut is an Out that converts an Emacs vector to the slice Data. The concrete element type is determined by the return value of the New function.
func (*VectorOut) FromEmacs ¶
FromEmacs sets v.Data to a new slice containing the elements of the Emacs vector u. It returns an error if u is not a vector. FromEmacs calls v.New for each element in u. v.New must return a new Out value for the element. If FromEmacs returns an error, it doesn’t modify v.Data.