Skip to content

Commit a48b0e8

Browse files
committed
Improve declaration-based indentation.
When an incomplete package was next to the "end" keyword of the project, it may be considered a valid package and therefore include the end of the project declaration in the re-indentation of the package. In order to prevent this from happening, the package name and end name must now match before the declaration-based indentation will be applied. Additionally, to provide a hint to the user, the end name of a package is only syntax highlighted when both package name and end name match. This provides a visual clue to the user of the mismatched names. Additional tests have been added to check for improper declaration-based indentation as well as testing the syntax highlighting for package declarations.
1 parent f13676f commit a48b0e8

File tree

4 files changed

+84
-8
lines changed

4 files changed

+84
-8
lines changed

gpr-ts-mode.el

+22-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
;; Author: Troy Brown <[email protected]>
66
;; Created: February 2023
7-
;; Version: 0.6.1
7+
;; Version: 0.6.2
88
;; Keywords: gpr gnat ada languages tree-sitter
99
;; URL: https://github.com/brownts/gpr-ts-mode
1010
;; Package-Requires: ((emacs "29.1"))
@@ -352,8 +352,15 @@ Return nil if no child of that type is found."
352352
'include-node)))
353353
(when (and (gpr-ts-mode--declaration-p candidate)
354354
(not (treesit-search-subtree candidate "ERROR")))
355-
(cons (treesit-node-start candidate)
356-
(treesit-node-end candidate))))))))
355+
;; Prevent interpreting a project declaration "end"
356+
;; next to an incomplete package declaration as a
357+
;; valid package declaration by checking if the names
358+
;; match.
359+
(unless
360+
(and (gpr-ts-mode--package-declaration-p candidate)
361+
(not (gpr-ts-mode--package-declaration-names-match-p candidate)))
362+
(cons (treesit-node-start candidate)
363+
(treesit-node-end candidate)))))))))
357364
(if region
358365
(progn
359366
(treesit-indent-region (car region) (cdr region))
@@ -541,8 +548,10 @@ Return nil if no child of that type is found."
541548
;; Definition
542549
:language 'gpr
543550
:feature 'definition
544-
'((package_declaration
545-
[name: (identifier) endname: (identifier)] @font-lock-function-name-face)
551+
'((package_declaration name: (identifier) @font-lock-function-name-face)
552+
((package_declaration endname: (identifier) @font-lock-function-name-face)
553+
@package-declaration
554+
(:pred gpr-ts-mode--package-declaration-names-match-p @package-declaration))
546555
(typed_string_declaration name: (identifier) @font-lock-type-face)
547556
(variable_declaration name: (identifier) @font-lock-variable-name-face)
548557
(attribute_declaration name: (identifier) @font-lock-property-name-face))
@@ -614,6 +623,14 @@ Return nil if no child of that type is found."
614623
(packages (mapcar #'downcase gpr-ts-mode-package-names)))
615624
(seq-find (apply-partially #'string-equal identifier) packages)))
616625

626+
(defun gpr-ts-mode--package-declaration-names-match-p (node)
627+
"Check if names match in package declaration NODE."
628+
(when (gpr-ts-mode--package-declaration-p node)
629+
(let ((name (treesit-node-child-by-field-name node "name"))
630+
(endname (treesit-node-child-by-field-name node "endname")))
631+
(string-equal-ignore-case (treesit-node-text name t)
632+
(treesit-node-text endname t)))))
633+
617634

618635
;;; Imenu
619636

test/gpr-ts-mode-tests.el

+7-3
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,18 @@ Use BINDING to navigate with optional prefix ARG."
143143
(let ((current-prefix-arg arg))
144144
(call-interactively (key-binding (kbd binding)))))
145145

146-
(defun newline-transform (&optional expect-error)
146+
(defun newline-transform (&optional expect-error declaration)
147147
"Newline transform function for test.
148148
149149
If EXPECT-ERROR is non-nil, then check for an error in the parse tree,
150-
otherwise check that there is no error in the parse tree."
150+
otherwise check that there is no error in the parse tree. If
151+
DECLARATION is non-nil use declaration indentation strategy, otherwise
152+
use line indentation strategy."
151153
(default-transform expect-error)
152154
(setq-local indent-tabs-mode nil)
153-
(setq-local gpr-ts-mode-indent-strategy 'line)
155+
(if declaration
156+
(setq-local gpr-ts-mode-indent-strategy 'declaration)
157+
(setq-local gpr-ts-mode-indent-strategy 'line))
154158
(call-interactively #'newline))
155159

156160
(dolist (file (directory-files (ert-resource-directory)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
with "shared";
2+
3+
project Test is
4+
package Package_A is
5+
-- ^ ^ font-lock-keyword-face
6+
-- ^ font-lock-function-name-face
7+
end Package_A;
8+
-- <- font-lock-keyword-face
9+
-- ^ font-lock-function-name-face
10+
-- ^ font-lock-delimiter-face
11+
12+
package Package_B renames Shared.Package_B;
13+
-- ^ ^ font-lock-keyword-face
14+
-- ^ font-lock-function-name-face
15+
-- ^ nil
16+
-- ^ ^ font-lock-delimiter-face
17+
-- ^ font-lock-function-call-face
18+
19+
package Package_C extends Shared.Package_C is
20+
-- ^ ^ ^ font-lock-keyword-face
21+
-- ^ font-lock-function-name-face
22+
-- ^ nil
23+
-- ^ font-lock-delimiter-face
24+
-- ^ font-lock-function-call-face
25+
end Package_C;
26+
-- <- font-lock-keyword-face
27+
-- ^ font-lock-function-name-face
28+
-- ^ font-lock-delimiter-face
29+
30+
package Different_Case is
31+
-- ^ font-lock-function-name-face
32+
end different_case;
33+
-- ^ font-lock-function-name-face
34+
35+
package Mismatched is
36+
-- ^ font-lock-function-name-face
37+
end Doesnt_Match;
38+
-- ^ nil
39+
end Test;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Code: (lambda () (newline-transform 'expect-error 'declaration))
2+
3+
Name: Incomplete package next to project "end"
4+
5+
Point-Char: |
6+
7+
=-=
8+
project Test is
9+
package Package_A is|
10+
end Test;
11+
=-=
12+
project Test is
13+
package Package_A is
14+
|
15+
end Test;
16+
=-=-=

0 commit comments

Comments
 (0)