* tree-sitter grammars for emacs memo
@ 2022-12-04 16:04 Murad Mamedov
2023-01-26 17:18 ` Simon Tournier
0 siblings, 1 reply; 2+ messages in thread
From: Murad Mamedov @ 2022-12-04 16:04 UTC (permalink / raw)
To: Guix-devel
[-- Attachment #1: Type: text/plain, Size: 957 bytes --]
Hi,
Today I spent some time on trying latest emacs with
--with-tree-siter enabled. It enables native support
for tree-sitter. However, language grammars are still
external. I came up with below snippet that makes
grammar packages. But I didn't find it worth committing.
So sharing it here if someone will want to try,
or may be form it to commit.
Current issues related to guix with tree-sitter below:
- Emacs tries to dlopen libraries with grammars.
Since we are under guix, one has to add grammar
packages to profile and use treesit-extra-load-path
variable. In the long run, this will require different
solution, probably patching emacs it self, idk.
--8<---------------cut here---------------start------------->8---
(use-package treesit
:demand t
:init
(setq treesit-extra-load-path
'("/home/muradm/.cache/guix-extra-profiles/desktop/lib")))
--8<---------------cut here---------------end--------------->8---
Regards,
muradm
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: emacs-tree-sitter-module.patch --]
[-- Type: text/x-patch, Size: 28539 bytes --]
From c8a8db2d46b5320185aaa5ba4ec9d7e8764af592 Mon Sep 17 00:00:00 2001
From: muradm <mail@muradm.net>
Date: Sun, 4 Dec 2022 13:22:07 +0300
Subject: [PATCH] tree-sitter-module
---
src/emacs-module.h | 763 ++++++++++++++++++++++++++++++++++++++++
src/tree-sitter-lang.in | 79 +++++
2 files changed, 842 insertions(+)
create mode 100644 src/emacs-module.h
create mode 100644 src/tree-sitter-lang.in
diff --git a/src/emacs-module.h b/src/emacs-module.h
new file mode 100644
index 0000000..1185c06
--- /dev/null
+++ b/src/emacs-module.h
@@ -0,0 +1,763 @@
+/* emacs-module.h - GNU Emacs module API.
+
+Copyright (C) 2015-2021 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
+
+/*
+This file defines the Emacs module API. Please see the chapter
+`Dynamic Modules' in the GNU Emacs Lisp Reference Manual for
+information how to write modules and use this header file.
+*/
+
+#ifndef EMACS_MODULE_H
+#define EMACS_MODULE_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <time.h>
+
+#ifndef __cplusplus
+#include <stdbool.h>
+#endif
+
+#define EMACS_MAJOR_VERSION 28
+
+#if defined __cplusplus && __cplusplus >= 201103L
+# define EMACS_NOEXCEPT noexcept
+#else
+# define EMACS_NOEXCEPT
+#endif
+
+#if defined __cplusplus && __cplusplus >= 201703L
+# define EMACS_NOEXCEPT_TYPEDEF noexcept
+#else
+# define EMACS_NOEXCEPT_TYPEDEF
+#endif
+
+#if 3 < __GNUC__ + (3 <= __GNUC_MINOR__)
+# define EMACS_ATTRIBUTE_NONNULL(...) \
+ __attribute__ ((__nonnull__ (__VA_ARGS__)))
+#elif (defined __has_attribute \
+ && (!defined __clang_minor__ \
+ || 3 < __clang_major__ + (5 <= __clang_minor__)))
+# if __has_attribute (__nonnull__)
+# define EMACS_ATTRIBUTE_NONNULL(...) \
+ __attribute__ ((__nonnull__ (__VA_ARGS__)))
+# endif
+#endif
+#ifndef EMACS_ATTRIBUTE_NONNULL
+# define EMACS_ATTRIBUTE_NONNULL(...)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Current environment. */
+typedef struct emacs_env_28 emacs_env;
+
+/* Opaque pointer representing an Emacs Lisp value.
+ BEWARE: Do not assume NULL is a valid value! */
+typedef struct emacs_value_tag *emacs_value;
+
+enum { emacs_variadic_function = -2 };
+
+/* Struct passed to a module init function (emacs_module_init). */
+struct emacs_runtime
+{
+ /* Structure size (for version checking). */
+ ptrdiff_t size;
+
+ /* Private data; users should not touch this. */
+ struct emacs_runtime_private *private_members;
+
+ /* Return an environment pointer. */
+ emacs_env *(*get_environment) (struct emacs_runtime *runtime)
+ EMACS_ATTRIBUTE_NONNULL (1);
+};
+
+/* Type aliases for function pointer types used in the module API.
+ Note that we don't use these aliases directly in the API to be able
+ to mark the function arguments as 'noexcept' before C++20.
+ However, users can use them if they want. */
+
+/* Function prototype for the module Lisp functions. These must not
+ throw C++ exceptions. */
+typedef emacs_value (*emacs_function) (emacs_env *env, ptrdiff_t nargs,
+ emacs_value *args,
+ void *data)
+ EMACS_NOEXCEPT_TYPEDEF EMACS_ATTRIBUTE_NONNULL (1);
+
+/* Function prototype for module user-pointer and function finalizers.
+ These must not throw C++ exceptions. */
+typedef void (*emacs_finalizer) (void *data) EMACS_NOEXCEPT_TYPEDEF;
+
+/* Possible Emacs function call outcomes. */
+enum emacs_funcall_exit
+{
+ /* Function has returned normally. */
+ emacs_funcall_exit_return = 0,
+
+ /* Function has signaled an error using `signal'. */
+ emacs_funcall_exit_signal = 1,
+
+ /* Function has exit using `throw'. */
+ emacs_funcall_exit_throw = 2
+};
+
+/* Possible return values for emacs_env.process_input. */
+enum emacs_process_input_result
+{
+ /* Module code may continue */
+ emacs_process_input_continue = 0,
+
+ /* Module code should return control to Emacs as soon as possible. */
+ emacs_process_input_quit = 1
+};
+
+/* Define emacs_limb_t so that it is likely to match GMP's mp_limb_t.
+ This micro-optimization can help modules that use mpz_export and
+ mpz_import, which operate more efficiently on mp_limb_t. It's OK
+ (if perhaps a bit slower) if the two types do not match, and
+ modules shouldn't rely on the two types matching. */
+typedef size_t emacs_limb_t;
+#define EMACS_LIMB_MAX SIZE_MAX
+
+struct emacs_env_25
+{
+ /* Structure size (for version checking). */
+ ptrdiff_t size;
+
+ /* Private data; users should not touch this. */
+ struct emacs_env_private *private_members;
+
+ /* Memory management. */
+
+ emacs_value (*make_global_ref) (emacs_env *env, emacs_value value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*free_global_ref) (emacs_env *env, emacs_value global_value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Non-local exit handling. */
+
+ enum emacs_funcall_exit (*non_local_exit_check) (emacs_env *env)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*non_local_exit_clear) (emacs_env *env)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ enum emacs_funcall_exit (*non_local_exit_get)
+ (emacs_env *env, emacs_value *symbol, emacs_value *data)
+ EMACS_ATTRIBUTE_NONNULL(1, 2, 3);
+
+ void (*non_local_exit_signal) (emacs_env *env,
+ emacs_value symbol, emacs_value data)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*non_local_exit_throw) (emacs_env *env,
+ emacs_value tag, emacs_value value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Function registration. */
+
+ emacs_value (*make_function) (emacs_env *env,
+ ptrdiff_t min_arity,
+ ptrdiff_t max_arity,
+ emacs_value (*func) (emacs_env *env,
+ ptrdiff_t nargs,
+ emacs_value* args,
+ void *data)
+ EMACS_NOEXCEPT
+ EMACS_ATTRIBUTE_NONNULL(1),
+ const char *docstring,
+ void *data)
+ EMACS_ATTRIBUTE_NONNULL(1, 4);
+
+ emacs_value (*funcall) (emacs_env *env,
+ emacs_value func,
+ ptrdiff_t nargs,
+ emacs_value* args)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ emacs_value (*intern) (emacs_env *env, const char *name)
+ EMACS_ATTRIBUTE_NONNULL(1, 2);
+
+ /* Type conversion. */
+
+ emacs_value (*type_of) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ bool (*is_not_nil) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ bool (*eq) (emacs_env *env, emacs_value a, emacs_value b)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ intmax_t (*extract_integer) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ emacs_value (*make_integer) (emacs_env *env, intmax_t n)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ double (*extract_float) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ emacs_value (*make_float) (emacs_env *env, double d)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Copy the content of the Lisp string VALUE to BUFFER as an utf8
+ null-terminated string.
+
+ SIZE must point to the total size of the buffer. If BUFFER is
+ NULL or if SIZE is not big enough, write the required buffer size
+ to SIZE and return true.
+
+ Note that SIZE must include the last null byte (e.g. "abc" needs
+ a buffer of size 4).
+
+ Return true if the string was successfully copied. */
+
+ bool (*copy_string_contents) (emacs_env *env,
+ emacs_value value,
+ char *buf,
+ ptrdiff_t *len)
+ EMACS_ATTRIBUTE_NONNULL(1, 4);
+
+ /* Create a Lisp string from a utf8 encoded string. */
+ emacs_value (*make_string) (emacs_env *env,
+ const char *str, ptrdiff_t len)
+ EMACS_ATTRIBUTE_NONNULL(1, 2);
+
+ /* Embedded pointer type. */
+ emacs_value (*make_user_ptr) (emacs_env *env,
+ void (*fin) (void *) EMACS_NOEXCEPT,
+ void *ptr)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void *(*get_user_ptr) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+ void (*set_user_ptr) (emacs_env *env, emacs_value arg, void *ptr)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*(*get_user_finalizer) (emacs_env *env, emacs_value uptr))
+ (void *) EMACS_NOEXCEPT EMACS_ATTRIBUTE_NONNULL(1);
+ void (*set_user_finalizer) (emacs_env *env, emacs_value arg,
+ void (*fin) (void *) EMACS_NOEXCEPT)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Vector functions. */
+ emacs_value (*vec_get) (emacs_env *env, emacs_value vector, ptrdiff_t index)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*vec_set) (emacs_env *env, emacs_value vector, ptrdiff_t index,
+ emacs_value value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ ptrdiff_t (*vec_size) (emacs_env *env, emacs_value vector)
+ EMACS_ATTRIBUTE_NONNULL(1);
+};
+
+struct emacs_env_26
+{
+ /* Structure size (for version checking). */
+ ptrdiff_t size;
+
+ /* Private data; users should not touch this. */
+ struct emacs_env_private *private_members;
+
+ /* Memory management. */
+
+ emacs_value (*make_global_ref) (emacs_env *env, emacs_value value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*free_global_ref) (emacs_env *env, emacs_value global_value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Non-local exit handling. */
+
+ enum emacs_funcall_exit (*non_local_exit_check) (emacs_env *env)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*non_local_exit_clear) (emacs_env *env)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ enum emacs_funcall_exit (*non_local_exit_get)
+ (emacs_env *env, emacs_value *symbol, emacs_value *data)
+ EMACS_ATTRIBUTE_NONNULL(1, 2, 3);
+
+ void (*non_local_exit_signal) (emacs_env *env,
+ emacs_value symbol, emacs_value data)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*non_local_exit_throw) (emacs_env *env,
+ emacs_value tag, emacs_value value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Function registration. */
+
+ emacs_value (*make_function) (emacs_env *env,
+ ptrdiff_t min_arity,
+ ptrdiff_t max_arity,
+ emacs_value (*func) (emacs_env *env,
+ ptrdiff_t nargs,
+ emacs_value* args,
+ void *data)
+ EMACS_NOEXCEPT
+ EMACS_ATTRIBUTE_NONNULL(1),
+ const char *docstring,
+ void *data)
+ EMACS_ATTRIBUTE_NONNULL(1, 4);
+
+ emacs_value (*funcall) (emacs_env *env,
+ emacs_value func,
+ ptrdiff_t nargs,
+ emacs_value* args)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ emacs_value (*intern) (emacs_env *env, const char *name)
+ EMACS_ATTRIBUTE_NONNULL(1, 2);
+
+ /* Type conversion. */
+
+ emacs_value (*type_of) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ bool (*is_not_nil) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ bool (*eq) (emacs_env *env, emacs_value a, emacs_value b)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ intmax_t (*extract_integer) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ emacs_value (*make_integer) (emacs_env *env, intmax_t n)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ double (*extract_float) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ emacs_value (*make_float) (emacs_env *env, double d)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Copy the content of the Lisp string VALUE to BUFFER as an utf8
+ null-terminated string.
+
+ SIZE must point to the total size of the buffer. If BUFFER is
+ NULL or if SIZE is not big enough, write the required buffer size
+ to SIZE and return true.
+
+ Note that SIZE must include the last null byte (e.g. "abc" needs
+ a buffer of size 4).
+
+ Return true if the string was successfully copied. */
+
+ bool (*copy_string_contents) (emacs_env *env,
+ emacs_value value,
+ char *buf,
+ ptrdiff_t *len)
+ EMACS_ATTRIBUTE_NONNULL(1, 4);
+
+ /* Create a Lisp string from a utf8 encoded string. */
+ emacs_value (*make_string) (emacs_env *env,
+ const char *str, ptrdiff_t len)
+ EMACS_ATTRIBUTE_NONNULL(1, 2);
+
+ /* Embedded pointer type. */
+ emacs_value (*make_user_ptr) (emacs_env *env,
+ void (*fin) (void *) EMACS_NOEXCEPT,
+ void *ptr)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void *(*get_user_ptr) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+ void (*set_user_ptr) (emacs_env *env, emacs_value arg, void *ptr)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*(*get_user_finalizer) (emacs_env *env, emacs_value uptr))
+ (void *) EMACS_NOEXCEPT EMACS_ATTRIBUTE_NONNULL(1);
+ void (*set_user_finalizer) (emacs_env *env, emacs_value arg,
+ void (*fin) (void *) EMACS_NOEXCEPT)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Vector functions. */
+ emacs_value (*vec_get) (emacs_env *env, emacs_value vector, ptrdiff_t index)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*vec_set) (emacs_env *env, emacs_value vector, ptrdiff_t index,
+ emacs_value value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ ptrdiff_t (*vec_size) (emacs_env *env, emacs_value vector)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Returns whether a quit is pending. */
+ bool (*should_quit) (emacs_env *env)
+ EMACS_ATTRIBUTE_NONNULL(1);
+};
+
+struct emacs_env_27
+{
+ /* Structure size (for version checking). */
+ ptrdiff_t size;
+
+ /* Private data; users should not touch this. */
+ struct emacs_env_private *private_members;
+
+ /* Memory management. */
+
+ emacs_value (*make_global_ref) (emacs_env *env, emacs_value value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*free_global_ref) (emacs_env *env, emacs_value global_value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Non-local exit handling. */
+
+ enum emacs_funcall_exit (*non_local_exit_check) (emacs_env *env)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*non_local_exit_clear) (emacs_env *env)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ enum emacs_funcall_exit (*non_local_exit_get)
+ (emacs_env *env, emacs_value *symbol, emacs_value *data)
+ EMACS_ATTRIBUTE_NONNULL(1, 2, 3);
+
+ void (*non_local_exit_signal) (emacs_env *env,
+ emacs_value symbol, emacs_value data)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*non_local_exit_throw) (emacs_env *env,
+ emacs_value tag, emacs_value value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Function registration. */
+
+ emacs_value (*make_function) (emacs_env *env,
+ ptrdiff_t min_arity,
+ ptrdiff_t max_arity,
+ emacs_value (*func) (emacs_env *env,
+ ptrdiff_t nargs,
+ emacs_value* args,
+ void *data)
+ EMACS_NOEXCEPT
+ EMACS_ATTRIBUTE_NONNULL(1),
+ const char *docstring,
+ void *data)
+ EMACS_ATTRIBUTE_NONNULL(1, 4);
+
+ emacs_value (*funcall) (emacs_env *env,
+ emacs_value func,
+ ptrdiff_t nargs,
+ emacs_value* args)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ emacs_value (*intern) (emacs_env *env, const char *name)
+ EMACS_ATTRIBUTE_NONNULL(1, 2);
+
+ /* Type conversion. */
+
+ emacs_value (*type_of) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ bool (*is_not_nil) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ bool (*eq) (emacs_env *env, emacs_value a, emacs_value b)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ intmax_t (*extract_integer) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ emacs_value (*make_integer) (emacs_env *env, intmax_t n)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ double (*extract_float) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ emacs_value (*make_float) (emacs_env *env, double d)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Copy the content of the Lisp string VALUE to BUFFER as an utf8
+ null-terminated string.
+
+ SIZE must point to the total size of the buffer. If BUFFER is
+ NULL or if SIZE is not big enough, write the required buffer size
+ to SIZE and return true.
+
+ Note that SIZE must include the last null byte (e.g. "abc" needs
+ a buffer of size 4).
+
+ Return true if the string was successfully copied. */
+
+ bool (*copy_string_contents) (emacs_env *env,
+ emacs_value value,
+ char *buf,
+ ptrdiff_t *len)
+ EMACS_ATTRIBUTE_NONNULL(1, 4);
+
+ /* Create a Lisp string from a utf8 encoded string. */
+ emacs_value (*make_string) (emacs_env *env,
+ const char *str, ptrdiff_t len)
+ EMACS_ATTRIBUTE_NONNULL(1, 2);
+
+ /* Embedded pointer type. */
+ emacs_value (*make_user_ptr) (emacs_env *env,
+ void (*fin) (void *) EMACS_NOEXCEPT,
+ void *ptr)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void *(*get_user_ptr) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+ void (*set_user_ptr) (emacs_env *env, emacs_value arg, void *ptr)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*(*get_user_finalizer) (emacs_env *env, emacs_value uptr))
+ (void *) EMACS_NOEXCEPT EMACS_ATTRIBUTE_NONNULL(1);
+ void (*set_user_finalizer) (emacs_env *env, emacs_value arg,
+ void (*fin) (void *) EMACS_NOEXCEPT)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Vector functions. */
+ emacs_value (*vec_get) (emacs_env *env, emacs_value vector, ptrdiff_t index)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*vec_set) (emacs_env *env, emacs_value vector, ptrdiff_t index,
+ emacs_value value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ ptrdiff_t (*vec_size) (emacs_env *env, emacs_value vector)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Returns whether a quit is pending. */
+ bool (*should_quit) (emacs_env *env)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Processes pending input events and returns whether the module
+ function should quit. */
+ enum emacs_process_input_result (*process_input) (emacs_env *env)
+ EMACS_ATTRIBUTE_NONNULL (1);
+
+ struct timespec (*extract_time) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL (1);
+
+ emacs_value (*make_time) (emacs_env *env, struct timespec time)
+ EMACS_ATTRIBUTE_NONNULL (1);
+
+ bool (*extract_big_integer) (emacs_env *env, emacs_value arg, int *sign,
+ ptrdiff_t *count, emacs_limb_t *magnitude)
+ EMACS_ATTRIBUTE_NONNULL (1);
+
+ emacs_value (*make_big_integer) (emacs_env *env, int sign, ptrdiff_t count,
+ const emacs_limb_t *magnitude)
+ EMACS_ATTRIBUTE_NONNULL (1);
+};
+
+struct emacs_env_28
+{
+ /* Structure size (for version checking). */
+ ptrdiff_t size;
+
+ /* Private data; users should not touch this. */
+ struct emacs_env_private *private_members;
+
+ /* Memory management. */
+
+ emacs_value (*make_global_ref) (emacs_env *env, emacs_value value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*free_global_ref) (emacs_env *env, emacs_value global_value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Non-local exit handling. */
+
+ enum emacs_funcall_exit (*non_local_exit_check) (emacs_env *env)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*non_local_exit_clear) (emacs_env *env)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ enum emacs_funcall_exit (*non_local_exit_get)
+ (emacs_env *env, emacs_value *symbol, emacs_value *data)
+ EMACS_ATTRIBUTE_NONNULL(1, 2, 3);
+
+ void (*non_local_exit_signal) (emacs_env *env,
+ emacs_value symbol, emacs_value data)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*non_local_exit_throw) (emacs_env *env,
+ emacs_value tag, emacs_value value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Function registration. */
+
+ emacs_value (*make_function) (emacs_env *env,
+ ptrdiff_t min_arity,
+ ptrdiff_t max_arity,
+ emacs_value (*func) (emacs_env *env,
+ ptrdiff_t nargs,
+ emacs_value* args,
+ void *data)
+ EMACS_NOEXCEPT
+ EMACS_ATTRIBUTE_NONNULL(1),
+ const char *docstring,
+ void *data)
+ EMACS_ATTRIBUTE_NONNULL(1, 4);
+
+ emacs_value (*funcall) (emacs_env *env,
+ emacs_value func,
+ ptrdiff_t nargs,
+ emacs_value* args)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ emacs_value (*intern) (emacs_env *env, const char *name)
+ EMACS_ATTRIBUTE_NONNULL(1, 2);
+
+ /* Type conversion. */
+
+ emacs_value (*type_of) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ bool (*is_not_nil) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ bool (*eq) (emacs_env *env, emacs_value a, emacs_value b)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ intmax_t (*extract_integer) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ emacs_value (*make_integer) (emacs_env *env, intmax_t n)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ double (*extract_float) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ emacs_value (*make_float) (emacs_env *env, double d)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Copy the content of the Lisp string VALUE to BUFFER as an utf8
+ null-terminated string.
+
+ SIZE must point to the total size of the buffer. If BUFFER is
+ NULL or if SIZE is not big enough, write the required buffer size
+ to SIZE and return true.
+
+ Note that SIZE must include the last null byte (e.g. "abc" needs
+ a buffer of size 4).
+
+ Return true if the string was successfully copied. */
+
+ bool (*copy_string_contents) (emacs_env *env,
+ emacs_value value,
+ char *buf,
+ ptrdiff_t *len)
+ EMACS_ATTRIBUTE_NONNULL(1, 4);
+
+ /* Create a Lisp string from a utf8 encoded string. */
+ emacs_value (*make_string) (emacs_env *env,
+ const char *str, ptrdiff_t len)
+ EMACS_ATTRIBUTE_NONNULL(1, 2);
+
+ /* Embedded pointer type. */
+ emacs_value (*make_user_ptr) (emacs_env *env,
+ void (*fin) (void *) EMACS_NOEXCEPT,
+ void *ptr)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void *(*get_user_ptr) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL(1);
+ void (*set_user_ptr) (emacs_env *env, emacs_value arg, void *ptr)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*(*get_user_finalizer) (emacs_env *env, emacs_value uptr))
+ (void *) EMACS_NOEXCEPT EMACS_ATTRIBUTE_NONNULL(1);
+ void (*set_user_finalizer) (emacs_env *env, emacs_value arg,
+ void (*fin) (void *) EMACS_NOEXCEPT)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Vector functions. */
+ emacs_value (*vec_get) (emacs_env *env, emacs_value vector, ptrdiff_t index)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ void (*vec_set) (emacs_env *env, emacs_value vector, ptrdiff_t index,
+ emacs_value value)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ ptrdiff_t (*vec_size) (emacs_env *env, emacs_value vector)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Returns whether a quit is pending. */
+ bool (*should_quit) (emacs_env *env)
+ EMACS_ATTRIBUTE_NONNULL(1);
+
+ /* Processes pending input events and returns whether the module
+ function should quit. */
+ enum emacs_process_input_result (*process_input) (emacs_env *env)
+ EMACS_ATTRIBUTE_NONNULL (1);
+
+ struct timespec (*extract_time) (emacs_env *env, emacs_value arg)
+ EMACS_ATTRIBUTE_NONNULL (1);
+
+ emacs_value (*make_time) (emacs_env *env, struct timespec time)
+ EMACS_ATTRIBUTE_NONNULL (1);
+
+ bool (*extract_big_integer) (emacs_env *env, emacs_value arg, int *sign,
+ ptrdiff_t *count, emacs_limb_t *magnitude)
+ EMACS_ATTRIBUTE_NONNULL (1);
+
+ emacs_value (*make_big_integer) (emacs_env *env, int sign, ptrdiff_t count,
+ const emacs_limb_t *magnitude)
+ EMACS_ATTRIBUTE_NONNULL (1);
+
+ /* Add module environment functions newly added in Emacs 28 here.
+ Before Emacs 28 is released, remove this comment and start
+ module-env-29.h on the master branch. */
+
+ void (*(*EMACS_ATTRIBUTE_NONNULL (1)
+ get_function_finalizer) (emacs_env *env,
+ emacs_value arg)) (void *) EMACS_NOEXCEPT;
+
+ void (*set_function_finalizer) (emacs_env *env, emacs_value arg,
+ void (*fin) (void *) EMACS_NOEXCEPT)
+ EMACS_ATTRIBUTE_NONNULL (1);
+
+ int (*open_channel) (emacs_env *env, emacs_value pipe_process)
+ EMACS_ATTRIBUTE_NONNULL (1);
+
+ void (*make_interactive) (emacs_env *env, emacs_value function,
+ emacs_value spec)
+ EMACS_ATTRIBUTE_NONNULL (1);
+
+ /* Create a unibyte Lisp string from a string. */
+ emacs_value (*make_unibyte_string) (emacs_env *env,
+ const char *str, ptrdiff_t len)
+ EMACS_ATTRIBUTE_NONNULL(1, 2);
+};
+
+/* Every module should define a function as follows. */
+extern int emacs_module_init (struct emacs_runtime *runtime)
+ EMACS_NOEXCEPT
+ EMACS_ATTRIBUTE_NONNULL (1);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EMACS_MODULE_H */
diff --git a/src/tree-sitter-lang.in b/src/tree-sitter-lang.in
new file mode 100644
index 0000000..4d27421
--- /dev/null
+++ b/src/tree-sitter-lang.in
@@ -0,0 +1,79 @@
+#include <string.h>
+#include <tree_sitter/parser.h>
+#include "emacs-module.h"
+
+int plugin_is_GPL_compatible;
+
+extern TSLanguage *tree_sitter_LANG_C(void);
+
+/* REF: http://diobla.info/blog-archive/modules-tut.html */
+
+/* Return a USER_PTR to the language definition. */
+static emacs_value
+Ftree_sitter_language
+(emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data)
+{
+ TSLanguage *language = tree_sitter_LANG_C();
+ return env->make_user_ptr (env, NULL, language);
+}
+
+/* Use this command to "dump" the file:
+ xxd -i < grammar.js > parser.c.dump
+ */
+static emacs_value
+Ftree_sitter_grammar
+(emacs_env *env, ptrdiff_t nargs, emacs_value args[], void *data)
+{
+ char grammar[] = {
+#include "grammar.js.dump"
+ , '\0' };
+ return env->make_string (env, grammar, strlen(grammar));
+}
+
+/* Bind NAME to FUN. */
+static void
+bind_function (emacs_env *env, const char *name, emacs_value Sfun)
+{
+ /* Set the function cell of the symbol named NAME to SFUN using
+ the 'fset' function. */
+
+ /* Convert the strings to symbols by interning them. */
+ emacs_value Qfset = env->intern (env, "fset");
+ emacs_value Qsym = env->intern (env, name);
+
+ emacs_value args[] = { Qsym, Sfun };
+ env->funcall (env, Qfset, 2, args);
+}
+
+/* Provide FEATURE to Emacs. */
+static void
+provide (emacs_env *env, const char *feature)
+{
+ /* Call 'provide' with FEATURE converted to a symbol. */
+ emacs_value Qfeat = env->intern (env, feature);
+ emacs_value Qprovide = env->intern (env, "provide");
+ emacs_value args[] = { Qfeat };
+
+ env->funcall (env, Qprovide, 1, args);
+}
+
+int
+emacs_module_init (struct emacs_runtime *ert)
+{
+ emacs_env *env = ert->get_environment (ert);
+
+ emacs_value lang = env->make_function
+ (env, 0, 0, &Ftree_sitter_language,
+ "Return a language object.", NULL);
+
+ emacs_value grammar = env->make_function
+ (env, 0, 0, &Ftree_sitter_grammar,
+ "Return a language definition.", NULL);
+
+ bind_function (env, "tree-sitter-LANG", lang);
+ bind_function (env, "tree-sitter-LANG-grammar", grammar);
+ provide (env, "tree-sitter-LANG");
+
+ /* Return 0 to indicate module loaded successfully. */
+ return 0;
+}
--
2.38.1
[-- Attachment #3: Type: text/plain, Size: 7775 bytes --]
--8<---------------cut here---------------start------------->8---
(define (emacs-tree-sitter-grammar org lang version commit hash
synopsis)
(let ((name
(string-append "emacs-tree-sitter-grammar-" lang))
(home-page
(string-append "https://github.com/" org "/tree-sitter-"
lang))
(src-dir (if (equal? "typescript" lang) "tsx/" ""))
(lib (format #f "libtree-sitter-~a.so"
(if (equal? "typescript" lang) "tsx" lang))))
(package
(name name)
(version version)
(home-page home-page)
(source (origin
(method git-fetch)
(uri (git-reference
(url home-page)
(commit commit)))
(file-name (git-file-name name version))
;; Patch includes two files necessary to build
each grammar
;; in emacs-with-tree-sitter loadable way. Files
are
;; emacs-module.h and tree-sitter-lang.in,
originated
;; from
https://github.com/casouri/tree-sitter-module.
(patches (list (local-file
"emacs-tree-sitter-module.patch")))
(modules '((guix build utils)))
(snippet
#~(begin
(copy-file (string-append #$src-dir
"grammar.js")
(string-append #$src-dir
"src/grammar.js"))
(for-each
(lambda (f) (rename-file f (string-append
#$src-dir f)))
'("src/emacs-module.h"
"src/tree-sitter-lang.in"))))
(sha256 (base32 hash))))
(build-system gnu-build-system)
(arguments
(list
;; Phases below and snippet above mimics actions from:
;;
https://github.com/casouri/tree-sitter-module/blob/master/build.sh
#:phases
#~(modify-phases %standard-phases
(delete 'configure)
(replace 'build
(lambda _
(with-directory-excursion (string-append #$src-dir
"src")
(let* ((scanner? (or (file-exists? "scanner.c")
(file-exists?
"scanner.cc")))
(CC (if (file-exists? "scanner.cc") "g++"
"gcc"))
(compile (lambda (f) (invoke CC "-fPIC"
"-c" "-I." f)))
(link-args `("-fPIC" "-shared" "parser.o"
,@(if scanner?
'("scanner.o") '())
"-o" ,#$lib)))
(invoke "gcc" "-fPIC" "-c" "-I." "parser.c")
(for-each
(lambda (f) (when (file-exists? f) (compile
f)))
'("scanner.c" "scanner.cc"))
(apply invoke CC link-args)))))
(delete 'check)
(replace 'install
(lambda _
(install-file (string-append #$src-dir "src/"
#$lib)
(string-append #$output
"/lib")))))))
(synopsis synopsis)
(description (string-append synopsis "."))
(license license:expat))))
(define-public emacs-tree-sitter-grammar-bash
(emacs-tree-sitter-grammar
"tree-sitter" "bash" "0.19.0" "v0.19.0"
"18c030bb65r50i6z37iy7jb9z9i8i36y7b08dbc9bchdifqsijs5"
"Bash grammar for tree-sitter in Emacs"))
(define-public emacs-tree-sitter-grammar-c
(emacs-tree-sitter-grammar
"tree-sitter" "c" "0.20.2" "v0.20.2"
"1w03r4l773ki4iq2xxsc2pqxf3pjsbybq3xq4glmnsihgylibn8v"
"C grammar for tree-sitter in Emacs"))
(define-public emacs-tree-sitter-grammar-cpp
(emacs-tree-sitter-grammar
"tree-sitter" "cpp" "0.20.0" "v0.20.0"
"0hxcpdvyyig8njga1mxp4qcnbbnr1d0aiy27vahijwbh98b081nr"
"C++ grammar for tree-sitter in Emacs"))
(define-public emacs-tree-sitter-grammar-css
(emacs-tree-sitter-grammar
"tree-sitter" "css" "0.19.0" "v0.19.0"
"014jrlgi7zfza9g38hsr4vlbi8964i5p7iglaih6qmzaiml7bja2"
"CSS grammar for tree-sitter in Emacs"))
(define-public emacs-tree-sitter-grammar-c-sharp
(emacs-tree-sitter-grammar
"tree-sitter" "c-sharp" "0.20.0" "v0.20.0"
"0lijbi5q49g50ji00p2lb45rvd76h07sif3xjl9b31yyxwillr6l"
"C# grammar for tree-sitter in Emacs"))
(define-public emacs-tree-sitter-grammar-elixir
(emacs-tree-sitter-grammar
"elixir-lang" "elixir" "0.0.1"
"0ba537df8692179f34cccc7efed05de6cf5178aa"
"1k35nfwnz8zjiw2mg8d6nphxp3gb7yhb0a5vw4cz2h3n10yyq75i"
"Elixir grammar for tree-sitter in Emacs"))
(define-public emacs-tree-sitter-grammar-go
(emacs-tree-sitter-grammar
"tree-sitter" "go" "0.19.1" "rust-0.19.1"
"0nxs47vd2fc2fr0qlxq496y852rwg39flhg334s7dlyq7d3lcx4x"
"Go grammar for tree-sitter in Emacs"))
(define-public emacs-tree-sitter-grammar-html
(emacs-tree-sitter-grammar
"tree-sitter" "html" "0.19.0" "v0.19.0"
"1hg7vbcy7bir6b8x11v0a4x0glvqnsqc3i2ixiarbxmycbgl3axy"
"HTML grammar for tree-sitter in Emacs"))
(define-public emacs-tree-sitter-grammar-java
(emacs-tree-sitter-grammar
"tree-sitter" "java" "0.20.0" "v0.20.0"
"1i9zfgqibinz3rkx6yws1wk49iys32x901dki65qihbxcmcfh341"
"Java grammar for tree-sitter in Emacs"))
(define-public emacs-tree-sitter-grammar-javascript
(emacs-tree-sitter-grammar
"tree-sitter" "javascript" "0.20.0" "rust-0.20.0"
"175yrk382n2di0c2xn4gpv8y4n83x1lg4hqn04vabf0yqynlkq67"
"JavaScript grammar for tree-sitter in Emacs"))
(define-public emacs-tree-sitter-grammar-json
(emacs-tree-sitter-grammar
"tree-sitter" "json" "0.19.0" "v0.19.0"
"06pjh31bv9ja9hlnykk257a6zh8bsxg2fqa54al7qk1r4n9ksnff"
"JSON grammar for tree-sitter in Emacs"))
(define-public emacs-tree-sitter-grammar-python
(emacs-tree-sitter-grammar
"tree-sitter" "python" "0.20.0" "v0.20.0"
"14nnnblbjxyri8x21kj59agiy3cn4fwfrab3dmidykdyq2r46f5w"
"Python grammar for tree-sitter in Emacs"))
(define-public emacs-tree-sitter-grammar-rust
(emacs-tree-sitter-grammar
"tree-sitter" "rust" "0.20.3" "v0.20.3"
"149jhy01mqvavwa8jlxb8bnn7sxpfq2x1w35si6zn60b7kqjlx8f"
"Rust grammar for tree-sitter in Emacs"))
(define-public emacs-tree-sitter-grammar-typescript
(emacs-tree-sitter-grammar
"tree-sitter" "typescript" "0.20.1" "v0.20.1"
"07fl9d968lal0aqj4f0n16p3n94cjkgfp54wynfr8gbdkjss5v5x"
"TypeScript/TSX grammar for tree-sitter in Emacs"))
(define-public emacs-next-pgtk-tree-sitter
(let ((commit "be67cc276a95a97a329fa633fef686ba06c8e6d2")
(revision "3"))
(package
(inherit emacs-next-pgtk)
(name "emacs-next-pgtk-tree-sitter")
(version (git-version "29.0.50" revision commit))
(source
(origin
(inherit (package-source emacs-next))
(method git-fetch)
(uri (git-reference
(url "https://git.savannah.gnu.org/git/emacs.git")
(commit commit)))
(file-name (git-file-name name version))
(sha256
(base32
"0daczbivmp1v8dzp98pn8d93m9np38avs0xyyvhd48b8ly71daia"))))
(arguments
(substitute-keyword-arguments (package-arguments
emacs-next-pgtk)
((#:configure-flags flags #~'())
#~(cons* "--with-tree-sitter" #$flags))))
(inputs
(modify-inputs
(package-inputs emacs-next-pgtk)
(prepend tree-sitter))))))
--8<---------------cut here---------------end--------------->8---
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: tree-sitter grammars for emacs memo
2022-12-04 16:04 tree-sitter grammars for emacs memo Murad Mamedov
@ 2023-01-26 17:18 ` Simon Tournier
0 siblings, 0 replies; 2+ messages in thread
From: Simon Tournier @ 2023-01-26 17:18 UTC (permalink / raw)
To: Murad Mamedov, Guix-devel
Hi,
Thanks for the tricks. :-)
On Sun, 04 Dec 2022 at 19:04, Murad Mamedov <muradm@encom.net> wrote:
> create mode 100644 src/emacs-module.h
> create mode 100644 src/tree-sitter-lang.in
>
> diff --git a/src/emacs-module.h b/src/emacs-module.h
> new file mode 100644
> index 0000000..1185c06
> --- /dev/null
> +++ b/src/emacs-module.h
[...]
> diff --git a/src/tree-sitter-lang.in b/src/tree-sitter-lang.in
> new file mode 100644
> index 0000000..4d27421
> --- /dev/null
> +++ b/src/tree-sitter-lang.in
What does Emacs upstream think about this? Discussion on emacs-devel
about tree-sitter are really lengthy. :-) Maybe it could be nice if
that fix would be in Emacs proper. Well, I do not know.
Cheers,
simon
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-01-26 17:39 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-04 16:04 tree-sitter grammars for emacs memo Murad Mamedov
2023-01-26 17:18 ` Simon Tournier
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.