[bug#33598] Optimizations for emacs-clang-format and emacs-clang-rename

Message ID 792d34a0-b048-b84f-b7b8-d9d996da2a28@yahoo.de
State Accepted
Headers show
Series [bug#33598] Optimizations for emacs-clang-format and emacs-clang-rename | expand

Checks

Context Check Description
cbaines/applying patch success Successfully applied

Commit Message

Tim Gesthuizen Jan. 6, 2019, 9:29 p.m. UTC
Hi Pierre,
thank you for reviewing!
On 06.01.19 20:00, Pierre Neidhardt wrote:
> Hi Tim,
> 
> I just reviewed your patch. Looks pretty good overall, thanks!
> 
> A few things:
> 
>> +(export package-elisp-from-package)
> 
> This should be placed at the beginning of the file in the (define-module...
> See bootstrap.scm.

As the new function can be defined with a normal lambda and not a
lambda* I just used define-public.

>> +;;; Returns a package definition that packages an emacs-lisp file from the
>> +;;; SRCPKG source. The package has the name PKGNAME and packages the file
>> +;;; SRC-FILE from the source in its root directory as TARGET-FILE or the
>> +;;; basename of SRC-FILE where INPUTS NATIVE-INPUTS and PROPAGATED-INPUTS are
>> +;;; added as package inputs and SUBSTITUTIONS substitutions will be performed
>> +;;; on the elisp file and SYNOPSIS and DESCRIPTION as the package synopsis and
>> +;;; description.
>> +(define* (package-elisp-from-package
> 
> Move the ";;;" comment to a docstring, e.g.
> 
> --8<---------------cut here---------------start------------->8---
> (define* (package-elisp-from-package
>           ...)
>   "Return ..."
> --8<---------------cut here---------------end--------------->8---

Done.

>> +;;; Returns a package definition that packages an emacs-lisp file from the
> 
> "Return", not "Returns".
> 
>> +;;; SRCPKG source. The package has the name PKGNAME and packages the file
> 
> Separate sentences with two spaces.

Done.

>> +          srcpkg pkgname src-file
> 
> Prefer complete words over abbreviations.  Here I'd suggest
> 
>   source-package
>   name
>   source-file

Done. name is called package-name.

>> +      (synopsis (if synopsis
>> +                    synopsis
>> +                    (package-synopsis srcpkg)))
>> +      (description (if description
>> +                       description
>> +                       (package-description srcpkg))))))
> 
> A more Lispy way:
> 
> --8<---------------cut here---------------start------------->8---
>  +      (synopsis (or synopsis
>  +                    (package-synopsis srcpkg)))
>  +      (description (or description
>  +                       (package-description srcpkg))))))
> --8<---------------cut here---------------end--------------->8---

Obsolete as this is now moved again to the final package definition.
Thanks for the tip :) I'm still quite new to scheme.

> Regarding the function parameters, I would turn SOURCE-FILE into SOURCE-FILES to
> make it more generic.  Indeed, the Emacs library could very well be split over
> multiple files.
> 
> One thing I'm not too sure about is the replication of the structure fields as
> keys.
> I think it's easier to ignore those and let the user define them as follows:
> 
> --8<---------------cut here---------------start------------->8---
> (define-public emacs-clang-rename
>   (package
>     (inherit (package-elisp-from-package
>              clang
>              "emacs-clang-rename"
>              "tools/clang-rename/clang-rename.el"))
>     (arguments ...)))
> --8<---------------cut here---------------end--------------->8---

I was also thinking about this. But with stuffing everything into the
function to evaluate to the final definition made multiple files
difficult as it would complicate the data structure for substitutions.
As this is not part of the function this is not a problem anymore.

Maybe we could make the function even more generic if we would just let
it modify the origin object.

> Makes sense?  This would also be more robust in case the package structure
> changes someday.
> 
> Finally, rebase your changes so that you directly use the last function, no
> need for the clang-specific function to appear in the history of commits.

Done. Patches are attached.

Tim.

Comments

Pierre Neidhardt Jan. 7, 2019, 1:47 p.m. UTC | #1
Merged!

> : > +;;; Returns a package definition that packages an emacs-lisp file from the
> : 
> : "Return", not "Returns".

