[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/csharp-mode 1e37eaf 407/459: Add dependency to tree-sit
From: |
ELPA Syncer |
Subject: |
[elpa] externals/csharp-mode 1e37eaf 407/459: Add dependency to tree-sitter-indent |
Date: |
Sun, 22 Aug 2021 14:00:11 -0400 (EDT) |
branch: externals/csharp-mode
commit 1e37eaf0d641ba1e5cbc6d187e5165ebbcd9727a
Author: Theodor Thornhill <theo@thornhill.no>
Commit: Theodor Thornhill <theo@thornhill.no>
Add dependency to tree-sitter-indent
---
csharp-tree-sitter.el | 379 +-------------------------------------------------
1 file changed, 5 insertions(+), 374 deletions(-)
diff --git a/csharp-tree-sitter.el b/csharp-tree-sitter.el
index f50a2f3..c050674 100644
--- a/csharp-tree-sitter.el
+++ b/csharp-tree-sitter.el
@@ -8,6 +8,7 @@
;; Version : 0.10.0
;; Keywords : c# languages oop mode
;; X-URL : https://github.com/josteink/csharp-mode
+;; Package-Requires: ((emacs "26.1") (tree-sitter "0.12.1")
(tree-sitter-indent "0.1"))
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
@@ -28,7 +29,7 @@
(require 'seq)
(require 'tree-sitter)
(require 'tree-sitter-hl)
-
+(require 'tree-sitter-indent)
;;; Tree-sitter
@@ -258,377 +259,6 @@
)
"Scopes for indenting in C#.")
-;;;; Private functions
-(defun csharp-mode-indent--node-is-indent-all (node)
- "Non-nil if NODE type is in indent-all group.
-
-Nodes in this group will be always +1 indentend."
- (let-alist csharp-mode-indent-scopes
- (member (tsc-node-type node)
- .indent-all)))
-
-(defun csharp-mode-indent--node-is-indent-rest (node)
- "Non-nil if NODE type is in indent-rest group.
-
-Nodes in this group will +1 indentend if they are a non-first
-child of parent node."
- (let-alist csharp-mode-indent-scopes
- (member (tsc-node-type node)
- .indent-rest)))
-
-(defun csharp-mode-indent--node-is-indent-body (node)
- "Non-nil if NODE type is in indent-body group.
-
-Nodes in this group will +1 indentend if they are both a
-non-first child of and non-last child of parent node."
- (let-alist csharp-mode-indent-scopes
- (member (tsc-node-type node)
- .indent-body)))
-
-(defun csharp-mode-indent--node-is-multi-line-text (node)
- "Non-nil if NODE type is in indent-rest group.
-
-Nodes in this group will keep their current indentation"
- (let-alist csharp-mode-indent-scopes
- (member (tsc-node-type node)
- .multi-line-text)))
-
-(defun csharp-mode-indent--node-is-aligned-sibling (node)
- "Non-nil if NODE type is in aligned-siblings group.
-
-Nodes in this group will be aligned to the column of the first sibling."
- (let-alist csharp-mode-indent-scopes
- (member (tsc-node-type node)
- .aligned-siblings)))
-
-(defun csharp-mode-indent--highest-node-at-position (position)
- "Get the node at buffer POSITION that's at the highest level.
-
-POSITION is a byte position in buffer like \\(point-min\\)."
- (save-excursion
- (goto-char position)
- ;; maybe implement this as a cl-loop
- (let* ((current-node (tree-sitter-node-at-point)))
- ;; move upwards until we either don't have aparent node
- ;; or we moved out of line
- (while (and
- current-node
- (when-let* ((parent-node (tsc-get-parent current-node)))
- (when (and ;; parent and current share same position
- (eq (tsc-node-start-byte parent-node)
- (tsc-node-start-byte current-node)))
- ;; move upwards to the parent node
- (setq current-node parent-node)))))
- current-node)))
-
-(defun csharp-mode-indent--parentwise-path (node)
- "Get list of nodes by moving parent-wise starting at NODE.
-
-The last element in returned path is NODE."
- (let ((next-parent-node (tsc-get-parent node))
- (path
- (list node)))
- (while next-parent-node
- ;; collect
- (push next-parent-node path)
- ;; move to next iteration
- (setq next-parent-node (tsc-get-parent next-parent-node)))
- path))
-
-(defun csharp-mode-indent--node-is-paren-indent (node)
- "Non-nil if NODE type is in paren-indent group.
-
-Child nodes in this group will be indentend to the paren opener
-column."
- (let-alist csharp-mode-indent-scopes
- (member (tsc-node-type node)
- .paren-indent)))
-
-(defun csharp-mode-indent--chain-column (current-node align-char-to-alist
parentwise-path)
- "When node is in a chain call, return column to align each call.
-
-CURRENT-NODE current node being indented
-ALIGN-CHAR-TO-ALIST char → group of node types we can move within when
searching
-for the first chain char.
-This group is supposed to contain all node types conformed by a chain.
-PARENTWISE-PATH nodes from CURRENT-NODE to tree root (\"document\")
-
-Returns a column to indent to or nil if no such column can / should be applied.
-
-Reads text from current buffer."
- (let ((first-character-for-current-node
- (string-to-char
- (tsc-node-text current-node))))
- (when-let* ((last-parent-belongs-to
- (alist-get first-character-for-current-node
- align-char-to-alist))
- (last-parent-belonging-to
- (thread-last parentwise-path
- (reverse) ;; path starts at (ts-parent current-node)
- (cdr) ;; skip current-node
- ;; walk within allowed boundaries
- (seq-take-while
- (lambda (node)
- (member (tsc-node-type node)
- last-parent-belongs-to)))
- (seq-first)))
- (first-char-position-within-last-parent-node
- ;; naive search, could be updated later
- ;; this may detect wrong column-char with something like
⎡a(should().ignore().this)\n.b()\n.c()⎦
- (save-excursion
- (goto-char
- (tsc-node-start-byte last-parent-belonging-to))
- (search-forward-regexp
- (regexp-quote
- (char-to-string
- first-character-for-current-node))
- (tsc-node-end-byte current-node)
- t)
- (- (point) 1)))
- (end-of-parent-line-pos
- (save-excursion
- (goto-char
- (tsc-node-start-byte last-parent-belonging-to))
- (line-end-position))))
- (when (and (numberp first-char-position-within-last-parent-node)
- ;; char is within parent line
- (or (< first-char-position-within-last-parent-node
- end-of-parent-line-pos)
- ;; char is the first in its line
- (eq first-char-position-within-last-parent-node
- (save-excursion
- (goto-char
- first-char-position-within-last-parent-node)
- (back-to-indentation)
- (point)))))
- ;; indent to column, which is (char-pos - line-begin-pos)
- (save-excursion
- (goto-char first-char-position-within-last-parent-node)
- (- first-char-position-within-last-parent-node
- (line-beginning-position)))))))
-
-(defun csharp-mode-indent--first-sibling-column (current-node parent-node)
- "Column position for CURRENT-NODE's first sibling.
-
-If CURRENT-NODE belongs to the aligned-siblings group, will look up the first
-sibling in same group \\(running through PARENT-NODE's children) and return
-its column.
-
-CSHARP-MODE-INDENT-SCOPES is used to test whether
-CURRENT-NODE belongs to the aligned-siblings group."
- (when (and parent-node
- (csharp-mode-indent--node-is-aligned-sibling current-node))
- (when-let* ((current-node-type
- (tsc-node-type current-node))
- (first-sibling
- (cl-loop for ith-sibling = (tsc-get-nth-child parent-node 0)
- then (tsc-get-next-sibling ith-sibling)
- while (not (null ith-sibling))
- if (equal current-node-type
- (tsc-node-type ith-sibling))
- return ith-sibling
- end))
- (first-sibling-position
- (tsc-node-start-byte first-sibling)))
- (when (not (tsc-node-eq current-node first-sibling))
- (save-excursion
- (goto-char first-sibling-position)
- (- first-sibling-position
- (line-beginning-position)))))))
-
-(cl-defun csharp-mode-indent--indents-in-path (parentwise-path original-column)
- "Map PARENTWISE-PATH into indent instructions.
-
-Each element of the returned list is one of the following
-
-no-indent nothing to add to current column
-indent add one indent to current column
-outdent subtract one indent to current column
-\(column-indent . COLUMN) match parent's parent opener column
-\(preserve . ORIGINAL-COLUMN) preserve the column that was before
-
-What is checked to add an indent:
-- A node bolongs into the \"indent\" group in CSHARP-MODE-INDENT-SCOPES
-- Deterimen what group the node's parent belongs to, and whether the node
-is in a middle position.
-- A node belongs to the \"outdent\" group in CSHARP-MODE-INDENT-SCOPES
-- A node belongs to the \"column-indent\" group in CSHARP-MODE-INDENT-SCOPES"
- (let ((last-node
- (seq-elt
- parentwise-path
- (-
- (length parentwise-path)
- 1))))
- (thread-last parentwise-path
- (seq-map
- (lambda (current-node)
- (let* ((previous-node
- (tsc-get-prev-sibling current-node))
- (next-node
- (tsc-get-next-sibling current-node))
- (parent-node
- (tsc-get-parent current-node))
- (current-node-is-rest
- previous-node)
- (current-node-is-middle-node
- (and current-node-is-rest next-node))
- (current-node-must-indent
- (csharp-mode-indent--node-is-indent-all current-node))
- (current-node-must-outdent
- (and
- (eq last-node current-node)
- (csharp-mode-indent--node-is-outdent current-node)))
- (chain-column
- (csharp-mode-indent--chain-column
- current-node
- (let-alist csharp-mode-indent-scopes
- .align-char-to)
- parentwise-path))
- (sibling-column
- (csharp-mode-indent--first-sibling-column
- current-node
- parent-node)))
- (cond
- ((numberp chain-column)
- `(column-indent ,chain-column))
- ((numberp sibling-column)
- `(column-indent ,sibling-column))
- ((csharp-mode-indent--node-is-multi-line-text current-node)
- `(preserve . ,original-column))
- ((and parent-node
- (csharp-mode-indent--node-is-paren-indent parent-node))
- (let* ((paren-opener
- (tsc-node-start-byte parent-node))
- (paren-point
- (save-excursion
- (goto-char paren-opener)
- (point)))
- (beginning-of-line-point
- (save-excursion
- (goto-char paren-opener)
- (beginning-of-line 1)
- (point)))
- (paren-indenting-column
- (+ 1
- (- paren-point beginning-of-line-point))))
- `(column-indent ,paren-indenting-column)))
-
- ((or current-node-must-indent
- (and parent-node
- current-node-is-rest
- (csharp-mode-indent--node-is-indent-rest parent-node))
- (and parent-node
- current-node-is-middle-node
- (csharp-mode-indent--node-is-indent-body parent-node)))
- (if current-node-must-outdent
- 'no-indent ;; if it's an outdent, cancel
- 'indent))
- (current-node-must-outdent
- 'outdent)
- (t
- 'no-indent))))))))
-
-(defun csharp-mode-indent--node-is-outdent (node)
- "Return non-nil if NODE outdents per SCOPES.
-
-NODE is tested if it belongs into the \"outdent\" group in SCOPES."
- (let-alist csharp-mode-indent-scopes
- (member (tsc-node-type node)
- .outdent)))
-
-(defun csharp-mode-indent--updated-column (column indent)
- "Return COLUMN after added indent instructions per INDENT.
-
-INDENT is one of `csharp-mode-indent--indents-in-path'.
-
-If \"1 indent\" is to be applied, then returned value is
-CSHARP-MODE-INDENT-OFFSET + INDENT."
- (pcase indent
- (`no-indent
- column)
- (`indent
- (+ column csharp-mode-indent-offset))
- (`outdent
- (- column csharp-mode-indent-offset))
- (`(column-indent ,paren-column)
- paren-column)
- (`(preserve . ,original-column)
- original-column)
- (_
- (error "Unexpected indent instruction: %s" indent))))
-
-(cl-defun csharp-mode-indent--indent-column (original-column)
- "Return the column the first non-whitespace char at POSITION should indent
to.
-
-Collect indent instruction per AST with
-`csharp-mode-indent--indents-in-path', then apply instructions
-with `csharp-mode-indent--updated-column' using
-CSHARP-MODE-INDENT-OFFSET as step.
-
-See `csharp-mode-indent-line'. ORIGINAL-COLUMN is forwarded to
-`csharp-mode-indent--indents-in-path'"
- (let* ((indenting-node
- (csharp-mode-indent--highest-node-at-position
- (save-excursion
- (back-to-indentation)
- (point))))
- (parentwise-path (csharp-mode-indent--parentwise-path indenting-node))
- (indents-in-path
- (csharp-mode-indent--indents-in-path parentwise-path
- original-column)))
- (seq-reduce #'csharp-mode-indent--updated-column
- indents-in-path
- 0 ;; start at column 0
- )))
-
-;;;; Public API
-
-;;;###autoload
-(defun csharp-mode-indent-line ()
- "Use Tree-sitter as backend to indent current line."
- ;;Use in buffer like so:
-
- ;; (setq-local indent-line-function #'csharp-mode-indent-line).
- (let* ((original-position
- (point))
- (first-non-blank-pos ;; see savep in `smie-indent-line'
- (save-excursion
- (forward-line 0)
- (skip-chars-forward " \t")
- (point)))
- (should-save-excursion
- (< first-non-blank-pos original-position))
- (original-column
- (abs (- (line-beginning-position)
- first-non-blank-pos)))
- (new-column
- (csharp-mode-indent--indent-column original-column)))
- (when (numberp new-column)
- (if should-save-excursion
- (save-excursion (indent-line-to new-column))
- (indent-line-to new-column)))))
-
-(defun csharp-mode-indent-line-and-debug ()
- "Call `csharp-mode-indent-line' while printing useful info."
- (let* ((line-str (thing-at-point 'line))
- (position (point))
- (indenting-node (csharp-mode-indent--highest-node-at-position
- position))
- (parentwise-path (csharp-mode-indent--parentwise-path indenting-node))
- (readable-parentwise-path
- (seq-map 'tsc-node-type parentwise-path))
- (tree-sitter-tree-before (tsc-tree-to-sexp tree-sitter-tree))
- (column
- (csharp-mode-indent-line)))
- (message "csharp-mode-indent: Indented ⎡%s⎦ to ⎡%s⎦ (col %s) because of
parentwise path of ⎡%s⎦ (while looking at ⎡%s⎦ & when tree is ⎡%s⎦)"
- line-str
- (thing-at-point 'line)
- column
- readable-parentwise-path
- (tsc-node-type indenting-node)
- tree-sitter-tree-before)))
-
-
;;;###autoload
(define-derived-mode csharp-tree-sitter-mode prog-mode "C#"
"Major mode for editing Csharp code.
@@ -639,8 +269,9 @@ Key bindings:
(setq csharp-mode-syntax-table nil)
(setq csharp-mode-map nil)
- (require 'csharp-tree-sitter)
- (setq-local indent-line-function #'csharp-mode-indent-line)
+ (setq-local tree-sitter-indent-current-scopes csharp-mode-indent-scopes)
+ (setq-local tree-sitter-indent-offset csharp-mode-indent-offset)
+ (setq-local indent-line-function #'tree-sitter-indent-line)
;; https://github.com/ubolonton/emacs-tree-sitter/issues/84
(unless font-lock-defaults
- [elpa] externals/csharp-mode 323a028 388/459: More cleaning, (continued)
- [elpa] externals/csharp-mode 323a028 388/459: More cleaning, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 84a5daa 389/459: Should not need to autoload c_sharp, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 4651004 391/459: Hassle with the defcustoms, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 5ac7484 392/459: Add back better support for interfaces, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 4eef364 394/459: Absorb tree-sitter-indent, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 8fdeedf 397/459: Indentation tweaking, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 3d0b60c 399/459: Add a little documentation, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 0de2bbc 400/459: Fix byte compilation errors, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 5730c99 401/459: Split functionality to two files, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 4eeccbd 402/459: Remove newly added tests, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 1e37eaf 407/459: Add dependency to tree-sitter-indent,
ELPA Syncer <=
- [elpa] externals/csharp-mode 00a3cd4 410/459: Add new url to csharp-tree-sitter.el, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 91d5161 414/459: Minor fix after version 0.11.0 (#209), ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 8466428 413/459: Version bump to 0.11.0, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 84ff0d0 415/459: Typo from PR-209., ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 74644d4 416/459: Merge pull request #210 from emacs-csharp/minor, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode d3b5b18 419/459: Ensure langs package for tree-sitter support (#214), ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode da26eb6 420/459: Add mode map and syntax table to tree-sitter, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode a402402 421/459: Add lock_statement, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode cb1b16f 417/459: Add some more documentation on tree-sitter support, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode cd39e53 423/459: Extract compilation support to its own module (#223), ELPA Syncer, 2021/08/22