Skip to content

Commit 0c009d3

Browse files
committed
Completely remove tree-sitter-langs dependency
1 parent 7bccc45 commit 0c009d3

File tree

2 files changed

+171
-29
lines changed

2 files changed

+171
-29
lines changed

Eask

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,3 @@
1313
(source 'melpa)
1414

1515
(depends-on "emacs" "29.1")
16-
(depends-on "tree-sitter-langs")

treesit-langs.el

Lines changed: 171 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
;; Maintainer: Shen, Jen-Chieh <[email protected]>
77
;; URL: https://github.com/emacs-tree-sitter/treesit-langs
88
;; Version: 0.1.0
9-
;; Package-Requires: ((emacs "29.1") (tree-sitter-langs "0.12.18"))
9+
;; Package-Requires: ((emacs "29.1"))
1010
;; Keywords: languages tools parsers tree-sitter
1111

1212
;; This file is not part of GNU Emacs.
@@ -34,8 +34,6 @@
3434
(require 'cl-lib)
3535
(require 'treesit)
3636

37-
(require 'tree-sitter-langs-build)
38-
3937
(defgroup treesit-langs nil
4038
"Grammar bundle for `treesit.el'."
4139
:group 'tree-sitter)
@@ -173,34 +171,179 @@
173171
:type 'hook
174172
:group 'treesit-langs)
175173

176-
(defun treesit-langs--grammar-files (new-bin)
177-
"Return grammar files from NEW-BIN."
178-
(cl-remove-if-not (lambda (file)
179-
(or (string-match-p ".so" file)
180-
(string-match-p ".dylib" file)
181-
(string-match-p ".dll" file)))
182-
(directory-files new-bin t)))
174+
(defcustom treesit-langs-bundle-version "0.12.208"
175+
"Version of the grammar bundle.
176+
177+
Ideally, we want this value to be same as `tree-sitter-langs--bundle-version'
178+
from `tree-sitter-langs' package."
179+
:type 'string
180+
:group 'treesit-langs)
181+
182+
(defconst treesit-langs--bundle-version-file "BUNDLE-VERSION")
183+
184+
(defconst treesit-langs--suffixes '(".dylib" ".dll" ".so")
185+
"List of suffixes for shared libraries that define tree-sitter languages.")
186+
187+
(defconst treesit-langs--os
188+
(pcase system-type
189+
('darwin "macos")
190+
('gnu/linux "linux")
191+
('android "linux")
192+
('berkeley-unix "freebsd")
193+
('windows-nt "windows")
194+
(_ (error "Unsupported system-type %s" system-type))))
195+
196+
(defvar treesit-langs--out nil)
197+
198+
;;
199+
;;; Externals
200+
201+
(declare-function dired-omit-mode "dired-x" (&optional arg))
202+
203+
;;
204+
;;; Uitl
205+
206+
;;; TODO: Use (maybe make) an async library, with a proper event loop, instead
207+
;;; of busy-waiting.
208+
(defun treesit-langs--call (program &rest args)
209+
"Call PROGRAM with ARGS, using BUFFER as stdout+stderr.
210+
If BUFFER is nil, `princ' is used to forward its stdout+stderr."
211+
(let* ((command `(,program . ,args))
212+
(_ (message "[treesit-langs] Running %s in %s" command default-directory))
213+
(base `(:name ,program :command ,command))
214+
(output (if treesit-langs--out
215+
`(:buffer ,treesit-langs--out)
216+
`(:filter (lambda (proc string)
217+
(princ string)))))
218+
(proc (apply #'make-process (append base output)))
219+
(exit-code (progn
220+
(while (not (memq (process-status proc)
221+
'(exit failed signal)))
222+
(sleep-for 0.1))
223+
(process-exit-status proc)))
224+
;; Flush buffered output. Not doing this caused
225+
;; `tree-sitter-langs-git-dir' to be set incorrectly, and
226+
;; `tree-sitter-langs-create-bundle's output to be unordered.
227+
(_ (accept-process-output proc)))
228+
(unless (= exit-code 0)
229+
(error "Error calling %s, exit code is %s" command exit-code))))
230+
231+
;;
232+
;;; Download
233+
234+
(defun treesit-langs--bundle-file (&optional ext version os)
235+
"Return the grammar bundle file's name, with optional EXT.
236+
237+
If VERSION and OS are not spcified, use the defaults of
238+
`treesit-langs-bundle-version' and `treesit-langs--os'."
239+
(setq os (or os treesit-langs--os)
240+
version (or version treesit-langs-bundle-version)
241+
ext (or ext ""))
242+
(format "tree-sitter-grammars.%s.v%s.tar%s"
243+
;; FIX: Implement this correctly, refactoring 'OS' -> 'platform'.
244+
(pcase os
245+
("windows" "x86_64-pc-windows-msvc")
246+
("linux" "x86_64-unknown-linux-gnu")
247+
("freebsd" "x86_64-unknown-freebsd")
248+
("macos" (if (string-prefix-p "aarch64" system-configuration)
249+
"aarch64-apple-darwin"
250+
"x86_64-apple-darwin")))
251+
version ext))
252+
253+
(defun treesit-langs--bundle-url (&optional version os)
254+
"Return the URL to download the grammar bundle.
255+
If VERSION and OS are not specified, use the defaults of
256+
`treesit-langs-bundle-version' and `treesit-langs--os'."
257+
(format "https://github.com/emacs-tree-sitter/tree-sitter-langs/releases/download/%s/%s"
258+
version
259+
(treesit-langs--bundle-file ".gz" version os)))
260+
261+
(defun treesit-langs--bin-dir ()
262+
"Return the directory to stored grammar binaries."
263+
(locate-user-emacs-file "tree-sitter"))
183264

184265
;;;###autoload
185-
(defun treesit-langs-install-grammars ()
186-
"Install grammars to treesit.el library location."
266+
(defun treesit-langs-install-grammars (&optional skip-if-installed version os keep-bundle)
267+
"Download and install the specified VERSION of the language grammar bundle.
268+
If VERSION or OS is not specified, use the default of
269+
`treesit-langs-bundle-version' and `treesit-langs--os'.
270+
271+
This installs the grammar bundle even if the same version was already installed,
272+
unless SKIP-IF-INSTALLED is non-nil.
273+
274+
The download bundle file is deleted after installation, unless KEEP-BUNDLE is
275+
non-nil."
276+
(interactive (list
277+
nil
278+
(read-string "Bundle version: " treesit-langs-bundle-version)
279+
treesit-langs--os
280+
nil))
281+
(let* ((bin-dir (treesit-langs--bin-dir))
282+
(_ (unless (unless (file-directory-p bin-dir)
283+
(make-directory bin-dir))))
284+
(version (or version treesit-langs-bundle-version))
285+
(default-directory bin-dir)
286+
(bundle-file (treesit-langs--bundle-file ".gz" version os))
287+
(current-version (when (file-exists-p
288+
treesit-langs--bundle-version-file)
289+
(with-temp-buffer
290+
(let ((coding-system-for-read 'utf-8))
291+
(insert-file-contents
292+
treesit-langs--bundle-version-file)
293+
(string-trim (buffer-string)))))))
294+
(cl-block nil
295+
(if (string= version current-version)
296+
(if skip-if-installed
297+
(progn (message "treesit-langs: Grammar bundle v%s was already installed; skipped" version)
298+
(cl-return))
299+
(message "treesit-langs: Grammar bundle v%s was already installed; reinstalling" version))
300+
(message "treesit-langs: Installing grammar bundle v%s (was v%s)" version current-version))
301+
;; FIX: Handle HTTP errors properly.
302+
(url-copy-file (treesit-langs--bundle-url version os)
303+
bundle-file 'ok-if-already-exists)
304+
(treesit-langs--call "tar" "-xvzf" bundle-file)
305+
;; FIX: This should be a metadata file in the bundle itself.
306+
(with-temp-file treesit-langs--bundle-version-file
307+
(let ((coding-system-for-write 'utf-8))
308+
(insert version)))
309+
(unless keep-bundle
310+
(delete-file bundle-file 'trash))
311+
(when (and (called-interactively-p 'any)
312+
(y-or-n-p (format "Show installed grammars in %s? " bin-dir)))
313+
(with-current-buffer (find-file bin-dir)
314+
(when (bound-and-true-p dired-omit-mode)
315+
(dired-omit-mode -1))))
316+
(treesit-langs--rename))))
317+
318+
(treesit-langs-install-grammars :skip-if-installed)
319+
320+
;;
321+
;;; Rename
322+
323+
(defun treesit-langs--grammar-files (bin)
324+
"Return grammar files from BIN."
325+
(cl-remove-if-not (lambda (file)
326+
(cl-some (lambda (suffix)
327+
(string-suffix-p suffix file))
328+
treesit-langs--suffixes))
329+
(directory-files bin t)))
330+
331+
(defun treesit-langs--rename ()
332+
"Rename installed grammars to `treesit.el' compatible cnaming convention."
187333
(interactive)
188-
(let ((bin (tree-sitter-langs--bin-dir))
189-
(new-bin (locate-user-emacs-file "tree-sitter")))
190-
(when (and (file-directory-p bin)
191-
(not (file-directory-p new-bin)))
192-
(copy-directory bin new-bin nil t t)
193-
(dolist (filename (treesit-langs--grammar-files new-bin))
194-
(let* ((dir (file-name-directory filename))
195-
(file (file-name-nondirectory filename))
196-
(lang (file-name-sans-extension file))
197-
(soext (car dynamic-library-suffixes))
198-
(new-file (expand-file-name (concat "libtree-sitter-" lang soext)
199-
dir)))
200-
(rename-file filename new-file))))))
201-
202-
;; Install only once.
203-
(treesit-langs-install-grammars)
334+
(when-let* ((bin (treesit-langs--bin-dir))
335+
((file-directory-p bin)))
336+
(dolist (filename (treesit-langs--grammar-files bin))
337+
(let* ((dir (file-name-directory filename))
338+
(file (file-name-nondirectory filename))
339+
(lang (file-name-sans-extension file))
340+
(soext (car dynamic-library-suffixes))
341+
(new-file (expand-file-name (concat "libtree-sitter-" lang soext)
342+
dir)))
343+
(rename-file filename new-file)))))
344+
345+
;;
346+
;;; Set up
204347

205348
(defun treesit-langs-major-mode-setup ()
206349
"Activate tree-sitter to power major-mode features."

0 commit comments

Comments
 (0)