You forgot this!  Anyways, I was confused by the docstring, so I took the
liberty to simplify it a little bit to the following:

  "Return a package definition named PACKAGE-NAME that packages the Emacs Lisp
SOURCE-FILES found in SOURCE-PACKAGE."

If you think this is missing something, let me know and I'll fix it.

Thanks for your great contribution!
Pierre Neidhardt Jan. 7, 2019, 2 p.m. UTC | #2
Oops, got too fast: there is a circular dependency problem because emacs.scm
depends on llvm.scm.
The function must be moved to some other place.  I'll place it in emacs utils or
something.
Pierre Neidhardt Jan. 7, 2019, 2:08 p.m. UTC | #3
Hmmm... Not too sure where to put package-elisp-from-package.
I see the following options:

- build-system/emacs.scm, but is it our policy?
- Or a separate file, but which one?
  
@Ludo?
Tim Gesthuizen Jan. 7, 2019, 3:37 p.m. UTC | #4
On 07.01.19 14:47, Pierre Neidhardt wrote:
> Merged!
> 
>> : > +;;; Returns a package definition that packages an emacs-lisp file from the
>> : 
>> : "Return", not "Returns".
> 
> You forgot this!  Anyways, I was confused by the docstring, so I took the
> liberty to simplify it a little bit to the following:

Whoops... Maybe I did not reformat the patches.

>   "Return a package definition named PACKAGE-NAME that packages the Emacs Lisp
> SOURCE-FILES found in SOURCE-PACKAGE."
> 
> If you think this is missing something, let me know and I'll fix it.

Much better. That was probably just to straight forward for me.

> Oops, got too fast: there is a circular dependency problem because emacs.scm
> depends on llvm.scm.
> The function must be moved to some other place.  I'll place it in emacs utils or
> something.

So that is my "weird issue"!
I first packaged the function in emacs-utils.scm and experienced much
worse things. I suspected it to be a circular dependency as any package
using emacs-build-system includes emacs-utils under the hood and moved
it to packages/emacs.scm.
I thought it was something different because the same error appeared
there too.

Maybe we should have a file with "shortcuts" for package definitions of
special kind and place the function there?
I would claim that we would have the same problems in emacs-utils.scm.

Tim.
Ludovic Courtès Jan. 7, 2019, 10:10 p.m. UTC | #5
Hello!

Pierre Neidhardt <mail@ambrevar.xyz> skribis:

> Hmmm... Not too sure where to put package-elisp-from-package.
> I see the following options:
>
> - build-system/emacs.scm, but is it our policy?
> - Or a separate file, but which one?
>   
> @Ludo?

I actually fixed it today right after you reverted the commit (I rebased
and didn’t notice it had been reverted in the meantime):

  https://git.savannah.gnu.org/cgit/guix.git/commit/?id=67eebb19b70acfe997b40d8c7978f9dc0673a4af

With this you should be able to reinstate the rest of the commit.

I tried to explain the reason for the issue in the commit log, let me
know if anything’s unclear.

Thanks,
Ludo’.
Pierre Neidhardt Jan. 7, 2019, 10:14 p.m. UTC | #6
It works, but it's semantically dubious.  For packages like emacs-cmake-mode now
have to use the llvm module to use package-elisp-from-package.
Thoughts?
Ludovic Courtès Jan. 8, 2019, 8:39 a.m. UTC | #7
Hi,

Pierre Neidhardt <mail@ambrevar.xyz> skribis:

> It works, but it's semantically dubious.  For packages like emacs-cmake-mode now
> have to use the llvm module to use package-elisp-from-package.
> Thoughts?

Sure, it probably belongs elsewhere.  I moved it there to quickly fix
the problem, and I purposefully made it private, but I agree, it could
go to some other places if there’s a need for it outside of llvm.scm.
I’m not sure exactly where.

I wonder how often the approach of ‘package-elisp-from-package’ is
applicable or desirable.  There are packages (e.g., recutils, GLOBAL)
that come with elisp files, which automatically get installed upon “make
install.”  I’m not sure we’d want to make them separate.

Thoughts?

Ludo’.
Pierre Neidhardt Jan. 8, 2019, 8:48 a.m. UTC | #8
The benefit of separate Emacs packages is if the Emacs library can be used
without installing the parent package to the user profile.

