[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/csharp-mode 3cff337 411/459: Merge pull request #204 fr
From: |
ELPA Syncer |
Subject: |
[elpa] externals/csharp-mode 3cff337 411/459: Merge pull request #204 from emacs-csharp/tree-sitter |
Date: |
Sun, 22 Aug 2021 14:00:12 -0400 (EDT) |
branch: externals/csharp-mode
commit 3cff337b41f39eebe77185d8f07dcd1db2f2c405
Merge: 76bbf26 00a3cd4
Author: Theodor Thornhill <theo@thornhill.no>
Commit: GitHub <noreply@github.com>
Merge pull request #204 from emacs-csharp/tree-sitter
Tree sitter support for csharp mode
---
README.org | 26 +++-
csharp-tree-sitter.el | 291 ++++++++++++++++++++++++++++++++++++++++
test-files/indentation-tests.cs | 2 -
3 files changed, 311 insertions(+), 8 deletions(-)
diff --git a/README.org b/README.org
index 4b9fcb9..4e82552 100644
--- a/README.org
+++ b/README.org
@@ -4,8 +4,7 @@
* csharp-mode
-This is a mode for editing C# in emacs. It's based on cc-mode, v5.30.3 and
above.
-
+This is a mode for editing C# in emacs. It's using
[[https://github.com/ubolonton/emacs-tree-sitter][tree-sitter]] for
highlighting and indentation.
** Main features
- font-lock and indent of C# syntax including:
@@ -17,11 +16,26 @@ This is a mode for editing C# in emacs. It's based on
cc-mode, v5.30.3 and above
- anonymous functions and methods
- verbatim literal strings (those that begin with @)
- generics
-- automagic code-doc generation when you type three slashes.
- intelligent insertion of matched pairs of curly braces.
-- imenu indexing of C# source, for easy menu-based navigation.
- compilation-mode support for msbuild, devenv and xbuild.
+** tree-sitter support
+You can enable experimental tree sitter support for indentation and
highlighting using
+#+begin_src elisp
+ (use-package tree-sitter)
+ (use-package tree-sitter-langs)
+
+ (use-package csharp-mode
+ :straight
+ (csharp-mode :type git
+ :host github
+ :repo "emacs-csharp/csharp-mode"
+ :branch "tree-sitter")
+ :config
+ (add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-tree-sitter-mode)))
+#+end_src
+If you are using this, clearly state so if you find any issues.
+
** Usage
This package is currently available on MELPA. Install using ~M-x
@@ -44,10 +58,10 @@ To do so, add the following to your .emacs-file:
(add-hook 'csharp-mode-hook 'my-csharp-mode-hook)
#+END_SRC
-For further mode-specific customization, ~M-x customize-group RET csharp RET~
will show available settings with documentation. For configuring ~cc-mode~
settings (which csharp-mode derives from) see the
[[https://www.gnu.org/software/emacs/manual/html_mono/ccmode.html][cc-mode
manual]].
+For further mode-specific customization, ~M-x customize-group RET csharp RET~
will show available settings with documentation.
For more advanced and IDE-like functionality we recommend using csharp-mode
together
-with [[https://github.com/OmniSharp/omnisharp-emacs][Omnisharp-Emacs]].
+with [[https://github.com/emacs-lsp/lsp-mode][lsp-mode]] or
[[https://github.com/joaotavora/eglot][eglot]]
* Attribution
diff --git a/csharp-tree-sitter.el b/csharp-tree-sitter.el
new file mode 100644
index 0000000..90f633a
--- /dev/null
+++ b/csharp-tree-sitter.el
@@ -0,0 +1,291 @@
+;;; csharp-tree-sitter.el --- tree sitter support for C# -*- lexical-binding:
t; -*-
+
+;; Author : Theodor Thornhill <theo@thornhill.no>
+;; Maintainer : Jostein Kjønigsen <jostein@gmail.com>
+;; : Theodor Thornhill <theo@thornhill.no>
+;; Created : September 2020
+;; Modified : 2020
+;; Version : 0.10.0
+;; Keywords : c# languages oop mode
+;; X-URL : https://github.com/emacs-csharp/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
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+;;; Code:
+(require 'cl-lib)
+(require 'seq)
+(require 'tree-sitter)
+(require 'tree-sitter-hl)
+(require 'tree-sitter-indent)
+
+;;; Tree-sitter
+
+(defvar-local csharp-mode-tree-sitter-patterns
+ [ ;; Various constructs
+ (comment) @comment
+ (modifier) @keyword
+ (this_expression) @keyword
+
+ ;; Literals
+ [(real_literal) (integer_literal)] @number
+ (null_literal) @constant
+ (boolean_literal) @constant
+ (character_literal) @string
+
+ ;; Keywords
+ ["using" "namespace" "class" "if" "else" "throw" "new" "for"
+ "return" "await" "struct" "enum" "switch" "case"
+ "default" "typeof" "try" "catch" "finally" "break"
+ "foreach" "in" "yield" "get" "set" "when" "as" "out"
+ "is" "while" "continue" "this" "ref" "goto" "interface"
+ "from" "where" "select"
+ ] @keyword
+
+ ;; Linq
+ (from_clause (identifier) @variable)
+ (group_clause)
+ (order_by_clause)
+ (select_clause (identifier) @variable)
+ (query_continuation (identifier) @variable) @keyword
+
+ ;; String
+ (interpolation (identifier) (interpolation_format_clause) @variable)
+ (interpolation (identifier)* @variable)
+ [(string_literal) (verbatim_string_literal)
(interpolated_string_expression)] @string
+
+ ;; Enum
+ (enum_member_declaration (identifier) @variable)
+ (enum_declaration (identifier) @type)
+
+ ;; Interface
+ (interface_declaration
+ name: (identifier) @type)
+
+ ;; Struct
+ (struct_declaration (identifier) @type)
+
+ ;; Namespace
+ (namespace_declaration
+ name: (identifier) @type)
+
+ ;; Class
+ (base_list (identifier) @type)
+ (property_declaration
+ type: (nullable_type) @type
+ name: (identifier) @variable)
+ (property_declaration
+ type: (predefined_type) @type
+ name: (identifier) @variable)
+ (property_declaration
+ type: (identifier) @type
+ name: (identifier) @variable)
+ (class_declaration
+ name: (identifier) @type)
+ (constructor_declaration (identifier) @type)
+
+ ;; Method
+ (method_declaration (identifier) @type (identifier) @function)
+ (method_declaration (predefined_type) @type (identifier) @function)
+ (method_declaration (nullable_type) @type (identifier) @function)
+ (method_declaration (void_keyword) @type (identifier) @function)
+ (method_declaration (generic_name) (identifier) @function)
+
+ ;; Function
+ (local_function_statement (identifier) @type (identifier) @function)
+ (local_function_statement (predefined_type) @type (identifier) @function)
+ (local_function_statement (nullable_type) @type (identifier) @function)
+ (local_function_statement (void_keyword) @type (identifier) @function)
+ (local_function_statement (generic_name) (identifier) @function)
+
+ ;; Parameter
+ (parameter
+ type: (identifier) @type
+ name: (identifier) @variable)
+ (parameter (identifier) @variable)
+
+ ;; Array
+ (array_rank_specifier (identifier) @variable)
+ (array_type (identifier) @type)
+ (array_creation_expression)
+
+ ;; Attribute
+ (attribute (identifier) @variable (attribute_argument_list))
+ (attribute (identifier) @variable)
+
+ ;; Object init
+ (anonymous_object_creation_expression)
+ (object_creation_expression (identifier) @type)
+ (initializer_expression (identifier) @variable)
+
+ ;; Variable
+ (variable_declaration (identifier) @type)
+ (variable_declarator (identifier) @variable)
+
+ ;; Equals value
+ (equals_value_clause (identifier) @variable)
+
+ ;; Return
+ (return_statement (identifier) @variable)
+ (yield_statement (identifier) @variable)
+
+ ;; Type
+ (type_parameter
+ (identifier) @type)
+ (type_argument_list
+ (identifier) @type)
+ (generic_name
+ (identifier) @type)
+ (implicit_type) @type
+ (predefined_type) @type
+ (nullable_type) @type
+ ["operator"] @type
+
+ ;; Exprs
+ (binary_expression (identifier) @variable (identifier) @variable)
+ (binary_expression (identifier)* @variable)
+ (conditional_expression (identifier) @variable)
+ (prefix_unary_expression (identifier)* @variable)
+ (postfix_unary_expression (identifier)* @variable)
+ (type_of_expression (identifier) @variable)
+ (assignment_expression (identifier) @variable)
+ (cast_expression (identifier) @type)
+
+ ;; Preprocessor
+ (preprocessor_directive) @constant
+ (preprocessor_call (identifier) @string)
+
+ ;; Loop
+ (for_each_statement (identifier) @type (identifier) @variable)
+ (for_each_statement (implicit_type) @type (identifier) @variable)
+ (for_each_statement (predefined_type) @type (identifier) @variable)
+
+ ;; Exception
+ (catch_declaration (identifier) @type (identifier) @variable)
+ (catch_declaration (identifier) @type)
+
+ ;; Switch
+ (switch_statement (identifier) @variable)
+ (switch_expression (identifier) @variable)
+
+ ;; If
+ (if_statement (identifier) @variable)
+
+ ;; Declaration expression
+ (declaration_expression (implicit_type) (identifier) @variable)
+
+ ;; Arrow expression
+ (arrow_expression_clause (identifier) @variable)
+
+ ;; Other
+ (label_name) @variable
+ (qualified_name (identifier) @type)
+ (using_directive (identifier)* @type)
+ (await_expression (identifier)* @function)
+ (invocation_expression (identifier) @function)
+ (element_access_expression (identifier) @variable)
+ (conditional_access_expression (identifier) @variable)
+ (member_binding_expression (identifier) @variable)
+ (member_access_expression (identifier) @function)
+ (name_colon (identifier)* @variable)
+ (name_equals (identifier) @type)
+ (field_declaration)
+ (argument (identifier) @variable)
+ ]
+ "Default patterns for tree-sitter support.")
+
+;;; Tree-sitter indentation
+
+(defgroup csharp-mode-indent nil "Indent lines using Tree-sitter as backend"
+ :group 'tree-sitter)
+
+(defcustom csharp-mode-indent-offset 4
+ "Indent offset for csharp-mode"
+ :type 'integer
+ :group 'csharp)
+
+(defvar csharp-mode-indent-scopes
+ '((indent-all . ;; these nodes are always indented
+ (accessor_declaration
+ break_statement
+ arrow_expression_clause
+ parameter_list
+ conditional_expression
+ "."))
+ (indent-rest . ;; if parent node is one of these and node is not first →
indent
+ (
+ binary_expression
+ switch_section
+ ))
+ (indent-body . ;; if parent node is one of these and current node is in
middle → indent
+ (block
+ anonymous_object_creation_expression
+ enum_member_declaration_list
+ initializer_expression
+ expression_statement
+ declaration_list
+ attribute_argument_list
+ switch_body))
+
+ (paren-indent . ;; if parent node is one of these → indent to paren opener
+ (parenthesized_expression))
+ (align-char-to . ;; chaining char → node types we move parentwise to find
the first chaining char
+ ())
+ (aligned-siblings . ;; siblings (nodes with same parent) should be aligned
to the first child
+ (parameter))
+
+ (multi-line-text . ;; if node is one of these, then don't modify the indent
+ ;; this is basically a peaceful way out by saying "this
looks like something
+ ;; that cannot be indented using AST, so best I leave it
as-is"
+ (comment
+ preprocessor_call
+ labeled_statement))
+ (outdent . ;; these nodes always outdent (1 shift in opposite direction)
+ (;; "}"
+ case_switch_label
+ ))
+ )
+ "Scopes for indenting in C#.")
+
+;;;###autoload
+(define-derived-mode csharp-tree-sitter-mode prog-mode "C#"
+ "Major mode for editing Csharp code.
+
+Key bindings:
+\\{csharp-mode-map}"
+ :group 'csharp
+
+ (setq csharp-mode-syntax-table nil)
+ (setq csharp-mode-map nil)
+ (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
+ (setq font-lock-defaults '(nil)))
+ (setq-local tree-sitter-hl-default-patterns csharp-mode-tree-sitter-patterns)
+ ;; Comments
+ (setq-local comment-start "// ")
+ (setq-local comment-end "")
+
+ (tree-sitter-hl-mode))
+
+;;;###autoload
+(add-to-list 'tree-sitter-major-mode-language-alist '(csharp-tree-sitter-mode
. c-sharp))
+
+(provide 'csharp-tree-sitter)
+
+;;; csharp-tree-sitter.el ends here
diff --git a/test-files/indentation-tests.cs b/test-files/indentation-tests.cs
index e0355f9..650ac1e 100644
--- a/test-files/indentation-tests.cs
+++ b/test-files/indentation-tests.cs
@@ -119,7 +119,6 @@ namespace Boo
PropB = 2
};
- // Commented out for rework -- Theodor Thornhill
// yield return new InnerA.InnerB {
// PropA = 1,
// PropB = 2
@@ -131,7 +130,6 @@ namespace Boo
May = "Yay"
};
- // Commented out for rework -- Theodor Thornhill
// yield return new InnerA.InnerB
// {
// Boo = "Foo",
- [elpa] externals/csharp-mode e30ed5e 393/459: Indent feature parity with previous implementation, (continued)
- [elpa] externals/csharp-mode e30ed5e 393/459: Indent feature parity with previous implementation, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 45d1e9f 395/459: These are passing again, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 5a3d4a9 396/459: More indentation fixes, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 0b1df32 398/459: Add tree-sitter as optional feature, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode f0b5efa 403/459: Use code with same arrangement as before rework, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 53fa8f1 404/459: Use dedicated major mode for tree-sitter, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode ea1718e 405/459: Use defvar instead of defcustom for indentation rules, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 5ddb761 406/459: Fix url and indentation., ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 76bbf26 408/459: Merge pull request #206 from jcs-PR/minor, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode f937426 409/459: Merge branch 'master' into tree-sitter, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 3cff337 411/459: Merge pull request #204 from emacs-csharp/tree-sitter,
ELPA Syncer <=
- [elpa] externals/csharp-mode 4947497 412/459: Update readme to reflect tree-sitter in master, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 064f481 418/459: Fix autoload for tree-sitter support (#211), ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 1de6556 422/459: Add base_list, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 1d02a54 424/459: Records and init-only fields, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 7d4af0d 425/459: Add with_expression, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 98a179a 427/459: Add dependencies to csharp-mode, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 6b232b1 429/459: Much better support for strings, interpolated in particular, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode c928423 435/459: Add generic property name, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode d272272 436/459: Add let keyword, ELPA Syncer, 2021/08/22
- [elpa] externals/csharp-mode 43e5919 438/459: Prevent c-default-style error when set to string (#202), ELPA Syncer, 2021/08/22