Write Emacs packages in Swift
EmacsSwiftModule
A Swift library to write Emacs plugins in Swift!
Overview
Emacs Swift module provides a convenient API for writing dynamic modules for Emacs in Swift. It marries a dynamic nature of Emacs Lisp with strong static typization of Swift and hides the roughness of the original C API together with harder aspects of that language such as a lack closures and manual memory management. It also translates Emacs Lisp errors and Swift exceptions into each other.
A Quick Tour
EmacsSwiftModule
allows you to call functions from Emacs Lisp using Swift’s own types.
let two: Int = try env.funcall("+", with: 1, 1)
assert(two == 2)
try env.funcall("message", with: "%S %S", "Hello", 42)
And define your own Lisp functions out of Swift closures
try env.defun("foo") {
(x: Int, y: Int) in x + y
}
try env.defun("bar") {
(input: [String]) in input.joined(separator: ", ")
}
that can be easily used in Emacs Lisp
(foo 1 1) ;; => 2
(bar ["Hello" "World"]) ;; => "Hello, World"
It handles errors on both sides so the user can almost always simply ignore them.
try env.defun("always-throws") { (x: Int) throws in
throw MyError(x: x)
}
try env.defun("calls-afdsiufs") {
(env: Environment) in
do {
try env.funcall("afdsiufs", with: 42)
} catch EmacsError.signal {
print("Whoops! It looks like 'afdsiufs' doesn't exist!")
}
}
And on the Lisp side too
(always-throws 42) ;; => raises (swift-error "Swift exception: MyError(x: 42)")
(calls-afdsiufs) ;; => nil because we caught the error
The same happens when a type requirement expected in Swift is not met.
(foo "Hello" "World") ;; => raises (wrong-type-argument numberp "Hello")