Copyright 2020-2026 Google LLC
February 21, 2022 · View on GitHub
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
#+TITLE: Bazel rules for Emacs Lisp #+LANGUAGE: en #+OPTIONS: author:nil date:nil ^:nil #+EXPORT_FILE_NAME: rules_elisp.texi #+TEXINFO_FILENAME: rules_elisp.info #+TEXINFO_DIR_CATEGORY: Emacs #+TEXINFO_DIR_TITLE: rules_elisp: (rules_elisp) #+TEXINFO_DIR_DESC: Compilation and testing support for Emacs Lisp in Bazel
#+MACRO: code @@texinfo:@code{@@$1@@texinfo:}@@ #+MACRO: var @@texinfo:@var{@@$1@@texinfo:}@@
- Introduction
This repository provides a Bazel integration for Emacs Lisp; see [[https://bazel.build/][the Bazel homepage]] for more information about Bazel, and see [[info:elisp#Top][the Emacs Lisp manual]]. It is modeled after the rules definitions for other languages, like the [[https://bazel.build/reference/be/c-cpp][C++ rules]].
This is not an officially supported Google product.
- Requirements
To use rules_elisp, you need [[https://bazel.build/][Bazel]]. For
installation instructions, see [[https://bazel.build/install][Installing
Bazel]]. This repository supports all full Bazel releases starting with Bazel
8.0.0. You’ll also need a recent C/C++ compiler (GCC or Clang on GNU/Linux and
macOS, Visual C++ 2019 on Windows). For further instructions how to use Bazel
on Windows, see [[https://bazel.build/install/windows][Installing Bazel on
Windows]].
This repository generally supports the two most recent major versions of Emacs. Currently, the supported versions are Emacs 29 and Emacs 30. Once Emacs 31 is released, support for Emacs 29 will be dropped.
- Usage
Add a snippet like the following to your MODULE.bazel file:
#+BEGIN_SRC bazel-module bazel_dep(name = "phst_rules_elisp") git_override( module_name = "phst_rules_elisp", remote = "https://github.com/phst/rules_elisp.git", commit = "c80b4ad393a971252b56364887f214c13a5ef026", ) #+END_SRC
#+TEXINFO: @noindent
See [[https://bazel.build/external/overview#bzlmod][the Bzlmod documentation]]
for background information. Then you can use the elisp_library,
elisp_cc_module, elisp_binary, and elisp_test rules. See the rule
documentation below and the examples in the examples directory for details.
Note that the C++ code used by rules_elisp requires at least C++17, but Bazel
still compiles with C++11 by default. See
[[https://github.com/abseil/abseil-cpp/blob/master/FAQ.md#how-to-i-set-the-c-dialect-used-to-build-abseil][the
Abseil FAQ]] how to correctly change the C++ standard for your project.
#+INCLUDE: elisp/elisp_library.org #+INCLUDE: elisp/elisp_cc_module.org #+INCLUDE: elisp/elisp_binary.org #+INCLUDE: elisp/elisp_test.org
- Load path management #+CINDEX: Load path
The Emacs Lisp rules by default only add the repository root directories to the
load path; see [[info:elisp#Library Search]]. However, many Emacs Lisp
libraries assume that their immediate parent directory is present in the load
path. To support such libraries, the elisp_library rule supports an optional
load_path attribute. You can specify additional load path directories using
this attribute. Relative directories are relative to the Bazel package
directory; absolute directories are relative to the repository root. A typical
use case is to specify load_path = ["."] to add the current package to the
load path.
- Runfiles #+CINDEX: Runfiles
This repository also includes a library to access runfiles; see
[[https://bazel.build/extending/rules#runfiles][the Bazel documentation on
runfiles]]. To use it, add a build dependency on
@phst_rules_elisp//elisp/runfiles.
#+FINDEX: elisp/runfiles/rlocation
#+TINDEX: elisp/runfiles/runfiles
Use the function elisp/runfiles/rlocation to map a runfile name to a
filename in the local filesystem. For more advanced use cases, see the
class elisp/runfiles/runfiles.
#+FINDEX: elisp/runfiles/file-handler
The library also provides a file name handler for runfiles,
elisp/runfiles/file-handler. It uses the prefix =/bazel-runfile:=.
- Protocol buffers #+CINDEX: Protocol buffers
By defining elisp_proto_library rules, you can use protocol buffers in Emacs
Lisp; see [[https://developers.google.com/protocol-buffers]]. To make a
protocol buffer definition available to Emacs Lisp, you first need a
proto_library rule; see
[[https://bazel.build/reference/be/protocol-buffer#proto_library]]. You can
either use an existing proto_library rule or add your own. Then, add an
elisp_proto_library rule that references the proto_library rule. Normally,
the name of the proto_library rule ends in =_proto=, and the name of the
corresponding elisp_proto_library rule has the same prefix and ends in
=_elisp_proto=. For example:
#+BEGIN_SRC bazel-build load("@phst_rules_elisp//elisp/proto:elisp_proto_library.bzl", "elisp_proto_library") load("@protobuf//bazel:proto_library.bzl", "proto_library")
proto_library( name = "my_proto", srcs = ["my.proto"], )
elisp_proto_library( name = "my_elisp_proto", deps = [":my_proto"], ) #+END_SRC
#+TEXINFO: @noindent
You can then use the elisp_proto_library rule in the same way as a normal
elisp_library rule, i.e., depend on it in other elisp_library,
elisp_binary, or elisp_test rules. The name of the Emacs Lisp feature for
the library is the same as the name of the original =.proto= file, relative to
its repository root. For example, if the above BUILD file is in a package named
=mypackage=, you would load the protocol buffer library using (require
'mypackage/my.proto).
#+INCLUDE: elisp/proto/elisp_proto_library.org
Emacs Lisp protocol buffer bindings contain Emacs Lisp equivalents for all
message and enumeration types defined in the underlying protocol buffer
definition files. Because Emacs Lisp doesn’t have namespaces, the names of all
defined entities are the full names of the corresponding protocol buffer
descriptors, including the protocol buffer package name (which is often
different from the Bazel package name), but with dots (=.=) replaced with
slashes (=/=), because dots are special characters in Emacs Lisp; see
[[info:elisp#Symbol Type]]. For example, the Lisp name of the protocol buffer
message type google.protobuf.Duration is google/protobuf/Duration, and the
Lisp name of the protocol buffer enumeration value
google.protobuf.FieldDescriptorProto.TYPE_BOOL is
google/protobuf/FieldDescriptorProto/TYPE_BOOL.
When accessing protocol buffer message fields, Emacs translates field values to
and from Lisp data types; see [[info:elisp#Programming Types]]. For scalar
types, the translation uses appropriate matching types, i.e., numbers and
strings. Boolean values are translated to either nil or t. The bytes
type is represented using unibyte strings; see [[info:elisp#Text
Representations]]. Accessing string and byte fields always creates copies; this
means that changing the return value using aset will not modify the original
protocol buffer message.
The situation is a bit more complex for submessage fields, repeated fields, and
map fields. Emacs represents values of these fields using specialized types.
For submessage fields, these types are again generated protocol buffer message
types. For repeated and map fields, Emacs uses the types elisp/proto/array
and elisp/proto/map, respectively. Message, array, and map objects can be
mutable or immutable; attempting to modify an immutable object signals an error.
The Lisp representations of these types are opaque structure-like types. Their
implementation is maintained internally, and you shouldn’t try to access or
modify it directly. Rather, the Emacs Lisp library elisp/proto/proto contains
the following facilities to use and manipulate these types.
#+ATTR_TEXINFO: :options Type elisp/proto/message #+BEGIN_deftp #+CINDEX: protocol buffer message The base type for all message types. This is an abstract type; you can’t instantiate it directly. #+END_deftp
#+ATTR_TEXINFO: :options elisp/proto/message-p object #+BEGIN_defun This predicate returns whether the given object is a protocol buffer message object. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/message-mutable-p object #+BEGIN_defun This predicate returns whether the given protocol buffer message object is mutable. #+END_defun
#+ATTR_TEXINFO: :options Type elisp/proto/array #+BEGIN_deftp #+CINDEX: protocol buffer array A type that represents repeated protocol buffer message fields. You can’t instantiate this type directly; instead, you obtain instances of this type by accessing repeated message fields.
Protocol buffer arrays are generalized sequences. This means you can use the
functions from the seq.el library with them. See [[info:elisp#Sequence
Functions]].
#+END_deftp
#+ATTR_TEXINFO: :options elisp/proto/array-p object #+BEGIN_defun This predicate returns whether the given object is a protocol buffer array object. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/array-mutable-p object #+BEGIN_defun This predicate returns whether the given protocol buffer array is mutable. #+END_defun
#+ATTR_TEXINFO: :options Type elisp/proto/map #+BEGIN_deftp #+CINDEX: protocol buffer map A type that represents protocol buffer map fields. You can’t instantiate this type directly; instead, you obtain instances of this type by accessing repeated message fields. See https://developers.google.com/protocol-buffers/docs/proto3#maps.
Protocol buffer maps are generalized maps. This means you can use the functions
from the map.el library with them. See the comments in map.el for details.
#+END_deftp
#+ATTR_TEXINFO: :options elisp/proto/map-p object #+BEGIN_defun This predicate returns whether the given object is a protocol buffer map object. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/map-mutable-p object #+BEGIN_defun This predicate returns whether the given protocol buffer map is mutable. #+END_defun
It should be noted that protocol buffer arrays and maps are not “full” types.
You can’t use them as replacement types for vectors or hash tables because
there’s no way to create objects of these types from scratch. You can only
obtain new objects by accessing protocol buffer message fields. This is also
the reason why these types don’t provide implementations of seq-into,
seq-concatenate or map-into that would return new protocol buffer arrays and
maps.
Another important difference between these types and the standard Emacs Lisp types is that protocol buffer arrays and maps are strongly-typed: all their elements have the same type, which is determined when creating the object. For example, you can’t add a string value to a protocol buffer array holding integers.
The Lisp representation of protocol buffer enumerations are plain Lisp constants. See [[info:elisp#Defining Variables]]. Their values are just the integral values of the corresponding enumerators.
Whenever Emacs needs to convert a Lisp value to a protocol buffer field value,
an array element, or a map key or value, it accepts values that are compatible
with the destination type. For example, you can use an integer to set a
floating-point protocol buffer message field. Setting a Boolean field accepts
any non-nil value as true. Setting a repeated field accepts lists, vectors,
and any other generalized sequence type. Setting a map field accepts
hash-tables, association lists, and any other generalized map type.
#+ATTR_TEXINFO: :options elisp/proto/make type [fields...]
#+BEGIN_defun
This function creates and initializes a new protocol buffer message object. The
{{{var(type)}}} must be a symbol denoting an existing protocol buffer message
type, using the conventions described above (i.e., periods replaced with
slashes). Before calling this function for a given type, you have to require
the generated library that defines the type, otherwise the function will fail.
The {{{var(fields)}}} are keyword-value pairs of the form
{{{code(:{{{var(field)}}} {{{var(value)}}})}}} that are used to initialize the
fields. If a field isn’t mentioned in {{{var(fields)}}}, it’s not set in the
resulting message. For example, the following code creates a new protocol
buffer message object of type google.protobuf.Duration:
#+BEGIN_SRC emacs-lisp (require 'elisp/proto/proto) (require 'duration_proto) (elisp/proto/make 'google/protobuf/Duration :seconds 3600) #+END_SRC
#+TEXINFO: @noindent
The nanos field remains uninitialized.
#+END_defun
For every protocol buffer message type, the generated library will also contain
a function {{{code({{{var(type)}}}-new)}}} that you can use as a shorthand for
elisp/proto/make. For example, you could also write the above example as
#+BEGIN_SRC emacs-lisp (require 'duration_proto) (google/protobuf/Duration-new :seconds 3600) #+END_SRC
To check whether an object is a protocol buffer message object of a given type, the generated libraries contain predicate functions like {{{code({{{var(type)}}}-p)}}}. For example, to test whether an object is a duration protocol buffer message, you can write
#+BEGIN_SRC emacs-lisp (require 'duration_proto) (google/protobuf/Duration-p object) #+END_SRC
You can also use the Common Lisp type predicates like cl-typep or
cl-check-type with protocol buffer message objects. See
[[info:cl#Type Predicates]].
** Accessing protocol buffer message fields :PROPERTIES: :ALT_TITLE: Protocol buffer fields :END:
The functions described in this section retrieve and manipulate message fields. They all accept a message object as first argument and a field name as second argument. The field name is a plain symbol denoting the unqualified field name.
#+ATTR_TEXINFO: :options elisp/proto/has-field message field #+BEGIN_defun This function returns whether the given field is present in the message object. If the field doesn’t have a notion of presence (e.g., it’s a repeated field), an error is signaled. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/field message field
#+BEGIN_defun
This function returns the value of the given field within the message object.
If the field isn’t set in the message, then the return value depends on the type
of the field. If the field is scalar, its default value is returned. If the
field is a submessage, repeated, or map field, nil is returned. For
non-scalar fields, the return value is immutable, i.e., trying to change it will
signal an error.
If the field is a string or byte array field, the return value is a newly-allocated string. This implies that it’s often a good idea to bind the return value to a local variable instead of retrieving the value many times. #+END_defun
#+ATTR_TEXINFO: :options {pcase pattern} elisp/proto type [fields...]
#+BEGIN_deffn
As a more compact alternative to type predicates and field access using
elisp/proto/field, you can use elisp/proto patterns in pcase form. See
[[info:elisp#Pattern-Matching Conditional]]. The elisp/proto form takes an
unquoted protocol buffer type and a list of fields. For example, the following
form extracts the fields of a duration message:
#+BEGIN_SRC emacs-lisp (pcase message ((elisp/proto google/protobuf/Duration seconds nanos) (message "Duration with %d seconds and %d nanoseconds" seconds nanos)) (_ (message "Some other thing"))) #+END_SRC
Instead of specifying plain field names, you can also specify
{{{code(({{{var(field)}}} {{{var(pattern)}}}))}}} pairs. These match the field
value against {{{var(pattern)}}}, which is again a pcase pattern. For
example, the following code tests whether a duration is strictly positive:
#+BEGIN_SRC emacs-lisp (pcase message ((or (elisp/proto google/protobuf/Duration (seconds (and (pred cl-plusp) seconds)) nanos) (elisp/proto google/protobuf/Duration (seconds (and 0 seconds)) (nanos (and (pred cl-plusp) nanos)))) (message "Duration with %d seconds and %d nanoseconds is positive" seconds nanos))) #+END_SRC
#+TEXINFO: @noindent A {{{var(field)}}} construct that is a plain symbol is thus the same as {{{code(({{{var(field)}}} {{{var(field)}}}))}}}. #+END_deffn
#+ATTR_TEXINFO: :options elisp/proto/set-field message field value #+BEGIN_defun This function sets the field to a new value. It signals an error if the message object is immutable, or if the new value isn’t compatible with the field type. #+END_defun
** Parsing and serializing protocol buffer messages :PROPERTIES: :ALT_TITLE: Protocol buffer serialization :END:
The primary purpose of protocol buffers is data serialization. The Emacs Lisp protocol buffer bindings support all three major forms of protocol buffer serialization: binary, JSON, and text. However, currently the textual protocol buffer representation can only be generated, not parsed. Since none of the serialized forms are self-describing, you have to explicitly pass the desired message type to the parsing functions.
You can customize the behavior of the parsing and serialization functions to some extend with optional keyword arguments. These are the most common keyword arguments:
:allow-partial:: This keyword argument affects how missing required fields are handled: by default, they cause an error to be signaled, but if the keyword argument is non-nil, they are silently ignored, and the result might not be fully initialized.:discard-unknown:: This keyword argument affects how unknown fields are handled: by default, they cause an error to be signaled, but if the keyword argument is non-nil, they are silently ignored.:deterministic:: If this keyword argument is non-nil, serialization functions attempt to produce slightly more deterministic output; however, this attempt is best-effort, since protocol buffer serialization is not guaranteed to be deterministic.
#+TEXINFO: @noindent Other keyword arguments are described in the main body of the function definitions below.
#+ATTR_TEXINFO: :options elisp/proto/parse type serialized [:allow-partial] #+BEGIN_defun This function parses a protocol buffer message from its binary serialization form. The {{{var(serialized)}}} argument must be a unibyte string containing the binary serialization of a protocol buffer message of type {{{var(type)}}}. The {{{var(type)}}} is again a symbol denoting a protocol buffer message type. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/parse-json type serialized [:discard-unknown]
#+BEGIN_defun
This function is like elisp/proto/parse, but it expects the JSON serialization
instead of the binary serialization.
#+END_defun
#+ATTR_TEXINFO: :options elisp/proto/serialize message [:allow-partial] [:discard-unknown] [:deterministic]
#+BEGIN_defun
This function is the inverse of elisp/proto/parse, producing the binary
serialization of the {{{var(message)}}} as a unibyte string.
#+END_defun
#+ATTR_TEXINFO: :options elisp/proto/serialize-text message [:compact] [:discard-unknown] [:deterministic]
#+BEGIN_defun
This function is the inverse of elisp/proto/parse, producing the binary
serialization of the {{{var(message)}}} as a unibyte string. If the
:compact keyword argument is non-nil, the output is a bit more compact, with
less vertical whitespace; however, you shouldn’t rely on any specific output
format in any case.
#+END_defun
#+ATTR_TEXINFO: :options elisp/proto/serialize-json message [:emit-defaults] [:proto-names]
#+BEGIN_defun
This function is the inverse of elisp/proto/parse-json, producing the JSON
serialization of the {{{var(message)}}} as a string. If the :emit-defaults
keyword argument is non-nil, the result will also include fields whose value
equals their default value; normally such fields are left out. The
:proto-names keyword argument determines the naming style for field names: by
default, camel-case versions of the names are used, but if the keyword argument
is non-nil, the names from the protocol buffer definition are used verbatim.
#+END_defun
You can print a human-readable representation of protocol buffer messages,
arrays, and maps using the functions cl-prin1, cl-prin1-to-string, or
cl-print-to-string-with-limit. However, these objects don’t have a read
syntax; see [[info:elisp#Printed Representation]]. Using plain Emacs functions
like print will result in a representation that’s not very human-readable; see
[[info:elisp#Read and Print]].
** Well-known protocol buffer types
The Emacs Lisp protocol buffer bindings contain some dedicated support for a few well-known message types. These are predefined types which are used frequently; see [[https://developers.google.com/protocol-buffers/docs/reference/google.protobuf]].
#+ATTR_TEXINFO: :options elisp/proto/timestamp message
#+BEGIN_defun
#+TEXINFO: @defunx elisp/proto/duration message
These functions convert protocol buffer messages of type
google.protobuf.Timestamp and google.protobuf.Duration to Lisp timestamps.
See [[info:elisp#Time of Day]], for the definition of a Lisp timestamp.
#+END_defun
#+ATTR_TEXINFO: :options elisp/proto/make-timestamp time
#+BEGIN_defun
#+TEXINFO: @defunx elisp/proto/make-duration time
These functions perform the opposite conversion, creating
google.protobuf.Timestamp and google.protobuf.Duration messages from Lisp
time values. See [[info:elisp#Time of Day]], for the definition of a Lisp time
value.
#+END_defun
#+ATTR_TEXINFO: :options elisp/proto/set-timestamp message time
#+BEGIN_defun
#+TEXINFO: @defunx elisp/proto/set-duration message time
These functions are similar, but they change message objects in place instead of
creating new ones. The {{{var(message)}}} arguments must be mutable. As an
alternative to calling these functions directly, you can also use
elisp/proto/timestamp and elisp/proto/duration as generalized variables; see
[[info:elisp#Generalized Variables]].
#+END_defun
#+ATTR_TEXINFO: :options elisp/proto/pack-any message
#+BEGIN_defun
This function returns a new protocol buffer message of type
google.protobuf.Any that wraps the given {{{var(message)}}}.
#+END_defun
#+ATTR_TEXINFO: :options elisp/proto/unpack-any any
#+BEGIN_defun
This function unpacks the given protocol buffer message of type
google.protobuf.Any. The return type depends on the type_url field. Even
though this allows you to handle message types dynamically, you still need to
load the generated bindings for the dynamic type for unpacking to work.
#+END_defun
#+ATTR_TEXINFO: :options elisp/proto/any-type-name any
#+BEGIN_defun
This function extracts the full type name from the type_url field of the given
protocol buffer message of type google.protobuf.Any. The return name is the
full name of the type of the message packed in {{{var(any)}}} as a string.
#+END_defun
** Specialized array and map functions :PROPERTIES: :ALT_TITLE: Protocol buffer array and map functions :END:
This section describes a few additional functions that deal with arrays and maps.
#+ATTR_TEXINFO: :options elisp/proto/array-length array #+BEGIN_defun #+TEXINFO: @defunx elisp/proto/map-length map These functions return the number of elements in the given array or map. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/do-array function array #+BEGIN_defun This function calls {{{var(function)}}} for each element in {{{var(array)}}} in ascending order. {{{var(function)}}} has to accept a single argument. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/do-map function map #+BEGIN_defun This function calls {{{var(function)}}} for each entry in {{{var(map)}}}. {{{var(function)}}} has to accept two arguments, the key and the value. The iteration order is arbitrary. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/append-array array value #+BEGIN_defun This function adds {{{var(value)}}} as a new element to the end of {{{var(array)}}}. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/extend-array dest source #+BEGIN_defun This function appends all elements in the {{{var(source)}}} sequence to the end of {{{var(dest)}}}. The {{{var(source)}}} must be a generalized sequence. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/update-map dest source #+BEGIN_defun This function inserts all entries in the {{{var(source)}}} map into {{{var(map)}}}. The {{{var(source)}}} must be a generalized map. If a given key already exists, the corresponding value is overwritten. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/copy-array array #+BEGIN_defun #+TEXINFO: @defunx elisp/proto/copy-map map These functions return a shallow copy of the given array or map. The returned copy is mutable, but its elements might still be immutable. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/clear-array array #+BEGIN_defun #+TEXINFO: @defunx elisp/proto/clear-map map These functions remove all elements from the given array or map. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/replace-array dest source #+BEGIN_defun #+TEXINFO: @defunx elisp/proto/replace-map dest source These functions first remove all elements from {{{var(dest)}}} and then add elements from {{{var(source)}}}. After the operation finishes successfully, {{{var(dest)}}} will have the same number of elements as {{{var(source)}}}. Elements in {{{var(source)}}} are converted to the element type of {{{var(dest)}}} as necessary. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/map-put map key value
#+BEGIN_defun
#+TEXINFO: @defunx elisp/proto/map-set map key value
These two functions perform an “upsert” operation: if {{{var(key)}}} is already
present in {{{var(map)}}}, they update its value to {{{var(value)}}}, otherwise
they insert a new entry into the map. The only difference is the return value:
elisp/proto/map-put follows the convention of puthash and always returns
{{{var(value)}}}, while elisp/proto/map-set returns whether a new entry was
inserted.
#+END_defun
#+ATTR_TEXINFO: :options elisp/proto/array-pop array index #+BEGIN_defun #+TEXINFO: @defunx elisp/proto/map-pop map key These functions remove the element with the given index or key and return its value. In the case of an array, elements are shifted left to fill the hole. #+END_defun
The following functions work on ranges in an array. A range is defined by a
start index and an end index; the start index is included in the range, but the
end index is not. If either index is negative, it’s treated as counting from
the end; this facilitates things like addressing the last five elements of an
array. If the end index is left out or nil, the length of the array is used
instead; this means that passing only a start index addresses the entire
remaining subarray starting at that index. These are exactly the same
conventions that the functions substring and seq-subseq use. See
[[info:elisp#Creating Strings]], and see [[info:elisp#Sequence Functions]].
#+ATTR_TEXINFO: :options elisp/proto/subarray array from [to] #+BEGIN_defun This function returns a shallow copy of the subsequence of {{{var(array)}}} delineated by {{{var(from)}}} and {{{var(to)}}}. #+END_defun
#+ATTR_TEXINFO: :options elisp/proto/array-delete array from [to] #+BEGIN_defun This function removes the range delineated by {{{var(from)}}} and {{{var(to)}}} from {{{var(array)}}}. Elements are shifted left to fill in the hole. #+END_defun
- Building manuals
You can use the elisp_manual rule to generate a Texinfo manual from an
Org-mode file. See [[info:texinfo#Top]], and see [[info:org#Top]].
#+INCLUDE: elisp/elisp_manual.org
- Depending on external libraries
rules_elisp provides a module extension to make it easier to depend on
external Emacs Lisp libraries that don’t bring their own Bazel support.
#+INCLUDE: elisp/extensions/elisp.org
- Starlark infrastructure
The emacs_library, emacs_cc_module, and emacs_proto_library return the
EmacsLispInfo provider to transport information about Emacs Lisp libraries
across target boundaries. See
[[https://bazel.build/extending/rules#providers][Providers]] for more
information about providers.
#+INCLUDE: elisp/common/elisp_info.org
To compile Emacs Lisp source files and runs tests, rules_elisp registers the
toolchains of type @phst_rules_elisp//elisp:toolchain_type; see
[[https://bazel.build/extending/toolchains][Toolchains]]. Emacs Lisp toolchains
are created using the elisp_toolchain rule.
#+INCLUDE: elisp/toolchains/elisp_toolchain.org #+INCLUDE: elisp/toolchains/elisp_emacs_binary.org
- Indices
** Concept index :PROPERTIES: :INDEX: cp :END:
** Symbol index :PROPERTIES: :INDEX: fn :END:
** Type index :PROPERTIES: :INDEX: tp :END: