Skip to content

Commit

Permalink
Complete automatic synchronization of jsx element tags feature.
Browse files Browse the repository at this point in the history
  • Loading branch information
llemaitre19 committed Feb 8, 2024
1 parent 094cf6d commit 84e5d66
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

## 0.3.4 (2024-02-08)

* Add automatic name synchronization of JSX element tags.
* Add unwrap and delete features.
* Fix jsx electric newline having side effects in none jtsx buffers.

Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Here an example of configuration using [use-package](https://github.com/jwiegley
;; (jtsx-jsx-element-move-allow-step-out t)
;; (jtsx-enable-jsx-electric-closing-element t)
;; (jtsx-enable-electric-open-newline-between-jsx-element-tags t)
;; (jtsx-enable-jsx-element-tags-auto-sync nil)
;; (jtsx-enable-all-syntax-highlighting-features t)
:config
(defun jtsx-bind-keys-to-mode-map (mode-map)
Expand Down Expand Up @@ -112,6 +113,10 @@ Here an example of configuration using [use-package](https://github.com/jwiegley

![Rename element](./examples/rename-element.gif)

As an alternative, you can turn `jtsx-enable-jsx-element-tags-auto-sync` to `t` to enable automatic name synchronization of `JSX` element tags. As soon as the name of an opening or a closing tag is edited, its paired tag is immediately synchronized.

![Auto sync element tags](./examples/auto-sync-tags.gif)

### Moving JSX elements

`jtsx` implements some commands to move a `JSX` tag or node through the `JSX` structure, re-indenting automatically the modified part of code. `JSX` nodes can be an element (self-closing or not), an expression or a text line.
Expand Down Expand Up @@ -199,6 +204,7 @@ Please refer to [Hideshow documentation](https://www.gnu.org/software/emacs/manu
| `jtsx-jsx-element-move-allow-step-out` | `t` | Allow to step out when moving a jsx element. |
| `jtsx-enable-jsx-electric-closing-element` | `t` | Enable electric JSX closing element feature. |
| `jtsx-enable-electric-open-newline-between-jsx-element-tags` | `t` | Enable electric new line between jsx element tags |
| `jtsx-enable-jsx-element-tags-auto-sync` | `nil` | Enable automatic name synchronization of jsx element opening and closing tags. |
| `jtsx-enable-all-syntax-highlighting-features` | `t` | Enable all available syntax highlighting features. |

## FAQ
Expand Down
Binary file added examples/auto-sync-tags.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified examples/rename-element.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 10 additions & 6 deletions jtsx.el
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
;; Maintainer: Loïc Lemaître <[email protected]>
;; URL: https://github.com/llemaitre19/jtsx
;; Package-Requires: ((emacs "29.1"))
;; Version: 0.3.4
;; Version: 0.4.0
;; Keywords: languages

;; This file is NOT part of GNU Emacs.
Expand Down Expand Up @@ -94,7 +94,7 @@ continuated expression."
:group 'jtsx)

(defcustom jtsx-enable-jsx-element-tags-auto-sync nil
"Enable jsx element tags automatic synchronization."
"Enable jsx automatic synchronization of element opening and closing tag name."
:type 'boolean
:safe 'booleanp
:group 'jtsx)
Expand Down Expand Up @@ -384,15 +384,19 @@ Point can be in the opening or closing."
(1- (treesit-node-start identifier-node)))))))

(defun jtsx-synchronize-jsx-element-tags ()
"Synchronize jsx element tags depending on the cursor position."
"Synchronize jsx element tags depending on the cursor position.
Under some circumtances, the synchronization can fail. Right after editing a
tag name and before synchronization, the code is syntactically wrong, thus the
tree-sitter parser can be lost. For example in that situation, where `A' has
just been erased form the opening tag: < attribute=\"text\"></A>."
(when (and jtsx-enable-jsx-element-tags-auto-sync (jtsx-command-modified-buffer-p))
(let* ((node (treesit-node-at (point)))
(parent-node (treesit-node-parent node))
(parent-node-type (treesit-node-type parent-node)))
(when (and (member (treesit-node-type node) '("identifier" ">" "<"))
(member parent-node-type jtsx-jsx-ts-element-tag-keys)
;; Downstream syntax must be clean to prevent unexpected behaviours.
;; e.g.
(member parent-node-type `(,@jtsx-jsx-ts-element-tag-keys "ERROR"))
;; Syntax must be clean to prevent unexpected behaviours.
(not (jtsx-treesit-syntax-error-in-descendants-p parent-node))
(not (jtsx-treesit-syntax-error-in-ancestors-p parent-node)))
(let* ((element-node (treesit-node-parent parent-node))
Expand Down
13 changes: 13 additions & 0 deletions tests/jtsx-tests.el
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,19 @@ Turn this buffer in MODE mode if supplied or defaults to jtsx-tsx-mode."
(should (equal (synchronize-jsx-element-tags-into-buffer content move-point #'jtsx-tsx-mode)
result))))

(ert-deftest jtsx-test-synchronize-jsx-element-tags-from-empty-opening-with-string-attribute ()
"Known bug.
In that situation, Tree-sitter parser is very confused with this syntax. No workaround for now."
:expected-result :failed
(let ((jtsx-enable-jsx-element-tags-auto-sync t)
(move-point #'(lambda () (goto-char 3)))
(content "(< label=\"Name\">Hello</ABC>);")
(result "(< label=\"Name\">Hello</>);"))
(should (equal (synchronize-jsx-element-tags-into-buffer content move-point #'jtsx-jsx-mode)
result))
(should (equal (synchronize-jsx-element-tags-into-buffer content move-point #'jtsx-tsx-mode)
result))))

(ert-deftest jtsx-test-synchronize-jsx-element-tags-from-empty-closing-with-attribute ()
(let ((jtsx-enable-jsx-element-tags-auto-sync t)
(move-point #'(lambda () (goto-char 18)))
Expand Down

0 comments on commit 84e5d66

Please sign in to comment.