* Use (eval-when-compile 'treesit) to save us from writing declare-function forms @ 2024-12-03 6:31 Yuan Fu 2024-12-03 8:30 ` Andrea Corallo 2024-12-03 13:12 ` Eli Zaretskii 0 siblings, 2 replies; 18+ messages in thread From: Yuan Fu @ 2024-12-03 6:31 UTC (permalink / raw) To: Emacs Devel Some of my recent changes to c-ts-mode.el uses some more C treesit functions, and I (again) forgot to add their declare-function forms to c-ts-mode.el, and Andrea has to fix it for me. The main problem for me is that (I think) you don’t get warning for them unless you build a non-tree-sitter build of Emacs. So I’m prone to forgot about them. Also it’s a burden for anyone wanting to use tree-sitter functions. treesit.el already has all the declare-function forms, how about we use (eval-when-compile 'treesit) in other files? I believe that should alleviate us from adding those declare-function forms in other files? I want to ask because IIRC I proposed this a while back but there were objections, the details of which I forgot. Yuan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-03 6:31 Use (eval-when-compile 'treesit) to save us from writing declare-function forms Yuan Fu @ 2024-12-03 8:30 ` Andrea Corallo 2024-12-04 18:21 ` Yuan Fu 2024-12-03 13:12 ` Eli Zaretskii 1 sibling, 1 reply; 18+ messages in thread From: Andrea Corallo @ 2024-12-03 8:30 UTC (permalink / raw) To: Yuan Fu; +Cc: Emacs Devel Yuan Fu <casouri@gmail.com> writes: > Some of my recent changes to c-ts-mode.el uses some more C treesit > functions, and I (again) forgot to add their declare-function forms to > c-ts-mode.el, and Andrea has to fix it for me. The main problem for me > is that (I think) you don’t get warning for them unless you build a > non-tree-sitter build of Emacs. So I’m prone to forgot about > them. Also it’s a burden for anyone wanting to use tree-sitter > functions. > > treesit.el already has all the declare-function forms, how about we > use (eval-when-compile 'treesit) in other files? I believe that should > alleviate us from adding those declare-function forms in other files? > > I want to ask because IIRC I proposed this a while back but there were objections, the details of which I forgot. > > Yuan Hi Yuan, I was not part of the discussion and I don't know what's the downside of (eval-when-compile 'treesit), maybe another alternative would be to have like a dedicated treesit-delcs.el to require where necessary? Andrea ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-03 8:30 ` Andrea Corallo @ 2024-12-04 18:21 ` Yuan Fu 0 siblings, 0 replies; 18+ messages in thread From: Yuan Fu @ 2024-12-04 18:21 UTC (permalink / raw) To: Andrea Corallo; +Cc: Emacs Devel > On Dec 3, 2024, at 12:30 AM, Andrea Corallo <acorallo@gnu.org> wrote: > > Yuan Fu <casouri@gmail.com> writes: > >> Some of my recent changes to c-ts-mode.el uses some more C treesit >> functions, and I (again) forgot to add their declare-function forms to >> c-ts-mode.el, and Andrea has to fix it for me. The main problem for me >> is that (I think) you don’t get warning for them unless you build a >> non-tree-sitter build of Emacs. So I’m prone to forgot about >> them. Also it’s a burden for anyone wanting to use tree-sitter >> functions. >> >> treesit.el already has all the declare-function forms, how about we >> use (eval-when-compile 'treesit) in other files? I believe that should >> alleviate us from adding those declare-function forms in other files? >> >> I want to ask because IIRC I proposed this a while back but there were objections, the details of which I forgot. >> >> Yuan > > Hi Yuan, > > I was not part of the discussion and I don't know what's the downside of > (eval-when-compile 'treesit), maybe another alternative would be to have > like a dedicated treesit-delcs.el to require where necessary? > That’ll be ok too. Though 99.99% the case, if some package uses tree-sitter, they’d need something in treesit.el too. Yuan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-03 6:31 Use (eval-when-compile 'treesit) to save us from writing declare-function forms Yuan Fu 2024-12-03 8:30 ` Andrea Corallo @ 2024-12-03 13:12 ` Eli Zaretskii 2024-12-04 18:19 ` Yuan Fu 1 sibling, 1 reply; 18+ messages in thread From: Eli Zaretskii @ 2024-12-03 13:12 UTC (permalink / raw) To: Yuan Fu; +Cc: emacs-devel > From: Yuan Fu <casouri@gmail.com> > Date: Mon, 2 Dec 2024 22:31:48 -0800 > > Some of my recent changes to c-ts-mode.el uses some more C treesit functions, and I (again) forgot to add their declare-function forms to c-ts-mode.el, and Andrea has to fix it for me. The main problem for me is that (I think) you don’t get warning for them unless you build a non-tree-sitter build of Emacs. So I’m prone to forgot about them. Also it’s a burden for anyone wanting to use tree-sitter functions. > > treesit.el already has all the declare-function forms, how about we use (eval-when-compile 'treesit) in other files? I believe that should alleviate us from adding those declare-function forms in other files? I don't understand" c-ts-mode.el already does (require 'treesit) So what would eval-when-compile add to that? ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-03 13:12 ` Eli Zaretskii @ 2024-12-04 18:19 ` Yuan Fu 2024-12-04 18:57 ` Eli Zaretskii 2024-12-08 16:01 ` Dmitry Gutov 0 siblings, 2 replies; 18+ messages in thread From: Yuan Fu @ 2024-12-04 18:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel > On Dec 3, 2024, at 5:12 AM, Eli Zaretskii <eliz@gnu.org> wrote: > >> From: Yuan Fu <casouri@gmail.com> >> Date: Mon, 2 Dec 2024 22:31:48 -0800 >> >> Some of my recent changes to c-ts-mode.el uses some more C treesit functions, and I (again) forgot to add their declare-function forms to c-ts-mode.el, and Andrea has to fix it for me. The main problem for me is that (I think) you don’t get warning for them unless you build a non-tree-sitter build of Emacs. So I’m prone to forgot about them. Also it’s a burden for anyone wanting to use tree-sitter functions. >> >> treesit.el already has all the declare-function forms, how about we use (eval-when-compile 'treesit) in other files? I believe that should alleviate us from adding those declare-function forms in other files? > > I don't understand" c-ts-mode.el already does > > (require 'treesit) > > So what would eval-when-compile add to that? When Emacs is built without tree-sitter, none of the treesit.c functions are available (except for treesit-ready-p). Now if this Emacs compiles c-ts-mode.el, it’ll signal undefined function error for all those functions. So we add declare-function forms for all the treesit.c functions used in c-ts-mode.el, and have to update the declare-function forms whenever we use some new treesit.c functions. If we use eval-when-compile, we don’t need to write declare-function forms in c-ts-mode.el anymore, because treesit.el has declare-function forms for all treesit.c functions. Yuan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-04 18:19 ` Yuan Fu @ 2024-12-04 18:57 ` Eli Zaretskii 2024-12-05 6:25 ` Yuan Fu 2024-12-08 16:01 ` Dmitry Gutov 1 sibling, 1 reply; 18+ messages in thread From: Eli Zaretskii @ 2024-12-04 18:57 UTC (permalink / raw) To: Yuan Fu; +Cc: emacs-devel > From: Yuan Fu <casouri@gmail.com> > Date: Wed, 4 Dec 2024 10:19:42 -0800 > Cc: emacs-devel@gnu.org > > > > > On Dec 3, 2024, at 5:12 AM, Eli Zaretskii <eliz@gnu.org> wrote: > > > > I don't understand" c-ts-mode.el already does > > > > (require 'treesit) > > > > So what would eval-when-compile add to that? > > When Emacs is built without tree-sitter, none of the treesit.c functions are available (except for treesit-ready-p). Now if this Emacs compiles c-ts-mode.el, it’ll signal undefined function error for all those functions. So we add declare-function forms for all the treesit.c functions used in c-ts-mode.el, and have to update the declare-function forms whenever we use some new treesit.c functions. > > If we use eval-when-compile, we don’t need to write declare-function forms in c-ts-mode.el anymore, because treesit.el has declare-function forms for all treesit.c functions. That's what I don't understand: how will eval-when-compile which loads treesit.el be different from (require 'treesit) we already have in c-ts-mode? Don't they both load treesit.el? ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-04 18:57 ` Eli Zaretskii @ 2024-12-05 6:25 ` Yuan Fu 2024-12-05 7:07 ` Eli Zaretskii 0 siblings, 1 reply; 18+ messages in thread From: Yuan Fu @ 2024-12-05 6:25 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel > On Dec 4, 2024, at 10:57 AM, Eli Zaretskii <eliz@gnu.org> wrote: > >> From: Yuan Fu <casouri@gmail.com> >> Date: Wed, 4 Dec 2024 10:19:42 -0800 >> Cc: emacs-devel@gnu.org >> >> >> >>> On Dec 3, 2024, at 5:12 AM, Eli Zaretskii <eliz@gnu.org> wrote: >>> >>> I don't understand" c-ts-mode.el already does >>> >>> (require 'treesit) >>> >>> So what would eval-when-compile add to that? >> >> When Emacs is built without tree-sitter, none of the treesit.c functions are available (except for treesit-ready-p). Now if this Emacs compiles c-ts-mode.el, it’ll signal undefined function error for all those functions. So we add declare-function forms for all the treesit.c functions used in c-ts-mode.el, and have to update the declare-function forms whenever we use some new treesit.c functions. >> >> If we use eval-when-compile, we don’t need to write declare-function forms in c-ts-mode.el anymore, because treesit.el has declare-function forms for all treesit.c functions. > > That's what I don't understand: how will eval-when-compile which loads > treesit.el be different from (require 'treesit) we already have in > c-ts-mode? Don't they both load treesit.el? I maybe wrong here, but I thought if you don’t use eval-when-compile, simply byte-compiling c-ts-mode.el wouldn’t load treesit.el? Yuan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-05 6:25 ` Yuan Fu @ 2024-12-05 7:07 ` Eli Zaretskii 2024-12-07 1:12 ` Yuan Fu 0 siblings, 1 reply; 18+ messages in thread From: Eli Zaretskii @ 2024-12-05 7:07 UTC (permalink / raw) To: Yuan Fu; +Cc: emacs-devel > From: Yuan Fu <casouri@gmail.com> > Date: Wed, 4 Dec 2024 22:25:33 -0800 > Cc: emacs-devel@gnu.org > > >> If we use eval-when-compile, we don’t need to write declare-function forms in c-ts-mode.el anymore, because treesit.el has declare-function forms for all treesit.c functions. > > > > That's what I don't understand: how will eval-when-compile which loads > > treesit.el be different from (require 'treesit) we already have in > > c-ts-mode? Don't they both load treesit.el? > > I maybe wrong here, but I thought if you don’t use eval-when-compile, simply byte-compiling c-ts-mode.el wouldn’t load treesit.el? Yes, it would. You can clearly see this in a debugger if you put a breakpoint in Fload and then byte-compile c-ts-mode.el. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-05 7:07 ` Eli Zaretskii @ 2024-12-07 1:12 ` Yuan Fu 2024-12-07 7:51 ` Eli Zaretskii 0 siblings, 1 reply; 18+ messages in thread From: Yuan Fu @ 2024-12-07 1:12 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel > On Dec 4, 2024, at 11:07 PM, Eli Zaretskii <eliz@gnu.org> wrote: > >> From: Yuan Fu <casouri@gmail.com> >> Date: Wed, 4 Dec 2024 22:25:33 -0800 >> Cc: emacs-devel@gnu.org >> >>>> If we use eval-when-compile, we don’t need to write declare-function forms in c-ts-mode.el anymore, because treesit.el has declare-function forms for all treesit.c functions. >>> >>> That's what I don't understand: how will eval-when-compile which loads >>> treesit.el be different from (require 'treesit) we already have in >>> c-ts-mode? Don't they both load treesit.el? >> >> I maybe wrong here, but I thought if you don’t use eval-when-compile, simply byte-compiling c-ts-mode.el wouldn’t load treesit.el? > > Yes, it would. You can clearly see this in a debugger if you put a > breakpoint in Fload and then byte-compile c-ts-mode.el. Does that mean declare-function forms only affect the file it’s in? Because if treesit.el has declare-function forms for all the treesit.c functions, and c-ts-mode.el requires treesit.el, why do we need to have declare-function forms in c-ts-mode.el? Yuan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-07 1:12 ` Yuan Fu @ 2024-12-07 7:51 ` Eli Zaretskii 2024-12-07 13:47 ` Stefan Monnier 0 siblings, 1 reply; 18+ messages in thread From: Eli Zaretskii @ 2024-12-07 7:51 UTC (permalink / raw) To: Yuan Fu, Stefan Monnier; +Cc: emacs-devel > From: Yuan Fu <casouri@gmail.com> > Date: Fri, 6 Dec 2024 17:12:38 -0800 > Cc: emacs-devel@gnu.org > > > > > On Dec 4, 2024, at 11:07 PM, Eli Zaretskii <eliz@gnu.org> wrote: > > > >> From: Yuan Fu <casouri@gmail.com> > >> Date: Wed, 4 Dec 2024 22:25:33 -0800 > >> Cc: emacs-devel@gnu.org > >> > >>>> If we use eval-when-compile, we don’t need to write declare-function forms in c-ts-mode.el anymore, because treesit.el has declare-function forms for all treesit.c functions. > >>> > >>> That's what I don't understand: how will eval-when-compile which loads > >>> treesit.el be different from (require 'treesit) we already have in > >>> c-ts-mode? Don't they both load treesit.el? > >> > >> I maybe wrong here, but I thought if you don’t use eval-when-compile, simply byte-compiling c-ts-mode.el wouldn’t load treesit.el? > > > > Yes, it would. You can clearly see this in a debugger if you put a > > breakpoint in Fload and then byte-compile c-ts-mode.el. > > Does that mean declare-function forms only affect the file it’s in? Because if treesit.el has declare-function forms for all the treesit.c functions, and c-ts-mode.el requires treesit.el, why do we need to have declare-function forms in c-ts-mode.el? Seems like that. Stefan, am I missing something here? ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-07 7:51 ` Eli Zaretskii @ 2024-12-07 13:47 ` Stefan Monnier 2024-12-08 6:39 ` Yuan Fu 0 siblings, 1 reply; 18+ messages in thread From: Stefan Monnier @ 2024-12-07 13:47 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Yuan Fu, emacs-devel >> Does that mean declare-function forms only affect the file it’s in? >> Because if treesit.el has declare-function forms for all the treesit.c >> functions, and c-ts-mode.el requires treesit.el, why do we need to have >> declare-function forms in c-ts-mode.el? > Seems like that. Stefan, am I missing something here? Yes, `declare-function` *should* follow the same principles as `(defvar FOO)`, meaning that they are compiler directives not functions to execute. They affect warnings only in the current lexical scope, and requiring a file full of `(defvar FOO)` and `declare-function` will have no effect at all. [ Side note regarding this *should*: it currently doesn't work quite as well as `defvar` because its effect is always file-wide, whereas it should be limited to the current scope. ] Stefan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-07 13:47 ` Stefan Monnier @ 2024-12-08 6:39 ` Yuan Fu 2024-12-08 7:20 ` Eli Zaretskii 2024-12-08 15:27 ` Stefan Monnier 0 siblings, 2 replies; 18+ messages in thread From: Yuan Fu @ 2024-12-08 6:39 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1151 bytes --] > On Dec 7, 2024, at 5:47 AM, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > >>> Does that mean declare-function forms only affect the file it’s in? >>> Because if treesit.el has declare-function forms for all the treesit.c >>> functions, and c-ts-mode.el requires treesit.el, why do we need to have >>> declare-function forms in c-ts-mode.el? >> Seems like that. Stefan, am I missing something here? > > Yes, `declare-function` *should* follow the same principles as `(defvar > FOO)`, meaning that they are compiler directives not functions to > execute. They affect warnings only in the current lexical scope, and > requiring a file full of `(defvar FOO)` and `declare-function` will have > no effect at all. > > [ Side note regarding this *should*: it currently doesn't work quite as > well as `defvar` because its effect is always file-wide, whereas it > should be limited to the current scope. ] Defining a macro that contains the declare-function forms, and calling it in eval-when-compile forms seem to work (see patch), WDYT? The name (treesit-declare-c-functions) could be better, any ideas? Yuan [-- Attachment #2: declare-function.patch --] [-- Type: application/octet-stream, Size: 7491 bytes --] From ba77886d5e250770251d8c1abec93d4fcf0e0268 Mon Sep 17 00:00:00 2001 From: Yuan Fu <casouri@gmail.com> Date: Sat, 7 Dec 2024 22:13:07 -0800 Subject: [PATCH] declare-function POC --- lisp/progmodes/c-ts-mode.el | 17 +----- lisp/treesit.el | 103 ++++++++++++++++++++---------------- 2 files changed, 60 insertions(+), 60 deletions(-) diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index dec9411b87c..4a1f616b048 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -73,21 +73,8 @@ (require 'c-ts-common) (eval-when-compile (require 'rx)) -(declare-function treesit-parser-create "treesit.c") -(declare-function treesit-parser-root-node "treesit.c") -(declare-function treesit-parser-set-included-ranges "treesit.c") -(declare-function treesit-node-parent "treesit.c") -(declare-function treesit-node-start "treesit.c") -(declare-function treesit-node-end "treesit.c") -(declare-function treesit-node-child "treesit.c") -(declare-function treesit-node-child-by-field-name "treesit.c") -(declare-function treesit-node-type "treesit.c") -(declare-function treesit-node-prev-sibling "treesit.c") -(declare-function treesit-node-first-child-for-pos "treesit.c") -(declare-function treesit-node-next-sibling "treesit.c") -(declare-function treesit-node-eq "treesit.c") -(declare-function treesit-node-match-p "treesit.c") -(declare-function treesit-query-compile "treesit.c") +(eval-when-compile + (treesit-declare-c-functions)) ;;; Custom variables diff --git a/lisp/treesit.el b/lisp/treesit.el index db3a706f016..2e189394983 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -39,61 +39,74 @@ ;;; Function declarations -(declare-function treesit-language-available-p "treesit.c") -(declare-function treesit-language-version "treesit.c") +(defmacro treesit-declare-c-functions () + "Declare C functions and variables defined in treesit.c. -(declare-function treesit-parser-p "treesit.c") -(declare-function treesit-node-p "treesit.c") -(declare-function treesit-compiled-query-p "treesit.c") -(declare-function treesit-query-p "treesit.c") -(declare-function treesit-query-language "treesit.c") +This macro is only needed for byte-compiling in Emacs not built with +tree-sitter library. It should be used with `eval-when-compile' like +this: -(declare-function treesit-node-parser "treesit.c") + (eval-when-compile + (treesit-declare-c-functions))" + '(progn + (declare-function treesit-language-available-p "treesit.c") + (declare-function treesit-language-version "treesit.c") -(declare-function treesit-parser-create "treesit.c") -(declare-function treesit-parser-delete "treesit.c") -(declare-function treesit-parser-list "treesit.c") -(declare-function treesit-parser-buffer "treesit.c") -(declare-function treesit-parser-language "treesit.c") -(declare-function treesit-parser-tag "treesit.c") + (declare-function treesit-parser-p "treesit.c") + (declare-function treesit-node-p "treesit.c") + (declare-function treesit-compiled-query-p "treesit.c") + (declare-function treesit-query-p "treesit.c") + (declare-function treesit-query-language "treesit.c") -(declare-function treesit-parser-root-node "treesit.c") + (declare-function treesit-node-parser "treesit.c") -(declare-function treesit-parser-set-included-ranges "treesit.c") -(declare-function treesit-parser-included-ranges "treesit.c") -(declare-function treesit-parser-changed-ranges "treesit.c") -(declare-function treesit-parser-add-notifier "treesit.c") + (declare-function treesit-parser-create "treesit.c") + (declare-function treesit-parser-delete "treesit.c") + (declare-function treesit-parser-list "treesit.c") + (declare-function treesit-parser-buffer "treesit.c") + (declare-function treesit-parser-language "treesit.c") + (declare-function treesit-parser-tag "treesit.c") -(declare-function treesit-node-type "treesit.c") -(declare-function treesit-node-start "treesit.c") -(declare-function treesit-node-end "treesit.c") -(declare-function treesit-node-string "treesit.c") -(declare-function treesit-node-parent "treesit.c") -(declare-function treesit-node-child "treesit.c") -(declare-function treesit-node-check "treesit.c") -(declare-function treesit-node-field-name-for-child "treesit.c") -(declare-function treesit-node-child-count "treesit.c") -(declare-function treesit-node-child-by-field-name "treesit.c") -(declare-function treesit-node-next-sibling "treesit.c") -(declare-function treesit-node-prev-sibling "treesit.c") -(declare-function treesit-node-first-child-for-pos "treesit.c") -(declare-function treesit-node-descendant-for-range "treesit.c") -(declare-function treesit-node-eq "treesit.c") + (declare-function treesit-parser-root-node "treesit.c") -(declare-function treesit-pattern-expand "treesit.c") -(declare-function treesit-query-expand "treesit.c") -(declare-function treesit-query-compile "treesit.c") -(declare-function treesit-query-capture "treesit.c") + (declare-function treesit-parser-set-included-ranges "treesit.c") + (declare-function treesit-parser-included-ranges "treesit.c") + (declare-function treesit-parser-changed-ranges "treesit.c") + (declare-function treesit-parser-add-notifier "treesit.c") -(declare-function treesit-search-subtree "treesit.c") -(declare-function treesit-search-forward "treesit.c") -(declare-function treesit-induce-sparse-tree "treesit.c") -(declare-function treesit-subtree-stat "treesit.c") -(declare-function treesit-node-match-p "treesit.c") + (declare-function treesit-node-type "treesit.c") + (declare-function treesit-node-start "treesit.c") + (declare-function treesit-node-end "treesit.c") + (declare-function treesit-node-string "treesit.c") + (declare-function treesit-node-parent "treesit.c") + (declare-function treesit-node-child "treesit.c") + (declare-function treesit-node-check "treesit.c") + (declare-function treesit-node-field-name-for-child "treesit.c") + (declare-function treesit-node-child-count "treesit.c") + (declare-function treesit-node-child-by-field-name "treesit.c") + (declare-function treesit-node-next-sibling "treesit.c") + (declare-function treesit-node-prev-sibling "treesit.c") + (declare-function treesit-node-first-child-for-pos "treesit.c") + (declare-function treesit-node-descendant-for-range "treesit.c") + (declare-function treesit-node-eq "treesit.c") -(declare-function treesit-available-p "treesit.c") + (declare-function treesit-pattern-expand "treesit.c") + (declare-function treesit-query-expand "treesit.c") + (declare-function treesit-query-compile "treesit.c") + (declare-function treesit-query-capture "treesit.c") -(defvar treesit-thing-settings) + (declare-function treesit-search-subtree "treesit.c") + (declare-function treesit-search-forward "treesit.c") + (declare-function treesit-induce-sparse-tree "treesit.c") + (declare-function treesit-subtree-stat "treesit.c") + (declare-function treesit-node-match-p "treesit.c") + + (declare-function treesit-available-p "treesit.c") + + (defvar treesit-thing-settings))) + +(eval-when-compile + (treesit-declare-c-functions)) ;;; Custom options -- 2.39.5 (Apple Git-151) [-- Attachment #3: Type: text/plain, Size: 2 bytes --] ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-08 6:39 ` Yuan Fu @ 2024-12-08 7:20 ` Eli Zaretskii 2024-12-08 15:27 ` Stefan Monnier 1 sibling, 0 replies; 18+ messages in thread From: Eli Zaretskii @ 2024-12-08 7:20 UTC (permalink / raw) To: Yuan Fu, Andrea Corallo; +Cc: monnier, emacs-devel > From: Yuan Fu <casouri@gmail.com> > Date: Sat, 7 Dec 2024 22:39:21 -0800 > Cc: Eli Zaretskii <eliz@gnu.org>, > emacs-devel@gnu.org > > > On Dec 7, 2024, at 5:47 AM, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > > > >>> Does that mean declare-function forms only affect the file it’s in? > >>> Because if treesit.el has declare-function forms for all the treesit.c > >>> functions, and c-ts-mode.el requires treesit.el, why do we need to have > >>> declare-function forms in c-ts-mode.el? > >> Seems like that. Stefan, am I missing something here? > > > > Yes, `declare-function` *should* follow the same principles as `(defvar > > FOO)`, meaning that they are compiler directives not functions to > > execute. They affect warnings only in the current lexical scope, and > > requiring a file full of `(defvar FOO)` and `declare-function` will have > > no effect at all. > > > > [ Side note regarding this *should*: it currently doesn't work quite as > > well as `defvar` because its effect is always file-wide, whereas it > > should be limited to the current scope. ] > > Defining a macro that contains the declare-function forms, and calling it in eval-when-compile forms seem to work (see patch), WDYT? The name (treesit-declare-c-functions) could be better, any ideas? Looks a bit ugly, but maybe this is the best we can do. Andrea, WDYT? ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-08 6:39 ` Yuan Fu 2024-12-08 7:20 ` Eli Zaretskii @ 2024-12-08 15:27 ` Stefan Monnier 2024-12-09 1:37 ` Yuan Fu 1 sibling, 1 reply; 18+ messages in thread From: Stefan Monnier @ 2024-12-08 15:27 UTC (permalink / raw) To: Yuan Fu; +Cc: Eli Zaretskii, emacs-devel > +(eval-when-compile > + (treesit-declare-c-functions)) `treesit-declare-c-functions` is a macro, that expands to `declare-function`s, i.e. to "no-ops". Why wrap it within `eval-when-compile`? If it works within an `eval-when-compile`, it's only by accident (just like the fact that (eval-when-compile (defvar foo)) "works" is an accident): code shouldn't rely on it. It's not the evaluation of `defvar` or `declare-function` that is needed (because such an evaluation should have no effect, as you can see if you look at the definition of `declare-function`), but instead the "calls" to `defvar` or `declare-function` need to be seen/processed by the compiler. By wrapping them within an `eval-when-compile` you risk *hiding* them from the compiler. Stefan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-08 15:27 ` Stefan Monnier @ 2024-12-09 1:37 ` Yuan Fu 2024-12-09 2:40 ` Stefan Monnier 0 siblings, 1 reply; 18+ messages in thread From: Yuan Fu @ 2024-12-09 1:37 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel > On Dec 8, 2024, at 7:27 AM, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > >> +(eval-when-compile >> + (treesit-declare-c-functions)) > > `treesit-declare-c-functions` is a macro, that expands to > `declare-function`s, i.e. to "no-ops". > Why wrap it within `eval-when-compile`? I thought that might be TRT since they’re only needed for compiling the file. > > If it works within an `eval-when-compile`, it's only by accident (just > like the fact that (eval-when-compile (defvar foo)) "works" is an > accident): code shouldn't rely on it. > > It's not the evaluation of `defvar` or `declare-function` that is needed > (because such an evaluation should have no effect, as you can see if > you look at the definition of `declare-function`), but instead the > "calls" to `defvar` or `declare-function` need to be seen/processed by > the compiler. By wrapping them within an `eval-when-compile` you risk > *hiding* them from the compiler. I thought eval-when-compile is more of a “include if compiling” macro, should’ve checked :) We can also go with Dmitry’s idea, and just define all the functions in treesit.el if Emacs is not built with tree-sitter. We can detect that with treesit-available-p. Yuan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-09 1:37 ` Yuan Fu @ 2024-12-09 2:40 ` Stefan Monnier 2024-12-11 1:57 ` Dmitry Gutov 0 siblings, 1 reply; 18+ messages in thread From: Stefan Monnier @ 2024-12-09 2:40 UTC (permalink / raw) To: Yuan Fu; +Cc: Eli Zaretskii, emacs-devel > I thought eval-when-compile is more of a “include if compiling” macro, should’ve checked :) > > We can also go with Dmitry’s idea, and just define all the functions in > treesit.el if Emacs is not built with tree-sitter. We can detect that with > treesit-available-p. I haven't really thought about it, so I don't have a strong opinion. AFAICT your proposal should work fine even if you remove the `eval-when-compile` wrappers to which I objected. 🙂 Stefan ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-09 2:40 ` Stefan Monnier @ 2024-12-11 1:57 ` Dmitry Gutov 0 siblings, 0 replies; 18+ messages in thread From: Dmitry Gutov @ 2024-12-11 1:57 UTC (permalink / raw) To: Stefan Monnier, Yuan Fu; +Cc: Eli Zaretskii, emacs-devel On 09/12/2024 04:40, Stefan Monnier wrote: >> I thought eval-when-compile is more of a “include if compiling” macro, should’ve checked 🙂 >> >> We can also go with Dmitry’s idea, and just define all the functions in >> treesit.el if Emacs is not built with tree-sitter. We can detect that with >> treesit-available-p. > I haven't really thought about it, so I don't have a strong opinion. > AFAICT your proposal should work fine even if you remove the > `eval-when-compile` wrappers to which I objected. 🙂 It seems to me that, having taken than route, we would recommend every (require 'treesit) to be accompanied by (treesit-declare-c-functions) ...or the familiar declare-function list, of course. And the same would also be true for transitive dependencies (so, both c-ts-common and c-ts-mode, even though otherwise the latter could drop the (require 'treesit) form). ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Use (eval-when-compile 'treesit) to save us from writing declare-function forms 2024-12-04 18:19 ` Yuan Fu 2024-12-04 18:57 ` Eli Zaretskii @ 2024-12-08 16:01 ` Dmitry Gutov 1 sibling, 0 replies; 18+ messages in thread From: Dmitry Gutov @ 2024-12-08 16:01 UTC (permalink / raw) To: Yuan Fu, Eli Zaretskii; +Cc: emacs-devel On 04/12/2024 20:19, Yuan Fu wrote: > When Emacs is built without tree-sitter, none of the treesit.c functions are available (except for treesit-ready-p) Have we considered having all of those functions defined but doing nothing in that case? Alias them to 'ignore' or something that raises an error. I think then we won't have to maintain these 'declare-function' lists in every package that depends on treesit.c. ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2024-12-11 1:57 UTC | newest] Thread overview: 18+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-12-03 6:31 Use (eval-when-compile 'treesit) to save us from writing declare-function forms Yuan Fu 2024-12-03 8:30 ` Andrea Corallo 2024-12-04 18:21 ` Yuan Fu 2024-12-03 13:12 ` Eli Zaretskii 2024-12-04 18:19 ` Yuan Fu 2024-12-04 18:57 ` Eli Zaretskii 2024-12-05 6:25 ` Yuan Fu 2024-12-05 7:07 ` Eli Zaretskii 2024-12-07 1:12 ` Yuan Fu 2024-12-07 7:51 ` Eli Zaretskii 2024-12-07 13:47 ` Stefan Monnier 2024-12-08 6:39 ` Yuan Fu 2024-12-08 7:20 ` Eli Zaretskii 2024-12-08 15:27 ` Stefan Monnier 2024-12-09 1:37 ` Yuan Fu 2024-12-09 2:40 ` Stefan Monnier 2024-12-11 1:57 ` Dmitry Gutov 2024-12-08 16:01 ` Dmitry Gutov
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).