For instance, emacs-clang-rename can be installed and it will work while the
user does not have to install clang.  (Clang remains an input, obviously.)

For this reason, "package-elisp-from-package" gives maximal flexibility in my
opinion.

Currently, there are a few more packages.  We can look up "emacs-build-system"
outside emacs.scm to find them (e.g. agda2).

Off the top of my head, there is also asymptote.

Now to the ideal place for package-elisp-from-package: it seems that no existing
file would be a fit.  So what about guix/utils/emacs.scm?  Having a separate
file would make sure we run into other meta-circular dependency issues.
Ludovic Courtès Jan. 8, 2019, 9:53 a.m. UTC | #9
Pierre Neidhardt <mail@ambrevar.xyz> skribis:

> The benefit of separate Emacs packages is if the Emacs library can be used
> without installing the parent package to the user profile.
>
> For instance, emacs-clang-rename can be installed and it will work while the
> user does not have to install clang.  (Clang remains an input, obviously.)
>
> For this reason, "package-elisp-from-package" gives maximal flexibility in my
> opinion.

Yes, I agree that it makes a lot of sense for ‘emacs-clang-rename’ for
instance.  I’m just unsure whether the approach generalize to other
packages.

> Currently, there are a few more packages.  We can look up "emacs-build-system"
> outside emacs.scm to find them (e.g. agda2).
>
> Off the top of my head, there is also asymptote.

I’m not convinced sure ‘emacs-agda2-mode’ and ‘asymptote’ need to be
changed; it doesn’t look like a clear win, dunno.

For example, ‘package-elisp-from-package’ preserves the name, synopsis,
and description, so you end up having to do:

  (define foo
    (package
      (inherit (package-elisp-from-package x))
      (name "emacs-foo")
      (license …)
      (synopsis …)
      (description …)))

… which I think it a marginal improvement compared to
‘emacs-agda2-mode’.  Also, the “find *.el” approach may not work out of
the box for all cases, so the procedure may need to be tweaked further,
etc.

> Now to the ideal place for package-elisp-from-package: it seems that no existing
> file would be a fit.  So what about guix/utils/emacs.scm?  Having a separate
> file would make sure we run into other meta-circular dependency issues.

Circular, not meta-circular.  ;-)

So yeah, (guix utils emacs) is one option; another one would be to trim
the list of modules emacs.scm depends on, such that we don’t have this
issue in the first place (that requires care, though.)

However, my suggestion would be to use ‘package-elisp-from-package’ as
Tim intended in the original patch, keeping the procedure private to
llvm.scm, and generalize if and when we see other use cases.

How does that sound?

Ludo’.
Pierre Neidhardt Jan. 8, 2019, 10:05 a.m. UTC | #10
Agreed, the win is not always obvious.
If we are all OK with this, let's close the issue.

Tim, what do you think?
Tim Gesthuizen Jan. 8, 2019, 3:35 p.m. UTC | #11
On 08.01.19 11:05, Pierre Neidhardt wrote:
> Agreed, the win is not always obvious.
> If we are all OK with this, let's close the issue.
> 
> Tim, what do you think?
> 

That's no problem for me.
After all my intent was to make sure I don't have clangs source tree 3
times in the store :)
I think we should still put the generic function into llvm.scm and not
the clang specific one.

Patch

From 012ba2f96b16d54e0e1c23ee912c8a219355216c Mon Sep 17 00:00:00 2001
From: Tim Gesthuizen <tim.gesthuizen@yahoo.de>
Date: Fri, 4 Jan 2019 22:34:56 +0100
Subject: [PATCH 2/2] gnu: Use package-elisp-from-package for clangs emacs lisp
 files

Use package-elisp-from-package for emacs-clang-format and emacs-clang-rename.
Also remove package-from-clang-elisp-file as it is not needed anymore.

* gnu/packages/llvm.scm (emacs-clang-format): Use package-elisp-from-package
* gnu/packages/llvm.scm (emacs-clang-rename): Use package-elisp-from-package
* gnu/packages/llvm.scm (package-from-clang-elisp-file): Remove function
---
 gnu/packages/llvm.scm | 65 +++++++++++++++++++++----------------------
 1 file changed, 32 insertions(+), 33 deletions(-)

