From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp10.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id 6KRrAsiSjWMONwAAbAwnHQ (envelope-from ) for ; Mon, 05 Dec 2022 07:42:16 +0100 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp10.migadu.com with LMTPS id EHp+AciSjWNJLgAAG6o9tA (envelope-from ) for ; Mon, 05 Dec 2022 07:42:16 +0100 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 2D161150FD for ; Mon, 5 Dec 2022 07:42:15 +0100 (CET) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1p25Ai-0005xi-BK; Mon, 05 Dec 2022 01:41:48 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p1rrh-0001rM-66 for guix-devel@gnu.org; Sun, 04 Dec 2022 11:29:17 -0500 Received: from mail-am6eur05on2060e.outbound.protection.outlook.com ([2a01:111:f400:7e1b::60e] helo=EUR05-AM6-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1p1rrc-0005xb-S2 for guix-devel@gnu.org; Sun, 04 Dec 2022 11:29:16 -0500 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YY8IEXQ84mrhdunOq7NHCLtZv7LGKn6v6iVE5+yj7eZLwbaftaim8BIYC82WZVSa8k/QSnPIjxsgNRhRVZy8B4B1Axev3D0OB1z7zvCSKEivPLhKlFMmeoxBcpEKsth0Rug50J3Dwb3kZyRBhlXid/adxPI4ZZXAHfgN2AJuKafDAbnxEqlsBEQCrJRPBXuR5kJPVMbghV7EoZnyQWd68DC0Q7cpoLVt+sOLhIjbaYs7UHwN35hQdRPmb9wOUKlXkul45H7StZKWNtgnaTx/Mm5Rr4bSfFlYRE4AysdiTb3MDNkrRN+t9wRgfxDtz8mEGokvG9KM5/RLmBrglwv1SQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=gBj10+EFFfkN+OzVPUDfRJUnJdRQPlzjBABJM6FdQag=; b=ZEzHxtrZR8mNCIyN2yyq0xRWD4lxQzIDxbJ2fA+eulVyr96caEupHH623yaVqYj9pr59Yg5/JATIC5DtPO4eBBP0bjC8VfcTv20b4OcIY1rwMeCj0oDaEqG2e7By6h7HwC6+fI+enyE/iScCTbamdaE/EQsa2mgKs1zsyOoQ++HwNX5Zknyq83h/hX7TaLU9xZ3lQRqkOElGBeraiIbV+55vq5OoN4DhVpyx87AnfC9nxTKqtds+8nVjH7C6fVrCgah+gFpLVKXYpi8ebQH32FOXadWJbxlDB4sigKnMHRRfBfuejmUDnoXAb2I9Erg7ceff07OZNvfOa/RlKILEYg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=encom.net; dmarc=pass action=none header.from=encom.net; dkim=pass header.d=encom.net; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=encomnet.onmicrosoft.com; s=selector2-encomnet-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=gBj10+EFFfkN+OzVPUDfRJUnJdRQPlzjBABJM6FdQag=; b=hRwkQIHrhDBgE5aBuGzlf5wG2IeS765ZreOnBcUIBVnRl7J15EkGYHKTGlJbfy/zOg3qvSjcC2NQ+IQikLZs18PewVKfObYjxCzYsC3VekhbgQ3AOD6j3LMTtYwYRYtY4rznMr+rRbDwzl6cYppopzEU+Tjm5xSvQp3A/yHfASU= Received: from AM0PR02MB5747.eurprd02.prod.outlook.com (2603:10a6:208:18d::12) by DB9PR02MB9897.eurprd02.prod.outlook.com (2603:10a6:10:456::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5880.10; Sun, 4 Dec 2022 16:24:05 +0000 Received: from AM0PR02MB5747.eurprd02.prod.outlook.com ([fe80::4bca:85f7:de5:aeed]) by AM0PR02MB5747.eurprd02.prod.outlook.com ([fe80::4bca:85f7:de5:aeed%5]) with mapi id 15.20.5880.013; Sun, 4 Dec 2022 16:24:05 +0000 User-agent: mu4e 1.8.11; emacs 29.0.50 From: Murad Mamedov To: Guix-devel Subject: tree-sitter grammars for emacs memo Date: Sun, 04 Dec 2022 19:04:02 +0300 Message-ID: <87sfhvm927.fsf@encom.net> Content-Type: multipart/mixed; boundary="=-=-=" X-ClientProxiedBy: ZR0P278CA0096.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:23::11) To AM0PR02MB5747.eurprd02.prod.outlook.com (2603:10a6:208:18d::12) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AM0PR02MB5747:EE_|DB9PR02MB9897:EE_ X-MS-Office365-Filtering-Correlation-Id: 3cd3f615-e958-44a8-3dc8-08dad613f519 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: oxxCxAUFyu+JrDfu3bE4UdKoUKvHmfRhA7a4HZzkOnPqpXPMaRjz9dHVoX50tPbxvrA75RHotvgknv4k+I92YSFK4IcMfwEviyg44ArqHLNW2LBLlOCYu3VzLQL+ylWJWBpsaYIDIUob+zoJmBjdU/pt5pLBd4ucmgAqKEr8YAh2a19jtM+Y8q7MrLsJqvHZTcvDKTBMSnY0X0ygNDJ3arEXKeIk+6E5Q4nw0wZdKM2sqMMqFb5srtRw0VUNzvkv6hSn7VihyFij7e4jk+sf7Xz4/yooTl3Ek+ehukx04YBdLZY4nMTR3kA9v7HcyvYAQ76FYU9Ru7kkieHU8MEELACeKL68TajTl/iEFYeNon2TBzNTvk8Ns++WEF9LhznP4gMa7MG6IhCJuzEuJhEsRDdl6cDsCTApxIAeYacmW1ZtTQEYuHHy5l/BuDOobf0z0VcLwwYgZZzndI/D0dpqLkjGKXyKu86KVvgbpZEWYd29Aeg/AObJgia9K7bwToWyKF6l+lLaYQjnizzK9YnjjKM+inaqftKOL1MoFIU6mRDSsVWpugZtKIQGUf5OsoYLwDgLgGnJob6xKvzxVQCqBxaVhYKTfoirPxEX8S3pzL96OQJIS1DPuy1xrZ9NSKo98hjjgHrQTypr8lYHl5WfoRBDapxT/VTgg6FnvQ2q1cgdrMJAZ5kb4to9LMOz/HtjoOyFoOVp310jHxSEdVFo4bivz7efeMh+OjIwsavYxRg= X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM0PR02MB5747.eurprd02.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230022)(376002)(136003)(366004)(396003)(346002)(39830400003)(451199015)(66476007)(66556008)(2906002)(8676002)(66946007)(478600001)(966005)(6486002)(316002)(36756003)(235185007)(5660300002)(6916009)(6666004)(86362001)(52116002)(6506007)(6512007)(26005)(2616005)(186003)(8936002)(38350700002)(83380400001)(38100700002)(41300700001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?aS2YxN4gCz1Y09fIYp/koTEtzwlQ1Up5gwdC+tzcyf1Oik9xOEBLwnht/mCu?= =?us-ascii?Q?4bVTGX/2QYNyrtK0Fmq7nTlXZtAiH3Mj5p4Qm/fnAiky5KG6YfiXiYH32hxV?= =?us-ascii?Q?wV/hNps0LBqoE8z8bEyldGn1VzxpKguAHL3J3VapBvE+pUSxbtGBumlWkMbp?= =?us-ascii?Q?ofmCsvdSFk8XYI+yWz0gRtc4Oi9RF4WfNqvJl30Y0J9ph2/2MACshUY128+g?= =?us-ascii?Q?lHM8KljsPSExQ7LlstEcqn2UUiklt10DZdTySpeduO4xnyuBTzUEw9QjZeU2?= =?us-ascii?Q?HAi1C81djSvPQlX6up+e1x9hZtZK9lBupfCVBVPHcaihkb1Vg4HTaawevJEK?= =?us-ascii?Q?glb0qZp2yB3cvXWWm+4zbgym1gQlu84m/cOW4aDSbLisGOs+4SOuazHSsHRZ?= =?us-ascii?Q?a9bux3iotnvc80hCXl9MBS9QPj46qUd2NELL8B9zcqSZGPyhdYaDdq5NH77q?= =?us-ascii?Q?bbraTRs2C9Jqy9p6XtnH6Anki/9lkYXtWNpHW6SIvngvfQ6MpjsnQa8QB1eJ?= =?us-ascii?Q?2xGMql3msmxx8OJNXm3m2N0xaS5fae1XdW2AvUOHCqbRqvrgcp4M9+kQNXE0?= =?us-ascii?Q?hfsosSxHWa5ZMXiIK0U8sKjPSpLRcFYdokZ8+0CQNvEZBSRTOLzQcM/s5ZDA?= =?us-ascii?Q?ISxkGum+9LQBveG8/5OQNWLUIsvoJlbyYhRrHduTUKcp2adQZ4afeRLulhiQ?= =?us-ascii?Q?ZJh8fCcdHY7HYu3yJ8TgGtH0tWk8mfP71gai3z9DScFnVdRLas3xsz48xR+7?= =?us-ascii?Q?uK1ykWJp0iWq4GeXTRnKUAA461J1F7f6APEK+6damnBHlvfmBE8Fkh/XRPvM?= =?us-ascii?Q?gBx6vSVoMfB0b4R25djmbT7nyiDW8qFdfr/z/KiDSjILWPyBlf/Fdc8doPmp?= =?us-ascii?Q?FsC4rYJoOZCAsLnHgNPP4aYtC39pI6iwJlYZ7vf8AiuU3r9pqtnzgHfqgufs?= =?us-ascii?Q?fr8h+5XWXCuvjeaqbP2nBDTqT3TKZp0FIMyEK003qPY3QQD/k5vKzAbQA1pL?= =?us-ascii?Q?YdF3AT8aV879+nqWhn2CPF+bAeTPQTzEtihKIta8oRTheEGzCY9Ihkp9Uf2+?= =?us-ascii?Q?akEG2/hRcjFIOuAjgORGJQ252UqVoX3VZ8qHEP56on9ofBFqfkAZpbWSvsx1?= =?us-ascii?Q?p6y49y/kvBB0yWdUNd8gnzsmNwaSqyGYHBOAv5w4yQy4gWHwVz67c8QvT7zr?= =?us-ascii?Q?WdAohgMzEE5eWiccAfk7wVs5uUaa/7e0e6Cac9DVn5YROAPKLfEvqyZCU1Y7?= =?us-ascii?Q?iWJ/qCnFEPqdlRMRbIQ6zVfq2AmzuG5zDPCOYd6QSK0NMx2yftAzeqIVkPEh?= =?us-ascii?Q?yhOG7rBabaFrjQbHJtBiP+g8J60fdgWzx5uF6Q5UOIuHMXXuAO1Vl02JqBJo?= =?us-ascii?Q?UFvy++RzaevvxOmRuRAa7Uux2FSq96vUlGp43xAX3eLUNO/Mm2N5mt8KrhKF?= =?us-ascii?Q?i/76mSKAYFKM1h6oUJ8tAs+ssYO2X+17EGVZGat+0EuVrYSNBeuuptirLj97?= =?us-ascii?Q?sC/97/UBKWTOu8AMlL8tquU35iXk0Gy4fTqYi9ssThPIoP21VTpzhVCrRxwC?= =?us-ascii?Q?05lheoInE380oGr/OSPFAjplmB68tpnpYjq3FA6j?= X-OriginatorOrg: encom.net X-MS-Exchange-CrossTenant-Network-Message-Id: 3cd3f615-e958-44a8-3dc8-08dad613f519 X-MS-Exchange-CrossTenant-AuthSource: AM0PR02MB5747.eurprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 04 Dec 2022 16:24:05.0838 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: b21dea5a-2d19-4db2-a1a6-845182667e66 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: e8HGmSO6lBGX+dGThkvO67pCwEQGMc/ParrcJWPqnBUNqlYIh3vtma9Yoz8uJ6wxABPvY45pRiVceyBLaSDvNg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR02MB9897 Received-SPF: pass client-ip=2a01:111:f400:7e1b::60e; envelope-from=muradm@encom.net; helo=EUR05-AM6-obe.outbound.protection.outlook.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Mon, 05 Dec 2022 01:41:41 -0500 X-BeenThere: guix-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+larch=yhetil.org@gnu.org Sender: guix-devel-bounces+larch=yhetil.org@gnu.org X-Migadu-Flow: FLOW_IN X-Migadu-Country: US ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1670222535; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=gBj10+EFFfkN+OzVPUDfRJUnJdRQPlzjBABJM6FdQag=; b=p1N0/kFoZKEUUWBr3kKb/prnfBNwUfns6jzBNEMv7wKjnjiaPjoe+6dLW7fYPQ4pvXJQjO bfgPDybUHIqUdv77pOxBX0P3brBLiKB8qVxLbT3h+ks7lFNggK1CQRiDf9FkUkxa0FDm60 M6sH0KSNXBJD/NpgcALFi6WZS6WMNKb5fPQNy70V2/SYIwSPw1Uxmilfz/AOwdm2gchf1X NwHr1pmUbq9y1dhn1hlB3nYB8y7at+j04yu1nnirK4lSKOjjjvo7PeeEjiQoqXw3mpXCja pkwRbtp2hod25M2xbFLn/D/IMIzwiRvQswuyqF9Bi2r91guPWXOAEBSdlHAAxQ== ARC-Seal: i=2; s=key1; d=yhetil.org; t=1670222535; a=rsa-sha256; cv=pass; b=bGk5Gi4mrzPVeXDIoh9BecFgSVRfwcJLg0e5CpKz9S6lYB5laM6agcx9sOXp0by4rbVzth xo4dwkcFD2jUb9+vVoFuJhMi7WwP0ImQtP7/gQEnFOY42LOf/2QJr78Z0ge8RJ7y1rcX5P 85NCNbAf+dJpzO4eE1JMtQP2FxyzSGj63T3mEZJeWx0vxfYywe4Y4Hz8G/6j9atzh9+sVa JOStmca+AXLokWfHHsRBpIWhs6PnuIo5rFGl2SOcnT5sf/FcKZpudgj0lvRF/BvjLEYufD 3V3V3mL8fVJ5wykkBU7eE0TjcWBhSGgxS5U/GP1xrU7MkhPzxepugndAPuJtcQ== ARC-Authentication-Results: i=2; aspmx1.migadu.com; dkim=pass header.d=encomnet.onmicrosoft.com header.s=selector2-encomnet-onmicrosoft-com header.b=hRwkQIHr; arc=pass ("microsoft.com:s=arcselector9901:i=1"); dmarc=none; spf=pass (aspmx1.migadu.com: domain of "guix-devel-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-devel-bounces+larch=yhetil.org@gnu.org" X-Migadu-Spam-Score: -6.47 Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=encomnet.onmicrosoft.com header.s=selector2-encomnet-onmicrosoft-com header.b=hRwkQIHr; arc=pass ("microsoft.com:s=arcselector9901:i=1"); dmarc=none; spf=pass (aspmx1.migadu.com: domain of "guix-devel-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-devel-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: 2D161150FD X-Spam-Score: -6.47 X-Migadu-Scanner: scn0.migadu.com X-TUID: oeI2O8nQtsuS --=-=-= Content-Type: text/plain; format=flowed 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 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=emacs-tree-sitter-module.patch >From c8a8db2d46b5320185aaa5ba4ec9d7e8764af592 Mon Sep 17 00:00:00 2001 From: muradm 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 . */ + +/* +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 +#include +#include + +#ifndef __cplusplus +#include +#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 +#include +#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 --=-=-= Content-Type: text/plain; format=flowed --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--- --=-=-=--