Subject: [PATCH v6 27/27] gnu: Add emacs-tree-sitter-langs.

From: Pierre Langlois <[email-masked]>
Date: Sun, 15 May 2022 19:38:34 +0100

* gnu/packages/tree-sitter.scm (make-emacs-tree-sitter-langs-grammar-bundle):
New procedure.
(emacs-tree-sitter-langs): New variable.
---
 gnu/packages/tree-sitter.scm | 148 +++++++++++++++++++++++++++++++++++
 1 file changed, 148 insertions(+)

diff --git a/gnu/packages/tree-sitter.scm b/gnu/packages/tree-sitter.scm
index cb3f326367..b80d912bfc 100644
--- a/gnu/packages/tree-sitter.scm
+++ b/gnu/packages/tree-sitter.scm
@@ -24,6 +24,7 @@ (define-module (gnu packages tree-sitter)
   #:use-module (guix build-system emacs)
   #:use-module (guix build-system gnu)
   #:use-module (guix build-system tree-sitter)
+  #:use-module (guix build-system trivial)
   #:use-module (guix download)
   #:use-module (guix git-download)
   #:use-module (guix packages)
@@ -797,3 +798,150 @@ (define-public emacs-tree-sitter
 @item More informative indexing for imenu.
 @end enumerate")
     (license license:expat)))
+
+(define emacs-tree-sitter-langs-grammar-bundle
+  (package
+    (name "emacs-tree-sitter-langs-grammar-bundle")
+    (source #f)
+    (version (package-version tree-sitter))
+    (build-system trivial-build-system)
+    (inputs
+     ;; FIXME: Support for some languages is still left to package.
+     (list tree-sitter-bash
+           tree-sitter-c
+           tree-sitter-c-sharp
+           tree-sitter-cpp
+           tree-sitter-css
+           tree-sitter-elixir
+           tree-sitter-elm
+           tree-sitter-go
+           tree-sitter-html
+           tree-sitter-java
+           tree-sitter-javascript
+           tree-sitter-json
+           tree-sitter-julia
+           tree-sitter-ocaml
+           tree-sitter-php
+           tree-sitter-python
+           tree-sitter-rust
+           tree-sitter-ruby
+           tree-sitter-typescript))
+    (arguments
+     (list #:builder
+           (with-imported-modules '((guix build union)
+                                    (guix build utils))
+             #~(begin
+                 (use-modules (ice-9 match)
+                              (guix build union)
+                              (guix build utils))
+                 (union-build
+                  #$output
+                  (filter directory-exists?
+                          (map (match-lambda
+                                 ((name directory)
+                                  (string-append directory "/lib/tree-sitter")))
+                               '#$(package-inputs this-package))))))))
+    (synopsis #f)
+    (description #f)
+    (home-page #f)
+    (license #f)))
+
+(define-public emacs-tree-sitter-langs
+  (package
+    (name "emacs-tree-sitter-langs")
+    (version "0.12.0")
+    (source (origin
+              (method git-fetch)
+              (uri (git-reference
+                    (url "https://github.com/emacs-tree-sitter/tree-sitter-langs")
+                    (commit version)))
+              (file-name (git-file-name name version))
+              (sha256
+               (base32
+                "1p2zbb6ac7wi6x6zpbczcmpkb2p45md2csd2bj43d8s56ckzw5mp"))))
+    (build-system emacs-build-system)
+    (inputs
+     (list emacs-tree-sitter-langs-grammar-bundle))
+    (propagated-inputs
+     (list emacs-tree-sitter))
+    (arguments
+     (list
+      #:tests? #t
+      #:test-command ''("script/test")
+      #:phases
+      #~(modify-phases %standard-phases
+          (add-after 'unpack 'disable-downloader
+            (lambda _
+              (call-with-output-file "tree-sitter-langs-build.el"
+                (lambda (port)
+                  (let ((on-load-message
+                         (string-append
+                          "tree-sitter-langs: Grammar bundle already installed "
+                          "via Guix.  Installing external grammars via this "
+                          "function isn't supported, if a language you need is "
+                          "missing please report a bug at [email-masked].")))
+                    (format
+                     port
+                     ";;;###autoload
+                      (defun tree-sitter-langs-install-grammars
+                             (&optional skip-if-installed version os
+                                        keep-bundle)
+                        (interactive)
+                        (message \"~a\"))
+                      (defconst tree-sitter-langs--queries-dir
+                        (file-name-as-directory
+                          (concat (file-name-directory (locate-library \"tree-sitter-langs.el\"))
+                                  \"queries\")))
+                      (defun tree-sitter-langs--bin-dir () \"~a\")
+                      (provide 'tree-sitter-langs-build)"
+                     on-load-message
+                     #$emacs-tree-sitter-langs-grammar-bundle))))))
+          (add-after 'unpack 'remove-cask
+            (lambda _
+              (substitute* "script/test"
+                (("cask") ""))))
+          (add-before 'check 'patch-tree-sitter-require-test
+            (lambda _
+              (use-modules (ice-9 regex))
+              ;; This test needs a git repositories with submodules for
+              ;; each languages in order to map all repositories.  We patch
+              ;; the mapping function with one that invokes the tests for each
+              ;; packaged language.
+              (let ((supported-languages
+                     (map (lambda (lib)
+                            (match:substring
+                             (string-match "(.*)\\.so$" (basename lib))
+                             1))
+                          (find-files "bin" "\\.so$"))))
+                (substitute* "tree-sitter-langs-tests.el"
+                  (("tree-sitter-langs--map-repos")
+                   (call-with-output-string
+                     (lambda (port)
+                       (write `(lambda (fn)
+                                 (dolist (lang ',supported-languages)
+                                         (funcall fn lang)))
+                              port))))))))
+          ;; Tests for queries will fail given those languages are not
+          ;; packages yet.
+          (add-before 'check 'remove-unused-highlight-queries
+            (lambda _
+              (delete-file-recursively "queries/hcl")
+              (delete-file-recursively "queries/pgn")))
+          (add-after 'install 'install-queries
+            (lambda* (#:key outputs #:allow-other-keys)
+              (let ((elpa (elpa-directory (assoc-ref outputs "out"))))
+                (copy-recursively "queries" (string-append elpa "/queries"))))))))
+    (home-page "https://ubolonton.github.io/emacs-tree-sitter/languages/")
+    (synopsis "Language support bundle for Tree-sitter")
+    (description "This package is a convenient language bundle for
+Tree-sitter.  For each supported language, this package provides:
+
+@enumerate
+@item Pre-compiled grammar binaries.
+@item An optional highlights.scm file that provides highlighting patterns.
+This is mainly intended for major modes that are not aware of tree-sitter.
+@item Optional query patterns for other minor modes that provide high-level
+functionalities on top of tree-sitter, such as code folding, evil text
+objects, ...etc.
+@end enumerate")
+    (license license:expat)))
--
2.36.0