unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#51572: [PATCH] tree-sitter-lock-mode
@ 2021-11-02 19:03 dick
  2021-11-04 18:47 ` Lars Ingebrigtsen
  2021-12-19  6:56 ` bug#51572: Yuan Fu
  0 siblings, 2 replies; 7+ messages in thread
From: dick @ 2021-11-02 19:03 UTC (permalink / raw)
  To: 51572

[-- Attachment #1: Type: text/plain, Size: 933 bytes --]


FWIW, fontification of xdisp.c under tree-sitter is under a
second versus 17s for jit-lock (on my 10yo Thinkpad).

Install rust backend:
git clone https://github.com/commercial-emacs/tree-sitter.git
make -C tree-sitter install
pkg-config --exact-version=0.6.3alpha tree-sitter || echo not found

Then build emacs:
./autogen.sh
LDFLAGS="-L$HOME/.local/lib" CFLAGS="-g3 -O2 -I$HOME/.local/include/" ./configure --prefix=$HOME/.local --with-tree-sitter
make -j4 bootstrap
ldd src/emacs | grep -q tree-sitter || echo not found
make test/src/tree-sitter-tests.log
src/emacs -Q --eval '(custom-set-variables (quote (font-lock-support-mode (quote tree-sitter-lock-mode))) (quote (font-lock-maximum-size nil)) (quote (package-archives (quote (("melpa" . "https://melpa.org/packages/"))))))' --eval '(package-refresh-contents)' --eval '(package-install (cadr (assq (quote tree-sitter-langs) package-archive-contents)))' --visit src/xdisp.c


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-tree-sitter-lock-mode.patch --]
[-- Type: text/x-diff, Size: 181873 bytes --]

From 2c82301209ce8a41e68c8c6d25393c01aea55cfd Mon Sep 17 00:00:00 2001
From: dickmao <dick.r.chiang@gmail.com>
Date: Tue, 2 Nov 2021 14:43:22 -0400
Subject: [PATCH] tree-sitter-lock-mode

Joint work with casouri@gmail.com.

* configure.ac (WIDE_EMACS_INT): Add tree-sitter infra.
* lisp/font-core.el (font-lock-default-function):
Use if-then as it was intended.
(turn-on-font-lock-if-desired): Font lock was
being turned on in minibuffers.
* lisp/font-lock.el (font-lock-initial-fontify): De-obfuscate.
(font-lock-mode-internal): Use if-then as it was intended.
(font-lock-support-mode): Pivot boolean.
(tree-sitter-lock-mode): Forward declare.
(tree-sitter-fontify-region): Forward declare.
(font-lock-turn-on-thing-lock): De-obfuscate.
(font-lock-turn-off-thing-lock): De-obfuscate.
(font-lock-ensure-function): Was not ensuring.
(font-lock-ensure): Set a flag that should really be eliminated.
(font-lock-after-change-function): Use when.
(font-lock-compile-keywords): Whitespace.
(font-lock-set-defaults): De-obfuscate.
* lisp/jit-lock.el (jit-lock-function): Demorgan.
(jit-lock--run-functions): "Loose" was a noop.
(jit-lock-fontify-now): "Loose" was a noop.
(jit-lock-force-redisplay): Apparently, this was written before
for-loops were invented.
* lisp/loadup.el ("tree-sitter"): Register tree-sitter.
* lisp/progmodes/cc-fonts.el (c-font-lock-complex-decl-prepare):
c-beginning-of-syntax was a noop.
(c-font-lock-ml-strings): Whitespace.
(c-force-redisplay): c-beginning-of-syntax was a noop.
* lisp/progmodes/cc-mode.el (c-font-lock-init):
c-beginning-of-syntax was a noop.
* lisp/ps-print.el (jit-lock-fontify-now):
c-beginning-of-syntax was a noop.
* src/Makefile.in (TREE_SITTER_LIBS): Add tree sitter infra.
* src/alloc.c (cleanup_vector): Memory manage tree sitters.
* src/casefiddle.c (casify_region): Update tree.
* src/data.c (Ftype_of): Add tree sitter infra.
(syms_of_data): Add tree sitter infra.
* src/emacs.c (main): Add tree sitter infra.
* src/eval.c (define_error): Allow defining errors at the
C level.
* src/fileio.c (write_region): Whitespace.
* src/insdel.c (insert_1_both): Update tree.
(insert_from_string_1): Update tree.
(insert_from_gap): Update tree.
(insert_from_buffer_1): Update tree.
(adjust_after_replace): Update tree.
(replace_range): Update tree.
(del_range_2): Update tree.
* src/lisp.h (DEFINE_GDB_SYMBOL_BEGIN):
Add tree sitter infra.
* src/print.c (print_vectorlike):
Add tree sitter infra.
* src/xdisp.c (handle_face_prop): Whitespace.
(next_element_from_buffer): Demorgan.
(syms_of_xdisp): Making the fontified property nonsticky
saves you the contortions of having to remove it
in jit-lock-after-change.
* test/src/tree-sitter-resources/queries/c/highlights.scm ("case"):
Test resource for tree-sitter.
---
 configure.ac                                  |  19 +
 lisp/font-core.el                             |  40 +-
 lisp/font-lock.el                             | 157 ++--
 lisp/jit-lock.el                              | 147 +---
 lisp/loadup.el                                |   1 +
 lisp/progmodes/cc-engine.el                   |  38 +-
 lisp/progmodes/cc-fonts.el                    |   9 +-
 lisp/progmodes/cc-mode.el                     |   1 -
 lisp/ps-print.el                              |   2 +-
 lisp/tree-sitter.el                           | 141 ++++
 src/Makefile.in                               |  11 +-
 src/alloc.c                                   |  23 +
 src/casefiddle.c                              |  12 +
 src/data.c                                    |   4 +
 src/editfns.c                                 |   2 +-
 src/emacs.c                                   |   7 +
 src/eval.c                                    |  13 +
 src/fileio.c                                  |   2 +-
 src/insdel.c                                  |  31 +
 src/json.c                                    |  16 -
 src/lisp.h                                    |  11 +
 src/print.c                                   |  14 +
 src/tree-sitter.c                             | 717 ++++++++++++++++++
 src/tree-sitter.h                             |  63 ++
 src/xdisp.c                                   |  10 +-
 test/src/tree-sitter-resources/bin/c.so       | Bin 0 -> 399152 bytes
 .../queries/c/highlights.scm                  | 133 ++++
 test/src/tree-sitter-tests.el                 | 111 +++
 28 files changed, 1436 insertions(+), 299 deletions(-)
 create mode 100644 lisp/tree-sitter.el
 create mode 100644 src/tree-sitter.c
 create mode 100644 src/tree-sitter.h
 create mode 100755 test/src/tree-sitter-resources/bin/c.so
 create mode 100644 test/src/tree-sitter-resources/queries/c/highlights.scm
 create mode 100644 test/src/tree-sitter-tests.el

diff --git a/configure.ac b/configure.ac
index 33e7037afe..1ba9dfcb55 100644
--- a/configure.ac
+++ b/configure.ac
@@ -455,6 +455,7 @@ AC_DEFUN
 OPTION_DEFAULT_OFF([imagemagick],[compile with ImageMagick image support])
 OPTION_DEFAULT_ON([native-image-api], [don't use native image APIs (GDI+ on Windows)])
 OPTION_DEFAULT_IFAVAILABLE([json], [compile with native JSON support])
+OPTION_DEFAULT_OFF([tree-sitter], [compile with tree-sitter])
 
 OPTION_DEFAULT_ON([xft],[don't use XFT for anti aliased fonts])
 OPTION_DEFAULT_ON([harfbuzz],[don't use HarfBuzz for text shaping])
@@ -2997,6 +2998,23 @@ AC_DEFUN
 AC_SUBST(JSON_CFLAGS)
 AC_SUBST(JSON_OBJ)
 
+HAVE_TREE_SITTER=no
+TREE_SITTER_OBJ=
+
+if test "${with_tree_sitter}" == "yes"; then
+  EMACS_CHECK_MODULES([TREE_SITTER], [tree-sitter = 0.6.3alpha])
+  if test "${HAVE_TREE_SITTER}" = yes; then
+    AC_DEFINE(HAVE_TREE_SITTER, 1, [Define if using tree-sitter.])
+    TREE_SITTER_LIBS="-ltree-sitter -ltree_sitter_highlight"
+    TREE_SITTER_OBJ="tree-sitter.o"
+  fi
+fi
+
+AC_SUBST(HAVE_TREE_SITTER)
+AC_SUBST(TREE_SITTER_LIBS)
+AC_SUBST(TREE_SITTER_CFLAGS)
+AC_SUBST(TREE_SITTER_OBJ)
+
 NOTIFY_OBJ=
 NOTIFY_SUMMARY=no
 
@@ -5984,6 +6002,7 @@ AC_DEFUN
   Does Emacs use -lxft?                                   ${HAVE_XFT}
   Does Emacs use -lsystemd?                               ${HAVE_LIBSYSTEMD}
   Does Emacs use -ljansson?                               ${HAVE_JSON}
+  Does Emacs use -ltree-sitter?                           ${HAVE_TREE_SITTER}
   Does Emacs use the GMP library?                         ${HAVE_GMP}
   Does Emacs directly use zlib?                           ${HAVE_ZLIB}
   Does Emacs have dynamic modules support?                ${HAVE_MODULES}
diff --git a/lisp/font-core.el b/lisp/font-core.el
index 95bf46c9b8..307593765e 100644
--- a/lisp/font-core.el
+++ b/lisp/font-core.el
@@ -158,25 +158,22 @@ font-lock-defontify
 
 (defvar font-lock-set-defaults)
 (defun font-lock-default-function (mode)
-  ;; Turn on Font Lock mode.
-  (when mode
-    (setq-local char-property-alias-alist
-                (copy-tree char-property-alias-alist))
-    ;; Add `font-lock-face' as an alias for the `face' property.
-    (let ((elt (assq 'face char-property-alias-alist)))
-      (if elt
-	  (unless (memq 'font-lock-face (cdr elt))
-	    (setcdr elt (nconc (cdr elt) (list 'font-lock-face))))
-	(push (list 'face 'font-lock-face) char-property-alias-alist))))
-  ;; Turn off Font Lock mode.
-  (unless mode
-    ;; Remove `font-lock-face' as an alias for the `face' property.
+  (if mode
+      (progn
+        (setq-local char-property-alias-alist
+                    (copy-tree char-property-alias-alist))
+        ;; Add `font-lock-face' as an alias for the `face' property.
+        (let ((elt (assq 'face char-property-alias-alist)))
+          (if elt
+	      (unless (memq 'font-lock-face (cdr elt))
+	        (setcdr elt (nconc (cdr elt) (list 'font-lock-face))))
+	    (push (list 'face 'font-lock-face) char-property-alias-alist))))
     (setq-local char-property-alias-alist
                 (copy-tree char-property-alias-alist))
     (let ((elt (assq 'face char-property-alias-alist)))
       (when elt
 	(setcdr elt (remq 'font-lock-face (cdr elt)))
-	(when (null (cdr elt))
+	(unless (cdr elt)
 	  (setq char-property-alias-alist
 		(delq elt char-property-alias-alist))))))
 
@@ -258,13 +255,14 @@ font-lock-global-modes
   :group 'font-lock)
 
 (defun turn-on-font-lock-if-desired ()
-  (when (cond ((eq font-lock-global-modes t)
-	       t)
-	      ((eq (car-safe font-lock-global-modes) 'not)
-	       (not (memq major-mode (cdr font-lock-global-modes))))
-	      (t (memq major-mode font-lock-global-modes)))
-    (let (inhibit-quit)
-      (turn-on-font-lock))))
+  (unless (minibufferp)
+    (when (cond ((eq font-lock-global-modes t)
+	         t)
+	        ((eq (car-safe font-lock-global-modes) 'not)
+	         (not (memq major-mode (cdr font-lock-global-modes))))
+	        (t (memq major-mode font-lock-global-modes)))
+      (let (inhibit-quit)
+        (turn-on-font-lock)))))
 
 (define-globalized-minor-mode global-font-lock-mode
   font-lock-mode turn-on-font-lock-if-desired
diff --git a/lisp/font-lock.el b/lisp/font-lock.el
index a4ab897f6f..f6743977f7 100644
--- a/lisp/font-lock.el
+++ b/lisp/font-lock.el
@@ -650,28 +650,24 @@ font-lock-specified-p
 	   (not (eq font-lock-major-mode major-mode)))))
 
 (defun font-lock-initial-fontify ()
-  ;; The first fontification after turning the mode on.  This must
-  ;;  only be called after the mode hooks have been run.
+  "The :after-hook of `font-lock-mode' minor mode."
   (when (and font-lock-mode
-	     (font-lock-specified-p t))
+	     (font-lock-specified-p t)
+             (not font-lock-fontified))
     (let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size)))
-      (cond (font-lock-fontified
-	     nil)
-	    ((or (null max-size) (> max-size (buffer-size)))
-             (with-no-warnings (font-lock-fontify-buffer)))
-	    (font-lock-verbose
-	     (message "Fontifying %s...buffer size greater than font-lock-maximum-size"
-		      (buffer-name)))))))
+      (if (or (not (fixnump max-size)) (<= (buffer-size) max-size))
+          (font-lock-ensure)
+        (when font-lock-verbose
+          (message "Fontifying %s...buffer size greater than font-lock-maximum-size"
+	           (buffer-name)))))))
 
 (defun font-lock-mode-internal (arg)
-  ;; Turn on Font Lock mode.
-  (when arg
-    (add-hook 'after-change-functions #'font-lock-after-change-function t t)
-    (font-lock-set-defaults)
-    (font-lock-turn-on-thing-lock))
-  ;; Turn off Font Lock mode.
-  (unless font-lock-mode
-    (remove-hook 'after-change-functions #'font-lock-after-change-function t)
+  "This was better embedded in a minor mode, obviously."
+  (if arg
+      (progn
+        (cl-assert font-lock-mode)
+        (font-lock-set-defaults)
+        (font-lock-turn-on-thing-lock))
     (font-lock-unfontify-buffer)
     (font-lock-turn-off-thing-lock)))
 
@@ -900,6 +896,7 @@ font-lock-support-mode
 		 (const :tag "fast lock" fast-lock-mode)
 		 (const :tag "lazy lock" lazy-lock-mode)
 		 (const :tag "jit lock" jit-lock-mode)
+		 (const :tag "tree sitter" tree-sitter-lock-mode)
 		 (repeat :menu-tag "mode specific" :tag "mode specific"
 			 :value ((t . jit-lock-mode))
 			 (cons :tag "Instance"
@@ -910,14 +907,15 @@ font-lock-support-mode
 				      (const :tag "none" nil)
 				      (const :tag "fast lock" fast-lock-mode)
 				      (const :tag "lazy lock" lazy-lock-mode)
-				      (const :tag "JIT lock" jit-lock-mode)))
-			 ))
+				      (const :tag "JIT lock" jit-lock-mode)
+                                      (const :tag "tree sitter" tree-sitter-lock-mode)))))
   :version "21.1"
   :group 'font-lock)
 
 (defvar fast-lock-mode)
 (defvar lazy-lock-mode)
 (defvar jit-lock-mode)
+(defvar tree-sitter-lock-mode)
 
 (declare-function fast-lock-after-fontify-buffer "fast-lock")
 (declare-function fast-lock-after-unfontify-buffer "fast-lock")
@@ -925,41 +923,48 @@ jit-lock-mode
 (declare-function lazy-lock-after-fontify-buffer "lazy-lock")
 (declare-function lazy-lock-after-unfontify-buffer "lazy-lock")
 (declare-function lazy-lock-mode "lazy-lock")
+(declare-function tree-sitter-fontify-region "tree-sitter")
+(declare-function tree-sitter-lock-mode "tree-sitter")
 
 (defun font-lock-turn-on-thing-lock ()
   (pcase (font-lock-value-in-major-mode font-lock-support-mode)
-    ('fast-lock-mode (fast-lock-mode t))
-    ('lazy-lock-mode (lazy-lock-mode t))
+    ('fast-lock-mode
+     (add-hook 'after-change-functions #'font-lock-after-change-function t t)
+     (fast-lock-mode t))
+    ('lazy-lock-mode
+     (add-hook 'after-change-functions #'font-lock-after-change-function t t)
+     (lazy-lock-mode t))
+    ('tree-sitter-lock-mode
+     (tree-sitter-lock-mode t))
     ('jit-lock-mode
-     ;; Prepare for jit-lock
-     (remove-hook 'after-change-functions
-                  #'font-lock-after-change-function t)
-     (setq-local font-lock-flush-function #'jit-lock-refontify)
-     (setq-local font-lock-ensure-function #'jit-lock-fontify-now)
-     ;; Prevent font-lock-fontify-buffer from fontifying eagerly the whole
-     ;; buffer.  This is important for things like CWarn mode which
-     ;; adds/removes a few keywords and does a refontify (which takes ages on
-     ;; large files).
-     (setq-local font-lock-fontify-buffer-function #'jit-lock-refontify)
-     ;; Don't fontify eagerly (and don't abort if the buffer is large).
-     (setq-local font-lock-fontified t)
-     ;; Use jit-lock.
-     (jit-lock-register #'font-lock-fontify-region
-                        (not font-lock-keywords-only))
-     ;; Tell jit-lock how we extend the region to refontify.
+     (setq-local font-lock-fontify-buffer-function #'jit-lock-refontify
+                 font-lock-flush-function #'jit-lock-refontify
+                 font-lock-ensure-function #'jit-lock-fontify-now
+                 font-lock-fontified t) ;; ramifies in `font-lock-initial-fontify'
+     (jit-lock-register #'font-lock-fontify-region (not font-lock-keywords-only))
      (add-hook 'jit-lock-after-change-extend-region-functions
                #'font-lock-extend-jit-lock-region-after-change
                nil t))))
 
 (defun font-lock-turn-off-thing-lock ()
+  (mapc #'kill-local-variable
+        '(font-lock-fontify-buffer-function
+          font-lock-fontify-region-function
+          font-lock-flush-function
+          font-lock-ensure-function))
   (cond ((bound-and-true-p fast-lock-mode)
-	 (fast-lock-mode -1))
-	((bound-and-true-p jit-lock-mode)
-	 (jit-lock-unregister 'font-lock-fontify-region)
-	 ;; Reset local vars to the non-jit-lock case.
-	 (kill-local-variable 'font-lock-fontify-buffer-function))
-	((bound-and-true-p lazy-lock-mode)
-	 (lazy-lock-mode -1))))
+	 (fast-lock-mode -1)
+         (remove-hook 'after-change-functions #'font-lock-after-change-function t))
+        ((bound-and-true-p lazy-lock-mode)
+	 (lazy-lock-mode -1)
+         (remove-hook 'after-change-functions #'font-lock-after-change-function t))
+        ((bound-and-true-p tree-sitter-lock-mode)
+         (tree-sitter-lock-mode -1))
+        ((bound-and-true-p jit-lock-mode)
+         (jit-lock-unregister 'font-lock-fontify-region)
+         (remove-hook 'jit-lock-after-change-extend-region-functions
+                      #'font-lock-extend-jit-lock-region-after-change
+                      t))))
 
 (defun font-lock-after-fontify-buffer ()
   (cond ((bound-and-true-p fast-lock-mode)
@@ -988,45 +993,6 @@ font-lock-after-unfontify-buffer
 \f
 ;;; Fontification functions.
 
-;; Rather than the function, e.g., `font-lock-fontify-region' containing the
-;; code to fontify a region, the function runs the function whose name is the
-;; value of the variable, e.g., `font-lock-fontify-region-function'.  Normally,
-;; the value of this variable is, e.g., `font-lock-default-fontify-region'
-;; which does contain the code to fontify a region.  However, the value of the
-;; variable could be anything and thus, e.g., `font-lock-fontify-region' could
-;; do anything.  The indirection of the fontification functions gives major
-;; modes the capability of modifying the way font-lock.el fontifies.  Major
-;; modes can modify the values of, e.g., `font-lock-fontify-region-function',
-;; via the variable `font-lock-defaults'.
-;;
-;; For example, Rmail mode sets the variable `font-lock-defaults' so that
-;; font-lock.el uses its own function for buffer fontification.  This function
-;; makes fontification be on a message-by-message basis and so visiting an
-;; RMAIL file is much faster.  A clever implementation of the function might
-;; fontify the headers differently from the message body.  (It should, and
-;; correspondingly for Mail mode, but I can't be bothered to do the work.  Can
-;; you?)  This hints at a more interesting use...
-;;
-;; Languages that contain text normally contained in different major modes
-;; could define their own fontification functions that treat text differently
-;; depending on its context.  For example, Perl mode could arrange that here
-;; docs are fontified differently from Perl code.  Or Yacc mode could fontify
-;; rules one way and C code another.  Neat!
-;;
-;; A further reason to use the fontification indirection feature is when the
-;; default syntactic fontification, or the default fontification in general,
-;; is not flexible enough for a particular major mode.  For example, perhaps
-;; comments are just too hairy for `font-lock-fontify-syntactically-region' to
-;; cope with.  You need to write your own version of that function, e.g.,
-;; `hairy-fontify-syntactically-region', and make your own version of
-;; `hairy-fontify-region' call that function before calling
-;; `font-lock-fontify-keywords-region' for the normal regexp fontification
-;; pass.  And Hairy mode would set `font-lock-defaults' so that font-lock.el
-;; would call your region fontification function instead of its own.  For
-;; example, TeX modes could fontify {\foo ...} and \bar{...}  etc. multi-line
-;; directives correctly and cleanly.  (It is the same problem as fontifying
-;; multi-line strings and comments; regexps are not appropriate for the job.)
-
 (defvar-local font-lock-extend-after-change-region-function nil
   "A function that determines the region to refontify after a change.
 
@@ -1094,7 +1060,7 @@ font-lock-flush
 
 (defvar font-lock-ensure-function
   (lambda (beg end)
-    (unless font-lock-fontified
+    (when (text-property-not-all beg end 'fontified t)
       (save-excursion
         (font-lock-fontify-region beg end))))
   "Function to make sure a region has been fontified.
@@ -1121,7 +1087,8 @@ font-lock-ensure
   (when (font-lock-specified-p t)
     (font-lock-set-defaults)
     (funcall font-lock-ensure-function
-             (or beg (point-min)) (or end (point-max)))))
+             (or beg (point-min)) (or end (point-max)))
+    (setq font-lock-fontified t)))
 
 (defun font-lock-update (&optional arg)
   "Update the syntax highlighting in this buffer.
@@ -1291,9 +1258,9 @@ font-lock-after-change-function
   (save-excursion
     (let ((inhibit-point-motion-hooks t)
           (inhibit-quit t)
-          (region (if font-lock-extend-after-change-region-function
-                      (funcall font-lock-extend-after-change-region-function
-                               beg end old-len))))
+          (region (when font-lock-extend-after-change-region-function
+                    (funcall font-lock-extend-after-change-region-function
+                             beg end old-len))))
       (save-match-data
 	(if region
 	    ;; Fontify the region the major mode has specified.
@@ -1828,7 +1795,7 @@ font-lock-compile-keywords
 		  (0
 		   (if (memq (get-text-property (match-beginning 0) 'face)
 			     '(font-lock-string-face font-lock-doc-face
-			       font-lock-comment-face))
+			                             font-lock-comment-face))
 		       (list 'face font-lock-warning-face
                              'help-echo "Looks like a toplevel defun: escape the parenthesis"))
 		   prepend)))))
@@ -1940,12 +1907,10 @@ font-lock-set-defaults
 	                    '(1 2 3))    ;"." "w" "_"
 	        (setq font-lock--syntax-table-affects-ppss t))
 	      ))))
-      ;; (nth 4 defaults) used to hold `font-lock-beginning-of-syntax-function',
-      ;; but that was removed in 25.1, so if it's a cons cell, we assume that
-      ;; it's part of the variable alist.
-      ;; Variable alist?
-      (dolist (x (nthcdr (if (consp (nth 4 defaults)) 4 5) defaults))
-	(set (make-local-variable (car x)) (cdr x)))
+      ;; rest is (var . val) bindings
+      (dolist (x (nthcdr 4 defaults))
+        (when (consp x)
+	  (set (make-local-variable (car x)) (cdr x))))
       ;; Set up `font-lock-keywords' last because its value might depend
       ;; on other settings.
       (setq-local font-lock-keywords
diff --git a/lisp/jit-lock.el b/lisp/jit-lock.el
index bb2df2b1ff..02a4033095 100644
--- a/lisp/jit-lock.el
+++ b/lisp/jit-lock.el
@@ -365,14 +365,11 @@ jit-lock-refontify
 ;;; On demand fontification.
 
 (defun jit-lock-function (start)
-  "Fontify current buffer starting at position START.
-This function is added to `fontification-functions' when `jit-lock-mode'
-is active."
+  "Workhorse called from handle_fontified_prop() in xdisp.c.
+Registered in `font-lock-turn-on-thing-lock' when `font-lock-support-mode'
+is `jit-lock-mode'."
   (when (and jit-lock-mode (not memory-full))
-    (if (not (and jit-lock-defer-timer
-                  (or (not (eq jit-lock-defer-time 0))
-                      (input-pending-p))))
-	;; No deferral.
+    (if (or (not jit-lock-defer-timer) (zerop jit-lock-defer-time))
 	(jit-lock-fontify-now start (+ start jit-lock-chunk-size))
       ;; Record the buffer for later fontification.
       (unless (memq (current-buffer) jit-lock-defer-buffers)
@@ -387,116 +384,42 @@ jit-lock-function
 			  'fontified 'defer)))))
 
 (defun jit-lock--run-functions (beg end)
-  (let ((tight-beg nil) (tight-end nil)
-        (loose-beg beg) (loose-end end))
+  (let ((tight-beg (point-min))
+        (tight-end (point-max)))
     (run-hook-wrapped
      'jit-lock-functions
      (lambda (fun)
-       (pcase-let*
-           ((res (funcall fun beg end))
-            (`(,this-beg . ,this-end)
-             (if (eq (car-safe res) 'jit-lock-bounds)
-                 (cdr res) (cons beg end))))
-         ;; If all functions don't fontify the same region, we currently
-         ;; just try to "still be correct".  But we could go further and for
-         ;; the chunks of text that was fontified by some functions but not
-         ;; all, we could add text-properties indicating which functions were
-         ;; already run to avoid running them redundantly when we get to
-         ;; those chunks.
-         (setq tight-beg (max (or tight-beg (point-min)) this-beg))
-         (setq tight-end (min (or tight-end (point-max)) this-end))
-         (setq loose-beg (min loose-beg this-beg))
-         (setq loose-end (max loose-end this-end))
-         nil)))
-    `(,(min tight-beg beg) ,(max tight-end end) ,loose-beg ,loose-end)))
-
-(defun jit-lock-fontify-now (&optional start end)
-  "Fontify current buffer from START to END.
-Defaults to the whole buffer.  END can be out of bounds."
+       (prog1 nil
+         (pcase-let*
+             ((res (funcall fun beg end))
+              (`(,this-beg . ,this-end)
+               (if (eq (car-safe res) 'jit-lock-bounds)
+                   (cdr res) (cons beg end))))
+           (setq tight-beg (max tight-beg this-beg))
+           (setq tight-end (min tight-end this-end))))))
+    (cons (min tight-beg beg) (max tight-end end))))
+
+(defun jit-lock-fontify-now (start end)
+  "One of about six levels of indirection leading up to `font-lock-fontify-region'."
+  (setq end (min (point-max) end))
   (with-buffer-prepared-for-jit-lock
    (save-excursion
-     (unless start (setq start (point-min)))
-     (setq end (if end (min end (point-max)) (point-max)))
-     (let ((orig-start start) next)
-       (save-match-data
-	 ;; Fontify chunks beginning at START.  The end of a
-	 ;; chunk is either `end', or the start of a region
-	 ;; before `end' that has already been fontified.
-	 (while (and start (< start end))
-	   ;; Determine the end of this chunk.
-	   (setq next (or (text-property-any start end 'fontified t)
-			  end))
-
-           ;; Avoid unnecessary work if the chunk is empty (bug#23278).
-           (when (> next start)
-             ;; Fontify the chunk, and mark it as fontified.
-             ;; We mark it first, to make sure that we don't indefinitely
-             ;; re-execute this fontification if an error occurs.
-             (put-text-property start next 'fontified t)
-             (pcase-let
-                 ;; `tight' is the part we've fully refontified, and `loose'
-                 ;; is the part we've partly refontified (some of the
-                 ;; functions have refontified it but maybe not all).
-                 ((`(,tight-beg ,tight-end ,loose-beg ,_loose-end)
-                   (condition-case err
-                       (jit-lock--run-functions start next)
-                     ;; If the user quits (which shouldn't happen in normal
-                     ;; on-the-fly jit-locking), make sure the fontification
-                     ;; will be performed before displaying the block again.
-                     (quit (put-text-property start next 'fontified nil)
-                           (signal (car err) (cdr err))))))
-
-               ;; In case we fontified more than requested, take
-               ;; advantage of the good news.
-               (when (or (< tight-beg start) (> tight-end next))
-                 (put-text-property tight-beg tight-end 'fontified t))
-
-               ;; Make sure the contextual refontification doesn't re-refontify
-               ;; what's already been refontified.
-               (when (and jit-lock-context-unfontify-pos
-                          (< jit-lock-context-unfontify-pos tight-end)
-                          (>= jit-lock-context-unfontify-pos tight-beg)
-                          ;; Don't move boundary forward if we have to
-                          ;; refontify previous text.  Otherwise, we risk moving
-                          ;; it past the end of the multiline property and thus
-                          ;; forget about this multiline region altogether.
-                          (not (get-text-property tight-beg
-                                                  'jit-lock-defer-multiline)))
-                 (setq jit-lock-context-unfontify-pos tight-end))
-
-               ;; The redisplay engine has already rendered the buffer up-to
-               ;; `orig-start' and won't notice if the above jit-lock-functions
-               ;; changed the appearance of any part of the buffer prior
-               ;; to that.  So if `loose-beg' is before `orig-start', we need to
-               ;; cause a new redisplay cycle after this one so that the changes
-               ;; are properly reflected on screen.
-               ;; To make such repeated redisplay happen less often, we can
-               ;; eagerly extend the refontified region with
-               ;; jit-lock-after-change-extend-region-functions.
-               (when (< loose-beg orig-start)
-                 (run-with-timer 0 nil #'jit-lock-force-redisplay
-                                 (copy-marker loose-beg)
-                                 (copy-marker orig-start)))
-
-               ;; Skip to the end of the fully refontified part.
-               (setq start tight-end)))
-           ;; Find the start of the next chunk, if any.
-           (setq start
-                 (text-property-any start end 'fontified nil))))))))
-
-(defun jit-lock-force-redisplay (start end)
-  "Force the display engine to re-render START's buffer from START to END.
-This applies to the buffer associated with marker START."
-  (when (marker-buffer start)
-    (with-current-buffer (marker-buffer start)
-      (with-buffer-prepared-for-jit-lock
-       (when (> end (point-max))
-         (setq end (point-max) start (min start end)))
-       (when (< start (point-min))
-         (setq start (point-min) end (max start end)))
-       ;; Don't cause refontification (it's already been done), but just do
-       ;; some random buffer change, so as to force redisplay.
-       (put-text-property start end 'fontified t)))))
+     (save-match-data
+       (cl-loop for istart = (text-property-any (or istart start) end 'fontified nil)
+                while istart
+                for iend = (or (text-property-any istart end 'fontified t) end)
+                do (pcase-let* ((`(,istart* . ,iend*)
+                                 (jit-lock--run-functions istart iend)))
+                     (put-text-property istart* iend* 'fontified t)
+
+                     ;; Mirror progress for context-aware fontifier (obsolete?)
+                     (when (and jit-lock-context-unfontify-pos
+                                (< jit-lock-context-unfontify-pos iend*)
+                                (>= jit-lock-context-unfontify-pos istart*)
+                                (not (get-text-property istart* 'jit-lock-defer-multiline)))
+                       (setq jit-lock-context-unfontify-pos iend*)))
+                do (setq istart iend))))))
+
 \f
 ;;; Stealth fontification.
 
diff --git a/lisp/loadup.el b/lisp/loadup.el
index e8ecb67d56..214eec7359 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -282,6 +282,7 @@
 (load "replace")
 (load "emacs-lisp/tabulated-list")
 (load "buff-menu")
+(load "tree-sitter")
 
 (if (fboundp 'x-create-frame)
     (progn
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index a4568bd4ef..858ea5aa6f 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -4747,42 +4747,6 @@ c-safe-position
 		;; level between the safe position and bufpos.
 		(throw 'done (min (1+ elem) bufpos))))
 	  (setq paren-state (cdr paren-state)))))))
-
-(defun c-beginning-of-syntax ()
-  ;; This is used for `font-lock-beginning-of-syntax-function'.  It
-  ;; goes to the closest previous point that is known to be outside
-  ;; any string literal or comment.  `c-state-cache' is used if it has
-  ;; a position in the vicinity.
-  (let* ((paren-state c-state-cache)
-	 elem
-
-	 (pos (catch 'done
-		;; Note: Similar code in `c-safe-position'.  The
-		;; difference is that we accept a safe position at
-		;; the point and don't bother to go forward past open
-		;; parens.
-		(while paren-state
-		  (setq elem (car paren-state))
-		  (if (consp elem)
-		      (cond ((<= (cdr elem) (point))
-			     (throw 'done (cdr elem)))
-			    ((<= (car elem) (point))
-			     (throw 'done (car elem))))
-		    (if (<= elem (point))
-			(throw 'done elem)))
-		  (setq paren-state (cdr paren-state)))
-		(point-min))))
-
-    (if (> pos (- (point) 4000))
-	(goto-char pos)
-      ;; The position is far back.  Try `c-beginning-of-defun-1'
-      ;; (although we can't be entirely sure it will go to a position
-      ;; outside a comment or string in current emacsen).  FIXME:
-      ;; Consult `syntax-ppss' here.
-      (c-beginning-of-defun-1)
-      (if (< (point) pos)
-	  (goto-char pos)))))
-
 \f
 ;; Tools for scanning identifiers and other tokens.
 
@@ -7329,7 +7293,7 @@ c-ml-string-opener-around-point
 	     (cons (match-beginning 1)
 		   (cons (match-end 1) (match-beginning 2))))
       (goto-char here))))
-	
+
 (defun c-ml-string-opener-intersects-region (&optional start finish)
   ;; If any part of the region [START FINISH] is inside an ml-string opener,
   ;; return a dotted list of the start, end and double-quote position of that
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 9355409b2a..465daa98e4 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -943,9 +943,7 @@ c-font-lock-complex-decl-prepare
 	   pos)
 	 limit 'c-type)))
 
-    ;; Update `c-state-cache' to the beginning of the region.  This will
-    ;; make `c-beginning-of-syntax' go faster when it's used later on,
-    ;; and it's near the point most of the time.
+    ;; Update `c-state-cache' to the beginning of the region.
     (c-parse-state)
 
     ;; Check if the fontified region starts inside a declarator list so
@@ -1937,7 +1935,7 @@ c-font-lock-ml-strings
 				 (cons (match-end 1) (match-beginning 2)))
 		string-delims (cons open-delim (c-get-ml-closer open-delim)))
 	  (goto-char (caar string-delims))))
-	
+
        ;; Point is in the body of an ml string.
        ((and string-delims
 	     (>= (point) (cadar string-delims))
@@ -2425,10 +2423,9 @@ c-override-default-keywords
 ;; redisplay.
 (defvar c-re-redisplay-timer nil)
 
-(defun c-force-redisplay (start end)
+(defun c-force-redisplay (_start _end)
   ;; Force redisplay immediately.  This assumes `font-lock-support-mode' is
   ;; 'jit-lock-mode.  Set the variable `c-re-redisplay-timer' to nil.
-  (jit-lock-force-redisplay (copy-marker start) (copy-marker end))
   (setq c-re-redisplay-timer nil))
 
 (defun c-fontify-new-found-type (type)
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index ee5872d761..4fde95ae41 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -2552,7 +2552,6 @@ c-font-lock-init
 		       "font-lock-keywords-2" "font-lock-keywords-3")))
 	  nil nil
 	  ,c-identifier-syntax-modifications
-	  c-beginning-of-syntax
 	  (font-lock-mark-block-function
 	   . c-mark-function)))
 
diff --git a/lisp/ps-print.el b/lisp/ps-print.el
index 0fc9554679..edc3464b11 100644
--- a/lisp/ps-print.el
+++ b/lisp/ps-print.el
@@ -6325,7 +6325,7 @@ ps-screen-to-bit-face
 		(ps-face-background-name face))))
 
 
-(declare-function jit-lock-fontify-now "jit-lock" (&optional start end))
+(declare-function jit-lock-fontify-now "jit-lock" (start end))
 (declare-function lazy-lock-fontify-region "lazy-lock" (beg end))
 
 ;; to avoid compilation gripes
diff --git a/lisp/tree-sitter.el b/lisp/tree-sitter.el
new file mode 100644
index 0000000000..3929041d7a
--- /dev/null
+++ b/lisp/tree-sitter.el
@@ -0,0 +1,141 @@
+;;; tree-sitter.el --- tree-sitter utilities -*- lexical-binding: t -*-
+
+;; Copyright (C) 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'font-lock)
+(declare-function tree-sitter-changed-range "tree-sitter.c")
+(declare-function tree-sitter-highlight-region "tree-sitter.c")
+
+(defgroup tree-sitter
+  nil
+  "Tree-sitter is an incremental parser."
+  :group 'tools)
+
+(defcustom tree-sitter-mode-alist
+  '((c++-mode . "cpp")
+    (rust-mode . "rust")
+    (sh-mode . "bash")
+    (c-mode . "c")
+    (go-mode . "go")
+    (html-mode . "html")
+    (java-mode . "java")
+    (js-mode . "javascript")
+    (python-mode . "python")
+    (ruby-mode . "ruby"))
+  "Map prog-mode to tree-sitter grammar."
+  :group 'tree-sitter
+  :type '(alist :key-type (symbol :tag "Prog mode")
+                :value-type (string :tag "Tree-sitter symbol"))
+  :risky t
+  :version "28.1")
+
+(defcustom tree-sitter-highlight-alist
+  '(("constant" . font-lock-constant-face)
+    ("type.builtin" . font-lock-type-face)
+    ("operator" . font-lock-builtin-face)
+    ("variable.parameter" . font-lock-variable-name-face)
+    ("function.builtin" . font-lock-function-name-face)
+    ;; ("punctuation.delimiter" . font-lock-constant-face)
+    ("attribute" . font-lock-variable-name-face)
+    ;; ("punctuation.bracket" . font-lock-constant-face)
+    ("string" . font-lock-string-face)
+    ("variable.builtin" . font-lock-builtin-face)
+    ("comment" . font-lock-comment-face)
+    ("number" . font-lock-constant-face)
+    ("type" . font-lock-type-face)
+    ("embedded" . font-lock-builtin-face)
+    ("function" . font-lock-function-name-face)
+    ("keyword" . font-lock-keyword-face)
+    ("constructor" . font-lock-function-name-face)
+    ("property" . font-lock-variable-name-face)
+    ("tag" . font-lock-type-face)
+    ("string.special" . font-lock-string-face)
+    ("constant.builtin" . font-lock-constant-face))
+  "Map tree-sitter highlight name to font lock face."
+  :group 'tree-sitter
+  :initialize 'custom-initialize-default
+  :set (lambda (symbol value)
+         (mapc (lambda (x)
+                 (when (listp (cdr x))
+                   (setcdr x (cadr x))))
+               value)
+         (if-let ((problem (seq-find (lambda (x)
+                                       (or (not (stringp (car x)))
+                                           (not (facep (cdr x)))))
+                                     value)))
+             (error "Bad setting %S" problem)
+           (set-default symbol value)))
+  :type '(alist :key-type (string :tag "Tree-sitter highlight")
+                :value-type (symbol :tag "Font lock face"))
+  :risky t
+  :version "28.1")
+
+(defun tree-sitter-do-fontify (pos)
+  "Analog to `jit-lock-fontify-now' without all the indirection."
+  (let ((end (or (text-property-any pos (point-max) 'fontified t)
+                 (point-max))))
+    (font-lock-fontify-region pos end font-lock-verbose)))
+
+(define-minor-mode tree-sitter-lock-mode
+  "Tree-sitter font-lock minor mode."
+  :lighter ""
+  (if tree-sitter-lock-mode
+      (progn
+        (setq-local font-lock-fontify-region-function #'tree-sitter-fontify-region)
+        (add-hook 'after-change-functions #'tree-sitter-fontify-refresh nil t))
+    (kill-local-variable 'font-lock-fontify-region-function)
+    (remove-hook 'after-change-functions #'tree-sitter-fontify-refresh t)))
+
+(defun tree-sitter-fontify-region (beg end loudly)
+  "Presumably widened in `font-lock-fontify-region'."
+  (ignore loudly)
+  (let ((inhibit-point-motion-hooks t))
+    (with-silent-modifications
+      (save-excursion
+        (save-match-data
+          (let* ((changed-range (tree-sitter-changed-range))
+                 (beg* (if changed-range
+                           (min beg (cl-first changed-range))
+                         beg))
+                 (end* (if changed-range
+                           (min (point-max)
+                                (max (min (+ beg jit-lock-chunk-size)
+                                          (cl-second changed-range))
+                                     end))
+                         end))
+                 (bounds (tree-sitter-highlight-region beg* end*))
+                 (leftmost (if bounds (min beg* (car bounds)) beg*))
+                 (rightmost (if bounds (max end* (cdr bounds)) end*)))
+            ;; (when loudly
+            ;;   (princ (format "changed [%s %s], initial [%d %d], final [%d %d]\n"
+            ;;                  (cl-first (tree-sitter-changed-range))
+            ;;                  (cl-second (tree-sitter-changed-range))
+            ;;                  beg end leftmost rightmost)
+            ;;          #'external-debugging-output))
+            (put-text-property leftmost rightmost 'fontified t)))))))
+
+(defsubst tree-sitter-fontify-refresh (start &rest _args)
+  (tree-sitter-do-fontify start))
+
+(provide 'tree-sitter)
+
+;;; tree-sitter.el ends here
diff --git a/src/Makefile.in b/src/Makefile.in
index 7c977e34ea..bd3f53995b 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -322,6 +322,10 @@ JSON_LIBS =
 JSON_CFLAGS = @JSON_CFLAGS@
 JSON_OBJ = @JSON_OBJ@
 
+TREE_SITTER_LIBS = @TREE_SITTER_LIBS@
+TREE_SITTER_FLAGS = @TREE_SITTER_FLAGS@
+TREE_SITTER_OBJ = @TREE_SITTER_OBJ@
+
 INTERVALS_H = dispextern.h intervals.h composite.h
 
 GETLOADAVG_LIBS = @GETLOADAVG_LIBS@
@@ -375,7 +379,7 @@ EMACS_CFLAGS=
   $(WEBKIT_CFLAGS) $(LCMS2_CFLAGS) \
   $(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
   $(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
-  $(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) \
+  $(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) $(TREE_SITTER_CFLAGS) \
   $(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
   $(WERROR_CFLAGS)
 ALL_CFLAGS = $(EMACS_CFLAGS) $(WARN_CFLAGS) $(CFLAGS)
@@ -409,7 +413,8 @@ base_obj =
 	thread.o systhread.o \
 	$(if $(HYBRID_MALLOC),sheap.o) \
 	$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
-	$(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ)
+	$(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ) \
+	$(TREE_SITTER_OBJ)
 obj = $(base_obj) $(NS_OBJC_OBJ)
 
 ## Object files used on some machine or other.
@@ -522,7 +527,7 @@ LIBES =
    $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
    $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \
    $(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \
-   $(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS)
+   $(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) $(TREE_SITTER_LIBS)
 
 ## FORCE it so that admin/unidata can decide whether this file is
 ## up-to-date.  Although since charprop depends on bootstrap-emacs,
diff --git a/src/alloc.c b/src/alloc.c
index aa790d3afa..a04f09f4d0 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -50,6 +50,10 @@ Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2021 Free Software
 #include TERM_HEADER
 #endif /* HAVE_WINDOW_SYSTEM */
 
+#ifdef HAVE_TREE_SITTER
+#include "tree-sitter.h"
+#endif
+
 #include <flexmember.h>
 #include <verify.h>
 #include <execinfo.h>           /* For backtrace.  */
@@ -3180,6 +3184,25 @@ cleanup_vector (struct Lisp_Vector *vector)
 	  xfree (subr->native_c_name[0]);
 	}
     }
+#ifdef HAVE_TREE_SITTER
+  else if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_TREE_SITTER))
+    {
+      struct Lisp_Tree_Sitter *lisp_parser
+	= PSEUDOVEC_STRUCT (vector, Lisp_Tree_Sitter);
+      if (lisp_parser->highlight_names != NULL)
+	xfree (lisp_parser->highlight_names);
+      if (lisp_parser->highlights_query != NULL)
+	xfree (lisp_parser->highlights_query);
+      if (lisp_parser->highlighter != NULL)
+	ts_highlighter_delete (lisp_parser->highlighter);
+      if (lisp_parser->tree != NULL)
+	ts_tree_delete(lisp_parser->tree);
+      if (lisp_parser->prev_tree != NULL)
+	ts_tree_delete(lisp_parser->prev_tree);
+      if (lisp_parser->parser != NULL)
+	ts_parser_delete(lisp_parser->parser);
+    }
+#endif
 }
 
 /* Reclaim space used by unmarked vectors.  */
diff --git a/src/casefiddle.c b/src/casefiddle.c
index 81e9ed153f..29c25ae6b8 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -30,6 +30,10 @@ Copyright (C) 1985, 1994, 1997-1999, 2001-2021 Free Software Foundation,
 #include "composite.h"
 #include "keymap.h"
 
+#ifdef HAVE_TREE_SITTER
+#include "tree-sitter.h"
+#endif
+
 enum case_action {CASE_UP, CASE_DOWN, CASE_CAPITALIZE, CASE_CAPITALIZE_UP};
 
 /* State for casing individual characters.  */
@@ -530,6 +534,11 @@ casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e)
   modify_text (start, end);
   prepare_casing_context (&ctx, flag, true);
 
+#ifdef HAVE_TREE_SITTER
+  ptrdiff_t start_byte = CHAR_TO_BYTE (start);
+  ptrdiff_t old_end_byte = CHAR_TO_BYTE (end);
+#endif
+
   ptrdiff_t orig_end = end;
   record_delete (start, make_buffer_string (start, end, true), false);
   if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
@@ -548,6 +557,9 @@ casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e)
     {
       signal_after_change (start, end - start - added, end - start);
       update_compositions (start, end, CHECK_ALL);
+#ifdef HAVE_TREE_SITTER
+      tree_sitter_record_change (start_byte, old_end_byte, CHAR_TO_BYTE (end));
+#endif
     }
 
   return orig_end + added;
diff --git a/src/data.c b/src/data.c
index 0d3376f090..3661fc7192 100644
--- a/src/data.c
+++ b/src/data.c
@@ -259,6 +259,8 @@ DEFUN ("type-of", Ftype_of, Stype_of, 1, 1, 0,
           return Qxwidget;
         case PVEC_XWIDGET_VIEW:
           return Qxwidget_view;
+	case PVEC_TREE_SITTER:
+	  return Qtree_sitter_parser;
         /* "Impossible" cases.  */
 	case PVEC_MISC_PTR:
         case PVEC_OTHER:
@@ -4065,6 +4067,8 @@ #define PUT_ERROR(sym, tail, msg)			\
   DEFSYM (Qterminal, "terminal");
   DEFSYM (Qxwidget, "xwidget");
   DEFSYM (Qxwidget_view, "xwidget-view");
+  DEFSYM (Qtree_sitter_parser, "tree-sitter-parser");
+  DEFSYM (Qtree_sitter_node, "tree-sitter-node");
 
   DEFSYM (Qdefun, "defun");
 
diff --git a/src/editfns.c b/src/editfns.c
index c8219decb0..d064fb2a45 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -1574,7 +1574,7 @@ make_buffer_string (ptrdiff_t start, ptrdiff_t end, bool props)
    have them, if PROPS is true.
 
    We don't want to use plain old make_string here, because it calls
-   make_uninit_string, which can cause the buffer arena to be
+   make_uninit_string, which can cause the buffer area to be
    compacted.  make_string has no way of knowing that the data has
    been moved, and thus copies the wrong data into the string.  This
    doesn't effect most of the other users of make_string, so it should
diff --git a/src/emacs.c b/src/emacs.c
index 032b27fcf3..cc3a947b4d 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -81,6 +81,10 @@ #define MAIN_PROGRAM
 #include TERM_HEADER
 #endif /* HAVE_WINDOW_SYSTEM */
 
+#ifdef HAVE_TREE_SITTER
+#include "tree-sitter.h"
+#endif /* HAVE_TREE_SITTER */
+
 #include "bignum.h"
 #include "intervals.h"
 #include "character.h"
@@ -2099,6 +2103,9 @@ main (int argc, char **argv)
       syms_of_floatfns ();
 
       syms_of_buffer ();
+      #ifdef HAVE_TREE_SITTER
+      syms_of_tree_sitter ();
+      #endif
       syms_of_bytecode ();
       syms_of_callint ();
       syms_of_casefiddle ();
diff --git a/src/eval.c b/src/eval.c
index 94ad060773..391e6da3be 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1973,6 +1973,19 @@ signal_error (const char *s, Lisp_Object arg)
   xsignal (Qerror, Fcons (build_string (s), arg));
 }
 
+void
+define_error (Lisp_Object name, const char *message, Lisp_Object parent)
+{
+  eassert (SYMBOLP (name));
+  eassert (SYMBOLP (parent));
+  Lisp_Object parent_conditions = Fget (parent, Qerror_conditions);
+  eassert (CONSP (parent_conditions));
+  eassert (!NILP (Fmemq (parent, parent_conditions)));
+  eassert (NILP (Fmemq (name, parent_conditions)));
+  Fput (name, Qerror_conditions, pure_cons (name, parent_conditions));
+  Fput (name, Qerror_message, build_pure_c_string (message));
+}
+
 /* Use this for arithmetic overflow, e.g., when an integer result is
    too large even for a bignum.  */
 void
diff --git a/src/fileio.c b/src/fileio.c
index 3c13d3fe41..e79de3bf20 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -5278,7 +5278,7 @@ write_region (Lisp_Object start, Lisp_Object end, Lisp_Object filename,
      unsavable chars (as was the case with X-Symbol).  */
   Vlast_coding_system_used
     = choose_write_coding_system (start, end, filename,
-                                 append, visit, lockname, &coding);
+				  append, visit, lockname, &coding);
 
   if (open_and_close_file && !auto_saving)
     {
diff --git a/src/insdel.c b/src/insdel.c
index 40674e15e4..157981730e 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -31,6 +31,10 @@
 #include "region-cache.h"
 #include "pdumper.h"
 
+#ifdef HAVE_TREE_SITTER
+#include "tree-sitter.h"
+#endif
+
 static void insert_from_string_1 (Lisp_Object, ptrdiff_t, ptrdiff_t, ptrdiff_t,
 				  ptrdiff_t, bool, bool);
 static void insert_from_buffer_1 (struct buffer *, ptrdiff_t, ptrdiff_t, bool);
@@ -940,6 +944,10 @@ insert_1_both (const char *string,
     set_text_properties (make_fixnum (PT), make_fixnum (PT + nchars),
 			 Qnil, Qnil, Qnil);
 
+#ifdef HAVE_TREE_SITTER
+  tree_sitter_record_change (PT, PT, PT + nchars);
+#endif
+
   adjust_point (nchars, nbytes);
 
   check_markers ();
@@ -1071,6 +1079,10 @@ insert_from_string_1 (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
   graft_intervals_into_buffer (intervals, PT, nchars,
 			       current_buffer, inherit);
 
+#ifdef HAVE_TREE_SITTER
+  tree_sitter_record_change (PT, PT, PT + nchars);
+#endif
+
   adjust_point (nchars, outgoing_nbytes);
 
   check_markers ();
@@ -1137,6 +1149,10 @@ insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail)
 				   current_buffer, 0);
     }
 
+#ifdef HAVE_TREE_SITTER
+  tree_sitter_record_change (ins_charpos, ins_charpos, ins_charpos + nchars);
+#endif
+
   if (ins_charpos < PT)
     adjust_point (nchars, nbytes);
 
@@ -1287,6 +1303,10 @@ insert_from_buffer_1 (struct buffer *buf,
   /* Insert those intervals.  */
   graft_intervals_into_buffer (intervals, PT, nchars, current_buffer, inherit);
 
+#ifdef HAVE_TREE_SITTER
+  tree_sitter_record_change (PT, PT, PT + nchars);
+#endif
+
   adjust_point (nchars, outgoing_nbytes);
 }
 \f
@@ -1340,6 +1360,9 @@ adjust_after_replace (ptrdiff_t from, ptrdiff_t from_byte,
 
   offset_intervals (current_buffer, from, len - nchars_del);
 
+#ifdef HAVE_TREE_SITTER
+  tree_sitter_record_change (from, from + nchars_del, from + len);
+#endif
   if (from < PT)
     adjust_point (len - nchars_del, len_byte - nbytes_del);
 
@@ -1535,6 +1558,10 @@ replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new,
   graft_intervals_into_buffer (intervals, from, inschars,
 			       current_buffer, inherit);
 
+#ifdef HAVE_TREE_SITTER
+  tree_sitter_record_change (from, from + nchars_del, from + inschars);
+#endif
+
   /* Relocate point as if it were a marker.  */
   if (from < PT)
     adjust_point ((from + inschars - (PT < to ? PT : to)),
@@ -1892,6 +1919,10 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte,
 
   evaporate_overlays (from);
 
+#ifdef HAVE_TREE_SITTER
+  tree_sitter_record_change (from, from + nchars_del, from);
+#endif
+
   return deletion;
 }
 
diff --git a/src/json.c b/src/json.c
index b0779b912a..914873b83f 100644
--- a/src/json.c
+++ b/src/json.c
@@ -1090,22 +1090,6 @@ DEFUN ("json-parse-buffer", Fjson_parse_buffer, Sjson_parse_buffer,
   return unbind_to (count, lisp);
 }
 
-/* Simplified version of 'define-error' that works with pure
-   objects.  */
-
-static void
-define_error (Lisp_Object name, const char *message, Lisp_Object parent)
-{
-  eassert (SYMBOLP (name));
-  eassert (SYMBOLP (parent));
-  Lisp_Object parent_conditions = Fget (parent, Qerror_conditions);
-  eassert (CONSP (parent_conditions));
-  eassert (!NILP (Fmemq (parent, parent_conditions)));
-  eassert (NILP (Fmemq (name, parent_conditions)));
-  Fput (name, Qerror_conditions, pure_cons (name, parent_conditions));
-  Fput (name, Qerror_message, build_pure_c_string (message));
-}
-
 void
 syms_of_json (void)
 {
diff --git a/src/lisp.h b/src/lisp.h
index 31656bb3b1..5e873029b7 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1070,6 +1070,7 @@ DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
   PVEC_CONDVAR,
   PVEC_MODULE_FUNCTION,
   PVEC_NATIVE_COMP_UNIT,
+  PVEC_TREE_SITTER,
 
   /* These should be last, for internal_equal and sxhash_obj.  */
   PVEC_COMPILED,
@@ -1316,6 +1317,7 @@ #define XSETTHREAD(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_THREAD))
 #define XSETMUTEX(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_MUTEX))
 #define XSETCONDVAR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_CONDVAR))
 #define XSETNATIVE_COMP_UNIT(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_NATIVE_COMP_UNIT))
+#define XSETTREE_SITTER(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_TREE_SITTER))
 
 /* Efficiently convert a pointer to a Lisp object and back.  The
    pointer is represented as a fixnum, so the garbage collector
@@ -4768,6 +4770,10 @@ maybe_disable_address_randomization (int argc, char **argv)
 extern void malloc_probe (size_t);
 extern void syms_of_profiler (void);
 
+/* Defined in tree-sitter.c.  */
+extern void tree_sitter_record_change (ptrdiff_t start_char, ptrdiff_t old_end_char,
+				       ptrdiff_t new_end_char);
+extern void syms_of_tree_sitter (void);
 
 #ifdef DOS_NT
 /* Defined in msdos.c, w32.c.  */
@@ -5153,6 +5159,11 @@ maybe_gc (void)
     maybe_garbage_collect ();
 }
 
+/* Simplified version of 'define-error' that works with pure
+   objects.  */
+void
+define_error (Lisp_Object name, const char *message, Lisp_Object parent);
+
 INLINE_HEADER_END
 
 #endif /* EMACS_LISP_H */
diff --git a/src/print.c b/src/print.c
index c13294c8e6..54319ed1ca 100644
--- a/src/print.c
+++ b/src/print.c
@@ -48,6 +48,10 @@ Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2021 Free Software
 # include <sys/socket.h> /* for F_DUPFD_CLOEXEC */
 #endif
 
+#ifdef HAVE_TREE_SITTER
+#include "tree-sitter.h"
+#endif
+
 struct terminal;
 
 /* Avoid actual stack overflow in print.  */
@@ -1856,6 +1860,16 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag,
 	printchar ('>', printcharfun);
       }
       break;
+#endif
+#ifdef HAVE_TREE_SITTER
+    case PVEC_TREE_SITTER:
+      print_c_string ("#<tree-sitter for ", printcharfun);
+      print_object (XTREE_SITTER (obj)->progmode, printcharfun, escapeflag);
+      printchar (' ', printcharfun);
+      int len = sprintf (buf, "%p", XTREE_SITTER (obj));
+      strout (buf, len, len, printcharfun);
+      printchar ('>', printcharfun);
+      break;
 #endif
     default:
       emacs_abort ();
diff --git a/src/tree-sitter.c b/src/tree-sitter.c
new file mode 100644
index 0000000000..40ab44035f
--- /dev/null
+++ b/src/tree-sitter.c
@@ -0,0 +1,717 @@
+/* Tree-sitter integration for GNU Emacs.
+
+Copyright (C) 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 <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+#include "lisp.h"
+#include "buffer.h"
+#include "tree-sitter.h"
+
+#define BUFFER_TO_SITTER(byte) ((uint32_t) CHAR_TO_BYTE (byte) - 1)
+#define SITTER_TO_BUFFER(byte) (BYTE_TO_CHAR ((EMACS_INT) byte) + 1)
+
+typedef TSLanguage *(*TSLanguageFunctor) (void);
+typedef Lisp_Object (*HighlightsFunctor) (const TSHighlightEventSlice *, const TSNode *, const char **);
+
+static Lisp_Object
+make_tree_sitter (TSParser *parser, TSTree *tree, Lisp_Object progmode_arg)
+{
+  struct Lisp_Tree_Sitter *sitter
+    = ALLOCATE_PSEUDOVECTOR
+    (struct Lisp_Tree_Sitter, progmode, PVEC_TREE_SITTER);
+
+  CHECK_SYMBOL (progmode_arg);
+
+  sitter->progmode = progmode_arg;
+  sitter->parser = parser;
+  sitter->prev_tree = NULL;
+  sitter->tree = tree;
+  sitter->highlighter = NULL;
+  sitter->highlight_names = NULL;
+  sitter->highlights_query = NULL;
+  return make_lisp_ptr (sitter, Lisp_Vectorlike);
+}
+
+static TSLanguageFunctor
+tree_sitter_language_functor (Lisp_Object progmode)
+{
+  static Lisp_Object cache = LISPSYM_INITIALLY (Qnil);
+  struct Lisp_Hash_Table *h;
+  Lisp_Object hash;
+  ptrdiff_t i;
+
+  if (NILP (cache))
+    {
+      cache = make_hash_table (hashtest_eq, DEFAULT_HASH_SIZE,
+			       DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD,
+			       Qnil, false);
+      staticpro (&cache);
+    }
+
+  CHECK_SYMBOL (progmode);
+  h = XHASH_TABLE (cache);
+  i = hash_lookup (h, progmode, &hash);
+  if (i < 0)
+    {
+      Lisp_Object language =
+	Fcdr_safe (Fassq (progmode, Fsymbol_value (Qtree_sitter_mode_alist)));
+      if (! NILP (language))
+	{
+	  Lisp_Object module_stem = concat2 (build_string ("bin/"), language);
+	  Lisp_Object module = Flocate_file_internal (module_stem,
+						      Vload_path,
+						      list1 (Vmodule_file_suffix),
+						      Qnil);
+	  if (NILP (module))
+	    xsignal2 (Qtree_sitter_language_error,
+		      module_stem, build_string ("Could not locate module"));
+	  else
+	    {
+	      dynlib_handle_ptr handle = dynlib_open (SSDATA (module));
+	      if (handle == NULL)
+		xsignal2 (Qtree_sitter_language_error,
+			  module, build_string (dynlib_error ()));
+	      else
+		{
+		  TSLanguageFunctor fn;
+		  dynlib_error ();
+		  fn = dynlib_sym (handle,
+				   SSDATA (concat2 (build_string ("tree_sitter_"),
+						    language)));
+		  if (fn == NULL)
+		    xsignal2 (Qtree_sitter_language_error,
+			      module, build_string (dynlib_error ()));
+		  else
+		    i = hash_put (h, progmode, make_misc_ptr (fn), hash);
+		}
+	    }
+	}
+    }
+  return i >= 0 ? (TSLanguageFunctor) (xmint_pointer (HASH_VALUE (h, i))) : NULL;
+}
+
+static Lisp_Object
+tree_sitter_create (Lisp_Object progmode)
+{
+  Lisp_Object tree_sitter = Qnil;
+  TSLanguageFunctor fn;
+
+  CHECK_SYMBOL (progmode);
+
+  fn = tree_sitter_language_functor (progmode);
+  if (fn != NULL)
+    {
+      TSParser *ts_parser = ts_parser_new ();
+      ts_parser_set_language (ts_parser, fn ());
+      tree_sitter = make_tree_sitter (ts_parser, NULL, progmode);
+    }
+  return tree_sitter;
+}
+
+static Lisp_Object
+list_highlights (const TSHighlightEventSlice *slice, const TSNode *node,
+		 const char **highlight_names)
+{
+  Lisp_Object
+    retval = Qnil,
+    alist = Fsymbol_value (Qtree_sitter_highlight_alist);
+  const EMACS_INT count = XFIXNUM (Flength (alist));
+  const uint32_t offset = ts_node_start_byte (*node);
+
+  for (int i=slice->len-1; i>=0; --i)
+    {
+      const TSHighlightEvent *ev = &(slice->arr[i]);
+      eassert (ev->index < count);
+      if (ev->index >= TSHighlightEventTypeStartMin) {
+	Lisp_Object name = make_string (highlight_names[ev->index],
+					strlen (highlight_names[ev->index]));
+	retval = Fcons (Fcdr (Fassoc (name, alist, Qnil)), retval);
+      } else if (ev->index == TSHighlightEventTypeSource) {
+	retval =
+	  Fcons (Fcons
+		 (make_fixnum (SITTER_TO_BUFFER (ev->start + offset)),
+		  make_fixnum (SITTER_TO_BUFFER (ev->end + offset))),
+		 retval);
+      } else if (ev->index == TSHighlightEventTypeEnd) {
+	retval = Fcons (Qnil, retval);
+      }
+    }
+  return retval;
+}
+
+static Lisp_Object
+highlight_region (const TSHighlightEventSlice *slice,
+		  const TSNode *node, const char **highlight_names)
+{
+  Lisp_Object
+    alist = Fsymbol_value (Qtree_sitter_highlight_alist),
+    prevailing = Qnil;
+  const EMACS_INT count = XFIXNUM (Flength (alist));
+  const uint32_t offset = ts_node_start_byte (*node);
+  ptrdiff_t smallest = PTRDIFF_MAX, biggest = PTRDIFF_MIN;
+
+  for (int i=0; i<slice->len; ++i)
+    {
+      const TSHighlightEvent *ev = &(slice->arr[i]);
+      eassert (ev->index < count);
+      if (ev->index >= TSHighlightEventTypeStartMin) {
+	Lisp_Object name = make_string (highlight_names[ev->index],
+					strlen (highlight_names[ev->index]));
+	prevailing = Fcdr (Fassoc (name, alist, Qnil));
+      } else if (ev->index == TSHighlightEventTypeSource) {
+	ptrdiff_t beg = SITTER_TO_BUFFER (ev->start + offset),
+	  end = SITTER_TO_BUFFER (ev->end + offset);
+	smallest = min (smallest, beg);
+	biggest = max (biggest, end);
+	if (NILP (prevailing))
+	  Fremove_text_properties (make_fixnum (beg), make_fixnum (end),
+				   list2 (Qface, Qt), Qnil);
+	else
+	  Fput_text_property (make_fixnum (beg), make_fixnum (end),
+			      Qface, prevailing, Qnil);
+
+      } else if (ev->index == TSHighlightEventTypeEnd) {
+	prevailing = Qnil;
+      }
+    }
+  return smallest > biggest
+    ? Qnil : list2 (make_fixnum (smallest), make_fixnum (biggest));
+}
+
+static TSHighlighter *
+ensure_highlighter(Lisp_Object sitter)
+{
+  TSHighlighter *ret = XTREE_SITTER (sitter)->highlighter;
+  if (ret == NULL)
+    {
+      char *scope;
+      const char *error = NULL;
+      Lisp_Object
+	suberror = Qnil, highlights_scm,
+	alist = Fsymbol_value (Qtree_sitter_highlight_alist),
+	language = Fcdr_safe (Fassq (XTREE_SITTER (sitter)->progmode,
+				     Fsymbol_value (Qtree_sitter_mode_alist)));
+      const EMACS_INT count = XFIXNUM (Flength (alist));
+      XTREE_SITTER (sitter)->highlight_names = xmalloc(sizeof (char *) * count);
+      intptr_t i = 0;
+      FILE *fp = NULL;
+
+      eassert (! NILP (language)); /* by tree_sitter_create() */
+
+      FOR_EACH_TAIL (alist)
+	{
+	  CHECK_STRING (XCAR (XCAR (alist)));
+	  XTREE_SITTER (sitter)->highlight_names[i++] =
+	    SSDATA (XCAR (XCAR (alist)));
+	}
+      alist = Fsymbol_value (Qtree_sitter_highlight_alist); /* FOR_EACH_TAIL mucks */
+
+      USE_SAFE_ALLOCA;
+      scope = SAFE_ALLOCA (strlen ("scope.") + SCHARS (language) + 1);
+      sprintf (scope, "scope.%s", SSDATA (language));
+
+      ret = (XTREE_SITTER (sitter)->highlighter =
+	     ts_highlighter_new (XTREE_SITTER (sitter)->highlight_names,
+				 XTREE_SITTER (sitter)->highlight_names,
+				 (uint32_t) count));
+
+      highlights_scm =
+	Flocate_file_internal (concat3 (build_string ("queries/"),
+					language, build_string ("/highlights.scm")),
+			       Vload_path, Qnil, Qnil);
+
+      if (NILP (highlights_scm))
+	{
+	  suberror = language;
+	  error = "Could not locate highlights scm";
+	}
+      else
+	{
+	  long highlights_query_length;
+	  fp = fopen (SSDATA (highlights_scm), "rb");
+	  if (! fp) {
+	      suberror = highlights_scm;
+	      error = "Cannot fopen";
+	      goto finally;
+	  }
+	  fseek (fp, 0L, SEEK_END);
+	  highlights_query_length = ftell (fp);
+	  rewind (fp);
+
+	  XTREE_SITTER (sitter)->highlights_query =
+	    xzalloc(highlights_query_length + 1);
+
+	  if (1 != fread (XTREE_SITTER (sitter)->highlights_query,
+			  highlights_query_length, 1, fp))
+	    {
+	      suberror = highlights_scm;
+	      error = "Cannot fread";
+	    }
+	  else
+	    {
+	      TSHighlightError ts_highlight_error =
+		ts_highlighter_add_language
+		(ret,
+		 scope,
+		 NULL,
+		 ts_parser_language (XTREE_SITTER (sitter)->parser),
+		 XTREE_SITTER (sitter)->highlights_query,
+		 "",
+		 "",
+		 strlen (XTREE_SITTER (sitter)->highlights_query),
+		 0,
+		 0);
+	      if (ts_highlight_error != TSHighlightOk)
+		{
+		  suberror = make_fixnum (ts_highlight_error);
+		  error = "ts_highlighter_add_language non-Ok return";
+		}
+	    }
+	}
+
+    finally:
+      SAFE_FREE ();
+      if (fp != NULL)
+	fclose (fp);
+      if (error != NULL)
+	xsignal2 (Qtree_sitter_error, build_string (error), suberror);
+    }
+  return ret;
+}
+
+static Lisp_Object
+do_highlights (Lisp_Object beg, Lisp_Object end, HighlightsFunctor fn)
+{
+  Lisp_Object retval = Qnil, sitter;
+
+  CHECK_FIXNUM (beg);
+  CHECK_FIXNUM (end);
+  sitter = Ftree_sitter (Fcurrent_buffer ());
+  if (! NILP (sitter))
+    {
+      TSHighlighter *ts_highlighter = ensure_highlighter (sitter);
+      Lisp_Object language = Fcdr_safe (Fassq (XTREE_SITTER (sitter)->progmode,
+					       Fsymbol_value (Qtree_sitter_mode_alist)));
+      char *scope;
+
+      USE_SAFE_ALLOCA;
+      scope = SAFE_ALLOCA (strlen ("scope.") + SCHARS (language) + 1);
+      sprintf (scope, "scope.%s", SSDATA (language));
+
+      if (ts_highlighter)
+	{
+	  for (TSNode node = ts_node_first_child_for_byte
+		 (ts_tree_root_node (XTREE_SITTER (sitter)->tree),
+		  BUFFER_TO_SITTER (XFIXNUM (beg)));
+	       (! ts_node_is_null (node)
+		&& ts_node_start_byte (node) < BUFFER_TO_SITTER (XFIXNUM (end)));
+	       node = ts_node_next_sibling (node))
+	    {
+	      Lisp_Object
+		node_start = make_fixnum (SITTER_TO_BUFFER (ts_node_start_byte (node))),
+		node_end = make_fixnum (SITTER_TO_BUFFER (ts_node_end_byte (node))),
+		source_code = Fbuffer_substring_no_properties (node_start, node_end);
+	      TSHighlightEventSlice ts_highlight_event_slice =
+		(TSHighlightEventSlice) { NULL, 0 };
+	      TSHighlightBuffer *ts_highlight_buffer = ts_highlight_buffer_new ();
+
+	      /* source code is relative coords */
+	      uint32_t restore_start = node.context[0];
+	      node.context[0] = 0;
+
+	      ts_highlight_event_slice =
+		ts_highlighter_return_highlights (ts_highlighter, scope,
+						  SSDATA (source_code),
+						  (uint32_t) SBYTES (source_code),
+						  &node,
+						  ts_highlight_buffer);
+
+	      /* restore to absolute coords */
+	      node.context[0] = restore_start;
+	      retval = nconc2 (fn (&ts_highlight_event_slice, &node,
+				   XTREE_SITTER (sitter)->highlight_names),
+			       retval);
+	      ts_highlighter_free_highlights (ts_highlight_event_slice);
+	      ts_highlight_buffer_delete (ts_highlight_buffer);
+	    }
+	}
+
+      SAFE_FREE ();
+    }
+  return retval;
+}
+
+DEFUN ("tree-sitter--testable",
+       Ftree_sitter__testable, Stree_sitter__testable,
+       1, 1, 0,
+       doc: /* Is the bundled dynamic library readable by my OS. */)
+  (Lisp_Object file)
+{
+  CHECK_STRING (file);
+  return dynlib_open (SSDATA (file)) ? Qt : Qnil;
+}
+
+DEFUN ("tree-sitter-root-node",
+       Ftree_sitter_root_node, Stree_sitter_root_node,
+       0, 1, 0,
+       doc: /* Return TSNode stash from BUFFER's sitter. */)
+  (Lisp_Object buffer)
+{
+  Lisp_Object retval = Qnil, sitter;
+
+  if (NILP (buffer))
+    buffer = Fcurrent_buffer ();
+
+  CHECK_BUFFER (buffer);
+  sitter = Ftree_sitter (buffer);
+
+  if (! NILP (sitter))
+    {
+      const TSTree *tree = XTREE_SITTER (sitter)->tree;
+      if (tree != NULL)
+	retval = build_string (ts_node_string (ts_tree_root_node (tree)));
+    }
+  return retval;
+}
+
+DEFUN ("tree-sitter-highlights",
+       Ftree_sitter_highlights, Stree_sitter_highlights,
+       2, 2, "r",
+       doc: /* Return list of highlights from BEG to END. */)
+  (Lisp_Object beg, Lisp_Object end)
+{
+  return do_highlights (beg, end, &list_highlights);
+}
+
+DEFUN ("tree-sitter-highlight-region",
+       Ftree_sitter_highlight_region, Stree_sitter_highlight_region,
+       2, 2, "r",
+       doc: /* Highlight BEG to END. */)
+  (Lisp_Object beg, Lisp_Object end)
+{
+  Lisp_Object bounds = do_highlights (beg, end, &highlight_region);
+  return NILP (bounds)
+    ? bounds : Fcons (apply1 (intern ("min"), bounds),
+		      apply1 (intern ("max"), bounds));
+}
+
+DEFUN ("tree-sitter-changed-range",
+       Ftree_sitter_changed_range, Stree_sitter_changed_range,
+       0, 1, 0,
+       doc: /* Return list of BEG and END of TSRange. */)
+  (Lisp_Object buffer)
+{
+  Lisp_Object retval = Qnil, sitter;
+
+  if (NILP (buffer))
+    buffer = Fcurrent_buffer ();
+
+  CHECK_BUFFER (buffer);
+  sitter = Ftree_sitter (buffer);
+
+  if (! NILP (sitter))
+    {
+      const TSTree *tree = XTREE_SITTER (sitter)->tree,
+	*prev_tree = XTREE_SITTER (sitter)->prev_tree;
+      if (tree != NULL && prev_tree != NULL)
+	{
+	  uint32_t count;
+	  TSRange *range = ts_tree_get_changed_ranges (prev_tree, tree, &count);
+	  retval = list2 (make_fixnum (SITTER_TO_BUFFER (range->start_byte)),
+			  make_fixnum (SITTER_TO_BUFFER (range->end_byte)));
+	  free (range);
+	}
+    }
+  return retval;
+}
+
+static const char*
+tree_sitter_read_buffer (void *payload, uint32_t byte_index,
+                         TSPoint position, uint32_t *bytes_read)
+{
+  static int thread_unsafe_last_scan_characters = -1;
+  static char *thread_unsafe_return_value = NULL;
+  EMACS_INT start = SITTER_TO_BUFFER (byte_index);
+  struct buffer *bp = (struct buffer *) payload;
+  ptrdiff_t pdl_count = SPECPDL_INDEX ();
+
+  if (thread_unsafe_last_scan_characters != tree_sitter_scan_characters)
+    {
+      if (thread_unsafe_return_value == NULL)
+        thread_unsafe_return_value = xmalloc (tree_sitter_scan_characters + 1);
+      else
+        thread_unsafe_return_value = xrealloc (thread_unsafe_return_value,
+                                               tree_sitter_scan_characters + 1);
+    }
+
+  if (! BUFFER_LIVE_P (bp))
+    error ("Selecting deleted buffer");
+
+  record_unwind_protect (save_restriction_restore, save_restriction_save ());
+  Fwiden ();
+  sprintf (thread_unsafe_return_value, "%s",
+           SSDATA (Fbuffer_substring_no_properties
+                   (make_fixnum (start),
+                    make_fixnum (min (start + tree_sitter_scan_characters,
+                                      BUF_Z (bp) - BUF_BEG (bp) + 1)))));
+  unbind_to (pdl_count, Qnil);
+  if (bytes_read)
+    *bytes_read = strlen (thread_unsafe_return_value);
+  return thread_unsafe_return_value;
+}
+
+DEFUN ("tree-sitter",
+       Ftree_sitter, Stree_sitter,
+       0, 1, 0,
+       doc: /* Return BUFFER's Lisp_Tree_Sitter. */)
+  (Lisp_Object buffer)
+{
+  Lisp_Object sitter;
+  if (NILP (buffer))
+    buffer = Fcurrent_buffer ();
+
+  CHECK_BUFFER (buffer);
+
+  sitter = Fbuffer_local_value (Qtree_sitter_sitter, buffer);
+  if (NILP (sitter)
+      || ! EQ (XTREE_SITTER (sitter)->progmode, BVAR (XBUFFER (buffer), major_mode)))
+    {
+      sitter = Fset (Qtree_sitter_sitter,
+		     tree_sitter_create (BVAR (XBUFFER (buffer), major_mode)));
+    }
+
+  if (! NILP (sitter))
+    {
+      if (XTREE_SITTER (sitter)->tree == NULL)
+	{
+	  XTREE_SITTER (sitter)->tree =
+	    ts_parser_parse (XTREE_SITTER (sitter)->parser,
+			     XTREE_SITTER (sitter)->tree,
+			     (TSInput) {
+			       XBUFFER (buffer),
+			       tree_sitter_read_buffer,
+			       TSInputEncodingUTF8
+			     });
+	  if (XTREE_SITTER (sitter)->tree == NULL)
+	    xsignal1 (Qtree_sitter_parse_error, BVAR (XBUFFER (buffer), name));
+	}
+    }
+  return sitter;
+}
+
+/* TODO buffers not utf-8-clean. */
+void
+tree_sitter_record_change (ptrdiff_t start_char, ptrdiff_t old_end_char,
+			   ptrdiff_t new_end_char)
+{
+  Lisp_Object sitter = Fbuffer_local_value (Qtree_sitter_sitter, Fcurrent_buffer ());
+  if (! NILP (sitter))
+    {
+      TSTree *tree = XTREE_SITTER (sitter)->tree;
+      if (tree != NULL)
+	{
+	  static const TSPoint dummy_point = { 0, 0 };
+	  TSInputEdit edit = {
+	    BUFFER_TO_SITTER (start_char),
+	    BUFFER_TO_SITTER (old_end_char),
+	    BUFFER_TO_SITTER (new_end_char),
+	    dummy_point,
+	    dummy_point,
+	    dummy_point
+	  };
+
+	  if (XTREE_SITTER (sitter)->prev_tree != NULL)
+	    ts_tree_delete (XTREE_SITTER (sitter)->prev_tree);
+	  XTREE_SITTER (sitter)->prev_tree = ts_tree_copy (tree);
+	  ts_tree_edit (tree, &edit);
+	  XTREE_SITTER (sitter)->tree =
+	    ts_parser_parse (XTREE_SITTER (sitter)->parser,
+			     tree,
+			     (TSInput) {
+			       current_buffer,
+			       tree_sitter_read_buffer,
+			       TSInputEncodingUTF8
+			     });
+	  ts_tree_delete (tree);
+	}
+      else
+	{
+	  xsignal1 (Qtree_sitter_error, BVAR (XBUFFER (Fcurrent_buffer ()), name));
+	}
+    }
+}
+
+DEFUN ("tree-sitter-expand-pattern",
+       Ftree_sitter_expand_pattern,
+       Stree_sitter_expand_pattern, 1, 1, 0,
+       doc: /* Expand PATTERN to its string form.
+
+PATTERN can be
+
+    :anchor
+    :?
+    :*
+    :+
+    (TYPE PATTERN...)
+    [PATTERN...]
+    FIELD-NAME:
+    @CAPTURE-NAME
+    (_)
+    _
+    \"TYPE\"  */)
+  (Lisp_Object pattern)
+{
+  if (EQ (pattern, intern_c_string (":anchor")))
+    return build_pure_c_string(".");
+  if (EQ (pattern, intern_c_string (":?")))
+    return build_pure_c_string("?");
+  if (EQ (pattern, intern_c_string (":*")))
+    return build_pure_c_string("*");
+  if (EQ (pattern, intern_c_string (":+")))
+    return build_pure_c_string("+");
+  if (VECTORP (pattern) || CONSP (pattern))
+    return concat3 (build_pure_c_string (VECTORP (pattern) ? "[" : "("),
+		    Fmapconcat (intern_c_string
+				("tree-sitter-expand-pattern"),
+				pattern,
+				build_pure_c_string (" ")),
+		    build_pure_c_string (VECTORP (pattern) ? "]" : ")"));
+  return CALLN (Fformat, build_pure_c_string("%S"), pattern);
+}
+
+DEFUN ("tree-sitter-query-capture",
+       Ftree_sitter_query_capture,
+       Stree_sitter_query_capture, 4, 4, 0,
+       doc: /* Query NODE with PATTERN.
+
+Returns a list of (CAPTURE_NAME . NODE).  CAPTURE_NAME is the name
+assigned to the node in PATTERN.  NODE is the captured node.
+
+PATTERN is either a string containing one or more matching patterns,
+or a list containing one or more s-expression matching patterns.
+
+BEG and END specify the query range.
+
+Raise an tree-sitter-query-error if PATTERN is malformed.  See the
+info node for how to read the error message.  */)
+  (Lisp_Object node, Lisp_Object pattern,
+   Lisp_Object beg, Lisp_Object end)
+{
+  TSNode *ts_node = (TSNode *) xmint_pointer (node);
+  TSQueryError error_type;
+  TSQuery *query;
+  TSQueryCursor *cursor;
+  TSQueryMatch match;
+  uint32_t error_offset, start_byte0, end_byte0;
+  Lisp_Object result = Qnil;
+  TSLanguageFunctor fn =
+    tree_sitter_language_functor (BVAR (current_buffer, major_mode));
+
+  validate_region (&beg, &end);
+  start_byte0 = XFIXNUM (beg);
+  end_byte0 = XFIXNUM (end);
+
+  if (CONSP (pattern))
+    pattern = Ftree_sitter_expand_pattern (pattern);
+  CHECK_STRING (pattern);
+
+  query = ts_query_new (fn (), SSDATA (pattern), strlen (SSDATA (pattern)),
+			&error_offset, &error_type);
+
+  if (query == NULL)
+    xsignal1 (Qtree_sitter_query_error, make_fixnum (error_type));
+
+  cursor = ts_query_cursor_new ();
+
+  ts_query_cursor_set_byte_range (cursor, start_byte0, end_byte0);
+  ts_query_cursor_exec (cursor, query, *ts_node);
+
+  while (ts_query_cursor_next_match (cursor, &match))
+    {
+      const TSQueryCapture *captures = match.captures;
+      for (int idx = 0; idx < match.capture_count; idx++)
+	{
+	  TSQueryCapture capture;
+	  Lisp_Object captured_node;
+	  const char *capture_name;
+	  Lisp_Object entry;
+	  uint32_t capture_name_len;
+
+	  capture = captures[idx];
+	  /* captured_node = make_tree_sitter_node (lisp_parser, capture.node); */
+	  captured_node = Qnil;
+	  capture_name = ts_query_capture_name_for_id
+	    (query, capture.index, &capture_name_len);
+	  entry = Fcons (intern_c_string (capture_name), captured_node);
+	  result = Fcons (entry, result);
+	}
+    }
+  ts_query_delete (query);
+  ts_query_cursor_delete (cursor);
+  return Freverse (result);
+}
+
+void
+syms_of_tree_sitter (void)
+{
+  DEFSYM (Qtree_sitter_error, "tree-sitter-error");
+  DEFSYM (Qtree_sitter_parse_error, "tree-sitter-parse-error");
+  DEFSYM (Qtree_sitter_query_error, "tree-sitter-query-error");
+  DEFSYM (Qtree_sitter_language_error, "tree-sitter-language-error");
+  DEFSYM (Qtree_sitterp, "tree-sitterp");
+
+  define_error (Qtree_sitter_error, "Generic tree-sitter exception", Qerror);
+  define_error (Qtree_sitter_parse_error, "Parse error",
+		Qtree_sitter_error);
+  define_error (Qtree_sitter_query_error, "Query pattern is malformed",
+		Qtree_sitter_error);
+  define_error (Qtree_sitter_language_error, "Cannot load language",
+		Qtree_sitter_error);
+
+  DEFVAR_INT ("tree-sitter-scan-characters", tree_sitter_scan_characters,
+	      doc: /* Number of characters to read per tree sitter scan.  */);
+  tree_sitter_scan_characters = 1024;
+
+  DEFSYM (Qtree_sitter_mode_alist, "tree-sitter-mode-alist");
+  DEFSYM (Qtree_sitter_highlight_alist, "tree-sitter-highlight-alist");
+  DEFSYM (Qtree_sitter_sitter, "tree-sitter-sitter");
+  Fmake_variable_buffer_local (Qtree_sitter_sitter);
+
+  defsubr (&Stree_sitter);
+  defsubr (&Stree_sitter_root_node);
+  defsubr (&Stree_sitter_highlights);
+  defsubr (&Stree_sitter_highlight_region);
+  defsubr (&Stree_sitter_changed_range);
+  defsubr (&Stree_sitter__testable);
+
+  /* defsubr (&Stree_sitter_node_type); */
+  /* defsubr (&Stree_sitter_node_start); */
+  /* defsubr (&Stree_sitter_node_end); */
+  /* defsubr (&Stree_sitter_node_string); */
+  /* defsubr (&Stree_sitter_node_parent); */
+  /* defsubr (&Stree_sitter_node_child); */
+  /* defsubr (&Stree_sitter_node_check); */
+  /* defsubr (&Stree_sitter_node_child_by_field_name); */
+  /* defsubr (&Stree_sitter_node_next_sibling); */
+  /* defsubr (&Stree_sitter_node_prev_sibling); */
+  /* defsubr (&Stree_sitter_node_first_child_for_pos); */
+  /* defsubr (&Stree_sitter_node_eq); */
+  defsubr (&Stree_sitter_expand_pattern);
+  defsubr (&Stree_sitter_query_capture);
+}
diff --git a/src/tree-sitter.h b/src/tree-sitter.h
new file mode 100644
index 0000000000..2022a5016c
--- /dev/null
+++ b/src/tree-sitter.h
@@ -0,0 +1,63 @@
+/* Header file for the tree-sitter integration.
+
+Copyright (C) 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 <https://www.gnu.org/licenses/>.  */
+
+#ifndef EMACS_TREE_SITTER_H
+#define EMACS_TREE_SITTER_H
+
+#include "lisp.h"
+
+#include <tree_sitter/api.h>
+#include <tree_sitter/highlight.h>
+
+INLINE_HEADER_BEGIN
+
+struct Lisp_Tree_Sitter
+{
+  union vectorlike_header header;
+  Lisp_Object progmode;
+  TSParser *parser;
+  TSTree *prev_tree;
+  TSTree *tree;
+  TSHighlighter *highlighter;
+  const char **highlight_names;
+  char *highlights_query;
+};
+
+INLINE bool
+TREE_SITTERP (Lisp_Object x)
+{
+  return PSEUDOVECTORP (x, PVEC_TREE_SITTER);
+}
+
+INLINE struct Lisp_Tree_Sitter *
+XTREE_SITTER (Lisp_Object a)
+{
+  eassert (TREE_SITTERP (a));
+  return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Tree_Sitter);
+}
+
+INLINE void
+CHECK_TREE_SITTER (Lisp_Object sitter)
+{
+  CHECK_TYPE (TREE_SITTERP (sitter), Qtree_sitterp, sitter);
+}
+
+INLINE_HEADER_END
+
+#endif /* EMACS_TREE_SITTER_H */
diff --git a/src/xdisp.c b/src/xdisp.c
index aa01db210b..9f670059a7 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -4515,7 +4515,6 @@ handle_face_prop (struct it *it)
           && IT_CHARPOS (*it) > BEG)
 	{
 	  const int prev_face_id = face_before_it_pos (it);
-
 	  old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
 	}
 
@@ -8903,9 +8902,9 @@ next_element_from_buffer (struct it *it)
 	      success_p = false;
 	    }
 	}
-      else if (!(!it->bidi_p
-		 || BIDI_AT_BASE_LEVEL (it->bidi_it)
-		 || IT_CHARPOS (*it) == it->stop_charpos))
+      else if (it->bidi_p
+	       && ! BIDI_AT_BASE_LEVEL (it->bidi_it)
+	       && IT_CHARPOS (*it) != it->stop_charpos)
 	{
 	  /* With bidi non-linear iteration, we could find ourselves
 	     far beyond the last computed stop_charpos, with several
@@ -35057,6 +35056,9 @@ syms_of_xdisp (void)
   DEFSYM (Qfontified, "fontified");
   DEFSYM (Qfontification_functions, "fontification-functions");
 
+  Vtext_property_default_nonsticky
+    = Fcons (Fcons (Qfontified, Qt), Vtext_property_default_nonsticky);
+
   /* Name of the symbol which disables Lisp evaluation in 'display'
      properties.  This is used by enriched.el.  */
   DEFSYM (Qdisable_eval, "disable-eval");
diff --git a/test/src/tree-sitter-resources/bin/c.so b/test/src/tree-sitter-resources/bin/c.so
new file mode 100755
index 0000000000000000000000000000000000000000..e61700cdf2bed6d1f5a9277c36241fe829978c9a
GIT binary patch
literal 399152
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

literal 0
HcmV?d00001

diff --git a/test/src/tree-sitter-resources/queries/c/highlights.scm b/test/src/tree-sitter-resources/queries/c/highlights.scm
new file mode 100644
index 0000000000..c9666b5b00
--- /dev/null
+++ b/test/src/tree-sitter-resources/queries/c/highlights.scm
@@ -0,0 +1,133 @@
+["break"
+ "case"
+ "const"
+ "continue"
+ "default"
+ "do"
+ "else"
+ "enum"
+ "extern"
+ "for"
+ "if"
+ "inline"
+ "return"
+ "sizeof"
+ "static"
+ "struct"
+ "switch"
+ "typedef"
+ "union"
+ "volatile"
+ "while"
+ "..."] @keyword
+
+[(storage_class_specifier)
+ (type_qualifier)] @keyword
+
+["#define"
+ "#else"
+ "#endif"
+ "#if"
+ "#ifdef"
+ "#ifndef"
+ "#include"
+ (preproc_directive)] @function.macro
+
+((["#ifdef" "#ifndef"] (identifier) @constant))
+
+["+" "-" "*" "/" "%"
+ "~" "|" "&" "<<" ">>"
+ "!" "||" "&&"
+ "->"
+ "==" "!=" "<" ">" "<=" ">="
+ "=" "+=" "-=" "*=" "/=" "%=" "|=" "&="
+ "++" "--"
+] @operator
+
+(conditional_expression ["?" ":"] @operator)
+
+["(" ")" "[" "]" "{" "}"] @punctuation.bracket
+
+["." "," ";"] @punctuation.delimiter
+
+;;; ----------------------------------------------------------------------------
+;;; Functions.
+
+(call_expression
+ function: [(identifier) @function.call
+            (field_expression field: (_) @method.call)])
+
+(function_declarator
+ declarator: [(identifier) @function
+              (parenthesized_declarator
+               (pointer_declarator (field_identifier) @function))])
+
+(preproc_function_def
+ name: (identifier) @function)
+
+;;; ----------------------------------------------------------------------------
+;;; Types.
+
+[(primitive_type)
+ (sized_type_specifier)] @type.builtin
+
+(type_identifier) @type
+
+;;; ----------------------------------------------------------------------------
+;;; Variables.
+
+(declaration declarator: [(identifier) @variable
+                          (_ (identifier) @variable)])
+
+(parameter_declaration declarator: [(identifier) @variable.parameter
+                                    (_ (identifier) @variable.parameter)])
+
+(init_declarator declarator: [(identifier) @variable
+                              (_ (identifier) @variable)])
+
+(assignment_expression
+ left: [(identifier) @variable
+        (field_expression field: (_) @variable)
+        (subscript_expression argument: (identifier) @variable)
+        (pointer_expression (identifier) @variable)])
+
+(update_expression
+ argument: (identifier) @variable)
+
+(preproc_def name: (identifier) @variable.special)
+
+(preproc_params
+ (identifier) @variable.parameter)
+
+;;; ----------------------------------------------------------------------------
+;;; Properties.
+
+(field_declaration
+ declarator: [(field_identifier) @property.definition
+              (pointer_declarator (field_identifier) @property.definition)
+              (pointer_declarator (pointer_declarator (field_identifier) @property.definition))])
+
+(enumerator name: (identifier) @property.definition)
+
+(field_identifier) @property
+
+;;; ----------------------------------------------------------------------------
+;;; Misc.
+
+((identifier) @constant
+ (.match? @constant "^[A-Z_][A-Z_\\d]*$"))
+
+[(null) (true) (false)] @constant.builtin
+
+[(number_literal)
+ (char_literal)] @number
+
+(statement_identifier) @label
+
+;;; ----------------------------------------------------------------------------
+;;; Strings and comments.
+
+(comment) @comment
+
+[(string_literal)
+ (system_lib_string)] @string
diff --git a/test/src/tree-sitter-tests.el b/test/src/tree-sitter-tests.el
new file mode 100644
index 0000000000..0c620d562a
--- /dev/null
+++ b/test/src/tree-sitter-tests.el
@@ -0,0 +1,111 @@
+;;; tree-sitter-tests.el --- tests for src/tree-sitter.c         -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; This file is NOT 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 <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'tree-sitter)
+
+(defsubst tree-sitter-testable ()
+  (when-let ((dylib (locate-file "bin/c" load-path (split-string ".so"))))
+    (tree-sitter--testable dylib)))
+
+(defmacro tree-sitter-tests-with-load-path (&rest body)
+  (declare (indent defun))
+  `(let ((load-path (cons (expand-file-name "src/tree-sitter-resources")
+                          load-path)))
+     (skip-unless (tree-sitter-testable))
+     ,@body))
+
+(defmacro tree-sitter-tests-doit (ext text &rest body)
+  "font-lock setup is highly circular, redundant, and difficult to isolate."
+  (declare (indent defun))
+  `(tree-sitter-tests-with-load-path
+     (let ((dir (make-temp-file "tree-sitter-tests" t))
+           (text (replace-regexp-in-string "^\n" "" ,text)))
+       (unwind-protect
+           (let ((font-lock-support-mode 'tree-sitter-lock-mode)
+                 (file-name (expand-file-name (concat "tree-sitter-tests" ,ext) dir))
+                 font-lock-global-modes ;; only works when not interactive
+                 enable-dir-local-variables)
+             (with-temp-file file-name (insert text))
+             (find-file file-name)
+             (let (noninteractive)
+               (turn-on-font-lock))
+             (should font-lock-mode)
+             (should tree-sitter-lock-mode)
+             (should-not (text-property-any (point-min) (point-max) 'fontified nil))
+             ,@body)
+         (let (kill-buffer-query-functions)
+           (kill-buffer))
+         (delete-directory dir t)))))
+
+(ert-deftest tree-sitter-basic-parsing ()
+  "Test basic parsing routines."
+  (let ((text "
+void main (void) {
+  return 0;
+}
+"))
+    (tree-sitter-tests-doit ".c" text
+      (should (equal (tree-sitter-highlights (point-min) (point-max))
+                     '(font-lock-type-face (1 . 5) nil (5 . 6) font-lock-function-name-face (6 . 10) nil (10 . 12) font-lock-type-face (12 . 16) nil (16 . 22) font-lock-keyword-face (22 . 28) nil (28 . 29) font-lock-constant-face (29 . 30) nil (30 . 33))))
+      (goto-char (point-min))
+      (forward-line 1)
+      (insert "\n  printf(\"hello world\");\n")
+      (should (equal (tree-sitter-highlights (point-min) (point-max))
+                     '(font-lock-type-face (1 . 5) nil (5 . 6) font-lock-function-name-face (6 . 10) nil (10 . 12) font-lock-type-face (12 . 16) nil (16 . 23) font-lock-function-name-face (23 . 29) nil (29 . 30) font-lock-string-face (30 . 43) nil (43 . 48) font-lock-keyword-face (48 . 54) nil (54 . 55) font-lock-constant-face (55 . 56) nil (56 . 59)))))))
+
+(ert-deftest tree-sitter-how-fast ()
+  "How fast can it fontify xdisp.c"
+  (tree-sitter-tests-with-load-path
+    (cl-flet ((bench
+                (file mode reps unfontify fontify)
+	        (save-window-excursion
+	          (find-file-literally file)
+	          (let (font-lock-maximum-size
+		        (font-lock-support-mode mode)
+		        enable-dir-local-variables
+		        font-lock-global-modes
+		        font-lock-fontified)
+	            (set-auto-mode)
+	            (cl-letf (((symbol-function 'font-lock-initial-fontify) #'ignore))
+                      (let (noninteractive)
+		        (turn-on-font-lock)))
+	            (cl-assert (null (text-property-any (point-min) (point-max) 'fontified t)))
+	            (unwind-protect
+                        (benchmark-run reps
+			  (funcall unfontify (point-min) (point-max))
+			  (funcall fontify (point-min) (point-max))
+                          (cl-assert (null (text-property-any (point-min) (point-max) 'fontified nil))))
+	              (let (kill-buffer-query-functions)
+		        (kill-buffer)))))))
+      (let ((fast (car (bench (expand-file-name "src/xdisp.c" "..")
+                              'tree-sitter-lock-mode 1
+                              #'font-lock-unfontify-region
+                              #'font-lock-fontify-region)))
+            (slow (car (bench (expand-file-name "src/xdisp.c" "..")
+                              'jit-lock-mode 1
+                              #'jit-lock-refontify
+                              #'jit-lock-fontify-now))))
+        (message "tree-sitter-how-fast: %s versus %s" fast slow)
+        (should (< fast (/ slow 3)))))))
+
+(provide 'tree-sitter-tests)
+;;; tree-sitter-tests.el ends here
-- 
2.26.2


[-- Attachment #3: Type: text/plain, Size: 7664 bytes --]




In Commercial Emacs 28.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.30, cairo version 1.15.10)
 of 2021-11-02 built on dick
Repository revision: 79a446d9792b36e7d84b75757f88953023868421
Repository branch: dev
Windowing system distributor 'The X.Org Foundation', version 11.0.11906000
System Description: Ubuntu 18.04.4 LTS

Configured using:
 'configure --prefix=/home/dick/.local --with-tree-sitter
 --enable-dumping-overwrite CC=gcc-10 'CFLAGS=-g3 -O2
 -I/home/dick/.local/include/' LDFLAGS=-L/home/dick/.local/lib
 PKG_CONFIG_PATH=/home/dick/.local/lib/pkgconfig'

Configured features:
CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON
TREE-SITTER LCMS2 LIBSELINUX LIBXML2 MODULES NOTIFY INOTIFY PDUMPER PNG RSVG
SECCOMP SOUND THREADS TIFF TOOLKIT_SCROLL_BARS WEBP X11 XDBE XIM XPM GTK3 ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Diff

Minor modes in effect:
  whitespace-mode: t
  async-bytecomp-package-mode: t
  global-git-commit-mode: t
  shell-dirtrack-mode: t
  projectile-mode: t
  flx-ido-mode: t
  override-global-mode: t
  global-hl-line-mode: t
  winner-mode: t
  tooltip-mode: t
  show-paren-mode: t
  mouse-wheel-mode: t
  tree-sitter-lock-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t

Load-path shadows:
/home/dick/gomacro-mode/gomacro-mode hides /home/dick/.emacs.d/elpa/gomacro-mode-20200326.1103/gomacro-mode
/home/dick/.emacs.d/elpa/hydra-20170924.2259/lv hides /home/dick/.emacs.d/elpa/lv-20191106.1238/lv
/home/dick/.emacs.d/elpa/magit-3.3.0/magit-section-pkg hides /home/dick/.emacs.d/elpa/magit-section-3.3.0/magit-section-pkg
/home/dick/org-gcal.el/org-gcal hides /home/dick/.emacs.d/elpa/org-gcal-0.3/org-gcal
/home/dick/.emacs.d/elpa/tree-sitter-20210912.1211/tree-sitter hides /home/dick/.local/share/emacs/28.0.50/lisp/tree-sitter
/home/dick/.emacs.d/lisp/json hides /home/dick/.local/share/emacs/28.0.50/lisp/json
/home/dick/.emacs.d/elpa/transient-0.3.6/transient hides /home/dick/.local/share/emacs/28.0.50/lisp/transient
/home/dick/.emacs.d/elpa/hierarchy-20171221.1151/hierarchy hides /home/dick/.local/share/emacs/28.0.50/lisp/emacs-lisp/hierarchy

Features:
(shadow sort footnote mail-extr gnus-msg emacsbug sendmail whitespace
magit-extras shortdoc help-fns radix-tree rect org-element avl-tree ol-eww eww
xdg url-queue ol-rmail ol-mhe ol-irc ol-info ol-gnus nnselect gnus-search
eieio-opt speedbar ezimage dframe gnus-art mm-uu mml2015 mm-view mml-smime
smime dig gnus-sum gnus-group mm-url gnus-undo gnus-start gnus-dbus gnus-cloud
nnimap nnmail mail-source utf7 netrc nnoo gnus-spec gnus-int gnus-range
gnus-win ol-docview doc-view jka-compr image-mode exif ol-bibtex ol-bbdb
ol-w3m ol-doi org-link-doi org-tempo tempo org org-macro org-footnote
org-pcomplete org-list org-faces org-entities org-version ob-R ob-emacs-lisp
ob-ein ein-cell ein-output-area shr kinsoku svg dom ein-kernel ein-ipdb
ein-query ein-events ein-websocket websocket bindat ein-node ewoc ein-log
ein-classes ein-core request anaphora ein ein-utils deferred ob ob-tangle
org-src ob-ref ob-lob ob-table ob-exp ob-comint ob-core ob-eval org-table
oc-basic bibtex ol org-keys oc org-compat org-macs org-loaddefs find-func
cal-menu calendar cal-loaddefs misearch multi-isearch tramp-archive tramp-gvfs
tramp-cache zeroconf dbus xml tramp tramp-loaddefs trampver tramp-integration
files-x tramp-compat parse-time iso8601 ls-lisp scheme make-mode texinfo
texinfo-loaddefs benchmark autoconf autoconf-mode vc-git vc vc-dispatcher
bug-reference cc-mode cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align
cc-engine cc-vars cc-defs face-remap magit-patch-changelog magit-patch
magit-submodule magit-obsolete magit-popup async-bytecomp async magit-blame
magit-stash magit-reflog magit-bisect magit-push magit-pull magit-fetch
magit-clone magit-remote magit-commit magit-sequence magit-notes
magit-worktree magit-tag magit-merge magit-branch magit-reset magit-files
magit-refs magit-status magit magit-repos magit-apply magit-wip magit-log
which-func imenu magit-diff smerge-mode diff diff-mode git-commit log-edit
message rmc puny dired-x dired dired-loaddefs rfc822 mml mml-sec epa epg
rfc6068 epg-config mm-decode mm-bodies mm-encode mailabbrev gmm-utils
mailheader pcvs-util add-log magit-core magit-margin magit-transient
magit-process with-editor shell pcomplete server magit-mode transient
format-spec paredit-ext paredit subed subed-vtt subed-srt subed-common
subed-mpv subed-debug subed-config inf-ruby ruby-mode smie company pcase
haskell-interactive-mode haskell-presentation-mode haskell-process
haskell-session haskell-compile haskell-mode haskell-cabal haskell-utils
haskell-font-lock haskell-indentation haskell-string haskell-sort-imports
haskell-lexeme haskell-align-imports haskell-complete-module
haskell-ghc-support noutline outline flymake-proc flymake warnings etags
fileloop generator xref project dabbrev haskell-customize hydra lv
use-package-ensure solarized-theme solarized-definitions projectile lisp-mnt
mail-parse rfc2231 ibuf-ext ibuffer ibuffer-loaddefs thingatpt
magit-autorevert autorevert filenotify magit-git magit-section magit-utils crm
dash rx grep compile comint ansi-color gnus nnheader gnus-util rmail
rmail-loaddefs rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils
text-property-search time-date flx-ido flx google-translate-default-ui
google-translate-core-ui facemenu color ido google-translate-core
google-translate-tk google-translate-backend use-package-bind-key bind-key
auto-complete easy-mmode advice edmacro kmacro popup cus-edit pp cus-load
wid-edit emms-player-mplayer emms-player-simple emms emms-compat cl-extra
use-package-core derived hl-line winner ring help-mode finder-inf
json-reformat-autoloads json-snatcher-autoloads sml-mode-autoloads
tornado-template-mode-autoloads info package browse-url url url-proxy
url-privacy url-expand url-methods url-history url-cookie url-domsuf url-util
mailcap url-handlers url-parse auth-source cl-seq eieio eieio-core cl-macs
eieio-loaddefs password-cache json map url-vars seq gv subr-x byte-opt
bytecomp byte-compile cconv cl-loaddefs cl-lib iso-transl tooltip eldoc paren
electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel
term/x-win x-win term/common-win x-dnd tool-bar dnd fontset image regexp-opt
fringe tree-sitter tabulated-list replace newcomment text-mode lisp-mode
prog-mode register page tab-bar menu-bar rfn-eshadow isearch easymenu timer
select scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer cl-generic cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese composite
emoji-zwj charscript charprop case-table epa-hook jka-cmpr-hook help simple
abbrev obarray cl-preloaded nadvice button loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env code-pages
mule custom widget hashtable-print-readable backquote threads dbusbind inotify
lcms2 dynamic-setting system-font-setting font-render-setting cairo
move-toolbar gtk x-toolkit x multi-tty make-network-process emacs)

Memory information:
((conses 16 759773 97091)
 (symbols 48 42652 4)
 (strings 32 160168 11293)
 (string-bytes 1 5531795)
 (vectors 16 93438)
 (vector-slots 8 1715124 101435)
 (floats 8 587 2181)
 (intervals 56 9737 1218)
 (buffers 992 23))

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* bug#51572: [PATCH] tree-sitter-lock-mode
  2021-11-02 19:03 bug#51572: [PATCH] tree-sitter-lock-mode dick
@ 2021-11-04 18:47 ` Lars Ingebrigtsen
  2021-11-04 19:31   ` Eli Zaretskii
  2021-12-19  6:56 ` bug#51572: Yuan Fu
  1 sibling, 1 reply; 7+ messages in thread
From: Lars Ingebrigtsen @ 2021-11-04 18:47 UTC (permalink / raw)
  To: dick; +Cc: 51572

dick <dick.r.chiang@gmail.com> writes:

> FWIW, fontification of xdisp.c under tree-sitter is under a
> second versus 17s for jit-lock (on my 10yo Thinkpad).

That's really cool.

Skimming the patch is rather difficult, though, because it contains so
many changes that seem irrelevant.  Like:

> -	(when (null (cdr elt))
> +	(unless (cdr elt)

And just snarky bits:

> +  "This was better embedded in a minor mode, obviously."

And a bunch of commentary that's been removed:

> -;; Rather than the function, e.g., `font-lock-fontify-region' containing the
> -;; code to fontify a region, the function runs the function whose name is the
> -;; value of the variable, e.g., `font-lock-fontify-region-function'.  Normally,

So I'm not sure where we're going with this.  Anybody got an opinion?

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#51572: [PATCH] tree-sitter-lock-mode
  2021-11-04 18:47 ` Lars Ingebrigtsen
@ 2021-11-04 19:31   ` Eli Zaretskii
  2021-11-07 17:21     ` Fu Yuan
  0 siblings, 1 reply; 7+ messages in thread
From: Eli Zaretskii @ 2021-11-04 19:31 UTC (permalink / raw)
  To: Lars Ingebrigtsen, Yuan Fu; +Cc: 51572, dick.r.chiang

> From: Lars Ingebrigtsen <larsi@gnus.org>
> Date: Thu, 04 Nov 2021 19:47:16 +0100
> Cc: 51572@debbugs.gnu.org
> 
> So I'm not sure where we're going with this.  Anybody got an opinion?

What's the status of the tree-sitter support that Yuan Fu (CC'ed) was
working on?  I thought he was very close to completion.





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#51572: [PATCH] tree-sitter-lock-mode
  2021-11-04 19:31   ` Eli Zaretskii
@ 2021-11-07 17:21     ` Fu Yuan
  2021-12-18  6:26       ` Yuan Fu
  0 siblings, 1 reply; 7+ messages in thread
From: Fu Yuan @ 2021-11-07 17:21 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Lars Ingebrigtsen, 51572, dick.r.chiang


> 在 2021年11月4日,下午12:31,Eli Zaretskii <eliz@gnu.org> 写道:
> 
> 
>> 
>> From: Lars Ingebrigtsen <larsi@gnus.org>
>> Date: Thu, 04 Nov 2021 19:47:16 +0100
>> Cc: 51572@debbugs.gnu.org
>> 
>> So I'm not sure where we're going with this.  Anybody got an opinion?
> 
> What's the status of the tree-sitter support that Yuan Fu (CC'ed) was
> working on?  I thought he was very close to completion.

Sorry that I missed this. The code only lacks manual for indentation and font-lock integration. I was waiting for someone to suggest some improvement in that two area before writing the manual but so far no one has provided any. I’ll probably just write the manual and call it done. I’m also waiting for the author of tree-sitter to 1) release 1.0 and 2) allow changing malloc mechanism on run-time.

Yuan 




^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#51572: [PATCH] tree-sitter-lock-mode
  2021-11-07 17:21     ` Fu Yuan
@ 2021-12-18  6:26       ` Yuan Fu
  2021-12-18  7:38         ` Eli Zaretskii
  0 siblings, 1 reply; 7+ messages in thread
From: Yuan Fu @ 2021-12-18  6:26 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Lars Ingebrigtsen, 51572, dick.r.chiang

>>> 
>>> From: Lars Ingebrigtsen <larsi@gnus.org>
>>> Date: Thu, 04 Nov 2021 19:47:16 +0100
>>> Cc: 51572@debbugs.gnu.org
>>> 
>>> So I'm not sure where we're going with this.  Anybody got an opinion?
>> 
>> What's the status of the tree-sitter support that Yuan Fu (CC'ed) was
>> working on?  I thought he was very close to completion.
> 
> Sorry that I missed this. The code only lacks manual for indentation and font-lock integration. I was waiting for someone to suggest some improvement in that two area before writing the manual but so far no one has provided any. I’ll probably just write the manual and call it done. I’m also waiting for the author of tree-sitter to 1) release 1.0 and 2) allow changing malloc mechanism on run-time.

Someone notified me of this commercial-emacs thing made by dickmao [1]. Looking at his README, I suspect that this report is just an excuse for using the patch on his commercial-emacs. So we can probably close this report. I’m happy to be corrected, of course.

[1] https://github.com/commercial-emacs/commercial-emacs

Yuan




^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#51572: [PATCH] tree-sitter-lock-mode
  2021-12-18  6:26       ` Yuan Fu
@ 2021-12-18  7:38         ` Eli Zaretskii
  0 siblings, 0 replies; 7+ messages in thread
From: Eli Zaretskii @ 2021-12-18  7:38 UTC (permalink / raw)
  To: Yuan Fu; +Cc: larsi, 51572, dick.r.chiang

> From: Yuan Fu <casouri@gmail.com>
> Date: Fri, 17 Dec 2021 22:26:58 -0800
> Cc: Lars Ingebrigtsen <larsi@gnus.org>,
>  dick.r.chiang@gmail.com,
>  51572@debbugs.gnu.org
> 
> Someone notified me of this commercial-emacs thing made by dickmao [1]. Looking at his README, I suspect that this report is just an excuse for using the patch on his commercial-emacs. So we can probably close this report. I’m happy to be corrected, of course.

If there's nothing in this proposal that can be useful for us, feel
free to close.





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#51572:
  2021-11-02 19:03 bug#51572: [PATCH] tree-sitter-lock-mode dick
  2021-11-04 18:47 ` Lars Ingebrigtsen
@ 2021-12-19  6:56 ` Yuan Fu
  1 sibling, 0 replies; 7+ messages in thread
From: Yuan Fu @ 2021-12-19  6:56 UTC (permalink / raw)
  To: 51572-done






^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-12-19  6:56 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-02 19:03 bug#51572: [PATCH] tree-sitter-lock-mode dick
2021-11-04 18:47 ` Lars Ingebrigtsen
2021-11-04 19:31   ` Eli Zaretskii
2021-11-07 17:21     ` Fu Yuan
2021-12-18  6:26       ` Yuan Fu
2021-12-18  7:38         ` Eli Zaretskii
2021-12-19  6:56 ` bug#51572: Yuan Fu

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).