|
125 | 125 | :package-version "0.5.0")
|
126 | 126 | ;;;###autoload(put 'gpr-ts-mode-indent-exp-item-offset 'safe-local-variable #'integerp)
|
127 | 127 |
|
| 128 | +(defcustom gpr-ts-mode-indent-strategy 'declaration |
| 129 | + "Indentation strategy to utilize." |
| 130 | + :type '(choice :tag "Indentation Strategy" |
| 131 | + (const :tag "Declaration" declaration) |
| 132 | + (const :tag "Line" line)) |
| 133 | + :group 'gpr-ts |
| 134 | + :link '(custom-manual :tag "Indentation" "(gpr-ts-mode)Indentation") |
| 135 | + :package-version "0.6.0") |
| 136 | + |
128 | 137 | (defcustom gpr-ts-mode-grammar "https://github.com/brownts/tree-sitter-gpr"
|
129 | 138 | "Configuration for downloading and installing the tree-sitter language grammar.
|
130 | 139 |
|
@@ -314,6 +323,50 @@ Return nil if no child of that type is found."
|
314 | 323 | (lambda (n)
|
315 | 324 | (equal (treesit-node-type n) type)))))
|
316 | 325 |
|
| 326 | +(cl-defgeneric gpr-ts-mode-indent (strategy) |
| 327 | + "Indent according to STRATEGY." |
| 328 | + (error "Unknown indentation strategy: %s" strategy)) |
| 329 | + |
| 330 | +(cl-defmethod gpr-ts-mode-indent ((_strategy (eql line))) |
| 331 | + "Indent according to line STRATEGY." |
| 332 | + (treesit-indent)) |
| 333 | + |
| 334 | +(cl-defmethod gpr-ts-mode-indent ((_strategy (eql declaration))) |
| 335 | + "Indent according to declaration STRATEGY." |
| 336 | + (let ((initial-point-column (current-column)) |
| 337 | + (initial-indentation-column (current-indentation)) |
| 338 | + (region |
| 339 | + (save-excursion |
| 340 | + (forward-line 0) |
| 341 | + (skip-chars-forward " \t") |
| 342 | + (unless (looking-at (rx (* whitespace) eol) t) |
| 343 | + (let* ((node (treesit-node-at (point))) |
| 344 | + (root (treesit-buffer-root-node)) |
| 345 | + (candidate |
| 346 | + (treesit-parent-until |
| 347 | + node |
| 348 | + (lambda (node) |
| 349 | + (or (treesit-node-eq node root) |
| 350 | + (string-equal (treesit-node-type node) "ERROR") |
| 351 | + (gpr-ts-mode--declaration-p node))) |
| 352 | + 'include-node))) |
| 353 | + (when (and (gpr-ts-mode--declaration-p candidate) |
| 354 | + (not (treesit-search-subtree candidate "ERROR"))) |
| 355 | + (cons (treesit-node-start candidate) |
| 356 | + (treesit-node-end candidate)))))))) |
| 357 | + (if region |
| 358 | + (progn |
| 359 | + (treesit-indent-region (car region) (cdr region)) |
| 360 | + ;; Move point if it was in the indentation. |
| 361 | + (when (<= initial-point-column |
| 362 | + initial-indentation-column) |
| 363 | + (back-to-indentation))) |
| 364 | + (treesit-indent)))) |
| 365 | + |
| 366 | +(defun gpr-ts-mode--indent-line () |
| 367 | + "Indent according to `gpr-ts-mode-indent-strategy'." |
| 368 | + (gpr-ts-mode-indent gpr-ts-mode-indent-strategy)) |
| 369 | + |
317 | 370 | (defvar gpr-ts-mode--keywords
|
318 | 371 | '("abstract" "all" "at"
|
319 | 372 | "case"
|
@@ -463,7 +516,7 @@ Return nil if no child of that type is found."
|
463 | 516 | (gpr-ts-mode--sibling-exists-p "("))
|
464 | 517 | (gpr-ts-mode--anchor-first-sibling-matching "(")
|
465 | 518 | 0)
|
466 |
| - ;; trival recovery for syntax error or unexpected broken line |
| 519 | + ;; trivial recovery for syntax error or unexpected broken line |
467 | 520 | (catch-all prev-line 0)))
|
468 | 521 | "Tree-sitter indent rules for `gpr-ts-mode'.")
|
469 | 522 |
|
@@ -620,6 +673,16 @@ Return nil if NODE is not an attribute declaration node."
|
620 | 673 | (when (gpr-ts-mode--attribute-declaration-p node)
|
621 | 674 | (gpr-ts-mode--tree-text node '("comment") "for" "use")))
|
622 | 675 |
|
| 676 | +(defun gpr-ts-mode--case_construction-p (node) |
| 677 | + "Determine if NODE is a case construction. |
| 678 | +Return non-nil to indicate it is." |
| 679 | + (string-equal (treesit-node-type node) "case_construction")) |
| 680 | + |
| 681 | +(defun gpr-ts-mode--empty-declaration-p (node) |
| 682 | + "Determine if NODE is an empty declaration. |
| 683 | +Return non-nil to indicate it is." |
| 684 | + (string-equal (treesit-node-type node) "empty_declaration")) |
| 685 | + |
623 | 686 | (defun gpr-ts-mode--package-declaration-p (node)
|
624 | 687 | "Determine if NODE is a package declaration.
|
625 | 688 | Return non-nil to indicate it is."
|
@@ -691,12 +754,27 @@ Return non-nil to indicate that it is."
|
691 | 754 | (and (gpr-ts-mode--variable-declaration-p node)
|
692 | 755 | (not (gpr-ts-mode--typed-variable-declaration-p node))))
|
693 | 756 |
|
| 757 | +(defun gpr-ts-mode--with-declaration-p (node) |
| 758 | + "Determine if NODE is a with declaration. |
| 759 | +Return non-nil to indicate that it is." |
| 760 | + (string-equal (treesit-node-type node) "with_declaration")) |
| 761 | + |
| 762 | +(defun gpr-ts-mode--declaration-p (node) |
| 763 | + "Determine if NODE is a declaration. |
| 764 | +Return non-nil to indicate that it is." |
| 765 | + (or (gpr-ts-mode--attribute-declaration-p node) |
| 766 | + (gpr-ts-mode--case_construction-p node) |
| 767 | + (gpr-ts-mode--empty-declaration-p node) |
| 768 | + (gpr-ts-mode--package-declaration-p node) |
| 769 | + (gpr-ts-mode--project-declaration-p node) |
| 770 | + (gpr-ts-mode--type-declaration-p node) |
| 771 | + (gpr-ts-mode--variable-declaration-p node) |
| 772 | + (gpr-ts-mode--with-declaration-p node))) |
| 773 | + |
694 | 774 | (defun gpr-ts-mode--with-clause-name-p (node)
|
695 | 775 | "Determine if NODE is a string within a with clause."
|
696 |
| - (and (string-equal (treesit-node-type (treesit-node-parent node)) |
697 |
| - "with_declaration") |
698 |
| - (string-equal (treesit-node-type node) |
699 |
| - "string_literal"))) |
| 776 | + (and (gpr-ts-mode--with-declaration-p (treesit-node-parent node)) |
| 777 | + (string-equal (treesit-node-type node) "string_literal"))) |
700 | 778 |
|
701 | 779 | (defun gpr-ts-mode--imenu-index (tree item-p branch-p item-name-fn branch-name-fn)
|
702 | 780 | "Return Imenu index for a specific item category given TREE.
|
@@ -939,7 +1017,10 @@ the name of the branch given the branch node."
|
939 | 1017 | (attribute function number operator package variable)
|
940 | 1018 | (bracket delimiter error)))
|
941 | 1019 |
|
942 |
| - (treesit-major-mode-setup)) |
| 1020 | + (treesit-major-mode-setup) |
| 1021 | + |
| 1022 | + ;; Override `treesit-major-mode-setup' settings. |
| 1023 | + (setq-local indent-line-function #'gpr-ts-mode--indent-line)) |
943 | 1024 |
|
944 | 1025 | ;;;###autoload
|
945 | 1026 | (progn
|
|
0 commit comments