diff --git a/gnu/packages/llvm.scm b/gnu/packages/llvm.scm
index 6dab9c519..32d7ef81b 100644
--- a/gnu/packages/llvm.scm
+++ b/gnu/packages/llvm.scm
@@ -8,7 +8,7 @@ 
 ;;; Copyright © 2018 Marius Bakke <mbakke@fastmail.com>
 ;;; Copyright © 2018 Tobias Geerinckx-Rice <me@tobias.gr>
 ;;; Copyright © 2018 Efraim Flashner <efraim@flashner.co.il>
-;;; Copyright © 2018 Tim Gesthuizen <tim.gesthuizen@yahoo.de>
+;;; Copyright © 2018, 2019 Tim Gesthuizen <tim.gesthuizen@yahoo.de>
 ;;; Copyright © 2018 Pierre Neidhardt <mail@ambrevar.xyz>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -39,6 +39,7 @@ 
   #:use-module (gnu packages gcc)
   #:use-module (gnu packages bootstrap)           ;glibc-dynamic-linker
   #:use-module (gnu packages compression)
+  #:use-module (gnu packages emacs)
   #:use-module (gnu packages libffi)
   #:use-module (gnu packages perl)
   #:use-module (gnu packages python)
@@ -481,22 +482,21 @@  code analysis tools.")
 
 (define-public emacs-clang-format
   (package
-    (inherit clang)
-    (name "emacs-clang-format")
-    (build-system emacs-build-system)
-    (inputs
-     `(("clang" ,clang)))
-    (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'configure
-           (lambda* (#:key inputs #:allow-other-keys)
-             (let ((clang (assoc-ref inputs "clang")))
-               (copy-file "tools/clang-format/clang-format.el" "clang-format.el")
-               (emacs-substitute-variables "clang-format.el"
-                 ("clang-format-executable"
-                  (string-append clang "/bin/clang-format"))))
-             #t)))))
+    (inherit (package-elisp-from-package
+              clang
+              "emacs-clang-format"
+              '("tools/clang-format/clang-format.el")))
+    (inputs `(("clang" ,clang)))
+    (arguments `(#:phases
+                 (modify-phases %standard-phases
+                                (add-after 'unpack 'configure
+                                  (lambda* (#:key inputs #:allow-other-keys)
+                                    (chmod "clang-format.el" #o644)
+                                    (emacs-substitute-variables "clang-format.el"
+                                      ("clang-format-executable"
+                                       (string-append (assoc-ref inputs "clang")
+                                                      "/bin/clang-format")))
+                                    #t)))))
     (synopsis "Format code using clang-format")
     (description "This package allows to filter code through @code{clang-format}
 to fix its formatting.  @code{clang-format} is a tool that formats
@@ -505,22 +505,21 @@  C/C++/Obj-C code according to a set of style options, see
 
 (define-public emacs-clang-rename
   (package
-    (inherit clang)
-    (name "emacs-clang-rename")
-    (build-system emacs-build-system)
-    (inputs
-     `(("clang" ,clang)))
-    (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after 'unpack 'configure
-           (lambda* (#:key inputs #:allow-other-keys)
-             (let ((clang (assoc-ref inputs "clang")))
-               (copy-file "tools/clang-rename/clang-rename.el" "clang-rename.el")
-               (emacs-substitute-variables "clang-rename.el"
-                 ("clang-rename-binary"
-                  (string-append clang "/bin/clang-rename"))))
-             #t)))))
+    (inherit (package-elisp-from-package
+              clang
+              "emacs-clang-rename"
+              '("tools/clang-rename/clang-rename.el")))
+    (inputs `(("clang" ,clang)))
+    (arguments `(#:phases
+                 (modify-phases %standard-phases
+                   (add-after 'unpack 'configure
+                     (lambda* (#:key inputs #:allow-other-keys)
+                       (chmod "clang-rename.el" #o644)
+                       (emacs-substitute-variables "clang-rename.el"
+                         ("clang-rename-binary"
+                          (string-append (assoc-ref inputs "clang")
+                                         "/bin/clang-rename")))
+                       #t)))))
     (synopsis "Rename every occurrence of a symbol using clang-rename")
     (description "This package renames every occurrence of a symbol at point
 using @code{clang-rename}.")))
-- 
2.20.1